ActivityManagerService.java revision 497175beffe26336c092ee11a67b90f79dcdaca7
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 20import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21import static com.android.internal.util.XmlUtils.readBooleanAttribute; 22import static com.android.internal.util.XmlUtils.readIntAttribute; 23import static com.android.internal.util.XmlUtils.readLongAttribute; 24import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 25import static com.android.internal.util.XmlUtils.writeIntAttribute; 26import static com.android.internal.util.XmlUtils.writeLongAttribute; 27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 29import static org.xmlpull.v1.XmlPullParser.START_TAG; 30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 31 32import android.Manifest; 33import android.app.AppOpsManager; 34import android.app.IActivityContainer; 35import android.app.IActivityContainerCallback; 36import android.app.IAppTask; 37import android.app.admin.DevicePolicyManager; 38import android.appwidget.AppWidgetManager; 39import android.graphics.Rect; 40import android.os.BatteryStats; 41import android.os.PersistableBundle; 42import android.service.voice.IVoiceInteractionSession; 43import android.util.ArrayMap; 44 45import com.android.internal.R; 46import com.android.internal.annotations.GuardedBy; 47import com.android.internal.app.IAppOpsService; 48import com.android.internal.app.IVoiceInteractor; 49import com.android.internal.app.ProcessMap; 50import com.android.internal.app.ProcessStats; 51import com.android.internal.content.PackageMonitor; 52import com.android.internal.os.BackgroundThread; 53import com.android.internal.os.BatteryStatsImpl; 54import com.android.internal.os.ProcessCpuTracker; 55import com.android.internal.os.TransferPipe; 56import com.android.internal.os.Zygote; 57import com.android.internal.util.FastPrintWriter; 58import com.android.internal.util.FastXmlSerializer; 59import com.android.internal.util.MemInfoReader; 60import com.android.internal.util.Preconditions; 61import com.android.server.AppOpsService; 62import com.android.server.AttributeCache; 63import com.android.server.IntentResolver; 64import com.android.server.LocalServices; 65import com.android.server.ServiceThread; 66import com.android.server.SystemService; 67import com.android.server.SystemServiceManager; 68import com.android.server.Watchdog; 69import com.android.server.am.ActivityStack.ActivityState; 70import com.android.server.firewall.IntentFirewall; 71import com.android.server.pm.UserManagerService; 72import com.android.server.wm.AppTransition; 73import com.android.server.wm.WindowManagerService; 74import com.google.android.collect.Lists; 75import com.google.android.collect.Maps; 76 77import libcore.io.IoUtils; 78 79import org.xmlpull.v1.XmlPullParser; 80import org.xmlpull.v1.XmlPullParserException; 81import org.xmlpull.v1.XmlSerializer; 82 83import android.app.Activity; 84import android.app.ActivityManager; 85import android.app.ActivityManager.RunningTaskInfo; 86import android.app.ActivityManager.StackInfo; 87import android.app.ActivityManagerInternal; 88import android.app.ActivityManagerNative; 89import android.app.ActivityOptions; 90import android.app.ActivityThread; 91import android.app.AlertDialog; 92import android.app.AppGlobals; 93import android.app.ApplicationErrorReport; 94import android.app.Dialog; 95import android.app.IActivityController; 96import android.app.IApplicationThread; 97import android.app.IInstrumentationWatcher; 98import android.app.INotificationManager; 99import android.app.IProcessObserver; 100import android.app.IServiceConnection; 101import android.app.IStopUserCallback; 102import android.app.IUiAutomationConnection; 103import android.app.IUserSwitchObserver; 104import android.app.Instrumentation; 105import android.app.Notification; 106import android.app.NotificationManager; 107import android.app.PendingIntent; 108import android.app.backup.IBackupManager; 109import android.content.ActivityNotFoundException; 110import android.content.BroadcastReceiver; 111import android.content.ClipData; 112import android.content.ComponentCallbacks2; 113import android.content.ComponentName; 114import android.content.ContentProvider; 115import android.content.ContentResolver; 116import android.content.Context; 117import android.content.DialogInterface; 118import android.content.IContentProvider; 119import android.content.IIntentReceiver; 120import android.content.IIntentSender; 121import android.content.Intent; 122import android.content.IntentFilter; 123import android.content.IntentSender; 124import android.content.pm.ActivityInfo; 125import android.content.pm.ApplicationInfo; 126import android.content.pm.ConfigurationInfo; 127import android.content.pm.IPackageDataObserver; 128import android.content.pm.IPackageManager; 129import android.content.pm.InstrumentationInfo; 130import android.content.pm.PackageInfo; 131import android.content.pm.PackageManager; 132import android.content.pm.ParceledListSlice; 133import android.content.pm.UserInfo; 134import android.content.pm.PackageManager.NameNotFoundException; 135import android.content.pm.PathPermission; 136import android.content.pm.ProviderInfo; 137import android.content.pm.ResolveInfo; 138import android.content.pm.ServiceInfo; 139import android.content.res.CompatibilityInfo; 140import android.content.res.Configuration; 141import android.graphics.Bitmap; 142import android.net.Proxy; 143import android.net.ProxyInfo; 144import android.net.Uri; 145import android.os.Binder; 146import android.os.Build; 147import android.os.Bundle; 148import android.os.Debug; 149import android.os.DropBoxManager; 150import android.os.Environment; 151import android.os.FactoryTest; 152import android.os.FileObserver; 153import android.os.FileUtils; 154import android.os.Handler; 155import android.os.IBinder; 156import android.os.IPermissionController; 157import android.os.IRemoteCallback; 158import android.os.IUserManager; 159import android.os.Looper; 160import android.os.Message; 161import android.os.Parcel; 162import android.os.ParcelFileDescriptor; 163import android.os.Process; 164import android.os.RemoteCallbackList; 165import android.os.RemoteException; 166import android.os.SELinux; 167import android.os.ServiceManager; 168import android.os.StrictMode; 169import android.os.SystemClock; 170import android.os.SystemProperties; 171import android.os.UpdateLock; 172import android.os.UserHandle; 173import android.provider.Settings; 174import android.text.format.DateUtils; 175import android.text.format.Time; 176import android.util.AtomicFile; 177import android.util.EventLog; 178import android.util.Log; 179import android.util.Pair; 180import android.util.PrintWriterPrinter; 181import android.util.Slog; 182import android.util.SparseArray; 183import android.util.TimeUtils; 184import android.util.Xml; 185import android.view.Gravity; 186import android.view.LayoutInflater; 187import android.view.View; 188import android.view.WindowManager; 189 190import java.io.BufferedInputStream; 191import java.io.BufferedOutputStream; 192import java.io.DataInputStream; 193import java.io.DataOutputStream; 194import java.io.File; 195import java.io.FileDescriptor; 196import java.io.FileInputStream; 197import java.io.FileNotFoundException; 198import java.io.FileOutputStream; 199import java.io.IOException; 200import java.io.InputStreamReader; 201import java.io.PrintWriter; 202import java.io.StringWriter; 203import java.lang.ref.WeakReference; 204import java.util.ArrayList; 205import java.util.Arrays; 206import java.util.Collections; 207import java.util.Comparator; 208import java.util.HashMap; 209import java.util.HashSet; 210import java.util.Iterator; 211import java.util.List; 212import java.util.Locale; 213import java.util.Map; 214import java.util.Set; 215import java.util.concurrent.atomic.AtomicBoolean; 216import java.util.concurrent.atomic.AtomicLong; 217 218public final class ActivityManagerService extends ActivityManagerNative 219 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 220 private static final String USER_DATA_DIR = "/data/user/"; 221 static final String TAG = "ActivityManager"; 222 static final String TAG_MU = "ActivityManagerServiceMU"; 223 static final boolean DEBUG = false; 224 static final boolean localLOGV = DEBUG; 225 static final boolean DEBUG_BACKUP = localLOGV || false; 226 static final boolean DEBUG_BROADCAST = localLOGV || false; 227 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 229 static final boolean DEBUG_CLEANUP = localLOGV || false; 230 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 231 static final boolean DEBUG_FOCUS = false; 232 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 233 static final boolean DEBUG_MU = localLOGV || false; 234 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 235 static final boolean DEBUG_LRU = localLOGV || false; 236 static final boolean DEBUG_PAUSE = localLOGV || false; 237 static final boolean DEBUG_POWER = localLOGV || false; 238 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 239 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 240 static final boolean DEBUG_PROCESSES = localLOGV || false; 241 static final boolean DEBUG_PROVIDER = localLOGV || false; 242 static final boolean DEBUG_RESULTS = localLOGV || false; 243 static final boolean DEBUG_SERVICE = localLOGV || false; 244 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 245 static final boolean DEBUG_STACK = localLOGV || false; 246 static final boolean DEBUG_SWITCH = localLOGV || false; 247 static final boolean DEBUG_TASKS = localLOGV || false; 248 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 249 static final boolean DEBUG_TRANSITION = localLOGV || false; 250 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 251 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 252 static final boolean DEBUG_VISBILITY = localLOGV || false; 253 static final boolean DEBUG_PSS = localLOGV || false; 254 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 255 static final boolean VALIDATE_TOKENS = false; 256 static final boolean SHOW_ACTIVITY_START_TIME = true; 257 258 // Control over CPU and battery monitoring. 259 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 260 static final boolean MONITOR_CPU_USAGE = true; 261 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 262 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 263 static final boolean MONITOR_THREAD_CPU_USAGE = false; 264 265 // The flags that are set for all calls we make to the package manager. 266 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 267 268 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 269 270 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 271 272 // Maximum number of recent tasks that we can remember. 273 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200; 274 275 // Amount of time after a call to stopAppSwitches() during which we will 276 // prevent further untrusted switches from happening. 277 static final long APP_SWITCH_DELAY_TIME = 5*1000; 278 279 // How long we wait for a launched process to attach to the activity manager 280 // before we decide it's never going to come up for real. 281 static final int PROC_START_TIMEOUT = 10*1000; 282 283 // How long we wait for a launched process to attach to the activity manager 284 // before we decide it's never going to come up for real, when the process was 285 // started with a wrapper for instrumentation (such as Valgrind) because it 286 // could take much longer than usual. 287 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 288 289 // How long to wait after going idle before forcing apps to GC. 290 static final int GC_TIMEOUT = 5*1000; 291 292 // The minimum amount of time between successive GC requests for a process. 293 static final int GC_MIN_INTERVAL = 60*1000; 294 295 // The minimum amount of time between successive PSS requests for a process. 296 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 297 298 // The minimum amount of time between successive PSS requests for a process 299 // when the request is due to the memory state being lowered. 300 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 301 302 // The rate at which we check for apps using excessive power -- 15 mins. 303 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 304 305 // The minimum sample duration we will allow before deciding we have 306 // enough data on wake locks to start killing things. 307 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 308 309 // The minimum sample duration we will allow before deciding we have 310 // enough data on CPU usage to start killing things. 311 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 312 313 // How long we allow a receiver to run before giving up on it. 314 static final int BROADCAST_FG_TIMEOUT = 10*1000; 315 static final int BROADCAST_BG_TIMEOUT = 60*1000; 316 317 // How long we wait until we timeout on key dispatching. 318 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 319 320 // How long we wait until we timeout on key dispatching during instrumentation. 321 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 322 323 // Amount of time we wait for observers to handle a user switch before 324 // giving up on them and unfreezing the screen. 325 static final int USER_SWITCH_TIMEOUT = 2*1000; 326 327 // Maximum number of users we allow to be running at a time. 328 static final int MAX_RUNNING_USERS = 3; 329 330 // How long to wait in getAssistContextExtras for the activity and foreground services 331 // to respond with the result. 332 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 333 334 // Maximum number of persisted Uri grants a package is allowed 335 static final int MAX_PERSISTED_URI_GRANTS = 128; 336 337 static final int MY_PID = Process.myPid(); 338 339 static final String[] EMPTY_STRING_ARRAY = new String[0]; 340 341 // How many bytes to write into the dropbox log before truncating 342 static final int DROPBOX_MAX_SIZE = 256 * 1024; 343 344 /** All system services */ 345 SystemServiceManager mSystemServiceManager; 346 347 /** Run all ActivityStacks through this */ 348 ActivityStackSupervisor mStackSupervisor; 349 350 public IntentFirewall mIntentFirewall; 351 352 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 353 // default actuion automatically. Important for devices without direct input 354 // devices. 355 private boolean mShowDialogs = true; 356 357 /** 358 * Description of a request to start a new activity, which has been held 359 * due to app switches being disabled. 360 */ 361 static class PendingActivityLaunch { 362 final ActivityRecord r; 363 final ActivityRecord sourceRecord; 364 final int startFlags; 365 final ActivityStack stack; 366 367 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 368 int _startFlags, ActivityStack _stack) { 369 r = _r; 370 sourceRecord = _sourceRecord; 371 startFlags = _startFlags; 372 stack = _stack; 373 } 374 } 375 376 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 377 = new ArrayList<PendingActivityLaunch>(); 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 415 public class PendingAssistExtras extends Binder implements Runnable { 416 public final ActivityRecord activity; 417 public boolean haveResult = false; 418 public Bundle result = null; 419 public PendingAssistExtras(ActivityRecord _activity) { 420 activity = _activity; 421 } 422 @Override 423 public void run() { 424 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 425 synchronized (this) { 426 haveResult = true; 427 notifyAll(); 428 } 429 } 430 } 431 432 final ArrayList<PendingAssistExtras> mPendingAssistExtras 433 = new ArrayList<PendingAssistExtras>(); 434 435 /** 436 * Process management. 437 */ 438 final ProcessList mProcessList = new ProcessList(); 439 440 /** 441 * All of the applications we currently have running organized by name. 442 * The keys are strings of the application package name (as 443 * returned by the package manager), and the keys are ApplicationRecord 444 * objects. 445 */ 446 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 447 448 /** 449 * Tracking long-term execution of processes to look for abuse and other 450 * bad app behavior. 451 */ 452 final ProcessStatsService mProcessStats; 453 454 /** 455 * The currently running isolated processes. 456 */ 457 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 458 459 /** 460 * Counter for assigning isolated process uids, to avoid frequently reusing the 461 * same ones. 462 */ 463 int mNextIsolatedProcessUid = 0; 464 465 /** 466 * The currently running heavy-weight process, if any. 467 */ 468 ProcessRecord mHeavyWeightProcess = null; 469 470 /** 471 * The last time that various processes have crashed. 472 */ 473 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 474 475 /** 476 * Information about a process that is currently marked as bad. 477 */ 478 static final class BadProcessInfo { 479 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 480 this.time = time; 481 this.shortMsg = shortMsg; 482 this.longMsg = longMsg; 483 this.stack = stack; 484 } 485 486 final long time; 487 final String shortMsg; 488 final String longMsg; 489 final String stack; 490 } 491 492 /** 493 * Set of applications that we consider to be bad, and will reject 494 * incoming broadcasts from (which the user has no control over). 495 * Processes are added to this set when they have crashed twice within 496 * a minimum amount of time; they are removed from it when they are 497 * later restarted (hopefully due to some user action). The value is the 498 * time it was added to the list. 499 */ 500 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 501 502 /** 503 * All of the processes we currently have running organized by pid. 504 * The keys are the pid running the application. 505 * 506 * <p>NOTE: This object is protected by its own lock, NOT the global 507 * activity manager lock! 508 */ 509 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 510 511 /** 512 * All of the processes that have been forced to be foreground. The key 513 * is the pid of the caller who requested it (we hold a death 514 * link on it). 515 */ 516 abstract class ForegroundToken implements IBinder.DeathRecipient { 517 int pid; 518 IBinder token; 519 } 520 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 521 522 /** 523 * List of records for processes that someone had tried to start before the 524 * system was ready. We don't start them at that point, but ensure they 525 * are started by the time booting is complete. 526 */ 527 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 528 529 /** 530 * List of persistent applications that are in the process 531 * of being started. 532 */ 533 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 534 535 /** 536 * Processes that are being forcibly torn down. 537 */ 538 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 539 540 /** 541 * List of running applications, sorted by recent usage. 542 * The first entry in the list is the least recently used. 543 */ 544 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 545 546 /** 547 * Where in mLruProcesses that the processes hosting activities start. 548 */ 549 int mLruProcessActivityStart = 0; 550 551 /** 552 * Where in mLruProcesses that the processes hosting services start. 553 * This is after (lower index) than mLruProcessesActivityStart. 554 */ 555 int mLruProcessServiceStart = 0; 556 557 /** 558 * List of processes that should gc as soon as things are idle. 559 */ 560 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Processes we want to collect PSS data from. 564 */ 565 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 566 567 /** 568 * Last time we requested PSS data of all processes. 569 */ 570 long mLastFullPssTime = SystemClock.uptimeMillis(); 571 572 /** 573 * If set, the next time we collect PSS data we should do a full collection 574 * with data from native processes and the kernel. 575 */ 576 boolean mFullPssPending = false; 577 578 /** 579 * This is the process holding what we currently consider to be 580 * the "home" activity. 581 */ 582 ProcessRecord mHomeProcess; 583 584 /** 585 * This is the process holding the activity the user last visited that 586 * is in a different process from the one they are currently in. 587 */ 588 ProcessRecord mPreviousProcess; 589 590 /** 591 * The time at which the previous process was last visible. 592 */ 593 long mPreviousProcessVisibleTime; 594 595 /** 596 * Which uses have been started, so are allowed to run code. 597 */ 598 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 599 600 /** 601 * LRU list of history of current users. Most recently current is at the end. 602 */ 603 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 604 605 /** 606 * Constant array of the users that are currently started. 607 */ 608 int[] mStartedUserArray = new int[] { 0 }; 609 610 /** 611 * Registered observers of the user switching mechanics. 612 */ 613 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 614 = new RemoteCallbackList<IUserSwitchObserver>(); 615 616 /** 617 * Currently active user switch. 618 */ 619 Object mCurUserSwitchCallback; 620 621 /** 622 * Packages that the user has asked to have run in screen size 623 * compatibility mode instead of filling the screen. 624 */ 625 final CompatModePackages mCompatModePackages; 626 627 /** 628 * Set of IntentSenderRecord objects that are currently active. 629 */ 630 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 631 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 632 633 /** 634 * Fingerprints (hashCode()) of stack traces that we've 635 * already logged DropBox entries for. Guarded by itself. If 636 * something (rogue user app) forces this over 637 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 638 */ 639 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 640 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 641 642 /** 643 * Strict Mode background batched logging state. 644 * 645 * The string buffer is guarded by itself, and its lock is also 646 * used to determine if another batched write is already 647 * in-flight. 648 */ 649 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 650 651 /** 652 * Keeps track of all IIntentReceivers that have been registered for 653 * broadcasts. Hash keys are the receiver IBinder, hash value is 654 * a ReceiverList. 655 */ 656 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 657 new HashMap<IBinder, ReceiverList>(); 658 659 /** 660 * Resolver for broadcast intents to registered receivers. 661 * Holds BroadcastFilter (subclass of IntentFilter). 662 */ 663 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 664 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 665 @Override 666 protected boolean allowFilterResult( 667 BroadcastFilter filter, List<BroadcastFilter> dest) { 668 IBinder target = filter.receiverList.receiver.asBinder(); 669 for (int i=dest.size()-1; i>=0; i--) { 670 if (dest.get(i).receiverList.receiver.asBinder() == target) { 671 return false; 672 } 673 } 674 return true; 675 } 676 677 @Override 678 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 679 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 680 || userId == filter.owningUserId) { 681 return super.newResult(filter, match, userId); 682 } 683 return null; 684 } 685 686 @Override 687 protected BroadcastFilter[] newArray(int size) { 688 return new BroadcastFilter[size]; 689 } 690 691 @Override 692 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 693 return packageName.equals(filter.packageName); 694 } 695 }; 696 697 /** 698 * State of all active sticky broadcasts per user. Keys are the action of the 699 * sticky Intent, values are an ArrayList of all broadcasted intents with 700 * that action (which should usually be one). The SparseArray is keyed 701 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 702 * for stickies that are sent to all users. 703 */ 704 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 705 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 706 707 final ActiveServices mServices; 708 709 /** 710 * Backup/restore process management 711 */ 712 String mBackupAppName = null; 713 BackupRecord mBackupTarget = null; 714 715 final ProviderMap mProviderMap; 716 717 /** 718 * List of content providers who have clients waiting for them. The 719 * application is currently being launched and the provider will be 720 * removed from this list once it is published. 721 */ 722 final ArrayList<ContentProviderRecord> mLaunchingProviders 723 = new ArrayList<ContentProviderRecord>(); 724 725 /** 726 * File storing persisted {@link #mGrantedUriPermissions}. 727 */ 728 private final AtomicFile mGrantFile; 729 730 /** XML constants used in {@link #mGrantFile} */ 731 private static final String TAG_URI_GRANTS = "uri-grants"; 732 private static final String TAG_URI_GRANT = "uri-grant"; 733 private static final String ATTR_USER_HANDLE = "userHandle"; 734 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 735 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 736 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 737 private static final String ATTR_TARGET_PKG = "targetPkg"; 738 private static final String ATTR_URI = "uri"; 739 private static final String ATTR_MODE_FLAGS = "modeFlags"; 740 private static final String ATTR_CREATED_TIME = "createdTime"; 741 private static final String ATTR_PREFIX = "prefix"; 742 743 /** 744 * Global set of specific {@link Uri} permissions that have been granted. 745 * This optimized lookup structure maps from {@link UriPermission#targetUid} 746 * to {@link UriPermission#uri} to {@link UriPermission}. 747 */ 748 @GuardedBy("this") 749 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 750 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 751 752 public static class GrantUri { 753 public final int sourceUserId; 754 public final Uri uri; 755 public boolean prefix; 756 757 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 758 this.sourceUserId = sourceUserId; 759 this.uri = uri; 760 this.prefix = prefix; 761 } 762 763 @Override 764 public int hashCode() { 765 return toString().hashCode(); 766 } 767 768 @Override 769 public boolean equals(Object o) { 770 if (o instanceof GrantUri) { 771 GrantUri other = (GrantUri) o; 772 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 773 && prefix == other.prefix; 774 } 775 return false; 776 } 777 778 @Override 779 public String toString() { 780 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 781 if (prefix) result += " [prefix]"; 782 return result; 783 } 784 785 public String toSafeString() { 786 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 787 if (prefix) result += " [prefix]"; 788 return result; 789 } 790 791 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 792 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 793 ContentProvider.getUriWithoutUserId(uri), false); 794 } 795 } 796 797 CoreSettingsObserver mCoreSettingsObserver; 798 799 /** 800 * Thread-local storage used to carry caller permissions over through 801 * indirect content-provider access. 802 */ 803 private class Identity { 804 public int pid; 805 public int uid; 806 807 Identity(int _pid, int _uid) { 808 pid = _pid; 809 uid = _uid; 810 } 811 } 812 813 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 814 815 /** 816 * All information we have collected about the runtime performance of 817 * any user id that can impact battery performance. 818 */ 819 final BatteryStatsService mBatteryStatsService; 820 821 /** 822 * Information about component usage 823 */ 824 final UsageStatsService mUsageStatsService; 825 826 /** 827 * Information about and control over application operations 828 */ 829 final AppOpsService mAppOpsService; 830 831 /** 832 * Save recent tasks information across reboots. 833 */ 834 final TaskPersister mTaskPersister; 835 836 /** 837 * Current configuration information. HistoryRecord objects are given 838 * a reference to this object to indicate which configuration they are 839 * currently running in, so this object must be kept immutable. 840 */ 841 Configuration mConfiguration = new Configuration(); 842 843 /** 844 * Current sequencing integer of the configuration, for skipping old 845 * configurations. 846 */ 847 int mConfigurationSeq = 0; 848 849 /** 850 * Hardware-reported OpenGLES version. 851 */ 852 final int GL_ES_VERSION; 853 854 /** 855 * List of initialization arguments to pass to all processes when binding applications to them. 856 * For example, references to the commonly used services. 857 */ 858 HashMap<String, IBinder> mAppBindArgs; 859 860 /** 861 * Temporary to avoid allocations. Protected by main lock. 862 */ 863 final StringBuilder mStringBuilder = new StringBuilder(256); 864 865 /** 866 * Used to control how we initialize the service. 867 */ 868 ComponentName mTopComponent; 869 String mTopAction = Intent.ACTION_MAIN; 870 String mTopData; 871 boolean mProcessesReady = false; 872 boolean mSystemReady = false; 873 boolean mBooting = false; 874 boolean mWaitingUpdate = false; 875 boolean mDidUpdate = false; 876 boolean mOnBattery = false; 877 boolean mLaunchWarningShown = false; 878 879 Context mContext; 880 881 int mFactoryTest; 882 883 boolean mCheckedForSetup; 884 885 /** 886 * The time at which we will allow normal application switches again, 887 * after a call to {@link #stopAppSwitches()}. 888 */ 889 long mAppSwitchesAllowedTime; 890 891 /** 892 * This is set to true after the first switch after mAppSwitchesAllowedTime 893 * is set; any switches after that will clear the time. 894 */ 895 boolean mDidAppSwitch; 896 897 /** 898 * Last time (in realtime) at which we checked for power usage. 899 */ 900 long mLastPowerCheckRealtime; 901 902 /** 903 * Last time (in uptime) at which we checked for power usage. 904 */ 905 long mLastPowerCheckUptime; 906 907 /** 908 * Set while we are wanting to sleep, to prevent any 909 * activities from being started/resumed. 910 */ 911 private boolean mSleeping = false; 912 913 /** 914 * Set while we are running a voice interaction. This overrides 915 * sleeping while it is active. 916 */ 917 private boolean mRunningVoice = false; 918 919 /** 920 * State of external calls telling us if the device is asleep. 921 */ 922 private boolean mWentToSleep = false; 923 924 /** 925 * State of external call telling us if the lock screen is shown. 926 */ 927 private boolean mLockScreenShown = false; 928 929 /** 930 * Set if we are shutting down the system, similar to sleeping. 931 */ 932 boolean mShuttingDown = false; 933 934 /** 935 * Current sequence id for oom_adj computation traversal. 936 */ 937 int mAdjSeq = 0; 938 939 /** 940 * Current sequence id for process LRU updating. 941 */ 942 int mLruSeq = 0; 943 944 /** 945 * Keep track of the non-cached/empty process we last found, to help 946 * determine how to distribute cached/empty processes next time. 947 */ 948 int mNumNonCachedProcs = 0; 949 950 /** 951 * Keep track of the number of cached hidden procs, to balance oom adj 952 * distribution between those and empty procs. 953 */ 954 int mNumCachedHiddenProcs = 0; 955 956 /** 957 * Keep track of the number of service processes we last found, to 958 * determine on the next iteration which should be B services. 959 */ 960 int mNumServiceProcs = 0; 961 int mNewNumAServiceProcs = 0; 962 int mNewNumServiceProcs = 0; 963 964 /** 965 * Allow the current computed overall memory level of the system to go down? 966 * This is set to false when we are killing processes for reasons other than 967 * memory management, so that the now smaller process list will not be taken as 968 * an indication that memory is tighter. 969 */ 970 boolean mAllowLowerMemLevel = false; 971 972 /** 973 * The last computed memory level, for holding when we are in a state that 974 * processes are going away for other reasons. 975 */ 976 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 977 978 /** 979 * The last total number of process we have, to determine if changes actually look 980 * like a shrinking number of process due to lower RAM. 981 */ 982 int mLastNumProcesses; 983 984 /** 985 * The uptime of the last time we performed idle maintenance. 986 */ 987 long mLastIdleTime = SystemClock.uptimeMillis(); 988 989 /** 990 * Total time spent with RAM that has been added in the past since the last idle time. 991 */ 992 long mLowRamTimeSinceLastIdle = 0; 993 994 /** 995 * If RAM is currently low, when that horrible situation started. 996 */ 997 long mLowRamStartTime = 0; 998 999 /** 1000 * For reporting to battery stats the current top application. 1001 */ 1002 private String mCurResumedPackage = null; 1003 private int mCurResumedUid = -1; 1004 1005 /** 1006 * For reporting to battery stats the apps currently running foreground 1007 * service. The ProcessMap is package/uid tuples; each of these contain 1008 * an array of the currently foreground processes. 1009 */ 1010 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1011 = new ProcessMap<ArrayList<ProcessRecord>>(); 1012 1013 /** 1014 * This is set if we had to do a delayed dexopt of an app before launching 1015 * it, to increase the ANR timeouts in that case. 1016 */ 1017 boolean mDidDexOpt; 1018 1019 /** 1020 * Set if the systemServer made a call to enterSafeMode. 1021 */ 1022 boolean mSafeMode; 1023 1024 String mDebugApp = null; 1025 boolean mWaitForDebugger = false; 1026 boolean mDebugTransient = false; 1027 String mOrigDebugApp = null; 1028 boolean mOrigWaitForDebugger = false; 1029 boolean mAlwaysFinishActivities = false; 1030 IActivityController mController = null; 1031 String mProfileApp = null; 1032 ProcessRecord mProfileProc = null; 1033 String mProfileFile; 1034 ParcelFileDescriptor mProfileFd; 1035 int mProfileType = 0; 1036 boolean mAutoStopProfiler = false; 1037 String mOpenGlTraceApp = null; 1038 1039 static class ProcessChangeItem { 1040 static final int CHANGE_ACTIVITIES = 1<<0; 1041 static final int CHANGE_PROCESS_STATE = 1<<1; 1042 int changes; 1043 int uid; 1044 int pid; 1045 int processState; 1046 boolean foregroundActivities; 1047 } 1048 1049 final RemoteCallbackList<IProcessObserver> mProcessObservers 1050 = new RemoteCallbackList<IProcessObserver>(); 1051 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1052 1053 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1054 = new ArrayList<ProcessChangeItem>(); 1055 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1056 = new ArrayList<ProcessChangeItem>(); 1057 1058 /** 1059 * Runtime CPU use collection thread. This object's lock is used to 1060 * protect all related state. 1061 */ 1062 final Thread mProcessCpuThread; 1063 1064 /** 1065 * Used to collect process stats when showing not responding dialog. 1066 * Protected by mProcessCpuThread. 1067 */ 1068 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1069 MONITOR_THREAD_CPU_USAGE); 1070 final AtomicLong mLastCpuTime = new AtomicLong(0); 1071 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1072 1073 long mLastWriteTime = 0; 1074 1075 /** 1076 * Used to retain an update lock when the foreground activity is in 1077 * immersive mode. 1078 */ 1079 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1080 1081 /** 1082 * Set to true after the system has finished booting. 1083 */ 1084 boolean mBooted = false; 1085 1086 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1087 int mProcessLimitOverride = -1; 1088 1089 WindowManagerService mWindowManager; 1090 1091 final ActivityThread mSystemThread; 1092 1093 int mCurrentUserId = 0; 1094 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1095 private UserManagerService mUserManager; 1096 1097 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1098 final ProcessRecord mApp; 1099 final int mPid; 1100 final IApplicationThread mAppThread; 1101 1102 AppDeathRecipient(ProcessRecord app, int pid, 1103 IApplicationThread thread) { 1104 if (localLOGV) Slog.v( 1105 TAG, "New death recipient " + this 1106 + " for thread " + thread.asBinder()); 1107 mApp = app; 1108 mPid = pid; 1109 mAppThread = thread; 1110 } 1111 1112 @Override 1113 public void binderDied() { 1114 if (localLOGV) Slog.v( 1115 TAG, "Death received in " + this 1116 + " for thread " + mAppThread.asBinder()); 1117 synchronized(ActivityManagerService.this) { 1118 appDiedLocked(mApp, mPid, mAppThread); 1119 } 1120 } 1121 } 1122 1123 static final int SHOW_ERROR_MSG = 1; 1124 static final int SHOW_NOT_RESPONDING_MSG = 2; 1125 static final int SHOW_FACTORY_ERROR_MSG = 3; 1126 static final int UPDATE_CONFIGURATION_MSG = 4; 1127 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1128 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1129 static final int SERVICE_TIMEOUT_MSG = 12; 1130 static final int UPDATE_TIME_ZONE = 13; 1131 static final int SHOW_UID_ERROR_MSG = 14; 1132 static final int IM_FEELING_LUCKY_MSG = 15; 1133 static final int PROC_START_TIMEOUT_MSG = 20; 1134 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1135 static final int KILL_APPLICATION_MSG = 22; 1136 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1137 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1138 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1139 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1140 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1141 static final int CLEAR_DNS_CACHE_MSG = 28; 1142 static final int UPDATE_HTTP_PROXY_MSG = 29; 1143 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1144 static final int DISPATCH_PROCESSES_CHANGED = 31; 1145 static final int DISPATCH_PROCESS_DIED = 32; 1146 static final int REPORT_MEM_USAGE_MSG = 33; 1147 static final int REPORT_USER_SWITCH_MSG = 34; 1148 static final int CONTINUE_USER_SWITCH_MSG = 35; 1149 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1150 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1151 static final int PERSIST_URI_GRANTS_MSG = 38; 1152 static final int REQUEST_ALL_PSS_MSG = 39; 1153 static final int START_PROFILES_MSG = 40; 1154 static final int UPDATE_TIME = 41; 1155 static final int SYSTEM_USER_START_MSG = 42; 1156 static final int SYSTEM_USER_CURRENT_MSG = 43; 1157 1158 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1159 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1160 static final int FIRST_COMPAT_MODE_MSG = 300; 1161 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1162 1163 AlertDialog mUidAlert; 1164 CompatModeDialog mCompatModeDialog; 1165 long mLastMemUsageReportTime = 0; 1166 1167 private LockToAppRequestDialog mLockToAppRequest; 1168 1169 /** 1170 * Flag whether the current user is a "monkey", i.e. whether 1171 * the UI is driven by a UI automation tool. 1172 */ 1173 private boolean mUserIsMonkey; 1174 1175 final ServiceThread mHandlerThread; 1176 final MainHandler mHandler; 1177 1178 final class MainHandler extends Handler { 1179 public MainHandler(Looper looper) { 1180 super(looper, null, true); 1181 } 1182 1183 @Override 1184 public void handleMessage(Message msg) { 1185 switch (msg.what) { 1186 case SHOW_ERROR_MSG: { 1187 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1188 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1189 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1190 synchronized (ActivityManagerService.this) { 1191 ProcessRecord proc = (ProcessRecord)data.get("app"); 1192 AppErrorResult res = (AppErrorResult) data.get("result"); 1193 if (proc != null && proc.crashDialog != null) { 1194 Slog.e(TAG, "App already has crash dialog: " + proc); 1195 if (res != null) { 1196 res.set(0); 1197 } 1198 return; 1199 } 1200 if (!showBackground && UserHandle.getAppId(proc.uid) 1201 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1202 && proc.pid != MY_PID) { 1203 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1204 if (res != null) { 1205 res.set(0); 1206 } 1207 return; 1208 } 1209 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1210 Dialog d = new AppErrorDialog(mContext, 1211 ActivityManagerService.this, res, proc); 1212 d.show(); 1213 proc.crashDialog = d; 1214 } else { 1215 // The device is asleep, so just pretend that the user 1216 // saw a crash dialog and hit "force quit". 1217 if (res != null) { 1218 res.set(0); 1219 } 1220 } 1221 } 1222 1223 ensureBootCompleted(); 1224 } break; 1225 case SHOW_NOT_RESPONDING_MSG: { 1226 synchronized (ActivityManagerService.this) { 1227 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1228 ProcessRecord proc = (ProcessRecord)data.get("app"); 1229 if (proc != null && proc.anrDialog != null) { 1230 Slog.e(TAG, "App already has anr dialog: " + proc); 1231 return; 1232 } 1233 1234 Intent intent = new Intent("android.intent.action.ANR"); 1235 if (!mProcessesReady) { 1236 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1237 | Intent.FLAG_RECEIVER_FOREGROUND); 1238 } 1239 broadcastIntentLocked(null, null, intent, 1240 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1241 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1242 1243 if (mShowDialogs) { 1244 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1245 mContext, proc, (ActivityRecord)data.get("activity"), 1246 msg.arg1 != 0); 1247 d.show(); 1248 proc.anrDialog = d; 1249 } else { 1250 // Just kill the app if there is no dialog to be shown. 1251 killAppAtUsersRequest(proc, null); 1252 } 1253 } 1254 1255 ensureBootCompleted(); 1256 } break; 1257 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1258 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1259 synchronized (ActivityManagerService.this) { 1260 ProcessRecord proc = (ProcessRecord) data.get("app"); 1261 if (proc == null) { 1262 Slog.e(TAG, "App not found when showing strict mode dialog."); 1263 break; 1264 } 1265 if (proc.crashDialog != null) { 1266 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1267 return; 1268 } 1269 AppErrorResult res = (AppErrorResult) data.get("result"); 1270 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1271 Dialog d = new StrictModeViolationDialog(mContext, 1272 ActivityManagerService.this, res, proc); 1273 d.show(); 1274 proc.crashDialog = d; 1275 } else { 1276 // The device is asleep, so just pretend that the user 1277 // saw a crash dialog and hit "force quit". 1278 res.set(0); 1279 } 1280 } 1281 ensureBootCompleted(); 1282 } break; 1283 case SHOW_FACTORY_ERROR_MSG: { 1284 Dialog d = new FactoryErrorDialog( 1285 mContext, msg.getData().getCharSequence("msg")); 1286 d.show(); 1287 ensureBootCompleted(); 1288 } break; 1289 case UPDATE_CONFIGURATION_MSG: { 1290 final ContentResolver resolver = mContext.getContentResolver(); 1291 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1292 } break; 1293 case GC_BACKGROUND_PROCESSES_MSG: { 1294 synchronized (ActivityManagerService.this) { 1295 performAppGcsIfAppropriateLocked(); 1296 } 1297 } break; 1298 case WAIT_FOR_DEBUGGER_MSG: { 1299 synchronized (ActivityManagerService.this) { 1300 ProcessRecord app = (ProcessRecord)msg.obj; 1301 if (msg.arg1 != 0) { 1302 if (!app.waitedForDebugger) { 1303 Dialog d = new AppWaitingForDebuggerDialog( 1304 ActivityManagerService.this, 1305 mContext, app); 1306 app.waitDialog = d; 1307 app.waitedForDebugger = true; 1308 d.show(); 1309 } 1310 } else { 1311 if (app.waitDialog != null) { 1312 app.waitDialog.dismiss(); 1313 app.waitDialog = null; 1314 } 1315 } 1316 } 1317 } break; 1318 case SERVICE_TIMEOUT_MSG: { 1319 if (mDidDexOpt) { 1320 mDidDexOpt = false; 1321 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1322 nmsg.obj = msg.obj; 1323 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1324 return; 1325 } 1326 mServices.serviceTimeout((ProcessRecord)msg.obj); 1327 } break; 1328 case UPDATE_TIME_ZONE: { 1329 synchronized (ActivityManagerService.this) { 1330 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1331 ProcessRecord r = mLruProcesses.get(i); 1332 if (r.thread != null) { 1333 try { 1334 r.thread.updateTimeZone(); 1335 } catch (RemoteException ex) { 1336 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1337 } 1338 } 1339 } 1340 } 1341 } break; 1342 case CLEAR_DNS_CACHE_MSG: { 1343 synchronized (ActivityManagerService.this) { 1344 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1345 ProcessRecord r = mLruProcesses.get(i); 1346 if (r.thread != null) { 1347 try { 1348 r.thread.clearDnsCache(); 1349 } catch (RemoteException ex) { 1350 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1351 } 1352 } 1353 } 1354 } 1355 } break; 1356 case UPDATE_HTTP_PROXY_MSG: { 1357 ProxyInfo proxy = (ProxyInfo)msg.obj; 1358 String host = ""; 1359 String port = ""; 1360 String exclList = ""; 1361 Uri pacFileUrl = Uri.EMPTY; 1362 if (proxy != null) { 1363 host = proxy.getHost(); 1364 port = Integer.toString(proxy.getPort()); 1365 exclList = proxy.getExclusionListAsString(); 1366 pacFileUrl = proxy.getPacFileUrl(); 1367 } 1368 synchronized (ActivityManagerService.this) { 1369 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1370 ProcessRecord r = mLruProcesses.get(i); 1371 if (r.thread != null) { 1372 try { 1373 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1374 } catch (RemoteException ex) { 1375 Slog.w(TAG, "Failed to update http proxy for: " + 1376 r.info.processName); 1377 } 1378 } 1379 } 1380 } 1381 } break; 1382 case SHOW_UID_ERROR_MSG: { 1383 String title = "System UIDs Inconsistent"; 1384 String text = "UIDs on the system are inconsistent, you need to wipe your" 1385 + " data partition or your device will be unstable."; 1386 Log.e(TAG, title + ": " + text); 1387 if (mShowDialogs) { 1388 // XXX This is a temporary dialog, no need to localize. 1389 AlertDialog d = new BaseErrorDialog(mContext); 1390 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1391 d.setCancelable(false); 1392 d.setTitle(title); 1393 d.setMessage(text); 1394 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1395 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1396 mUidAlert = d; 1397 d.show(); 1398 } 1399 } break; 1400 case IM_FEELING_LUCKY_MSG: { 1401 if (mUidAlert != null) { 1402 mUidAlert.dismiss(); 1403 mUidAlert = null; 1404 } 1405 } break; 1406 case PROC_START_TIMEOUT_MSG: { 1407 if (mDidDexOpt) { 1408 mDidDexOpt = false; 1409 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1410 nmsg.obj = msg.obj; 1411 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1412 return; 1413 } 1414 ProcessRecord app = (ProcessRecord)msg.obj; 1415 synchronized (ActivityManagerService.this) { 1416 processStartTimedOutLocked(app); 1417 } 1418 } break; 1419 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1420 synchronized (ActivityManagerService.this) { 1421 doPendingActivityLaunchesLocked(true); 1422 } 1423 } break; 1424 case KILL_APPLICATION_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 int appid = msg.arg1; 1427 boolean restart = (msg.arg2 == 1); 1428 Bundle bundle = (Bundle)msg.obj; 1429 String pkg = bundle.getString("pkg"); 1430 String reason = bundle.getString("reason"); 1431 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1432 false, UserHandle.USER_ALL, reason); 1433 } 1434 } break; 1435 case FINALIZE_PENDING_INTENT_MSG: { 1436 ((PendingIntentRecord)msg.obj).completeFinalize(); 1437 } break; 1438 case POST_HEAVY_NOTIFICATION_MSG: { 1439 INotificationManager inm = NotificationManager.getService(); 1440 if (inm == null) { 1441 return; 1442 } 1443 1444 ActivityRecord root = (ActivityRecord)msg.obj; 1445 ProcessRecord process = root.app; 1446 if (process == null) { 1447 return; 1448 } 1449 1450 try { 1451 Context context = mContext.createPackageContext(process.info.packageName, 0); 1452 String text = mContext.getString(R.string.heavy_weight_notification, 1453 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1454 Notification notification = new Notification(); 1455 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1456 notification.when = 0; 1457 notification.flags = Notification.FLAG_ONGOING_EVENT; 1458 notification.tickerText = text; 1459 notification.defaults = 0; // please be quiet 1460 notification.sound = null; 1461 notification.vibrate = null; 1462 notification.setLatestEventInfo(context, text, 1463 mContext.getText(R.string.heavy_weight_notification_detail), 1464 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1465 PendingIntent.FLAG_CANCEL_CURRENT, null, 1466 new UserHandle(root.userId))); 1467 1468 try { 1469 int[] outId = new int[1]; 1470 inm.enqueueNotificationWithTag("android", "android", null, 1471 R.string.heavy_weight_notification, 1472 notification, outId, root.userId); 1473 } catch (RuntimeException e) { 1474 Slog.w(ActivityManagerService.TAG, 1475 "Error showing notification for heavy-weight app", e); 1476 } catch (RemoteException e) { 1477 } 1478 } catch (NameNotFoundException e) { 1479 Slog.w(TAG, "Unable to create context for heavy notification", e); 1480 } 1481 } break; 1482 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1483 INotificationManager inm = NotificationManager.getService(); 1484 if (inm == null) { 1485 return; 1486 } 1487 try { 1488 inm.cancelNotificationWithTag("android", null, 1489 R.string.heavy_weight_notification, msg.arg1); 1490 } catch (RuntimeException e) { 1491 Slog.w(ActivityManagerService.TAG, 1492 "Error canceling notification for service", e); 1493 } catch (RemoteException e) { 1494 } 1495 } break; 1496 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1497 synchronized (ActivityManagerService.this) { 1498 checkExcessivePowerUsageLocked(true); 1499 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1500 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1501 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1502 } 1503 } break; 1504 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1505 synchronized (ActivityManagerService.this) { 1506 ActivityRecord ar = (ActivityRecord)msg.obj; 1507 if (mCompatModeDialog != null) { 1508 if (mCompatModeDialog.mAppInfo.packageName.equals( 1509 ar.info.applicationInfo.packageName)) { 1510 return; 1511 } 1512 mCompatModeDialog.dismiss(); 1513 mCompatModeDialog = null; 1514 } 1515 if (ar != null && false) { 1516 if (mCompatModePackages.getPackageAskCompatModeLocked( 1517 ar.packageName)) { 1518 int mode = mCompatModePackages.computeCompatModeLocked( 1519 ar.info.applicationInfo); 1520 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1521 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1522 mCompatModeDialog = new CompatModeDialog( 1523 ActivityManagerService.this, mContext, 1524 ar.info.applicationInfo); 1525 mCompatModeDialog.show(); 1526 } 1527 } 1528 } 1529 } 1530 break; 1531 } 1532 case DISPATCH_PROCESSES_CHANGED: { 1533 dispatchProcessesChanged(); 1534 break; 1535 } 1536 case DISPATCH_PROCESS_DIED: { 1537 final int pid = msg.arg1; 1538 final int uid = msg.arg2; 1539 dispatchProcessDied(pid, uid); 1540 break; 1541 } 1542 case REPORT_MEM_USAGE_MSG: { 1543 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1544 Thread thread = new Thread() { 1545 @Override public void run() { 1546 final SparseArray<ProcessMemInfo> infoMap 1547 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1548 for (int i=0, N=memInfos.size(); i<N; i++) { 1549 ProcessMemInfo mi = memInfos.get(i); 1550 infoMap.put(mi.pid, mi); 1551 } 1552 updateCpuStatsNow(); 1553 synchronized (mProcessCpuThread) { 1554 final int N = mProcessCpuTracker.countStats(); 1555 for (int i=0; i<N; i++) { 1556 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1557 if (st.vsize > 0) { 1558 long pss = Debug.getPss(st.pid, null); 1559 if (pss > 0) { 1560 if (infoMap.indexOfKey(st.pid) < 0) { 1561 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1562 ProcessList.NATIVE_ADJ, -1, "native", null); 1563 mi.pss = pss; 1564 memInfos.add(mi); 1565 } 1566 } 1567 } 1568 } 1569 } 1570 1571 long totalPss = 0; 1572 for (int i=0, N=memInfos.size(); i<N; i++) { 1573 ProcessMemInfo mi = memInfos.get(i); 1574 if (mi.pss == 0) { 1575 mi.pss = Debug.getPss(mi.pid, null); 1576 } 1577 totalPss += mi.pss; 1578 } 1579 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1580 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1581 if (lhs.oomAdj != rhs.oomAdj) { 1582 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1583 } 1584 if (lhs.pss != rhs.pss) { 1585 return lhs.pss < rhs.pss ? 1 : -1; 1586 } 1587 return 0; 1588 } 1589 }); 1590 1591 StringBuilder tag = new StringBuilder(128); 1592 StringBuilder stack = new StringBuilder(128); 1593 tag.append("Low on memory -- "); 1594 appendMemBucket(tag, totalPss, "total", false); 1595 appendMemBucket(stack, totalPss, "total", true); 1596 1597 StringBuilder logBuilder = new StringBuilder(1024); 1598 logBuilder.append("Low on memory:\n"); 1599 1600 boolean firstLine = true; 1601 int lastOomAdj = Integer.MIN_VALUE; 1602 for (int i=0, N=memInfos.size(); i<N; i++) { 1603 ProcessMemInfo mi = memInfos.get(i); 1604 1605 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1606 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1607 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1608 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1609 if (lastOomAdj != mi.oomAdj) { 1610 lastOomAdj = mi.oomAdj; 1611 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1612 tag.append(" / "); 1613 } 1614 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1615 if (firstLine) { 1616 stack.append(":"); 1617 firstLine = false; 1618 } 1619 stack.append("\n\t at "); 1620 } else { 1621 stack.append("$"); 1622 } 1623 } else { 1624 tag.append(" "); 1625 stack.append("$"); 1626 } 1627 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1628 appendMemBucket(tag, mi.pss, mi.name, false); 1629 } 1630 appendMemBucket(stack, mi.pss, mi.name, true); 1631 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1632 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1633 stack.append("("); 1634 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1635 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1636 stack.append(DUMP_MEM_OOM_LABEL[k]); 1637 stack.append(":"); 1638 stack.append(DUMP_MEM_OOM_ADJ[k]); 1639 } 1640 } 1641 stack.append(")"); 1642 } 1643 } 1644 1645 logBuilder.append(" "); 1646 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1647 logBuilder.append(' '); 1648 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1649 logBuilder.append(' '); 1650 ProcessList.appendRamKb(logBuilder, mi.pss); 1651 logBuilder.append(" kB: "); 1652 logBuilder.append(mi.name); 1653 logBuilder.append(" ("); 1654 logBuilder.append(mi.pid); 1655 logBuilder.append(") "); 1656 logBuilder.append(mi.adjType); 1657 logBuilder.append('\n'); 1658 if (mi.adjReason != null) { 1659 logBuilder.append(" "); 1660 logBuilder.append(mi.adjReason); 1661 logBuilder.append('\n'); 1662 } 1663 } 1664 1665 logBuilder.append(" "); 1666 ProcessList.appendRamKb(logBuilder, totalPss); 1667 logBuilder.append(" kB: TOTAL\n"); 1668 1669 long[] infos = new long[Debug.MEMINFO_COUNT]; 1670 Debug.getMemInfo(infos); 1671 logBuilder.append(" MemInfo: "); 1672 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1673 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1674 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1675 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1676 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1677 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1678 logBuilder.append(" ZRAM: "); 1679 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1680 logBuilder.append(" kB RAM, "); 1681 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1682 logBuilder.append(" kB swap total, "); 1683 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1684 logBuilder.append(" kB swap free\n"); 1685 } 1686 Slog.i(TAG, logBuilder.toString()); 1687 1688 StringBuilder dropBuilder = new StringBuilder(1024); 1689 /* 1690 StringWriter oomSw = new StringWriter(); 1691 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1692 StringWriter catSw = new StringWriter(); 1693 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1694 String[] emptyArgs = new String[] { }; 1695 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1696 oomPw.flush(); 1697 String oomString = oomSw.toString(); 1698 */ 1699 dropBuilder.append(stack); 1700 dropBuilder.append('\n'); 1701 dropBuilder.append('\n'); 1702 dropBuilder.append(logBuilder); 1703 dropBuilder.append('\n'); 1704 /* 1705 dropBuilder.append(oomString); 1706 dropBuilder.append('\n'); 1707 */ 1708 StringWriter catSw = new StringWriter(); 1709 synchronized (ActivityManagerService.this) { 1710 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1711 String[] emptyArgs = new String[] { }; 1712 catPw.println(); 1713 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1714 catPw.println(); 1715 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1716 false, false, null); 1717 catPw.println(); 1718 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1719 catPw.flush(); 1720 } 1721 dropBuilder.append(catSw.toString()); 1722 addErrorToDropBox("lowmem", null, "system_server", null, 1723 null, tag.toString(), dropBuilder.toString(), null, null); 1724 //Slog.i(TAG, "Sent to dropbox:"); 1725 //Slog.i(TAG, dropBuilder.toString()); 1726 synchronized (ActivityManagerService.this) { 1727 long now = SystemClock.uptimeMillis(); 1728 if (mLastMemUsageReportTime < now) { 1729 mLastMemUsageReportTime = now; 1730 } 1731 } 1732 } 1733 }; 1734 thread.start(); 1735 break; 1736 } 1737 case REPORT_USER_SWITCH_MSG: { 1738 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1739 break; 1740 } 1741 case CONTINUE_USER_SWITCH_MSG: { 1742 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1743 break; 1744 } 1745 case USER_SWITCH_TIMEOUT_MSG: { 1746 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1747 break; 1748 } 1749 case IMMERSIVE_MODE_LOCK_MSG: { 1750 final boolean nextState = (msg.arg1 != 0); 1751 if (mUpdateLock.isHeld() != nextState) { 1752 if (DEBUG_IMMERSIVE) { 1753 final ActivityRecord r = (ActivityRecord) msg.obj; 1754 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1755 } 1756 if (nextState) { 1757 mUpdateLock.acquire(); 1758 } else { 1759 mUpdateLock.release(); 1760 } 1761 } 1762 break; 1763 } 1764 case PERSIST_URI_GRANTS_MSG: { 1765 writeGrantedUriPermissions(); 1766 break; 1767 } 1768 case REQUEST_ALL_PSS_MSG: { 1769 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1770 break; 1771 } 1772 case START_PROFILES_MSG: { 1773 synchronized (ActivityManagerService.this) { 1774 startProfilesLocked(); 1775 } 1776 break; 1777 } 1778 case UPDATE_TIME: { 1779 synchronized (ActivityManagerService.this) { 1780 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1781 ProcessRecord r = mLruProcesses.get(i); 1782 if (r.thread != null) { 1783 try { 1784 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1785 } catch (RemoteException ex) { 1786 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1787 } 1788 } 1789 } 1790 } 1791 break; 1792 } 1793 case SYSTEM_USER_START_MSG: { 1794 mSystemServiceManager.startUser(msg.arg1); 1795 break; 1796 } 1797 case SYSTEM_USER_CURRENT_MSG: { 1798 mSystemServiceManager.switchUser(msg.arg1); 1799 break; 1800 } 1801 } 1802 } 1803 }; 1804 1805 static final int COLLECT_PSS_BG_MSG = 1; 1806 1807 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1808 @Override 1809 public void handleMessage(Message msg) { 1810 switch (msg.what) { 1811 case COLLECT_PSS_BG_MSG: { 1812 long start = SystemClock.uptimeMillis(); 1813 MemInfoReader memInfo = null; 1814 synchronized (ActivityManagerService.this) { 1815 if (mFullPssPending) { 1816 mFullPssPending = false; 1817 memInfo = new MemInfoReader(); 1818 } 1819 } 1820 if (memInfo != null) { 1821 updateCpuStatsNow(); 1822 long nativeTotalPss = 0; 1823 synchronized (mProcessCpuThread) { 1824 final int N = mProcessCpuTracker.countStats(); 1825 for (int j=0; j<N; j++) { 1826 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1827 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1828 // This is definitely an application process; skip it. 1829 continue; 1830 } 1831 synchronized (mPidsSelfLocked) { 1832 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1833 // This is one of our own processes; skip it. 1834 continue; 1835 } 1836 } 1837 nativeTotalPss += Debug.getPss(st.pid, null); 1838 } 1839 } 1840 memInfo.readMemInfo(); 1841 synchronized (this) { 1842 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1843 + (SystemClock.uptimeMillis()-start) + "ms"); 1844 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1845 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1846 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1847 +memInfo.getSlabSizeKb(), 1848 nativeTotalPss); 1849 } 1850 } 1851 1852 int i=0, num=0; 1853 long[] tmp = new long[1]; 1854 do { 1855 ProcessRecord proc; 1856 int procState; 1857 int pid; 1858 synchronized (ActivityManagerService.this) { 1859 if (i >= mPendingPssProcesses.size()) { 1860 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1861 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1862 mPendingPssProcesses.clear(); 1863 return; 1864 } 1865 proc = mPendingPssProcesses.get(i); 1866 procState = proc.pssProcState; 1867 if (proc.thread != null && procState == proc.setProcState) { 1868 pid = proc.pid; 1869 } else { 1870 proc = null; 1871 pid = 0; 1872 } 1873 i++; 1874 } 1875 if (proc != null) { 1876 long pss = Debug.getPss(pid, tmp); 1877 synchronized (ActivityManagerService.this) { 1878 if (proc.thread != null && proc.setProcState == procState 1879 && proc.pid == pid) { 1880 num++; 1881 proc.lastPssTime = SystemClock.uptimeMillis(); 1882 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1883 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1884 + ": " + pss + " lastPss=" + proc.lastPss 1885 + " state=" + ProcessList.makeProcStateString(procState)); 1886 if (proc.initialIdlePss == 0) { 1887 proc.initialIdlePss = pss; 1888 } 1889 proc.lastPss = pss; 1890 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1891 proc.lastCachedPss = pss; 1892 } 1893 } 1894 } 1895 } 1896 } while (true); 1897 } 1898 } 1899 } 1900 }; 1901 1902 /** 1903 * Monitor for package changes and update our internal state. 1904 */ 1905 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1906 @Override 1907 public void onPackageRemoved(String packageName, int uid) { 1908 // Remove all tasks with activities in the specified package from the list of recent tasks 1909 synchronized (ActivityManagerService.this) { 1910 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1911 TaskRecord tr = mRecentTasks.get(i); 1912 ComponentName cn = tr.intent.getComponent(); 1913 if (cn != null && cn.getPackageName().equals(packageName)) { 1914 // If the package name matches, remove the task and kill the process 1915 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1916 } 1917 } 1918 } 1919 } 1920 1921 @Override 1922 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1923 onPackageModified(packageName); 1924 return true; 1925 } 1926 1927 @Override 1928 public void onPackageModified(String packageName) { 1929 final PackageManager pm = mContext.getPackageManager(); 1930 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1931 new ArrayList<Pair<Intent, Integer>>(); 1932 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1933 // Copy the list of recent tasks so that we don't hold onto the lock on 1934 // ActivityManagerService for long periods while checking if components exist. 1935 synchronized (ActivityManagerService.this) { 1936 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1937 TaskRecord tr = mRecentTasks.get(i); 1938 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1939 } 1940 } 1941 // Check the recent tasks and filter out all tasks with components that no longer exist. 1942 Intent tmpI = new Intent(); 1943 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1944 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1945 ComponentName cn = p.first.getComponent(); 1946 if (cn != null && cn.getPackageName().equals(packageName)) { 1947 try { 1948 // Add the task to the list to remove if the component no longer exists 1949 tmpI.setComponent(cn); 1950 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1951 tasksToRemove.add(p.second); 1952 } 1953 } catch (Exception e) {} 1954 } 1955 } 1956 // Prune all the tasks with removed components from the list of recent tasks 1957 synchronized (ActivityManagerService.this) { 1958 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1959 // Remove the task but don't kill the process (since other components in that 1960 // package may still be running and in the background) 1961 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1962 } 1963 } 1964 } 1965 1966 @Override 1967 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1968 // Force stop the specified packages 1969 if (packages != null) { 1970 for (String pkg : packages) { 1971 synchronized (ActivityManagerService.this) { 1972 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1973 "finished booting")) { 1974 return true; 1975 } 1976 } 1977 } 1978 } 1979 return false; 1980 } 1981 }; 1982 1983 public void setSystemProcess() { 1984 try { 1985 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1986 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1987 ServiceManager.addService("meminfo", new MemBinder(this)); 1988 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1989 ServiceManager.addService("dbinfo", new DbBinder(this)); 1990 if (MONITOR_CPU_USAGE) { 1991 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1992 } 1993 ServiceManager.addService("permission", new PermissionController(this)); 1994 1995 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1996 "android", STOCK_PM_FLAGS); 1997 mSystemThread.installSystemApplicationInfo(info); 1998 1999 synchronized (this) { 2000 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2001 app.persistent = true; 2002 app.pid = MY_PID; 2003 app.maxAdj = ProcessList.SYSTEM_ADJ; 2004 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2005 mProcessNames.put(app.processName, app.uid, app); 2006 synchronized (mPidsSelfLocked) { 2007 mPidsSelfLocked.put(app.pid, app); 2008 } 2009 updateLruProcessLocked(app, false, null); 2010 updateOomAdjLocked(); 2011 } 2012 } catch (PackageManager.NameNotFoundException e) { 2013 throw new RuntimeException( 2014 "Unable to find android system package", e); 2015 } 2016 } 2017 2018 public void setWindowManager(WindowManagerService wm) { 2019 mWindowManager = wm; 2020 mStackSupervisor.setWindowManager(wm); 2021 } 2022 2023 public void startObservingNativeCrashes() { 2024 final NativeCrashListener ncl = new NativeCrashListener(this); 2025 ncl.start(); 2026 } 2027 2028 public IAppOpsService getAppOpsService() { 2029 return mAppOpsService; 2030 } 2031 2032 static class MemBinder extends Binder { 2033 ActivityManagerService mActivityManagerService; 2034 MemBinder(ActivityManagerService activityManagerService) { 2035 mActivityManagerService = activityManagerService; 2036 } 2037 2038 @Override 2039 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2040 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2041 != PackageManager.PERMISSION_GRANTED) { 2042 pw.println("Permission Denial: can't dump meminfo from from pid=" 2043 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2044 + " without permission " + android.Manifest.permission.DUMP); 2045 return; 2046 } 2047 2048 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2049 } 2050 } 2051 2052 static class GraphicsBinder extends Binder { 2053 ActivityManagerService mActivityManagerService; 2054 GraphicsBinder(ActivityManagerService activityManagerService) { 2055 mActivityManagerService = activityManagerService; 2056 } 2057 2058 @Override 2059 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2060 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2061 != PackageManager.PERMISSION_GRANTED) { 2062 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2063 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2064 + " without permission " + android.Manifest.permission.DUMP); 2065 return; 2066 } 2067 2068 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2069 } 2070 } 2071 2072 static class DbBinder extends Binder { 2073 ActivityManagerService mActivityManagerService; 2074 DbBinder(ActivityManagerService activityManagerService) { 2075 mActivityManagerService = activityManagerService; 2076 } 2077 2078 @Override 2079 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2080 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2081 != PackageManager.PERMISSION_GRANTED) { 2082 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2083 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2084 + " without permission " + android.Manifest.permission.DUMP); 2085 return; 2086 } 2087 2088 mActivityManagerService.dumpDbInfo(fd, pw, args); 2089 } 2090 } 2091 2092 static class CpuBinder extends Binder { 2093 ActivityManagerService mActivityManagerService; 2094 CpuBinder(ActivityManagerService activityManagerService) { 2095 mActivityManagerService = activityManagerService; 2096 } 2097 2098 @Override 2099 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2100 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2101 != PackageManager.PERMISSION_GRANTED) { 2102 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2103 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2104 + " without permission " + android.Manifest.permission.DUMP); 2105 return; 2106 } 2107 2108 synchronized (mActivityManagerService.mProcessCpuThread) { 2109 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2110 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2111 SystemClock.uptimeMillis())); 2112 } 2113 } 2114 } 2115 2116 public static final class Lifecycle extends SystemService { 2117 private final ActivityManagerService mService; 2118 2119 public Lifecycle(Context context) { 2120 super(context); 2121 mService = new ActivityManagerService(context); 2122 } 2123 2124 @Override 2125 public void onStart() { 2126 mService.start(); 2127 } 2128 2129 public ActivityManagerService getService() { 2130 return mService; 2131 } 2132 } 2133 2134 // Note: This method is invoked on the main thread but may need to attach various 2135 // handlers to other threads. So take care to be explicit about the looper. 2136 public ActivityManagerService(Context systemContext) { 2137 mContext = systemContext; 2138 mFactoryTest = FactoryTest.getMode(); 2139 mSystemThread = ActivityThread.currentActivityThread(); 2140 2141 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2142 2143 mHandlerThread = new ServiceThread(TAG, 2144 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2145 mHandlerThread.start(); 2146 mHandler = new MainHandler(mHandlerThread.getLooper()); 2147 2148 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2149 "foreground", BROADCAST_FG_TIMEOUT, false); 2150 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2151 "background", BROADCAST_BG_TIMEOUT, true); 2152 mBroadcastQueues[0] = mFgBroadcastQueue; 2153 mBroadcastQueues[1] = mBgBroadcastQueue; 2154 2155 mServices = new ActiveServices(this); 2156 mProviderMap = new ProviderMap(this); 2157 2158 // TODO: Move creation of battery stats service outside of activity manager service. 2159 File dataDir = Environment.getDataDirectory(); 2160 File systemDir = new File(dataDir, "system"); 2161 systemDir.mkdirs(); 2162 mBatteryStatsService = new BatteryStatsService(new File( 2163 systemDir, "batterystats.bin").toString(), mHandler); 2164 mBatteryStatsService.getActiveStatistics().readLocked(); 2165 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2166 mOnBattery = DEBUG_POWER ? true 2167 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2168 mBatteryStatsService.getActiveStatistics().setCallback(this); 2169 2170 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2171 2172 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2173 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2174 2175 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2176 2177 // User 0 is the first and only user that runs at boot. 2178 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2179 mUserLru.add(Integer.valueOf(0)); 2180 updateStartedUserArrayLocked(); 2181 2182 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2183 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2184 2185 mConfiguration.setToDefaults(); 2186 mConfiguration.setLocale(Locale.getDefault()); 2187 2188 mConfigurationSeq = mConfiguration.seq = 1; 2189 mProcessCpuTracker.init(); 2190 2191 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2192 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2193 mStackSupervisor = new ActivityStackSupervisor(this); 2194 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2195 2196 mProcessCpuThread = new Thread("CpuTracker") { 2197 @Override 2198 public void run() { 2199 while (true) { 2200 try { 2201 try { 2202 synchronized(this) { 2203 final long now = SystemClock.uptimeMillis(); 2204 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2205 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2206 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2207 // + ", write delay=" + nextWriteDelay); 2208 if (nextWriteDelay < nextCpuDelay) { 2209 nextCpuDelay = nextWriteDelay; 2210 } 2211 if (nextCpuDelay > 0) { 2212 mProcessCpuMutexFree.set(true); 2213 this.wait(nextCpuDelay); 2214 } 2215 } 2216 } catch (InterruptedException e) { 2217 } 2218 updateCpuStatsNow(); 2219 } catch (Exception e) { 2220 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2221 } 2222 } 2223 } 2224 }; 2225 2226 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2227 2228 Watchdog.getInstance().addMonitor(this); 2229 Watchdog.getInstance().addThread(mHandler); 2230 } 2231 2232 public void setSystemServiceManager(SystemServiceManager mgr) { 2233 mSystemServiceManager = mgr; 2234 } 2235 2236 private void start() { 2237 mProcessCpuThread.start(); 2238 2239 mBatteryStatsService.publish(mContext); 2240 mUsageStatsService.publish(mContext); 2241 mAppOpsService.publish(mContext); 2242 Slog.d("AppOps", "AppOpsService published"); 2243 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2244 } 2245 2246 public void initPowerManagement() { 2247 mStackSupervisor.initPowerManagement(); 2248 mBatteryStatsService.initPowerManagement(); 2249 } 2250 2251 @Override 2252 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2253 throws RemoteException { 2254 if (code == SYSPROPS_TRANSACTION) { 2255 // We need to tell all apps about the system property change. 2256 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2257 synchronized(this) { 2258 final int NP = mProcessNames.getMap().size(); 2259 for (int ip=0; ip<NP; ip++) { 2260 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2261 final int NA = apps.size(); 2262 for (int ia=0; ia<NA; ia++) { 2263 ProcessRecord app = apps.valueAt(ia); 2264 if (app.thread != null) { 2265 procs.add(app.thread.asBinder()); 2266 } 2267 } 2268 } 2269 } 2270 2271 int N = procs.size(); 2272 for (int i=0; i<N; i++) { 2273 Parcel data2 = Parcel.obtain(); 2274 try { 2275 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2276 } catch (RemoteException e) { 2277 } 2278 data2.recycle(); 2279 } 2280 } 2281 try { 2282 return super.onTransact(code, data, reply, flags); 2283 } catch (RuntimeException e) { 2284 // The activity manager only throws security exceptions, so let's 2285 // log all others. 2286 if (!(e instanceof SecurityException)) { 2287 Slog.wtf(TAG, "Activity Manager Crash", e); 2288 } 2289 throw e; 2290 } 2291 } 2292 2293 void updateCpuStats() { 2294 final long now = SystemClock.uptimeMillis(); 2295 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2296 return; 2297 } 2298 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2299 synchronized (mProcessCpuThread) { 2300 mProcessCpuThread.notify(); 2301 } 2302 } 2303 } 2304 2305 void updateCpuStatsNow() { 2306 synchronized (mProcessCpuThread) { 2307 mProcessCpuMutexFree.set(false); 2308 final long now = SystemClock.uptimeMillis(); 2309 boolean haveNewCpuStats = false; 2310 2311 if (MONITOR_CPU_USAGE && 2312 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2313 mLastCpuTime.set(now); 2314 haveNewCpuStats = true; 2315 mProcessCpuTracker.update(); 2316 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2317 //Slog.i(TAG, "Total CPU usage: " 2318 // + mProcessCpu.getTotalCpuPercent() + "%"); 2319 2320 // Slog the cpu usage if the property is set. 2321 if ("true".equals(SystemProperties.get("events.cpu"))) { 2322 int user = mProcessCpuTracker.getLastUserTime(); 2323 int system = mProcessCpuTracker.getLastSystemTime(); 2324 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2325 int irq = mProcessCpuTracker.getLastIrqTime(); 2326 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2327 int idle = mProcessCpuTracker.getLastIdleTime(); 2328 2329 int total = user + system + iowait + irq + softIrq + idle; 2330 if (total == 0) total = 1; 2331 2332 EventLog.writeEvent(EventLogTags.CPU, 2333 ((user+system+iowait+irq+softIrq) * 100) / total, 2334 (user * 100) / total, 2335 (system * 100) / total, 2336 (iowait * 100) / total, 2337 (irq * 100) / total, 2338 (softIrq * 100) / total); 2339 } 2340 } 2341 2342 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2343 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2344 synchronized(bstats) { 2345 synchronized(mPidsSelfLocked) { 2346 if (haveNewCpuStats) { 2347 if (mOnBattery) { 2348 int perc = bstats.startAddingCpuLocked(); 2349 int totalUTime = 0; 2350 int totalSTime = 0; 2351 final int N = mProcessCpuTracker.countStats(); 2352 for (int i=0; i<N; i++) { 2353 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2354 if (!st.working) { 2355 continue; 2356 } 2357 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2358 int otherUTime = (st.rel_utime*perc)/100; 2359 int otherSTime = (st.rel_stime*perc)/100; 2360 totalUTime += otherUTime; 2361 totalSTime += otherSTime; 2362 if (pr != null) { 2363 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2364 if (ps == null || !ps.isActive()) { 2365 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2366 pr.info.uid, pr.processName); 2367 } 2368 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2369 st.rel_stime-otherSTime); 2370 ps.addSpeedStepTimes(cpuSpeedTimes); 2371 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2372 } else { 2373 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2374 if (ps == null || !ps.isActive()) { 2375 st.batteryStats = ps = bstats.getProcessStatsLocked( 2376 bstats.mapUid(st.uid), st.name); 2377 } 2378 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2379 st.rel_stime-otherSTime); 2380 ps.addSpeedStepTimes(cpuSpeedTimes); 2381 } 2382 } 2383 bstats.finishAddingCpuLocked(perc, totalUTime, 2384 totalSTime, cpuSpeedTimes); 2385 } 2386 } 2387 } 2388 2389 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2390 mLastWriteTime = now; 2391 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2392 } 2393 } 2394 } 2395 } 2396 2397 @Override 2398 public void batteryNeedsCpuUpdate() { 2399 updateCpuStatsNow(); 2400 } 2401 2402 @Override 2403 public void batteryPowerChanged(boolean onBattery) { 2404 // When plugging in, update the CPU stats first before changing 2405 // the plug state. 2406 updateCpuStatsNow(); 2407 synchronized (this) { 2408 synchronized(mPidsSelfLocked) { 2409 mOnBattery = DEBUG_POWER ? true : onBattery; 2410 } 2411 } 2412 } 2413 2414 /** 2415 * Initialize the application bind args. These are passed to each 2416 * process when the bindApplication() IPC is sent to the process. They're 2417 * lazily setup to make sure the services are running when they're asked for. 2418 */ 2419 private HashMap<String, IBinder> getCommonServicesLocked() { 2420 if (mAppBindArgs == null) { 2421 mAppBindArgs = new HashMap<String, IBinder>(); 2422 2423 // Setup the application init args 2424 mAppBindArgs.put("package", ServiceManager.getService("package")); 2425 mAppBindArgs.put("window", ServiceManager.getService("window")); 2426 mAppBindArgs.put(Context.ALARM_SERVICE, 2427 ServiceManager.getService(Context.ALARM_SERVICE)); 2428 } 2429 return mAppBindArgs; 2430 } 2431 2432 final void setFocusedActivityLocked(ActivityRecord r) { 2433 if (mFocusedActivity != r) { 2434 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2435 mFocusedActivity = r; 2436 if (r.task != null && r.task.voiceInteractor != null) { 2437 startRunningVoiceLocked(); 2438 } else { 2439 finishRunningVoiceLocked(); 2440 } 2441 mStackSupervisor.setFocusedStack(r); 2442 if (r != null) { 2443 mWindowManager.setFocusedApp(r.appToken, true); 2444 } 2445 applyUpdateLockStateLocked(r); 2446 } 2447 } 2448 2449 final void clearFocusedActivity(ActivityRecord r) { 2450 if (mFocusedActivity == r) { 2451 mFocusedActivity = null; 2452 } 2453 } 2454 2455 @Override 2456 public void setFocusedStack(int stackId) { 2457 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2458 synchronized (ActivityManagerService.this) { 2459 ActivityStack stack = mStackSupervisor.getStack(stackId); 2460 if (stack != null) { 2461 ActivityRecord r = stack.topRunningActivityLocked(null); 2462 if (r != null) { 2463 setFocusedActivityLocked(r); 2464 } 2465 } 2466 } 2467 } 2468 2469 @Override 2470 public void notifyActivityDrawn(IBinder token) { 2471 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2472 synchronized (this) { 2473 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2474 if (r != null) { 2475 r.task.stack.notifyActivityDrawnLocked(r); 2476 } 2477 } 2478 } 2479 2480 final void applyUpdateLockStateLocked(ActivityRecord r) { 2481 // Modifications to the UpdateLock state are done on our handler, outside 2482 // the activity manager's locks. The new state is determined based on the 2483 // state *now* of the relevant activity record. The object is passed to 2484 // the handler solely for logging detail, not to be consulted/modified. 2485 final boolean nextState = r != null && r.immersive; 2486 mHandler.sendMessage( 2487 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2488 } 2489 2490 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2491 Message msg = Message.obtain(); 2492 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2493 msg.obj = r.task.askedCompatMode ? null : r; 2494 mHandler.sendMessage(msg); 2495 } 2496 2497 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2498 String what, Object obj, ProcessRecord srcApp) { 2499 app.lastActivityTime = now; 2500 2501 if (app.activities.size() > 0) { 2502 // Don't want to touch dependent processes that are hosting activities. 2503 return index; 2504 } 2505 2506 int lrui = mLruProcesses.lastIndexOf(app); 2507 if (lrui < 0) { 2508 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2509 + what + " " + obj + " from " + srcApp); 2510 return index; 2511 } 2512 2513 if (lrui >= index) { 2514 // Don't want to cause this to move dependent processes *back* in the 2515 // list as if they were less frequently used. 2516 return index; 2517 } 2518 2519 if (lrui >= mLruProcessActivityStart) { 2520 // Don't want to touch dependent processes that are hosting activities. 2521 return index; 2522 } 2523 2524 mLruProcesses.remove(lrui); 2525 if (index > 0) { 2526 index--; 2527 } 2528 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2529 + " in LRU list: " + app); 2530 mLruProcesses.add(index, app); 2531 return index; 2532 } 2533 2534 final void removeLruProcessLocked(ProcessRecord app) { 2535 int lrui = mLruProcesses.lastIndexOf(app); 2536 if (lrui >= 0) { 2537 if (lrui <= mLruProcessActivityStart) { 2538 mLruProcessActivityStart--; 2539 } 2540 if (lrui <= mLruProcessServiceStart) { 2541 mLruProcessServiceStart--; 2542 } 2543 mLruProcesses.remove(lrui); 2544 } 2545 } 2546 2547 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2548 ProcessRecord client) { 2549 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2550 || app.treatLikeActivity; 2551 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2552 if (!activityChange && hasActivity) { 2553 // The process has activities, so we are only allowing activity-based adjustments 2554 // to move it. It should be kept in the front of the list with other 2555 // processes that have activities, and we don't want those to change their 2556 // order except due to activity operations. 2557 return; 2558 } 2559 2560 mLruSeq++; 2561 final long now = SystemClock.uptimeMillis(); 2562 app.lastActivityTime = now; 2563 2564 // First a quick reject: if the app is already at the position we will 2565 // put it, then there is nothing to do. 2566 if (hasActivity) { 2567 final int N = mLruProcesses.size(); 2568 if (N > 0 && mLruProcesses.get(N-1) == app) { 2569 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2570 return; 2571 } 2572 } else { 2573 if (mLruProcessServiceStart > 0 2574 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2575 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2576 return; 2577 } 2578 } 2579 2580 int lrui = mLruProcesses.lastIndexOf(app); 2581 2582 if (app.persistent && lrui >= 0) { 2583 // We don't care about the position of persistent processes, as long as 2584 // they are in the list. 2585 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2586 return; 2587 } 2588 2589 /* In progress: compute new position first, so we can avoid doing work 2590 if the process is not actually going to move. Not yet working. 2591 int addIndex; 2592 int nextIndex; 2593 boolean inActivity = false, inService = false; 2594 if (hasActivity) { 2595 // Process has activities, put it at the very tipsy-top. 2596 addIndex = mLruProcesses.size(); 2597 nextIndex = mLruProcessServiceStart; 2598 inActivity = true; 2599 } else if (hasService) { 2600 // Process has services, put it at the top of the service list. 2601 addIndex = mLruProcessActivityStart; 2602 nextIndex = mLruProcessServiceStart; 2603 inActivity = true; 2604 inService = true; 2605 } else { 2606 // Process not otherwise of interest, it goes to the top of the non-service area. 2607 addIndex = mLruProcessServiceStart; 2608 if (client != null) { 2609 int clientIndex = mLruProcesses.lastIndexOf(client); 2610 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2611 + app); 2612 if (clientIndex >= 0 && addIndex > clientIndex) { 2613 addIndex = clientIndex; 2614 } 2615 } 2616 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2617 } 2618 2619 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2620 + mLruProcessActivityStart + "): " + app); 2621 */ 2622 2623 if (lrui >= 0) { 2624 if (lrui < mLruProcessActivityStart) { 2625 mLruProcessActivityStart--; 2626 } 2627 if (lrui < mLruProcessServiceStart) { 2628 mLruProcessServiceStart--; 2629 } 2630 /* 2631 if (addIndex > lrui) { 2632 addIndex--; 2633 } 2634 if (nextIndex > lrui) { 2635 nextIndex--; 2636 } 2637 */ 2638 mLruProcesses.remove(lrui); 2639 } 2640 2641 /* 2642 mLruProcesses.add(addIndex, app); 2643 if (inActivity) { 2644 mLruProcessActivityStart++; 2645 } 2646 if (inService) { 2647 mLruProcessActivityStart++; 2648 } 2649 */ 2650 2651 int nextIndex; 2652 if (hasActivity) { 2653 final int N = mLruProcesses.size(); 2654 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2655 // Process doesn't have activities, but has clients with 2656 // activities... move it up, but one below the top (the top 2657 // should always have a real activity). 2658 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2659 mLruProcesses.add(N-1, app); 2660 // To keep it from spamming the LRU list (by making a bunch of clients), 2661 // we will push down any other entries owned by the app. 2662 final int uid = app.info.uid; 2663 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2664 ProcessRecord subProc = mLruProcesses.get(i); 2665 if (subProc.info.uid == uid) { 2666 // We want to push this one down the list. If the process after 2667 // it is for the same uid, however, don't do so, because we don't 2668 // want them internally to be re-ordered. 2669 if (mLruProcesses.get(i-1).info.uid != uid) { 2670 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2671 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2672 ProcessRecord tmp = mLruProcesses.get(i); 2673 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2674 mLruProcesses.set(i-1, tmp); 2675 i--; 2676 } 2677 } else { 2678 // A gap, we can stop here. 2679 break; 2680 } 2681 } 2682 } else { 2683 // Process has activities, put it at the very tipsy-top. 2684 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2685 mLruProcesses.add(app); 2686 } 2687 nextIndex = mLruProcessServiceStart; 2688 } else if (hasService) { 2689 // Process has services, put it at the top of the service list. 2690 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2691 mLruProcesses.add(mLruProcessActivityStart, app); 2692 nextIndex = mLruProcessServiceStart; 2693 mLruProcessActivityStart++; 2694 } else { 2695 // Process not otherwise of interest, it goes to the top of the non-service area. 2696 int index = mLruProcessServiceStart; 2697 if (client != null) { 2698 // If there is a client, don't allow the process to be moved up higher 2699 // in the list than that client. 2700 int clientIndex = mLruProcesses.lastIndexOf(client); 2701 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2702 + " when updating " + app); 2703 if (clientIndex <= lrui) { 2704 // Don't allow the client index restriction to push it down farther in the 2705 // list than it already is. 2706 clientIndex = lrui; 2707 } 2708 if (clientIndex >= 0 && index > clientIndex) { 2709 index = clientIndex; 2710 } 2711 } 2712 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2713 mLruProcesses.add(index, app); 2714 nextIndex = index-1; 2715 mLruProcessActivityStart++; 2716 mLruProcessServiceStart++; 2717 } 2718 2719 // If the app is currently using a content provider or service, 2720 // bump those processes as well. 2721 for (int j=app.connections.size()-1; j>=0; j--) { 2722 ConnectionRecord cr = app.connections.valueAt(j); 2723 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2724 && cr.binding.service.app != null 2725 && cr.binding.service.app.lruSeq != mLruSeq 2726 && !cr.binding.service.app.persistent) { 2727 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2728 "service connection", cr, app); 2729 } 2730 } 2731 for (int j=app.conProviders.size()-1; j>=0; j--) { 2732 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2733 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2734 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2735 "provider reference", cpr, app); 2736 } 2737 } 2738 } 2739 2740 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2741 if (uid == Process.SYSTEM_UID) { 2742 // The system gets to run in any process. If there are multiple 2743 // processes with the same uid, just pick the first (this 2744 // should never happen). 2745 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2746 if (procs == null) return null; 2747 final int N = procs.size(); 2748 for (int i = 0; i < N; i++) { 2749 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2750 } 2751 } 2752 ProcessRecord proc = mProcessNames.get(processName, uid); 2753 if (false && proc != null && !keepIfLarge 2754 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2755 && proc.lastCachedPss >= 4000) { 2756 // Turn this condition on to cause killing to happen regularly, for testing. 2757 if (proc.baseProcessTracker != null) { 2758 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2759 } 2760 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2761 + "k from cached"); 2762 } else if (proc != null && !keepIfLarge 2763 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2764 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2765 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2766 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2767 if (proc.baseProcessTracker != null) { 2768 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2769 } 2770 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2771 + "k from cached"); 2772 } 2773 } 2774 return proc; 2775 } 2776 2777 void ensurePackageDexOpt(String packageName) { 2778 IPackageManager pm = AppGlobals.getPackageManager(); 2779 try { 2780 if (pm.performDexOpt(packageName)) { 2781 mDidDexOpt = true; 2782 } 2783 } catch (RemoteException e) { 2784 } 2785 } 2786 2787 boolean isNextTransitionForward() { 2788 int transit = mWindowManager.getPendingAppTransition(); 2789 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2790 || transit == AppTransition.TRANSIT_TASK_OPEN 2791 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2792 } 2793 2794 final ProcessRecord startProcessLocked(String processName, 2795 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2796 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2797 boolean isolated, boolean keepIfLarge) { 2798 ProcessRecord app; 2799 if (!isolated) { 2800 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2801 } else { 2802 // If this is an isolated process, it can't re-use an existing process. 2803 app = null; 2804 } 2805 // We don't have to do anything more if: 2806 // (1) There is an existing application record; and 2807 // (2) The caller doesn't think it is dead, OR there is no thread 2808 // object attached to it so we know it couldn't have crashed; and 2809 // (3) There is a pid assigned to it, so it is either starting or 2810 // already running. 2811 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2812 + " app=" + app + " knownToBeDead=" + knownToBeDead 2813 + " thread=" + (app != null ? app.thread : null) 2814 + " pid=" + (app != null ? app.pid : -1)); 2815 if (app != null && app.pid > 0) { 2816 if (!knownToBeDead || app.thread == null) { 2817 // We already have the app running, or are waiting for it to 2818 // come up (we have a pid but not yet its thread), so keep it. 2819 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2820 // If this is a new package in the process, add the package to the list 2821 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2822 return app; 2823 } 2824 2825 // An application record is attached to a previous process, 2826 // clean it up now. 2827 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2828 handleAppDiedLocked(app, true, true); 2829 } 2830 2831 String hostingNameStr = hostingName != null 2832 ? hostingName.flattenToShortString() : null; 2833 2834 if (!isolated) { 2835 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2836 // If we are in the background, then check to see if this process 2837 // is bad. If so, we will just silently fail. 2838 if (mBadProcesses.get(info.processName, info.uid) != null) { 2839 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2840 + "/" + info.processName); 2841 return null; 2842 } 2843 } else { 2844 // When the user is explicitly starting a process, then clear its 2845 // crash count so that we won't make it bad until they see at 2846 // least one crash dialog again, and make the process good again 2847 // if it had been bad. 2848 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2849 + "/" + info.processName); 2850 mProcessCrashTimes.remove(info.processName, info.uid); 2851 if (mBadProcesses.get(info.processName, info.uid) != null) { 2852 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2853 UserHandle.getUserId(info.uid), info.uid, 2854 info.processName); 2855 mBadProcesses.remove(info.processName, info.uid); 2856 if (app != null) { 2857 app.bad = false; 2858 } 2859 } 2860 } 2861 } 2862 2863 if (app == null) { 2864 app = newProcessRecordLocked(info, processName, isolated); 2865 if (app == null) { 2866 Slog.w(TAG, "Failed making new process record for " 2867 + processName + "/" + info.uid + " isolated=" + isolated); 2868 return null; 2869 } 2870 mProcessNames.put(processName, app.uid, app); 2871 if (isolated) { 2872 mIsolatedProcesses.put(app.uid, app); 2873 } 2874 } else { 2875 // If this is a new package in the process, add the package to the list 2876 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2877 } 2878 2879 // If the system is not ready yet, then hold off on starting this 2880 // process until it is. 2881 if (!mProcessesReady 2882 && !isAllowedWhileBooting(info) 2883 && !allowWhileBooting) { 2884 if (!mProcessesOnHold.contains(app)) { 2885 mProcessesOnHold.add(app); 2886 } 2887 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2888 return app; 2889 } 2890 2891 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2892 return (app.pid != 0) ? app : null; 2893 } 2894 2895 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2896 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2897 } 2898 2899 private final void startProcessLocked(ProcessRecord app, 2900 String hostingType, String hostingNameStr, String abiOverride) { 2901 if (app.pid > 0 && app.pid != MY_PID) { 2902 synchronized (mPidsSelfLocked) { 2903 mPidsSelfLocked.remove(app.pid); 2904 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2905 } 2906 app.setPid(0); 2907 } 2908 2909 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2910 "startProcessLocked removing on hold: " + app); 2911 mProcessesOnHold.remove(app); 2912 2913 updateCpuStats(); 2914 2915 try { 2916 int uid = app.uid; 2917 2918 int[] gids = null; 2919 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2920 if (!app.isolated) { 2921 int[] permGids = null; 2922 try { 2923 final PackageManager pm = mContext.getPackageManager(); 2924 permGids = pm.getPackageGids(app.info.packageName); 2925 2926 if (Environment.isExternalStorageEmulated()) { 2927 if (pm.checkPermission( 2928 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2929 app.info.packageName) == PERMISSION_GRANTED) { 2930 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2931 } else { 2932 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2933 } 2934 } 2935 } catch (PackageManager.NameNotFoundException e) { 2936 Slog.w(TAG, "Unable to retrieve gids", e); 2937 } 2938 2939 /* 2940 * Add shared application and profile GIDs so applications can share some 2941 * resources like shared libraries and access user-wide resources 2942 */ 2943 if (permGids == null) { 2944 gids = new int[2]; 2945 } else { 2946 gids = new int[permGids.length + 2]; 2947 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2948 } 2949 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2950 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2951 } 2952 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2953 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2954 && mTopComponent != null 2955 && app.processName.equals(mTopComponent.getPackageName())) { 2956 uid = 0; 2957 } 2958 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2959 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2960 uid = 0; 2961 } 2962 } 2963 int debugFlags = 0; 2964 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2965 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2966 // Also turn on CheckJNI for debuggable apps. It's quite 2967 // awkward to turn on otherwise. 2968 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2969 } 2970 // Run the app in safe mode if its manifest requests so or the 2971 // system is booted in safe mode. 2972 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2973 mSafeMode == true) { 2974 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2975 } 2976 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2977 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2978 } 2979 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2980 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2981 } 2982 if ("1".equals(SystemProperties.get("debug.assert"))) { 2983 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2984 } 2985 2986 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi; 2987 if (requiredAbi == null) { 2988 requiredAbi = Build.SUPPORTED_ABIS[0]; 2989 } 2990 2991 // Start the process. It will either succeed and return a result containing 2992 // the PID of the new process, or else throw a RuntimeException. 2993 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2994 app.processName, uid, uid, gids, debugFlags, mountExternal, 2995 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2996 2997 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2998 synchronized (bs) { 2999 if (bs.isOnBattery()) { 3000 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 3001 } 3002 } 3003 3004 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3005 UserHandle.getUserId(uid), startResult.pid, uid, 3006 app.processName, hostingType, 3007 hostingNameStr != null ? hostingNameStr : ""); 3008 3009 if (app.persistent) { 3010 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3011 } 3012 3013 StringBuilder buf = mStringBuilder; 3014 buf.setLength(0); 3015 buf.append("Start proc "); 3016 buf.append(app.processName); 3017 buf.append(" for "); 3018 buf.append(hostingType); 3019 if (hostingNameStr != null) { 3020 buf.append(" "); 3021 buf.append(hostingNameStr); 3022 } 3023 buf.append(": pid="); 3024 buf.append(startResult.pid); 3025 buf.append(" uid="); 3026 buf.append(uid); 3027 buf.append(" gids={"); 3028 if (gids != null) { 3029 for (int gi=0; gi<gids.length; gi++) { 3030 if (gi != 0) buf.append(", "); 3031 buf.append(gids[gi]); 3032 3033 } 3034 } 3035 buf.append("}"); 3036 if (requiredAbi != null) { 3037 buf.append(" abi="); 3038 buf.append(requiredAbi); 3039 } 3040 Slog.i(TAG, buf.toString()); 3041 app.setPid(startResult.pid); 3042 app.usingWrapper = startResult.usingWrapper; 3043 app.removed = false; 3044 synchronized (mPidsSelfLocked) { 3045 this.mPidsSelfLocked.put(startResult.pid, app); 3046 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3047 msg.obj = app; 3048 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3049 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3050 } 3051 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 3052 app.processName, app.info.uid); 3053 if (app.isolated) { 3054 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3055 } 3056 } catch (RuntimeException e) { 3057 // XXX do better error recovery. 3058 app.setPid(0); 3059 Slog.e(TAG, "Failure starting process " + app.processName, e); 3060 } 3061 } 3062 3063 void updateUsageStats(ActivityRecord component, boolean resumed) { 3064 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3065 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3066 if (resumed) { 3067 mUsageStatsService.noteResumeComponent(component.realActivity); 3068 synchronized (stats) { 3069 stats.noteActivityResumedLocked(component.app.uid); 3070 } 3071 } else { 3072 mUsageStatsService.notePauseComponent(component.realActivity); 3073 synchronized (stats) { 3074 stats.noteActivityPausedLocked(component.app.uid); 3075 } 3076 } 3077 } 3078 3079 Intent getHomeIntent() { 3080 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3081 intent.setComponent(mTopComponent); 3082 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3083 intent.addCategory(Intent.CATEGORY_HOME); 3084 } 3085 return intent; 3086 } 3087 3088 boolean startHomeActivityLocked(int userId) { 3089 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3090 && mTopAction == null) { 3091 // We are running in factory test mode, but unable to find 3092 // the factory test app, so just sit around displaying the 3093 // error message and don't try to start anything. 3094 return false; 3095 } 3096 Intent intent = getHomeIntent(); 3097 ActivityInfo aInfo = 3098 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3099 if (aInfo != null) { 3100 intent.setComponent(new ComponentName( 3101 aInfo.applicationInfo.packageName, aInfo.name)); 3102 // Don't do this if the home app is currently being 3103 // instrumented. 3104 aInfo = new ActivityInfo(aInfo); 3105 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3106 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3107 aInfo.applicationInfo.uid, true); 3108 if (app == null || app.instrumentationClass == null) { 3109 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3110 mStackSupervisor.startHomeActivity(intent, aInfo); 3111 } 3112 } 3113 3114 return true; 3115 } 3116 3117 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3118 ActivityInfo ai = null; 3119 ComponentName comp = intent.getComponent(); 3120 try { 3121 if (comp != null) { 3122 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3123 } else { 3124 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3125 intent, 3126 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3127 flags, userId); 3128 3129 if (info != null) { 3130 ai = info.activityInfo; 3131 } 3132 } 3133 } catch (RemoteException e) { 3134 // ignore 3135 } 3136 3137 return ai; 3138 } 3139 3140 /** 3141 * Starts the "new version setup screen" if appropriate. 3142 */ 3143 void startSetupActivityLocked() { 3144 // Only do this once per boot. 3145 if (mCheckedForSetup) { 3146 return; 3147 } 3148 3149 // We will show this screen if the current one is a different 3150 // version than the last one shown, and we are not running in 3151 // low-level factory test mode. 3152 final ContentResolver resolver = mContext.getContentResolver(); 3153 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3154 Settings.Global.getInt(resolver, 3155 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3156 mCheckedForSetup = true; 3157 3158 // See if we should be showing the platform update setup UI. 3159 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3160 List<ResolveInfo> ris = mContext.getPackageManager() 3161 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3162 3163 // We don't allow third party apps to replace this. 3164 ResolveInfo ri = null; 3165 for (int i=0; ris != null && i<ris.size(); i++) { 3166 if ((ris.get(i).activityInfo.applicationInfo.flags 3167 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3168 ri = ris.get(i); 3169 break; 3170 } 3171 } 3172 3173 if (ri != null) { 3174 String vers = ri.activityInfo.metaData != null 3175 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3176 : null; 3177 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3178 vers = ri.activityInfo.applicationInfo.metaData.getString( 3179 Intent.METADATA_SETUP_VERSION); 3180 } 3181 String lastVers = Settings.Secure.getString( 3182 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3183 if (vers != null && !vers.equals(lastVers)) { 3184 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3185 intent.setComponent(new ComponentName( 3186 ri.activityInfo.packageName, ri.activityInfo.name)); 3187 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3188 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3189 } 3190 } 3191 } 3192 } 3193 3194 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3195 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3196 } 3197 3198 void enforceNotIsolatedCaller(String caller) { 3199 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3200 throw new SecurityException("Isolated process not allowed to call " + caller); 3201 } 3202 } 3203 3204 @Override 3205 public int getFrontActivityScreenCompatMode() { 3206 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3207 synchronized (this) { 3208 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3209 } 3210 } 3211 3212 @Override 3213 public void setFrontActivityScreenCompatMode(int mode) { 3214 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3215 "setFrontActivityScreenCompatMode"); 3216 synchronized (this) { 3217 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3218 } 3219 } 3220 3221 @Override 3222 public int getPackageScreenCompatMode(String packageName) { 3223 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3224 synchronized (this) { 3225 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3226 } 3227 } 3228 3229 @Override 3230 public void setPackageScreenCompatMode(String packageName, int mode) { 3231 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3232 "setPackageScreenCompatMode"); 3233 synchronized (this) { 3234 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3235 } 3236 } 3237 3238 @Override 3239 public boolean getPackageAskScreenCompat(String packageName) { 3240 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3241 synchronized (this) { 3242 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3243 } 3244 } 3245 3246 @Override 3247 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3248 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3249 "setPackageAskScreenCompat"); 3250 synchronized (this) { 3251 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3252 } 3253 } 3254 3255 private void dispatchProcessesChanged() { 3256 int N; 3257 synchronized (this) { 3258 N = mPendingProcessChanges.size(); 3259 if (mActiveProcessChanges.length < N) { 3260 mActiveProcessChanges = new ProcessChangeItem[N]; 3261 } 3262 mPendingProcessChanges.toArray(mActiveProcessChanges); 3263 mAvailProcessChanges.addAll(mPendingProcessChanges); 3264 mPendingProcessChanges.clear(); 3265 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3266 } 3267 3268 int i = mProcessObservers.beginBroadcast(); 3269 while (i > 0) { 3270 i--; 3271 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3272 if (observer != null) { 3273 try { 3274 for (int j=0; j<N; j++) { 3275 ProcessChangeItem item = mActiveProcessChanges[j]; 3276 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3277 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3278 + item.pid + " uid=" + item.uid + ": " 3279 + item.foregroundActivities); 3280 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3281 item.foregroundActivities); 3282 } 3283 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3284 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3285 + item.pid + " uid=" + item.uid + ": " + item.processState); 3286 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3287 } 3288 } 3289 } catch (RemoteException e) { 3290 } 3291 } 3292 } 3293 mProcessObservers.finishBroadcast(); 3294 } 3295 3296 private void dispatchProcessDied(int pid, int uid) { 3297 int i = mProcessObservers.beginBroadcast(); 3298 while (i > 0) { 3299 i--; 3300 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3301 if (observer != null) { 3302 try { 3303 observer.onProcessDied(pid, uid); 3304 } catch (RemoteException e) { 3305 } 3306 } 3307 } 3308 mProcessObservers.finishBroadcast(); 3309 } 3310 3311 final void doPendingActivityLaunchesLocked(boolean doResume) { 3312 final int N = mPendingActivityLaunches.size(); 3313 if (N <= 0) { 3314 return; 3315 } 3316 for (int i=0; i<N; i++) { 3317 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3318 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3319 doResume && i == (N-1), null); 3320 } 3321 mPendingActivityLaunches.clear(); 3322 } 3323 3324 @Override 3325 public final int startActivity(IApplicationThread caller, String callingPackage, 3326 Intent intent, String resolvedType, IBinder resultTo, 3327 String resultWho, int requestCode, int startFlags, 3328 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3329 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3330 resultWho, requestCode, 3331 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3332 } 3333 3334 @Override 3335 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3336 Intent intent, String resolvedType, IBinder resultTo, 3337 String resultWho, int requestCode, int startFlags, 3338 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3339 enforceNotIsolatedCaller("startActivity"); 3340 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3341 false, true, "startActivity", null); 3342 // TODO: Switch to user app stacks here. 3343 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3344 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3345 null, null, options, userId, null); 3346 } 3347 3348 @Override 3349 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3350 Intent intent, String resolvedType, IBinder resultTo, 3351 String resultWho, int requestCode, int startFlags, String profileFile, 3352 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3353 enforceNotIsolatedCaller("startActivityAndWait"); 3354 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3355 false, true, "startActivityAndWait", null); 3356 WaitResult res = new WaitResult(); 3357 // TODO: Switch to user app stacks here. 3358 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3359 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3360 res, null, options, UserHandle.getCallingUserId(), null); 3361 return res; 3362 } 3363 3364 @Override 3365 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3366 Intent intent, String resolvedType, IBinder resultTo, 3367 String resultWho, int requestCode, int startFlags, Configuration config, 3368 Bundle options, int userId) { 3369 enforceNotIsolatedCaller("startActivityWithConfig"); 3370 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3371 false, true, "startActivityWithConfig", null); 3372 // TODO: Switch to user app stacks here. 3373 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3374 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3375 null, null, null, config, options, userId, null); 3376 return ret; 3377 } 3378 3379 @Override 3380 public int startActivityIntentSender(IApplicationThread caller, 3381 IntentSender intent, Intent fillInIntent, String resolvedType, 3382 IBinder resultTo, String resultWho, int requestCode, 3383 int flagsMask, int flagsValues, Bundle options) { 3384 enforceNotIsolatedCaller("startActivityIntentSender"); 3385 // Refuse possible leaked file descriptors 3386 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3387 throw new IllegalArgumentException("File descriptors passed in Intent"); 3388 } 3389 3390 IIntentSender sender = intent.getTarget(); 3391 if (!(sender instanceof PendingIntentRecord)) { 3392 throw new IllegalArgumentException("Bad PendingIntent object"); 3393 } 3394 3395 PendingIntentRecord pir = (PendingIntentRecord)sender; 3396 3397 synchronized (this) { 3398 // If this is coming from the currently resumed activity, it is 3399 // effectively saying that app switches are allowed at this point. 3400 final ActivityStack stack = getFocusedStack(); 3401 if (stack.mResumedActivity != null && 3402 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3403 mAppSwitchesAllowedTime = 0; 3404 } 3405 } 3406 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3407 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3408 return ret; 3409 } 3410 3411 @Override 3412 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3413 Intent intent, String resolvedType, IVoiceInteractionSession session, 3414 IVoiceInteractor interactor, int startFlags, String profileFile, 3415 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3416 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3417 != PackageManager.PERMISSION_GRANTED) { 3418 String msg = "Permission Denial: startVoiceActivity() from pid=" 3419 + Binder.getCallingPid() 3420 + ", uid=" + Binder.getCallingUid() 3421 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3422 Slog.w(TAG, msg); 3423 throw new SecurityException(msg); 3424 } 3425 if (session == null || interactor == null) { 3426 throw new NullPointerException("null session or interactor"); 3427 } 3428 userId = handleIncomingUser(callingPid, callingUid, userId, 3429 false, true, "startVoiceActivity", null); 3430 // TODO: Switch to user app stacks here. 3431 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3432 resolvedType, session, interactor, null, null, 0, startFlags, 3433 profileFile, profileFd, null, null, options, userId, null); 3434 } 3435 3436 @Override 3437 public boolean startNextMatchingActivity(IBinder callingActivity, 3438 Intent intent, Bundle options) { 3439 // Refuse possible leaked file descriptors 3440 if (intent != null && intent.hasFileDescriptors() == true) { 3441 throw new IllegalArgumentException("File descriptors passed in Intent"); 3442 } 3443 3444 synchronized (this) { 3445 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3446 if (r == null) { 3447 ActivityOptions.abort(options); 3448 return false; 3449 } 3450 if (r.app == null || r.app.thread == null) { 3451 // The caller is not running... d'oh! 3452 ActivityOptions.abort(options); 3453 return false; 3454 } 3455 intent = new Intent(intent); 3456 // The caller is not allowed to change the data. 3457 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3458 // And we are resetting to find the next component... 3459 intent.setComponent(null); 3460 3461 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3462 3463 ActivityInfo aInfo = null; 3464 try { 3465 List<ResolveInfo> resolves = 3466 AppGlobals.getPackageManager().queryIntentActivities( 3467 intent, r.resolvedType, 3468 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3469 UserHandle.getCallingUserId()); 3470 3471 // Look for the original activity in the list... 3472 final int N = resolves != null ? resolves.size() : 0; 3473 for (int i=0; i<N; i++) { 3474 ResolveInfo rInfo = resolves.get(i); 3475 if (rInfo.activityInfo.packageName.equals(r.packageName) 3476 && rInfo.activityInfo.name.equals(r.info.name)) { 3477 // We found the current one... the next matching is 3478 // after it. 3479 i++; 3480 if (i<N) { 3481 aInfo = resolves.get(i).activityInfo; 3482 } 3483 if (debug) { 3484 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3485 + "/" + r.info.name); 3486 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3487 + "/" + aInfo.name); 3488 } 3489 break; 3490 } 3491 } 3492 } catch (RemoteException e) { 3493 } 3494 3495 if (aInfo == null) { 3496 // Nobody who is next! 3497 ActivityOptions.abort(options); 3498 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3499 return false; 3500 } 3501 3502 intent.setComponent(new ComponentName( 3503 aInfo.applicationInfo.packageName, aInfo.name)); 3504 intent.setFlags(intent.getFlags()&~( 3505 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3506 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3507 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3508 Intent.FLAG_ACTIVITY_NEW_TASK)); 3509 3510 // Okay now we need to start the new activity, replacing the 3511 // currently running activity. This is a little tricky because 3512 // we want to start the new one as if the current one is finished, 3513 // but not finish the current one first so that there is no flicker. 3514 // And thus... 3515 final boolean wasFinishing = r.finishing; 3516 r.finishing = true; 3517 3518 // Propagate reply information over to the new activity. 3519 final ActivityRecord resultTo = r.resultTo; 3520 final String resultWho = r.resultWho; 3521 final int requestCode = r.requestCode; 3522 r.resultTo = null; 3523 if (resultTo != null) { 3524 resultTo.removeResultsLocked(r, resultWho, requestCode); 3525 } 3526 3527 final long origId = Binder.clearCallingIdentity(); 3528 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3529 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3530 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3531 options, false, null, null); 3532 Binder.restoreCallingIdentity(origId); 3533 3534 r.finishing = wasFinishing; 3535 if (res != ActivityManager.START_SUCCESS) { 3536 return false; 3537 } 3538 return true; 3539 } 3540 } 3541 3542 final int startActivityInPackage(int uid, String callingPackage, 3543 Intent intent, String resolvedType, IBinder resultTo, 3544 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3545 IActivityContainer container) { 3546 3547 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3548 false, true, "startActivityInPackage", null); 3549 3550 // TODO: Switch to user app stacks here. 3551 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3552 null, null, resultTo, resultWho, requestCode, startFlags, 3553 null, null, null, null, options, userId, container); 3554 return ret; 3555 } 3556 3557 @Override 3558 public final int startActivities(IApplicationThread caller, String callingPackage, 3559 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3560 int userId) { 3561 enforceNotIsolatedCaller("startActivities"); 3562 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3563 false, true, "startActivity", null); 3564 // TODO: Switch to user app stacks here. 3565 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3566 resolvedTypes, resultTo, options, userId); 3567 return ret; 3568 } 3569 3570 final int startActivitiesInPackage(int uid, String callingPackage, 3571 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3572 Bundle options, int userId) { 3573 3574 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3575 false, true, "startActivityInPackage", null); 3576 // TODO: Switch to user app stacks here. 3577 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3578 resultTo, options, userId); 3579 return ret; 3580 } 3581 3582 final void addRecentTaskLocked(TaskRecord task) { 3583 int N = mRecentTasks.size(); 3584 // Quick case: check if the top-most recent task is the same. 3585 if (N > 0 && mRecentTasks.get(0) == task) { 3586 return; 3587 } 3588 // Another quick case: never add voice sessions. 3589 if (task.voiceSession != null) { 3590 return; 3591 } 3592 // Remove any existing entries that are the same kind of task. 3593 final Intent intent = task.intent; 3594 final boolean document = intent != null && intent.isDocument(); 3595 final ComponentName comp = intent.getComponent(); 3596 3597 int maxRecents = task.maxRecents - 1; 3598 for (int i=0; i<N; i++) { 3599 TaskRecord tr = mRecentTasks.get(i); 3600 if (task != tr) { 3601 if (task.userId != tr.userId) { 3602 continue; 3603 } 3604 final Intent trIntent = tr.intent; 3605 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3606 (intent == null || !intent.filterEquals(trIntent))) { 3607 continue; 3608 } 3609 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3610 if (document && trIsDocument) { 3611 // These are the same document activity (not necessarily the same doc). 3612 if (maxRecents > 0) { 3613 --maxRecents; 3614 continue; 3615 } 3616 // Hit the maximum number of documents for this task. Fall through 3617 // and remove this document from recents. 3618 } else if (document || trIsDocument) { 3619 // Only one of these is a document. Not the droid we're looking for. 3620 continue; 3621 } 3622 } 3623 3624 // Either task and tr are the same or, their affinities match or their intents match 3625 // and neither of them is a document, or they are documents using the same activity 3626 // and their maxRecents has been reached. 3627 tr.disposeThumbnail(); 3628 mRecentTasks.remove(i); 3629 i--; 3630 N--; 3631 if (task.intent == null) { 3632 // If the new recent task we are adding is not fully 3633 // specified, then replace it with the existing recent task. 3634 task = tr; 3635 } 3636 mTaskPersister.notify(tr, false); 3637 } 3638 if (N >= MAX_RECENT_TASKS) { 3639 mRecentTasks.remove(N-1).disposeThumbnail(); 3640 } 3641 mRecentTasks.add(0, task); 3642 } 3643 3644 @Override 3645 public void reportActivityFullyDrawn(IBinder token) { 3646 synchronized (this) { 3647 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3648 if (r == null) { 3649 return; 3650 } 3651 r.reportFullyDrawnLocked(); 3652 } 3653 } 3654 3655 @Override 3656 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3657 synchronized (this) { 3658 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3659 if (r == null) { 3660 return; 3661 } 3662 final long origId = Binder.clearCallingIdentity(); 3663 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3664 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3665 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3666 if (config != null) { 3667 r.frozenBeforeDestroy = true; 3668 if (!updateConfigurationLocked(config, r, false, false)) { 3669 mStackSupervisor.resumeTopActivitiesLocked(); 3670 } 3671 } 3672 Binder.restoreCallingIdentity(origId); 3673 } 3674 } 3675 3676 @Override 3677 public int getRequestedOrientation(IBinder token) { 3678 synchronized (this) { 3679 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3680 if (r == null) { 3681 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3682 } 3683 return mWindowManager.getAppOrientation(r.appToken); 3684 } 3685 } 3686 3687 /** 3688 * This is the internal entry point for handling Activity.finish(). 3689 * 3690 * @param token The Binder token referencing the Activity we want to finish. 3691 * @param resultCode Result code, if any, from this Activity. 3692 * @param resultData Result data (Intent), if any, from this Activity. 3693 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3694 * the root Activity in the task. 3695 * 3696 * @return Returns true if the activity successfully finished, or false if it is still running. 3697 */ 3698 @Override 3699 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3700 boolean finishTask) { 3701 // Refuse possible leaked file descriptors 3702 if (resultData != null && resultData.hasFileDescriptors() == true) { 3703 throw new IllegalArgumentException("File descriptors passed in Intent"); 3704 } 3705 3706 synchronized(this) { 3707 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3708 if (r == null) { 3709 return true; 3710 } 3711 // Keep track of the root activity of the task before we finish it 3712 TaskRecord tr = r.task; 3713 ActivityRecord rootR = tr.getRootActivity(); 3714 // Do not allow task to finish in Lock Task mode. 3715 if (tr == mStackSupervisor.mLockTaskModeTask) { 3716 if (rootR == r) { 3717 return false; 3718 } 3719 } 3720 if (mController != null) { 3721 // Find the first activity that is not finishing. 3722 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3723 if (next != null) { 3724 // ask watcher if this is allowed 3725 boolean resumeOK = true; 3726 try { 3727 resumeOK = mController.activityResuming(next.packageName); 3728 } catch (RemoteException e) { 3729 mController = null; 3730 Watchdog.getInstance().setActivityController(null); 3731 } 3732 3733 if (!resumeOK) { 3734 return false; 3735 } 3736 } 3737 } 3738 final long origId = Binder.clearCallingIdentity(); 3739 try { 3740 boolean res; 3741 if (finishTask && r == rootR) { 3742 // If requested, remove the task that is associated to this activity only if it 3743 // was the root activity in the task. The result code and data is ignored because 3744 // we don't support returning them across task boundaries. 3745 res = removeTaskByIdLocked(tr.taskId, 0); 3746 } else { 3747 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3748 resultData, "app-request", true); 3749 } 3750 return res; 3751 } finally { 3752 Binder.restoreCallingIdentity(origId); 3753 } 3754 } 3755 } 3756 3757 @Override 3758 public final void finishHeavyWeightApp() { 3759 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3760 != PackageManager.PERMISSION_GRANTED) { 3761 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3762 + Binder.getCallingPid() 3763 + ", uid=" + Binder.getCallingUid() 3764 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3765 Slog.w(TAG, msg); 3766 throw new SecurityException(msg); 3767 } 3768 3769 synchronized(this) { 3770 if (mHeavyWeightProcess == null) { 3771 return; 3772 } 3773 3774 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3775 mHeavyWeightProcess.activities); 3776 for (int i=0; i<activities.size(); i++) { 3777 ActivityRecord r = activities.get(i); 3778 if (!r.finishing) { 3779 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3780 null, "finish-heavy", true); 3781 } 3782 } 3783 3784 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3785 mHeavyWeightProcess.userId, 0)); 3786 mHeavyWeightProcess = null; 3787 } 3788 } 3789 3790 @Override 3791 public void crashApplication(int uid, int initialPid, String packageName, 3792 String message) { 3793 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3794 != PackageManager.PERMISSION_GRANTED) { 3795 String msg = "Permission Denial: crashApplication() from pid=" 3796 + Binder.getCallingPid() 3797 + ", uid=" + Binder.getCallingUid() 3798 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3799 Slog.w(TAG, msg); 3800 throw new SecurityException(msg); 3801 } 3802 3803 synchronized(this) { 3804 ProcessRecord proc = null; 3805 3806 // Figure out which process to kill. We don't trust that initialPid 3807 // still has any relation to current pids, so must scan through the 3808 // list. 3809 synchronized (mPidsSelfLocked) { 3810 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3811 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3812 if (p.uid != uid) { 3813 continue; 3814 } 3815 if (p.pid == initialPid) { 3816 proc = p; 3817 break; 3818 } 3819 if (p.pkgList.containsKey(packageName)) { 3820 proc = p; 3821 } 3822 } 3823 } 3824 3825 if (proc == null) { 3826 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3827 + " initialPid=" + initialPid 3828 + " packageName=" + packageName); 3829 return; 3830 } 3831 3832 if (proc.thread != null) { 3833 if (proc.pid == Process.myPid()) { 3834 Log.w(TAG, "crashApplication: trying to crash self!"); 3835 return; 3836 } 3837 long ident = Binder.clearCallingIdentity(); 3838 try { 3839 proc.thread.scheduleCrash(message); 3840 } catch (RemoteException e) { 3841 } 3842 Binder.restoreCallingIdentity(ident); 3843 } 3844 } 3845 } 3846 3847 @Override 3848 public final void finishSubActivity(IBinder token, String resultWho, 3849 int requestCode) { 3850 synchronized(this) { 3851 final long origId = Binder.clearCallingIdentity(); 3852 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3853 if (r != null) { 3854 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3855 } 3856 Binder.restoreCallingIdentity(origId); 3857 } 3858 } 3859 3860 @Override 3861 public boolean finishActivityAffinity(IBinder token) { 3862 synchronized(this) { 3863 final long origId = Binder.clearCallingIdentity(); 3864 try { 3865 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3866 3867 ActivityRecord rootR = r.task.getRootActivity(); 3868 // Do not allow task to finish in Lock Task mode. 3869 if (r.task == mStackSupervisor.mLockTaskModeTask) { 3870 if (rootR == r) { 3871 Binder.restoreCallingIdentity(origId); 3872 return false; 3873 } 3874 } 3875 boolean res = false; 3876 if (r != null) { 3877 res = r.task.stack.finishActivityAffinityLocked(r); 3878 } 3879 return res; 3880 } finally { 3881 Binder.restoreCallingIdentity(origId); 3882 } 3883 } 3884 } 3885 3886 @Override 3887 public boolean willActivityBeVisible(IBinder token) { 3888 synchronized(this) { 3889 ActivityStack stack = ActivityRecord.getStackLocked(token); 3890 if (stack != null) { 3891 return stack.willActivityBeVisibleLocked(token); 3892 } 3893 return false; 3894 } 3895 } 3896 3897 @Override 3898 public void overridePendingTransition(IBinder token, String packageName, 3899 int enterAnim, int exitAnim) { 3900 synchronized(this) { 3901 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3902 if (self == null) { 3903 return; 3904 } 3905 3906 final long origId = Binder.clearCallingIdentity(); 3907 3908 if (self.state == ActivityState.RESUMED 3909 || self.state == ActivityState.PAUSING) { 3910 mWindowManager.overridePendingAppTransition(packageName, 3911 enterAnim, exitAnim, null); 3912 } 3913 3914 Binder.restoreCallingIdentity(origId); 3915 } 3916 } 3917 3918 /** 3919 * Main function for removing an existing process from the activity manager 3920 * as a result of that process going away. Clears out all connections 3921 * to the process. 3922 */ 3923 private final void handleAppDiedLocked(ProcessRecord app, 3924 boolean restarting, boolean allowRestart) { 3925 int pid = app.pid; 3926 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3927 if (!restarting) { 3928 removeLruProcessLocked(app); 3929 if (pid > 0) { 3930 ProcessList.remove(pid); 3931 } 3932 } 3933 3934 if (mProfileProc == app) { 3935 clearProfilerLocked(); 3936 } 3937 3938 // Remove this application's activities from active lists. 3939 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3940 3941 app.activities.clear(); 3942 3943 if (app.instrumentationClass != null) { 3944 Slog.w(TAG, "Crash of app " + app.processName 3945 + " running instrumentation " + app.instrumentationClass); 3946 Bundle info = new Bundle(); 3947 info.putString("shortMsg", "Process crashed."); 3948 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3949 } 3950 3951 if (!restarting) { 3952 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3953 // If there was nothing to resume, and we are not already 3954 // restarting this process, but there is a visible activity that 3955 // is hosted by the process... then make sure all visible 3956 // activities are running, taking care of restarting this 3957 // process. 3958 if (hasVisibleActivities) { 3959 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3960 } 3961 } 3962 } 3963 } 3964 3965 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3966 IBinder threadBinder = thread.asBinder(); 3967 // Find the application record. 3968 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3969 ProcessRecord rec = mLruProcesses.get(i); 3970 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3971 return i; 3972 } 3973 } 3974 return -1; 3975 } 3976 3977 final ProcessRecord getRecordForAppLocked( 3978 IApplicationThread thread) { 3979 if (thread == null) { 3980 return null; 3981 } 3982 3983 int appIndex = getLRURecordIndexForAppLocked(thread); 3984 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3985 } 3986 3987 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3988 // If there are no longer any background processes running, 3989 // and the app that died was not running instrumentation, 3990 // then tell everyone we are now low on memory. 3991 boolean haveBg = false; 3992 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3993 ProcessRecord rec = mLruProcesses.get(i); 3994 if (rec.thread != null 3995 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3996 haveBg = true; 3997 break; 3998 } 3999 } 4000 4001 if (!haveBg) { 4002 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4003 if (doReport) { 4004 long now = SystemClock.uptimeMillis(); 4005 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4006 doReport = false; 4007 } else { 4008 mLastMemUsageReportTime = now; 4009 } 4010 } 4011 final ArrayList<ProcessMemInfo> memInfos 4012 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4013 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4014 long now = SystemClock.uptimeMillis(); 4015 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4016 ProcessRecord rec = mLruProcesses.get(i); 4017 if (rec == dyingProc || rec.thread == null) { 4018 continue; 4019 } 4020 if (doReport) { 4021 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4022 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4023 } 4024 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4025 // The low memory report is overriding any current 4026 // state for a GC request. Make sure to do 4027 // heavy/important/visible/foreground processes first. 4028 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4029 rec.lastRequestedGc = 0; 4030 } else { 4031 rec.lastRequestedGc = rec.lastLowMemory; 4032 } 4033 rec.reportLowMemory = true; 4034 rec.lastLowMemory = now; 4035 mProcessesToGc.remove(rec); 4036 addProcessToGcListLocked(rec); 4037 } 4038 } 4039 if (doReport) { 4040 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4041 mHandler.sendMessage(msg); 4042 } 4043 scheduleAppGcsLocked(); 4044 } 4045 } 4046 4047 final void appDiedLocked(ProcessRecord app, int pid, 4048 IApplicationThread thread) { 4049 4050 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4051 synchronized (stats) { 4052 stats.noteProcessDiedLocked(app.info.uid, pid); 4053 } 4054 4055 // Clean up already done if the process has been re-started. 4056 if (app.pid == pid && app.thread != null && 4057 app.thread.asBinder() == thread.asBinder()) { 4058 boolean doLowMem = app.instrumentationClass == null; 4059 boolean doOomAdj = doLowMem; 4060 if (!app.killedByAm) { 4061 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4062 + ") has died."); 4063 mAllowLowerMemLevel = true; 4064 } else { 4065 // Note that we always want to do oom adj to update our state with the 4066 // new number of procs. 4067 mAllowLowerMemLevel = false; 4068 doLowMem = false; 4069 } 4070 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4071 if (DEBUG_CLEANUP) Slog.v( 4072 TAG, "Dying app: " + app + ", pid: " + pid 4073 + ", thread: " + thread.asBinder()); 4074 handleAppDiedLocked(app, false, true); 4075 4076 if (doOomAdj) { 4077 updateOomAdjLocked(); 4078 } 4079 if (doLowMem) { 4080 doLowMemReportIfNeededLocked(app); 4081 } 4082 } else if (app.pid != pid) { 4083 // A new process has already been started. 4084 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4085 + ") has died and restarted (pid " + app.pid + ")."); 4086 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4087 } else if (DEBUG_PROCESSES) { 4088 Slog.d(TAG, "Received spurious death notification for thread " 4089 + thread.asBinder()); 4090 } 4091 } 4092 4093 /** 4094 * If a stack trace dump file is configured, dump process stack traces. 4095 * @param clearTraces causes the dump file to be erased prior to the new 4096 * traces being written, if true; when false, the new traces will be 4097 * appended to any existing file content. 4098 * @param firstPids of dalvik VM processes to dump stack traces for first 4099 * @param lastPids of dalvik VM processes to dump stack traces for last 4100 * @param nativeProcs optional list of native process names to dump stack crawls 4101 * @return file containing stack traces, or null if no dump file is configured 4102 */ 4103 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4104 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4105 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4106 if (tracesPath == null || tracesPath.length() == 0) { 4107 return null; 4108 } 4109 4110 File tracesFile = new File(tracesPath); 4111 try { 4112 File tracesDir = tracesFile.getParentFile(); 4113 if (!tracesDir.exists()) { 4114 tracesFile.mkdirs(); 4115 if (!SELinux.restorecon(tracesDir)) { 4116 return null; 4117 } 4118 } 4119 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4120 4121 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4122 tracesFile.createNewFile(); 4123 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4124 } catch (IOException e) { 4125 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4126 return null; 4127 } 4128 4129 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4130 return tracesFile; 4131 } 4132 4133 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4134 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4135 // Use a FileObserver to detect when traces finish writing. 4136 // The order of traces is considered important to maintain for legibility. 4137 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4138 @Override 4139 public synchronized void onEvent(int event, String path) { notify(); } 4140 }; 4141 4142 try { 4143 observer.startWatching(); 4144 4145 // First collect all of the stacks of the most important pids. 4146 if (firstPids != null) { 4147 try { 4148 int num = firstPids.size(); 4149 for (int i = 0; i < num; i++) { 4150 synchronized (observer) { 4151 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4152 observer.wait(200); // Wait for write-close, give up after 200msec 4153 } 4154 } 4155 } catch (InterruptedException e) { 4156 Log.wtf(TAG, e); 4157 } 4158 } 4159 4160 // Next collect the stacks of the native pids 4161 if (nativeProcs != null) { 4162 int[] pids = Process.getPidsForCommands(nativeProcs); 4163 if (pids != null) { 4164 for (int pid : pids) { 4165 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4166 } 4167 } 4168 } 4169 4170 // Lastly, measure CPU usage. 4171 if (processCpuTracker != null) { 4172 processCpuTracker.init(); 4173 System.gc(); 4174 processCpuTracker.update(); 4175 try { 4176 synchronized (processCpuTracker) { 4177 processCpuTracker.wait(500); // measure over 1/2 second. 4178 } 4179 } catch (InterruptedException e) { 4180 } 4181 processCpuTracker.update(); 4182 4183 // We'll take the stack crawls of just the top apps using CPU. 4184 final int N = processCpuTracker.countWorkingStats(); 4185 int numProcs = 0; 4186 for (int i=0; i<N && numProcs<5; i++) { 4187 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4188 if (lastPids.indexOfKey(stats.pid) >= 0) { 4189 numProcs++; 4190 try { 4191 synchronized (observer) { 4192 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4193 observer.wait(200); // Wait for write-close, give up after 200msec 4194 } 4195 } catch (InterruptedException e) { 4196 Log.wtf(TAG, e); 4197 } 4198 4199 } 4200 } 4201 } 4202 } finally { 4203 observer.stopWatching(); 4204 } 4205 } 4206 4207 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4208 if (true || IS_USER_BUILD) { 4209 return; 4210 } 4211 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4212 if (tracesPath == null || tracesPath.length() == 0) { 4213 return; 4214 } 4215 4216 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4217 StrictMode.allowThreadDiskWrites(); 4218 try { 4219 final File tracesFile = new File(tracesPath); 4220 final File tracesDir = tracesFile.getParentFile(); 4221 final File tracesTmp = new File(tracesDir, "__tmp__"); 4222 try { 4223 if (!tracesDir.exists()) { 4224 tracesFile.mkdirs(); 4225 if (!SELinux.restorecon(tracesDir.getPath())) { 4226 return; 4227 } 4228 } 4229 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4230 4231 if (tracesFile.exists()) { 4232 tracesTmp.delete(); 4233 tracesFile.renameTo(tracesTmp); 4234 } 4235 StringBuilder sb = new StringBuilder(); 4236 Time tobj = new Time(); 4237 tobj.set(System.currentTimeMillis()); 4238 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4239 sb.append(": "); 4240 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4241 sb.append(" since "); 4242 sb.append(msg); 4243 FileOutputStream fos = new FileOutputStream(tracesFile); 4244 fos.write(sb.toString().getBytes()); 4245 if (app == null) { 4246 fos.write("\n*** No application process!".getBytes()); 4247 } 4248 fos.close(); 4249 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4250 } catch (IOException e) { 4251 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4252 return; 4253 } 4254 4255 if (app != null) { 4256 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4257 firstPids.add(app.pid); 4258 dumpStackTraces(tracesPath, firstPids, null, null, null); 4259 } 4260 4261 File lastTracesFile = null; 4262 File curTracesFile = null; 4263 for (int i=9; i>=0; i--) { 4264 String name = String.format(Locale.US, "slow%02d.txt", i); 4265 curTracesFile = new File(tracesDir, name); 4266 if (curTracesFile.exists()) { 4267 if (lastTracesFile != null) { 4268 curTracesFile.renameTo(lastTracesFile); 4269 } else { 4270 curTracesFile.delete(); 4271 } 4272 } 4273 lastTracesFile = curTracesFile; 4274 } 4275 tracesFile.renameTo(curTracesFile); 4276 if (tracesTmp.exists()) { 4277 tracesTmp.renameTo(tracesFile); 4278 } 4279 } finally { 4280 StrictMode.setThreadPolicy(oldPolicy); 4281 } 4282 } 4283 4284 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4285 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4286 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4287 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4288 4289 if (mController != null) { 4290 try { 4291 // 0 == continue, -1 = kill process immediately 4292 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4293 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4294 } catch (RemoteException e) { 4295 mController = null; 4296 Watchdog.getInstance().setActivityController(null); 4297 } 4298 } 4299 4300 long anrTime = SystemClock.uptimeMillis(); 4301 if (MONITOR_CPU_USAGE) { 4302 updateCpuStatsNow(); 4303 } 4304 4305 synchronized (this) { 4306 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4307 if (mShuttingDown) { 4308 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4309 return; 4310 } else if (app.notResponding) { 4311 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4312 return; 4313 } else if (app.crashing) { 4314 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4315 return; 4316 } 4317 4318 // In case we come through here for the same app before completing 4319 // this one, mark as anring now so we will bail out. 4320 app.notResponding = true; 4321 4322 // Log the ANR to the event log. 4323 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4324 app.processName, app.info.flags, annotation); 4325 4326 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4327 firstPids.add(app.pid); 4328 4329 int parentPid = app.pid; 4330 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4331 if (parentPid != app.pid) firstPids.add(parentPid); 4332 4333 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4334 4335 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4336 ProcessRecord r = mLruProcesses.get(i); 4337 if (r != null && r.thread != null) { 4338 int pid = r.pid; 4339 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4340 if (r.persistent) { 4341 firstPids.add(pid); 4342 } else { 4343 lastPids.put(pid, Boolean.TRUE); 4344 } 4345 } 4346 } 4347 } 4348 } 4349 4350 // Log the ANR to the main log. 4351 StringBuilder info = new StringBuilder(); 4352 info.setLength(0); 4353 info.append("ANR in ").append(app.processName); 4354 if (activity != null && activity.shortComponentName != null) { 4355 info.append(" (").append(activity.shortComponentName).append(")"); 4356 } 4357 info.append("\n"); 4358 info.append("PID: ").append(app.pid).append("\n"); 4359 if (annotation != null) { 4360 info.append("Reason: ").append(annotation).append("\n"); 4361 } 4362 if (parent != null && parent != activity) { 4363 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4364 } 4365 4366 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4367 4368 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4369 NATIVE_STACKS_OF_INTEREST); 4370 4371 String cpuInfo = null; 4372 if (MONITOR_CPU_USAGE) { 4373 updateCpuStatsNow(); 4374 synchronized (mProcessCpuThread) { 4375 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4376 } 4377 info.append(processCpuTracker.printCurrentLoad()); 4378 info.append(cpuInfo); 4379 } 4380 4381 info.append(processCpuTracker.printCurrentState(anrTime)); 4382 4383 Slog.e(TAG, info.toString()); 4384 if (tracesFile == null) { 4385 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4386 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4387 } 4388 4389 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4390 cpuInfo, tracesFile, null); 4391 4392 if (mController != null) { 4393 try { 4394 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4395 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4396 if (res != 0) { 4397 if (res < 0 && app.pid != MY_PID) { 4398 Process.killProcess(app.pid); 4399 } else { 4400 synchronized (this) { 4401 mServices.scheduleServiceTimeoutLocked(app); 4402 } 4403 } 4404 return; 4405 } 4406 } catch (RemoteException e) { 4407 mController = null; 4408 Watchdog.getInstance().setActivityController(null); 4409 } 4410 } 4411 4412 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4413 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4414 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4415 4416 synchronized (this) { 4417 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4418 killUnneededProcessLocked(app, "background ANR"); 4419 return; 4420 } 4421 4422 // Set the app's notResponding state, and look up the errorReportReceiver 4423 makeAppNotRespondingLocked(app, 4424 activity != null ? activity.shortComponentName : null, 4425 annotation != null ? "ANR " + annotation : "ANR", 4426 info.toString()); 4427 4428 // Bring up the infamous App Not Responding dialog 4429 Message msg = Message.obtain(); 4430 HashMap<String, Object> map = new HashMap<String, Object>(); 4431 msg.what = SHOW_NOT_RESPONDING_MSG; 4432 msg.obj = map; 4433 msg.arg1 = aboveSystem ? 1 : 0; 4434 map.put("app", app); 4435 if (activity != null) { 4436 map.put("activity", activity); 4437 } 4438 4439 mHandler.sendMessage(msg); 4440 } 4441 } 4442 4443 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4444 if (!mLaunchWarningShown) { 4445 mLaunchWarningShown = true; 4446 mHandler.post(new Runnable() { 4447 @Override 4448 public void run() { 4449 synchronized (ActivityManagerService.this) { 4450 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4451 d.show(); 4452 mHandler.postDelayed(new Runnable() { 4453 @Override 4454 public void run() { 4455 synchronized (ActivityManagerService.this) { 4456 d.dismiss(); 4457 mLaunchWarningShown = false; 4458 } 4459 } 4460 }, 4000); 4461 } 4462 } 4463 }); 4464 } 4465 } 4466 4467 @Override 4468 public boolean clearApplicationUserData(final String packageName, 4469 final IPackageDataObserver observer, int userId) { 4470 enforceNotIsolatedCaller("clearApplicationUserData"); 4471 int uid = Binder.getCallingUid(); 4472 int pid = Binder.getCallingPid(); 4473 userId = handleIncomingUser(pid, uid, 4474 userId, false, true, "clearApplicationUserData", null); 4475 long callingId = Binder.clearCallingIdentity(); 4476 try { 4477 IPackageManager pm = AppGlobals.getPackageManager(); 4478 int pkgUid = -1; 4479 synchronized(this) { 4480 try { 4481 pkgUid = pm.getPackageUid(packageName, userId); 4482 } catch (RemoteException e) { 4483 } 4484 if (pkgUid == -1) { 4485 Slog.w(TAG, "Invalid packageName: " + packageName); 4486 if (observer != null) { 4487 try { 4488 observer.onRemoveCompleted(packageName, false); 4489 } catch (RemoteException e) { 4490 Slog.i(TAG, "Observer no longer exists."); 4491 } 4492 } 4493 return false; 4494 } 4495 if (uid == pkgUid || checkComponentPermission( 4496 android.Manifest.permission.CLEAR_APP_USER_DATA, 4497 pid, uid, -1, true) 4498 == PackageManager.PERMISSION_GRANTED) { 4499 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4500 } else { 4501 throw new SecurityException("PID " + pid + " does not have permission " 4502 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4503 + " of package " + packageName); 4504 } 4505 } 4506 4507 try { 4508 // Clear application user data 4509 pm.clearApplicationUserData(packageName, observer, userId); 4510 4511 // Remove all permissions granted from/to this package 4512 removeUriPermissionsForPackageLocked(packageName, userId, true); 4513 4514 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4515 Uri.fromParts("package", packageName, null)); 4516 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4517 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4518 null, null, 0, null, null, null, false, false, userId); 4519 } catch (RemoteException e) { 4520 } 4521 } finally { 4522 Binder.restoreCallingIdentity(callingId); 4523 } 4524 return true; 4525 } 4526 4527 @Override 4528 public void killBackgroundProcesses(final String packageName, int userId) { 4529 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4530 != PackageManager.PERMISSION_GRANTED && 4531 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4532 != PackageManager.PERMISSION_GRANTED) { 4533 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4534 + Binder.getCallingPid() 4535 + ", uid=" + Binder.getCallingUid() 4536 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4537 Slog.w(TAG, msg); 4538 throw new SecurityException(msg); 4539 } 4540 4541 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4542 userId, true, true, "killBackgroundProcesses", null); 4543 long callingId = Binder.clearCallingIdentity(); 4544 try { 4545 IPackageManager pm = AppGlobals.getPackageManager(); 4546 synchronized(this) { 4547 int appId = -1; 4548 try { 4549 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4550 } catch (RemoteException e) { 4551 } 4552 if (appId == -1) { 4553 Slog.w(TAG, "Invalid packageName: " + packageName); 4554 return; 4555 } 4556 killPackageProcessesLocked(packageName, appId, userId, 4557 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4558 } 4559 } finally { 4560 Binder.restoreCallingIdentity(callingId); 4561 } 4562 } 4563 4564 @Override 4565 public void killAllBackgroundProcesses() { 4566 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4567 != PackageManager.PERMISSION_GRANTED) { 4568 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4569 + Binder.getCallingPid() 4570 + ", uid=" + Binder.getCallingUid() 4571 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4572 Slog.w(TAG, msg); 4573 throw new SecurityException(msg); 4574 } 4575 4576 long callingId = Binder.clearCallingIdentity(); 4577 try { 4578 synchronized(this) { 4579 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4580 final int NP = mProcessNames.getMap().size(); 4581 for (int ip=0; ip<NP; ip++) { 4582 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4583 final int NA = apps.size(); 4584 for (int ia=0; ia<NA; ia++) { 4585 ProcessRecord app = apps.valueAt(ia); 4586 if (app.persistent) { 4587 // we don't kill persistent processes 4588 continue; 4589 } 4590 if (app.removed) { 4591 procs.add(app); 4592 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4593 app.removed = true; 4594 procs.add(app); 4595 } 4596 } 4597 } 4598 4599 int N = procs.size(); 4600 for (int i=0; i<N; i++) { 4601 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4602 } 4603 mAllowLowerMemLevel = true; 4604 updateOomAdjLocked(); 4605 doLowMemReportIfNeededLocked(null); 4606 } 4607 } finally { 4608 Binder.restoreCallingIdentity(callingId); 4609 } 4610 } 4611 4612 @Override 4613 public void forceStopPackage(final String packageName, int userId) { 4614 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4615 != PackageManager.PERMISSION_GRANTED) { 4616 String msg = "Permission Denial: forceStopPackage() from pid=" 4617 + Binder.getCallingPid() 4618 + ", uid=" + Binder.getCallingUid() 4619 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4620 Slog.w(TAG, msg); 4621 throw new SecurityException(msg); 4622 } 4623 final int callingPid = Binder.getCallingPid(); 4624 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4625 userId, true, true, "forceStopPackage", null); 4626 long callingId = Binder.clearCallingIdentity(); 4627 try { 4628 IPackageManager pm = AppGlobals.getPackageManager(); 4629 synchronized(this) { 4630 int[] users = userId == UserHandle.USER_ALL 4631 ? getUsersLocked() : new int[] { userId }; 4632 for (int user : users) { 4633 int pkgUid = -1; 4634 try { 4635 pkgUid = pm.getPackageUid(packageName, user); 4636 } catch (RemoteException e) { 4637 } 4638 if (pkgUid == -1) { 4639 Slog.w(TAG, "Invalid packageName: " + packageName); 4640 continue; 4641 } 4642 try { 4643 pm.setPackageStoppedState(packageName, true, user); 4644 } catch (RemoteException e) { 4645 } catch (IllegalArgumentException e) { 4646 Slog.w(TAG, "Failed trying to unstop package " 4647 + packageName + ": " + e); 4648 } 4649 if (isUserRunningLocked(user, false)) { 4650 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4651 } 4652 } 4653 } 4654 } finally { 4655 Binder.restoreCallingIdentity(callingId); 4656 } 4657 } 4658 4659 /* 4660 * The pkg name and app id have to be specified. 4661 */ 4662 @Override 4663 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4664 if (pkg == null) { 4665 return; 4666 } 4667 // Make sure the uid is valid. 4668 if (appid < 0) { 4669 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4670 return; 4671 } 4672 int callerUid = Binder.getCallingUid(); 4673 // Only the system server can kill an application 4674 if (callerUid == Process.SYSTEM_UID) { 4675 // Post an aysnc message to kill the application 4676 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4677 msg.arg1 = appid; 4678 msg.arg2 = 0; 4679 Bundle bundle = new Bundle(); 4680 bundle.putString("pkg", pkg); 4681 bundle.putString("reason", reason); 4682 msg.obj = bundle; 4683 mHandler.sendMessage(msg); 4684 } else { 4685 throw new SecurityException(callerUid + " cannot kill pkg: " + 4686 pkg); 4687 } 4688 } 4689 4690 @Override 4691 public void closeSystemDialogs(String reason) { 4692 enforceNotIsolatedCaller("closeSystemDialogs"); 4693 4694 final int pid = Binder.getCallingPid(); 4695 final int uid = Binder.getCallingUid(); 4696 final long origId = Binder.clearCallingIdentity(); 4697 try { 4698 synchronized (this) { 4699 // Only allow this from foreground processes, so that background 4700 // applications can't abuse it to prevent system UI from being shown. 4701 if (uid >= Process.FIRST_APPLICATION_UID) { 4702 ProcessRecord proc; 4703 synchronized (mPidsSelfLocked) { 4704 proc = mPidsSelfLocked.get(pid); 4705 } 4706 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4707 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4708 + " from background process " + proc); 4709 return; 4710 } 4711 } 4712 closeSystemDialogsLocked(reason); 4713 } 4714 } finally { 4715 Binder.restoreCallingIdentity(origId); 4716 } 4717 } 4718 4719 void closeSystemDialogsLocked(String reason) { 4720 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4721 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4722 | Intent.FLAG_RECEIVER_FOREGROUND); 4723 if (reason != null) { 4724 intent.putExtra("reason", reason); 4725 } 4726 mWindowManager.closeSystemDialogs(reason); 4727 4728 mStackSupervisor.closeSystemDialogsLocked(); 4729 4730 broadcastIntentLocked(null, null, intent, null, 4731 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4732 Process.SYSTEM_UID, UserHandle.USER_ALL); 4733 } 4734 4735 @Override 4736 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4737 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4738 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4739 for (int i=pids.length-1; i>=0; i--) { 4740 ProcessRecord proc; 4741 int oomAdj; 4742 synchronized (this) { 4743 synchronized (mPidsSelfLocked) { 4744 proc = mPidsSelfLocked.get(pids[i]); 4745 oomAdj = proc != null ? proc.setAdj : 0; 4746 } 4747 } 4748 infos[i] = new Debug.MemoryInfo(); 4749 Debug.getMemoryInfo(pids[i], infos[i]); 4750 if (proc != null) { 4751 synchronized (this) { 4752 if (proc.thread != null && proc.setAdj == oomAdj) { 4753 // Record this for posterity if the process has been stable. 4754 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4755 infos[i].getTotalUss(), false, proc.pkgList); 4756 } 4757 } 4758 } 4759 } 4760 return infos; 4761 } 4762 4763 @Override 4764 public long[] getProcessPss(int[] pids) { 4765 enforceNotIsolatedCaller("getProcessPss"); 4766 long[] pss = new long[pids.length]; 4767 for (int i=pids.length-1; i>=0; i--) { 4768 ProcessRecord proc; 4769 int oomAdj; 4770 synchronized (this) { 4771 synchronized (mPidsSelfLocked) { 4772 proc = mPidsSelfLocked.get(pids[i]); 4773 oomAdj = proc != null ? proc.setAdj : 0; 4774 } 4775 } 4776 long[] tmpUss = new long[1]; 4777 pss[i] = Debug.getPss(pids[i], tmpUss); 4778 if (proc != null) { 4779 synchronized (this) { 4780 if (proc.thread != null && proc.setAdj == oomAdj) { 4781 // Record this for posterity if the process has been stable. 4782 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4783 } 4784 } 4785 } 4786 } 4787 return pss; 4788 } 4789 4790 @Override 4791 public void killApplicationProcess(String processName, int uid) { 4792 if (processName == null) { 4793 return; 4794 } 4795 4796 int callerUid = Binder.getCallingUid(); 4797 // Only the system server can kill an application 4798 if (callerUid == Process.SYSTEM_UID) { 4799 synchronized (this) { 4800 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4801 if (app != null && app.thread != null) { 4802 try { 4803 app.thread.scheduleSuicide(); 4804 } catch (RemoteException e) { 4805 // If the other end already died, then our work here is done. 4806 } 4807 } else { 4808 Slog.w(TAG, "Process/uid not found attempting kill of " 4809 + processName + " / " + uid); 4810 } 4811 } 4812 } else { 4813 throw new SecurityException(callerUid + " cannot kill app process: " + 4814 processName); 4815 } 4816 } 4817 4818 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4819 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4820 false, true, false, false, UserHandle.getUserId(uid), reason); 4821 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4822 Uri.fromParts("package", packageName, null)); 4823 if (!mProcessesReady) { 4824 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4825 | Intent.FLAG_RECEIVER_FOREGROUND); 4826 } 4827 intent.putExtra(Intent.EXTRA_UID, uid); 4828 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4829 broadcastIntentLocked(null, null, intent, 4830 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4831 false, false, 4832 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4833 } 4834 4835 private void forceStopUserLocked(int userId, String reason) { 4836 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4837 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4838 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4839 | Intent.FLAG_RECEIVER_FOREGROUND); 4840 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4841 broadcastIntentLocked(null, null, intent, 4842 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4843 false, false, 4844 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4845 } 4846 4847 private final boolean killPackageProcessesLocked(String packageName, int appId, 4848 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4849 boolean doit, boolean evenPersistent, String reason) { 4850 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4851 4852 // Remove all processes this package may have touched: all with the 4853 // same UID (except for the system or root user), and all whose name 4854 // matches the package name. 4855 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4856 final int NP = mProcessNames.getMap().size(); 4857 for (int ip=0; ip<NP; ip++) { 4858 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4859 final int NA = apps.size(); 4860 for (int ia=0; ia<NA; ia++) { 4861 ProcessRecord app = apps.valueAt(ia); 4862 if (app.persistent && !evenPersistent) { 4863 // we don't kill persistent processes 4864 continue; 4865 } 4866 if (app.removed) { 4867 if (doit) { 4868 procs.add(app); 4869 } 4870 continue; 4871 } 4872 4873 // Skip process if it doesn't meet our oom adj requirement. 4874 if (app.setAdj < minOomAdj) { 4875 continue; 4876 } 4877 4878 // If no package is specified, we call all processes under the 4879 // give user id. 4880 if (packageName == null) { 4881 if (app.userId != userId) { 4882 continue; 4883 } 4884 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4885 continue; 4886 } 4887 // Package has been specified, we want to hit all processes 4888 // that match it. We need to qualify this by the processes 4889 // that are running under the specified app and user ID. 4890 } else { 4891 if (UserHandle.getAppId(app.uid) != appId) { 4892 continue; 4893 } 4894 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4895 continue; 4896 } 4897 if (!app.pkgList.containsKey(packageName)) { 4898 continue; 4899 } 4900 } 4901 4902 // Process has passed all conditions, kill it! 4903 if (!doit) { 4904 return true; 4905 } 4906 app.removed = true; 4907 procs.add(app); 4908 } 4909 } 4910 4911 int N = procs.size(); 4912 for (int i=0; i<N; i++) { 4913 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4914 } 4915 updateOomAdjLocked(); 4916 return N > 0; 4917 } 4918 4919 private final boolean forceStopPackageLocked(String name, int appId, 4920 boolean callerWillRestart, boolean purgeCache, boolean doit, 4921 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4922 int i; 4923 int N; 4924 4925 if (userId == UserHandle.USER_ALL && name == null) { 4926 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4927 } 4928 4929 if (appId < 0 && name != null) { 4930 try { 4931 appId = UserHandle.getAppId( 4932 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4933 } catch (RemoteException e) { 4934 } 4935 } 4936 4937 if (doit) { 4938 if (name != null) { 4939 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4940 + " user=" + userId + ": " + reason); 4941 } else { 4942 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4943 } 4944 4945 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4946 for (int ip=pmap.size()-1; ip>=0; ip--) { 4947 SparseArray<Long> ba = pmap.valueAt(ip); 4948 for (i=ba.size()-1; i>=0; i--) { 4949 boolean remove = false; 4950 final int entUid = ba.keyAt(i); 4951 if (name != null) { 4952 if (userId == UserHandle.USER_ALL) { 4953 if (UserHandle.getAppId(entUid) == appId) { 4954 remove = true; 4955 } 4956 } else { 4957 if (entUid == UserHandle.getUid(userId, appId)) { 4958 remove = true; 4959 } 4960 } 4961 } else if (UserHandle.getUserId(entUid) == userId) { 4962 remove = true; 4963 } 4964 if (remove) { 4965 ba.removeAt(i); 4966 } 4967 } 4968 if (ba.size() == 0) { 4969 pmap.removeAt(ip); 4970 } 4971 } 4972 } 4973 4974 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4975 -100, callerWillRestart, true, doit, evenPersistent, 4976 name == null ? ("stop user " + userId) : ("stop " + name)); 4977 4978 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4979 if (!doit) { 4980 return true; 4981 } 4982 didSomething = true; 4983 } 4984 4985 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4986 if (!doit) { 4987 return true; 4988 } 4989 didSomething = true; 4990 } 4991 4992 if (name == null) { 4993 // Remove all sticky broadcasts from this user. 4994 mStickyBroadcasts.remove(userId); 4995 } 4996 4997 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4998 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4999 userId, providers)) { 5000 if (!doit) { 5001 return true; 5002 } 5003 didSomething = true; 5004 } 5005 N = providers.size(); 5006 for (i=0; i<N; i++) { 5007 removeDyingProviderLocked(null, providers.get(i), true); 5008 } 5009 5010 // Remove transient permissions granted from/to this package/user 5011 removeUriPermissionsForPackageLocked(name, userId, false); 5012 5013 if (name == null || uninstalling) { 5014 // Remove pending intents. For now we only do this when force 5015 // stopping users, because we have some problems when doing this 5016 // for packages -- app widgets are not currently cleaned up for 5017 // such packages, so they can be left with bad pending intents. 5018 if (mIntentSenderRecords.size() > 0) { 5019 Iterator<WeakReference<PendingIntentRecord>> it 5020 = mIntentSenderRecords.values().iterator(); 5021 while (it.hasNext()) { 5022 WeakReference<PendingIntentRecord> wpir = it.next(); 5023 if (wpir == null) { 5024 it.remove(); 5025 continue; 5026 } 5027 PendingIntentRecord pir = wpir.get(); 5028 if (pir == null) { 5029 it.remove(); 5030 continue; 5031 } 5032 if (name == null) { 5033 // Stopping user, remove all objects for the user. 5034 if (pir.key.userId != userId) { 5035 // Not the same user, skip it. 5036 continue; 5037 } 5038 } else { 5039 if (UserHandle.getAppId(pir.uid) != appId) { 5040 // Different app id, skip it. 5041 continue; 5042 } 5043 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5044 // Different user, skip it. 5045 continue; 5046 } 5047 if (!pir.key.packageName.equals(name)) { 5048 // Different package, skip it. 5049 continue; 5050 } 5051 } 5052 if (!doit) { 5053 return true; 5054 } 5055 didSomething = true; 5056 it.remove(); 5057 pir.canceled = true; 5058 if (pir.key.activity != null) { 5059 pir.key.activity.pendingResults.remove(pir.ref); 5060 } 5061 } 5062 } 5063 } 5064 5065 if (doit) { 5066 if (purgeCache && name != null) { 5067 AttributeCache ac = AttributeCache.instance(); 5068 if (ac != null) { 5069 ac.removePackage(name); 5070 } 5071 } 5072 if (mBooted) { 5073 mStackSupervisor.resumeTopActivitiesLocked(); 5074 mStackSupervisor.scheduleIdleLocked(); 5075 } 5076 } 5077 5078 return didSomething; 5079 } 5080 5081 private final boolean removeProcessLocked(ProcessRecord app, 5082 boolean callerWillRestart, boolean allowRestart, String reason) { 5083 final String name = app.processName; 5084 final int uid = app.uid; 5085 if (DEBUG_PROCESSES) Slog.d( 5086 TAG, "Force removing proc " + app.toShortString() + " (" + name 5087 + "/" + uid + ")"); 5088 5089 mProcessNames.remove(name, uid); 5090 mIsolatedProcesses.remove(app.uid); 5091 if (mHeavyWeightProcess == app) { 5092 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5093 mHeavyWeightProcess.userId, 0)); 5094 mHeavyWeightProcess = null; 5095 } 5096 boolean needRestart = false; 5097 if (app.pid > 0 && app.pid != MY_PID) { 5098 int pid = app.pid; 5099 synchronized (mPidsSelfLocked) { 5100 mPidsSelfLocked.remove(pid); 5101 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5102 } 5103 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5104 app.processName, app.info.uid); 5105 if (app.isolated) { 5106 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5107 } 5108 killUnneededProcessLocked(app, reason); 5109 handleAppDiedLocked(app, true, allowRestart); 5110 removeLruProcessLocked(app); 5111 5112 if (app.persistent && !app.isolated) { 5113 if (!callerWillRestart) { 5114 addAppLocked(app.info, false, null /* ABI override */); 5115 } else { 5116 needRestart = true; 5117 } 5118 } 5119 } else { 5120 mRemovedProcesses.add(app); 5121 } 5122 5123 return needRestart; 5124 } 5125 5126 private final void processStartTimedOutLocked(ProcessRecord app) { 5127 final int pid = app.pid; 5128 boolean gone = false; 5129 synchronized (mPidsSelfLocked) { 5130 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5131 if (knownApp != null && knownApp.thread == null) { 5132 mPidsSelfLocked.remove(pid); 5133 gone = true; 5134 } 5135 } 5136 5137 if (gone) { 5138 Slog.w(TAG, "Process " + app + " failed to attach"); 5139 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5140 pid, app.uid, app.processName); 5141 mProcessNames.remove(app.processName, app.uid); 5142 mIsolatedProcesses.remove(app.uid); 5143 if (mHeavyWeightProcess == app) { 5144 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5145 mHeavyWeightProcess.userId, 0)); 5146 mHeavyWeightProcess = null; 5147 } 5148 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5149 app.processName, app.info.uid); 5150 if (app.isolated) { 5151 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5152 } 5153 // Take care of any launching providers waiting for this process. 5154 checkAppInLaunchingProvidersLocked(app, true); 5155 // Take care of any services that are waiting for the process. 5156 mServices.processStartTimedOutLocked(app); 5157 killUnneededProcessLocked(app, "start timeout"); 5158 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5159 Slog.w(TAG, "Unattached app died before backup, skipping"); 5160 try { 5161 IBackupManager bm = IBackupManager.Stub.asInterface( 5162 ServiceManager.getService(Context.BACKUP_SERVICE)); 5163 bm.agentDisconnected(app.info.packageName); 5164 } catch (RemoteException e) { 5165 // Can't happen; the backup manager is local 5166 } 5167 } 5168 if (isPendingBroadcastProcessLocked(pid)) { 5169 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5170 skipPendingBroadcastLocked(pid); 5171 } 5172 } else { 5173 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5174 } 5175 } 5176 5177 private final boolean attachApplicationLocked(IApplicationThread thread, 5178 int pid) { 5179 5180 // Find the application record that is being attached... either via 5181 // the pid if we are running in multiple processes, or just pull the 5182 // next app record if we are emulating process with anonymous threads. 5183 ProcessRecord app; 5184 if (pid != MY_PID && pid >= 0) { 5185 synchronized (mPidsSelfLocked) { 5186 app = mPidsSelfLocked.get(pid); 5187 } 5188 } else { 5189 app = null; 5190 } 5191 5192 if (app == null) { 5193 Slog.w(TAG, "No pending application record for pid " + pid 5194 + " (IApplicationThread " + thread + "); dropping process"); 5195 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5196 if (pid > 0 && pid != MY_PID) { 5197 Process.killProcessQuiet(pid); 5198 } else { 5199 try { 5200 thread.scheduleExit(); 5201 } catch (Exception e) { 5202 // Ignore exceptions. 5203 } 5204 } 5205 return false; 5206 } 5207 5208 // If this application record is still attached to a previous 5209 // process, clean it up now. 5210 if (app.thread != null) { 5211 handleAppDiedLocked(app, true, true); 5212 } 5213 5214 // Tell the process all about itself. 5215 5216 if (localLOGV) Slog.v( 5217 TAG, "Binding process pid " + pid + " to record " + app); 5218 5219 final String processName = app.processName; 5220 try { 5221 AppDeathRecipient adr = new AppDeathRecipient( 5222 app, pid, thread); 5223 thread.asBinder().linkToDeath(adr, 0); 5224 app.deathRecipient = adr; 5225 } catch (RemoteException e) { 5226 app.resetPackageList(mProcessStats); 5227 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5228 return false; 5229 } 5230 5231 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5232 5233 app.makeActive(thread, mProcessStats); 5234 app.curAdj = app.setAdj = -100; 5235 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5236 app.forcingToForeground = null; 5237 updateProcessForegroundLocked(app, false, false); 5238 app.hasShownUi = false; 5239 app.debugging = false; 5240 app.cached = false; 5241 5242 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5243 5244 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5245 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5246 5247 if (!normalMode) { 5248 Slog.i(TAG, "Launching preboot mode app: " + app); 5249 } 5250 5251 if (localLOGV) Slog.v( 5252 TAG, "New app record " + app 5253 + " thread=" + thread.asBinder() + " pid=" + pid); 5254 try { 5255 int testMode = IApplicationThread.DEBUG_OFF; 5256 if (mDebugApp != null && mDebugApp.equals(processName)) { 5257 testMode = mWaitForDebugger 5258 ? IApplicationThread.DEBUG_WAIT 5259 : IApplicationThread.DEBUG_ON; 5260 app.debugging = true; 5261 if (mDebugTransient) { 5262 mDebugApp = mOrigDebugApp; 5263 mWaitForDebugger = mOrigWaitForDebugger; 5264 } 5265 } 5266 String profileFile = app.instrumentationProfileFile; 5267 ParcelFileDescriptor profileFd = null; 5268 boolean profileAutoStop = false; 5269 if (mProfileApp != null && mProfileApp.equals(processName)) { 5270 mProfileProc = app; 5271 profileFile = mProfileFile; 5272 profileFd = mProfileFd; 5273 profileAutoStop = mAutoStopProfiler; 5274 } 5275 boolean enableOpenGlTrace = false; 5276 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5277 enableOpenGlTrace = true; 5278 mOpenGlTraceApp = null; 5279 } 5280 5281 // If the app is being launched for restore or full backup, set it up specially 5282 boolean isRestrictedBackupMode = false; 5283 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5284 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5285 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5286 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5287 } 5288 5289 ensurePackageDexOpt(app.instrumentationInfo != null 5290 ? app.instrumentationInfo.packageName 5291 : app.info.packageName); 5292 if (app.instrumentationClass != null) { 5293 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5294 } 5295 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5296 + processName + " with config " + mConfiguration); 5297 ApplicationInfo appInfo = app.instrumentationInfo != null 5298 ? app.instrumentationInfo : app.info; 5299 app.compat = compatibilityInfoForPackageLocked(appInfo); 5300 if (profileFd != null) { 5301 profileFd = profileFd.dup(); 5302 } 5303 thread.bindApplication(processName, appInfo, providers, 5304 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5305 app.instrumentationArguments, app.instrumentationWatcher, 5306 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5307 isRestrictedBackupMode || !normalMode, app.persistent, 5308 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5309 mCoreSettingsObserver.getCoreSettingsLocked()); 5310 updateLruProcessLocked(app, false, null); 5311 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5312 } catch (Exception e) { 5313 // todo: Yikes! What should we do? For now we will try to 5314 // start another process, but that could easily get us in 5315 // an infinite loop of restarting processes... 5316 Slog.w(TAG, "Exception thrown during bind!", e); 5317 5318 app.resetPackageList(mProcessStats); 5319 app.unlinkDeathRecipient(); 5320 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5321 return false; 5322 } 5323 5324 // Remove this record from the list of starting applications. 5325 mPersistentStartingProcesses.remove(app); 5326 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5327 "Attach application locked removing on hold: " + app); 5328 mProcessesOnHold.remove(app); 5329 5330 boolean badApp = false; 5331 boolean didSomething = false; 5332 5333 // See if the top visible activity is waiting to run in this process... 5334 if (normalMode) { 5335 try { 5336 if (mStackSupervisor.attachApplicationLocked(app)) { 5337 didSomething = true; 5338 } 5339 } catch (Exception e) { 5340 badApp = true; 5341 } 5342 } 5343 5344 // Find any services that should be running in this process... 5345 if (!badApp) { 5346 try { 5347 didSomething |= mServices.attachApplicationLocked(app, processName); 5348 } catch (Exception e) { 5349 badApp = true; 5350 } 5351 } 5352 5353 // Check if a next-broadcast receiver is in this process... 5354 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5355 try { 5356 didSomething |= sendPendingBroadcastsLocked(app); 5357 } catch (Exception e) { 5358 // If the app died trying to launch the receiver we declare it 'bad' 5359 badApp = true; 5360 } 5361 } 5362 5363 // Check whether the next backup agent is in this process... 5364 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5365 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5366 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5367 try { 5368 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5369 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5370 mBackupTarget.backupMode); 5371 } catch (Exception e) { 5372 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5373 e.printStackTrace(); 5374 } 5375 } 5376 5377 if (badApp) { 5378 // todo: Also need to kill application to deal with all 5379 // kinds of exceptions. 5380 handleAppDiedLocked(app, false, true); 5381 return false; 5382 } 5383 5384 if (!didSomething) { 5385 updateOomAdjLocked(); 5386 } 5387 5388 return true; 5389 } 5390 5391 @Override 5392 public final void attachApplication(IApplicationThread thread) { 5393 synchronized (this) { 5394 int callingPid = Binder.getCallingPid(); 5395 final long origId = Binder.clearCallingIdentity(); 5396 attachApplicationLocked(thread, callingPid); 5397 Binder.restoreCallingIdentity(origId); 5398 } 5399 } 5400 5401 @Override 5402 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5403 final long origId = Binder.clearCallingIdentity(); 5404 synchronized (this) { 5405 ActivityStack stack = ActivityRecord.getStackLocked(token); 5406 if (stack != null) { 5407 ActivityRecord r = 5408 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5409 if (stopProfiling) { 5410 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5411 try { 5412 mProfileFd.close(); 5413 } catch (IOException e) { 5414 } 5415 clearProfilerLocked(); 5416 } 5417 } 5418 } 5419 } 5420 Binder.restoreCallingIdentity(origId); 5421 } 5422 5423 void enableScreenAfterBoot() { 5424 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5425 SystemClock.uptimeMillis()); 5426 mWindowManager.enableScreenAfterBoot(); 5427 5428 synchronized (this) { 5429 updateEventDispatchingLocked(); 5430 } 5431 } 5432 5433 @Override 5434 public void showBootMessage(final CharSequence msg, final boolean always) { 5435 enforceNotIsolatedCaller("showBootMessage"); 5436 mWindowManager.showBootMessage(msg, always); 5437 } 5438 5439 @Override 5440 public void dismissKeyguardOnNextActivity() { 5441 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5442 final long token = Binder.clearCallingIdentity(); 5443 try { 5444 synchronized (this) { 5445 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5446 if (mLockScreenShown) { 5447 mLockScreenShown = false; 5448 comeOutOfSleepIfNeededLocked(); 5449 } 5450 mStackSupervisor.setDismissKeyguard(true); 5451 } 5452 } finally { 5453 Binder.restoreCallingIdentity(token); 5454 } 5455 } 5456 5457 final void finishBooting() { 5458 // Register receivers to handle package update events 5459 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5460 5461 synchronized (this) { 5462 // Ensure that any processes we had put on hold are now started 5463 // up. 5464 final int NP = mProcessesOnHold.size(); 5465 if (NP > 0) { 5466 ArrayList<ProcessRecord> procs = 5467 new ArrayList<ProcessRecord>(mProcessesOnHold); 5468 for (int ip=0; ip<NP; ip++) { 5469 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5470 + procs.get(ip)); 5471 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5472 } 5473 } 5474 5475 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5476 // Start looking for apps that are abusing wake locks. 5477 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5478 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5479 // Tell anyone interested that we are done booting! 5480 SystemProperties.set("sys.boot_completed", "1"); 5481 SystemProperties.set("dev.bootcomplete", "1"); 5482 for (int i=0; i<mStartedUsers.size(); i++) { 5483 UserStartedState uss = mStartedUsers.valueAt(i); 5484 if (uss.mState == UserStartedState.STATE_BOOTING) { 5485 uss.mState = UserStartedState.STATE_RUNNING; 5486 final int userId = mStartedUsers.keyAt(i); 5487 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5488 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5489 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5490 broadcastIntentLocked(null, null, intent, null, 5491 new IIntentReceiver.Stub() { 5492 @Override 5493 public void performReceive(Intent intent, int resultCode, 5494 String data, Bundle extras, boolean ordered, 5495 boolean sticky, int sendingUser) { 5496 synchronized (ActivityManagerService.this) { 5497 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5498 true, false); 5499 } 5500 } 5501 }, 5502 0, null, null, 5503 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5504 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5505 userId); 5506 } 5507 } 5508 scheduleStartProfilesLocked(); 5509 } 5510 } 5511 } 5512 5513 final void ensureBootCompleted() { 5514 boolean booting; 5515 boolean enableScreen; 5516 synchronized (this) { 5517 booting = mBooting; 5518 mBooting = false; 5519 enableScreen = !mBooted; 5520 mBooted = true; 5521 } 5522 5523 if (booting) { 5524 finishBooting(); 5525 } 5526 5527 if (enableScreen) { 5528 enableScreenAfterBoot(); 5529 } 5530 } 5531 5532 @Override 5533 public final void activityResumed(IBinder token) { 5534 final long origId = Binder.clearCallingIdentity(); 5535 synchronized(this) { 5536 ActivityStack stack = ActivityRecord.getStackLocked(token); 5537 if (stack != null) { 5538 ActivityRecord.activityResumedLocked(token); 5539 } 5540 } 5541 Binder.restoreCallingIdentity(origId); 5542 } 5543 5544 @Override 5545 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5546 final long origId = Binder.clearCallingIdentity(); 5547 synchronized(this) { 5548 ActivityStack stack = ActivityRecord.getStackLocked(token); 5549 if (stack != null) { 5550 stack.activityPausedLocked(token, false, persistentState); 5551 } 5552 } 5553 Binder.restoreCallingIdentity(origId); 5554 } 5555 5556 @Override 5557 public final void activityStopped(IBinder token, Bundle icicle, 5558 PersistableBundle persistentState, CharSequence description) { 5559 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5560 5561 // Refuse possible leaked file descriptors 5562 if (icicle != null && icicle.hasFileDescriptors()) { 5563 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5564 } 5565 5566 final long origId = Binder.clearCallingIdentity(); 5567 5568 synchronized (this) { 5569 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5570 if (r != null) { 5571 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5572 } 5573 } 5574 5575 trimApplications(); 5576 5577 Binder.restoreCallingIdentity(origId); 5578 } 5579 5580 @Override 5581 public final void activityDestroyed(IBinder token) { 5582 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5583 synchronized (this) { 5584 ActivityStack stack = ActivityRecord.getStackLocked(token); 5585 if (stack != null) { 5586 stack.activityDestroyedLocked(token); 5587 } 5588 } 5589 } 5590 5591 @Override 5592 public String getCallingPackage(IBinder token) { 5593 synchronized (this) { 5594 ActivityRecord r = getCallingRecordLocked(token); 5595 return r != null ? r.info.packageName : null; 5596 } 5597 } 5598 5599 @Override 5600 public ComponentName getCallingActivity(IBinder token) { 5601 synchronized (this) { 5602 ActivityRecord r = getCallingRecordLocked(token); 5603 return r != null ? r.intent.getComponent() : null; 5604 } 5605 } 5606 5607 private ActivityRecord getCallingRecordLocked(IBinder token) { 5608 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5609 if (r == null) { 5610 return null; 5611 } 5612 return r.resultTo; 5613 } 5614 5615 @Override 5616 public ComponentName getActivityClassForToken(IBinder token) { 5617 synchronized(this) { 5618 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5619 if (r == null) { 5620 return null; 5621 } 5622 return r.intent.getComponent(); 5623 } 5624 } 5625 5626 @Override 5627 public String getPackageForToken(IBinder token) { 5628 synchronized(this) { 5629 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5630 if (r == null) { 5631 return null; 5632 } 5633 return r.packageName; 5634 } 5635 } 5636 5637 @Override 5638 public IIntentSender getIntentSender(int type, 5639 String packageName, IBinder token, String resultWho, 5640 int requestCode, Intent[] intents, String[] resolvedTypes, 5641 int flags, Bundle options, int userId) { 5642 enforceNotIsolatedCaller("getIntentSender"); 5643 // Refuse possible leaked file descriptors 5644 if (intents != null) { 5645 if (intents.length < 1) { 5646 throw new IllegalArgumentException("Intents array length must be >= 1"); 5647 } 5648 for (int i=0; i<intents.length; i++) { 5649 Intent intent = intents[i]; 5650 if (intent != null) { 5651 if (intent.hasFileDescriptors()) { 5652 throw new IllegalArgumentException("File descriptors passed in Intent"); 5653 } 5654 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5655 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5656 throw new IllegalArgumentException( 5657 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5658 } 5659 intents[i] = new Intent(intent); 5660 } 5661 } 5662 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5663 throw new IllegalArgumentException( 5664 "Intent array length does not match resolvedTypes length"); 5665 } 5666 } 5667 if (options != null) { 5668 if (options.hasFileDescriptors()) { 5669 throw new IllegalArgumentException("File descriptors passed in options"); 5670 } 5671 } 5672 5673 synchronized(this) { 5674 int callingUid = Binder.getCallingUid(); 5675 int origUserId = userId; 5676 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5677 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5678 "getIntentSender", null); 5679 if (origUserId == UserHandle.USER_CURRENT) { 5680 // We don't want to evaluate this until the pending intent is 5681 // actually executed. However, we do want to always do the 5682 // security checking for it above. 5683 userId = UserHandle.USER_CURRENT; 5684 } 5685 try { 5686 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5687 int uid = AppGlobals.getPackageManager() 5688 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5689 if (!UserHandle.isSameApp(callingUid, uid)) { 5690 String msg = "Permission Denial: getIntentSender() from pid=" 5691 + Binder.getCallingPid() 5692 + ", uid=" + Binder.getCallingUid() 5693 + ", (need uid=" + uid + ")" 5694 + " is not allowed to send as package " + packageName; 5695 Slog.w(TAG, msg); 5696 throw new SecurityException(msg); 5697 } 5698 } 5699 5700 return getIntentSenderLocked(type, packageName, callingUid, userId, 5701 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5702 5703 } catch (RemoteException e) { 5704 throw new SecurityException(e); 5705 } 5706 } 5707 } 5708 5709 IIntentSender getIntentSenderLocked(int type, String packageName, 5710 int callingUid, int userId, IBinder token, String resultWho, 5711 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5712 Bundle options) { 5713 if (DEBUG_MU) 5714 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5715 ActivityRecord activity = null; 5716 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5717 activity = ActivityRecord.isInStackLocked(token); 5718 if (activity == null) { 5719 return null; 5720 } 5721 if (activity.finishing) { 5722 return null; 5723 } 5724 } 5725 5726 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5727 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5728 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5729 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5730 |PendingIntent.FLAG_UPDATE_CURRENT); 5731 5732 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5733 type, packageName, activity, resultWho, 5734 requestCode, intents, resolvedTypes, flags, options, userId); 5735 WeakReference<PendingIntentRecord> ref; 5736 ref = mIntentSenderRecords.get(key); 5737 PendingIntentRecord rec = ref != null ? ref.get() : null; 5738 if (rec != null) { 5739 if (!cancelCurrent) { 5740 if (updateCurrent) { 5741 if (rec.key.requestIntent != null) { 5742 rec.key.requestIntent.replaceExtras(intents != null ? 5743 intents[intents.length - 1] : null); 5744 } 5745 if (intents != null) { 5746 intents[intents.length-1] = rec.key.requestIntent; 5747 rec.key.allIntents = intents; 5748 rec.key.allResolvedTypes = resolvedTypes; 5749 } else { 5750 rec.key.allIntents = null; 5751 rec.key.allResolvedTypes = null; 5752 } 5753 } 5754 return rec; 5755 } 5756 rec.canceled = true; 5757 mIntentSenderRecords.remove(key); 5758 } 5759 if (noCreate) { 5760 return rec; 5761 } 5762 rec = new PendingIntentRecord(this, key, callingUid); 5763 mIntentSenderRecords.put(key, rec.ref); 5764 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5765 if (activity.pendingResults == null) { 5766 activity.pendingResults 5767 = new HashSet<WeakReference<PendingIntentRecord>>(); 5768 } 5769 activity.pendingResults.add(rec.ref); 5770 } 5771 return rec; 5772 } 5773 5774 @Override 5775 public void cancelIntentSender(IIntentSender sender) { 5776 if (!(sender instanceof PendingIntentRecord)) { 5777 return; 5778 } 5779 synchronized(this) { 5780 PendingIntentRecord rec = (PendingIntentRecord)sender; 5781 try { 5782 int uid = AppGlobals.getPackageManager() 5783 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5784 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5785 String msg = "Permission Denial: cancelIntentSender() from pid=" 5786 + Binder.getCallingPid() 5787 + ", uid=" + Binder.getCallingUid() 5788 + " is not allowed to cancel packges " 5789 + rec.key.packageName; 5790 Slog.w(TAG, msg); 5791 throw new SecurityException(msg); 5792 } 5793 } catch (RemoteException e) { 5794 throw new SecurityException(e); 5795 } 5796 cancelIntentSenderLocked(rec, true); 5797 } 5798 } 5799 5800 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5801 rec.canceled = true; 5802 mIntentSenderRecords.remove(rec.key); 5803 if (cleanActivity && rec.key.activity != null) { 5804 rec.key.activity.pendingResults.remove(rec.ref); 5805 } 5806 } 5807 5808 @Override 5809 public String getPackageForIntentSender(IIntentSender pendingResult) { 5810 if (!(pendingResult instanceof PendingIntentRecord)) { 5811 return null; 5812 } 5813 try { 5814 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5815 return res.key.packageName; 5816 } catch (ClassCastException e) { 5817 } 5818 return null; 5819 } 5820 5821 @Override 5822 public int getUidForIntentSender(IIntentSender sender) { 5823 if (sender instanceof PendingIntentRecord) { 5824 try { 5825 PendingIntentRecord res = (PendingIntentRecord)sender; 5826 return res.uid; 5827 } catch (ClassCastException e) { 5828 } 5829 } 5830 return -1; 5831 } 5832 5833 @Override 5834 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5835 if (!(pendingResult instanceof PendingIntentRecord)) { 5836 return false; 5837 } 5838 try { 5839 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5840 if (res.key.allIntents == null) { 5841 return false; 5842 } 5843 for (int i=0; i<res.key.allIntents.length; i++) { 5844 Intent intent = res.key.allIntents[i]; 5845 if (intent.getPackage() != null && intent.getComponent() != null) { 5846 return false; 5847 } 5848 } 5849 return true; 5850 } catch (ClassCastException e) { 5851 } 5852 return false; 5853 } 5854 5855 @Override 5856 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5857 if (!(pendingResult instanceof PendingIntentRecord)) { 5858 return false; 5859 } 5860 try { 5861 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5862 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5863 return true; 5864 } 5865 return false; 5866 } catch (ClassCastException e) { 5867 } 5868 return false; 5869 } 5870 5871 @Override 5872 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5873 if (!(pendingResult instanceof PendingIntentRecord)) { 5874 return null; 5875 } 5876 try { 5877 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5878 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5879 } catch (ClassCastException e) { 5880 } 5881 return null; 5882 } 5883 5884 @Override 5885 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5886 if (!(pendingResult instanceof PendingIntentRecord)) { 5887 return null; 5888 } 5889 try { 5890 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5891 Intent intent = res.key.requestIntent; 5892 if (intent != null) { 5893 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5894 || res.lastTagPrefix.equals(prefix))) { 5895 return res.lastTag; 5896 } 5897 res.lastTagPrefix = prefix; 5898 StringBuilder sb = new StringBuilder(128); 5899 if (prefix != null) { 5900 sb.append(prefix); 5901 } 5902 if (intent.getAction() != null) { 5903 sb.append(intent.getAction()); 5904 } else if (intent.getComponent() != null) { 5905 intent.getComponent().appendShortString(sb); 5906 } else { 5907 sb.append("?"); 5908 } 5909 return res.lastTag = sb.toString(); 5910 } 5911 } catch (ClassCastException e) { 5912 } 5913 return null; 5914 } 5915 5916 @Override 5917 public void setProcessLimit(int max) { 5918 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5919 "setProcessLimit()"); 5920 synchronized (this) { 5921 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5922 mProcessLimitOverride = max; 5923 } 5924 trimApplications(); 5925 } 5926 5927 @Override 5928 public int getProcessLimit() { 5929 synchronized (this) { 5930 return mProcessLimitOverride; 5931 } 5932 } 5933 5934 void foregroundTokenDied(ForegroundToken token) { 5935 synchronized (ActivityManagerService.this) { 5936 synchronized (mPidsSelfLocked) { 5937 ForegroundToken cur 5938 = mForegroundProcesses.get(token.pid); 5939 if (cur != token) { 5940 return; 5941 } 5942 mForegroundProcesses.remove(token.pid); 5943 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5944 if (pr == null) { 5945 return; 5946 } 5947 pr.forcingToForeground = null; 5948 updateProcessForegroundLocked(pr, false, false); 5949 } 5950 updateOomAdjLocked(); 5951 } 5952 } 5953 5954 @Override 5955 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5956 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5957 "setProcessForeground()"); 5958 synchronized(this) { 5959 boolean changed = false; 5960 5961 synchronized (mPidsSelfLocked) { 5962 ProcessRecord pr = mPidsSelfLocked.get(pid); 5963 if (pr == null && isForeground) { 5964 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5965 return; 5966 } 5967 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5968 if (oldToken != null) { 5969 oldToken.token.unlinkToDeath(oldToken, 0); 5970 mForegroundProcesses.remove(pid); 5971 if (pr != null) { 5972 pr.forcingToForeground = null; 5973 } 5974 changed = true; 5975 } 5976 if (isForeground && token != null) { 5977 ForegroundToken newToken = new ForegroundToken() { 5978 @Override 5979 public void binderDied() { 5980 foregroundTokenDied(this); 5981 } 5982 }; 5983 newToken.pid = pid; 5984 newToken.token = token; 5985 try { 5986 token.linkToDeath(newToken, 0); 5987 mForegroundProcesses.put(pid, newToken); 5988 pr.forcingToForeground = token; 5989 changed = true; 5990 } catch (RemoteException e) { 5991 // If the process died while doing this, we will later 5992 // do the cleanup with the process death link. 5993 } 5994 } 5995 } 5996 5997 if (changed) { 5998 updateOomAdjLocked(); 5999 } 6000 } 6001 } 6002 6003 // ========================================================= 6004 // PERMISSIONS 6005 // ========================================================= 6006 6007 static class PermissionController extends IPermissionController.Stub { 6008 ActivityManagerService mActivityManagerService; 6009 PermissionController(ActivityManagerService activityManagerService) { 6010 mActivityManagerService = activityManagerService; 6011 } 6012 6013 @Override 6014 public boolean checkPermission(String permission, int pid, int uid) { 6015 return mActivityManagerService.checkPermission(permission, pid, 6016 uid) == PackageManager.PERMISSION_GRANTED; 6017 } 6018 } 6019 6020 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6021 @Override 6022 public int checkComponentPermission(String permission, int pid, int uid, 6023 int owningUid, boolean exported) { 6024 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6025 owningUid, exported); 6026 } 6027 6028 @Override 6029 public Object getAMSLock() { 6030 return ActivityManagerService.this; 6031 } 6032 } 6033 6034 /** 6035 * This can be called with or without the global lock held. 6036 */ 6037 int checkComponentPermission(String permission, int pid, int uid, 6038 int owningUid, boolean exported) { 6039 // We might be performing an operation on behalf of an indirect binder 6040 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6041 // client identity accordingly before proceeding. 6042 Identity tlsIdentity = sCallerIdentity.get(); 6043 if (tlsIdentity != null) { 6044 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6045 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6046 uid = tlsIdentity.uid; 6047 pid = tlsIdentity.pid; 6048 } 6049 6050 if (pid == MY_PID) { 6051 return PackageManager.PERMISSION_GRANTED; 6052 } 6053 6054 return ActivityManager.checkComponentPermission(permission, uid, 6055 owningUid, exported); 6056 } 6057 6058 /** 6059 * As the only public entry point for permissions checking, this method 6060 * can enforce the semantic that requesting a check on a null global 6061 * permission is automatically denied. (Internally a null permission 6062 * string is used when calling {@link #checkComponentPermission} in cases 6063 * when only uid-based security is needed.) 6064 * 6065 * This can be called with or without the global lock held. 6066 */ 6067 @Override 6068 public int checkPermission(String permission, int pid, int uid) { 6069 if (permission == null) { 6070 return PackageManager.PERMISSION_DENIED; 6071 } 6072 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6073 } 6074 6075 /** 6076 * Binder IPC calls go through the public entry point. 6077 * This can be called with or without the global lock held. 6078 */ 6079 int checkCallingPermission(String permission) { 6080 return checkPermission(permission, 6081 Binder.getCallingPid(), 6082 UserHandle.getAppId(Binder.getCallingUid())); 6083 } 6084 6085 /** 6086 * This can be called with or without the global lock held. 6087 */ 6088 void enforceCallingPermission(String permission, String func) { 6089 if (checkCallingPermission(permission) 6090 == PackageManager.PERMISSION_GRANTED) { 6091 return; 6092 } 6093 6094 String msg = "Permission Denial: " + func + " from pid=" 6095 + Binder.getCallingPid() 6096 + ", uid=" + Binder.getCallingUid() 6097 + " requires " + permission; 6098 Slog.w(TAG, msg); 6099 throw new SecurityException(msg); 6100 } 6101 6102 /** 6103 * Determine if UID is holding permissions required to access {@link Uri} in 6104 * the given {@link ProviderInfo}. Final permission checking is always done 6105 * in {@link ContentProvider}. 6106 */ 6107 private final boolean checkHoldingPermissionsLocked( 6108 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6109 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6110 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6111 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6112 return false; 6113 } 6114 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6115 } 6116 6117 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6118 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6119 if (pi.applicationInfo.uid == uid) { 6120 return true; 6121 } else if (!pi.exported) { 6122 return false; 6123 } 6124 6125 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6126 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6127 try { 6128 // check if target holds top-level <provider> permissions 6129 if (!readMet && pi.readPermission != null && considerUidPermissions 6130 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6131 readMet = true; 6132 } 6133 if (!writeMet && pi.writePermission != null && considerUidPermissions 6134 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6135 writeMet = true; 6136 } 6137 6138 // track if unprotected read/write is allowed; any denied 6139 // <path-permission> below removes this ability 6140 boolean allowDefaultRead = pi.readPermission == null; 6141 boolean allowDefaultWrite = pi.writePermission == null; 6142 6143 // check if target holds any <path-permission> that match uri 6144 final PathPermission[] pps = pi.pathPermissions; 6145 if (pps != null) { 6146 final String path = grantUri.uri.getPath(); 6147 int i = pps.length; 6148 while (i > 0 && (!readMet || !writeMet)) { 6149 i--; 6150 PathPermission pp = pps[i]; 6151 if (pp.match(path)) { 6152 if (!readMet) { 6153 final String pprperm = pp.getReadPermission(); 6154 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6155 + pprperm + " for " + pp.getPath() 6156 + ": match=" + pp.match(path) 6157 + " check=" + pm.checkUidPermission(pprperm, uid)); 6158 if (pprperm != null) { 6159 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6160 == PERMISSION_GRANTED) { 6161 readMet = true; 6162 } else { 6163 allowDefaultRead = false; 6164 } 6165 } 6166 } 6167 if (!writeMet) { 6168 final String ppwperm = pp.getWritePermission(); 6169 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6170 + ppwperm + " for " + pp.getPath() 6171 + ": match=" + pp.match(path) 6172 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6173 if (ppwperm != null) { 6174 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6175 == PERMISSION_GRANTED) { 6176 writeMet = true; 6177 } else { 6178 allowDefaultWrite = false; 6179 } 6180 } 6181 } 6182 } 6183 } 6184 } 6185 6186 // grant unprotected <provider> read/write, if not blocked by 6187 // <path-permission> above 6188 if (allowDefaultRead) readMet = true; 6189 if (allowDefaultWrite) writeMet = true; 6190 6191 } catch (RemoteException e) { 6192 return false; 6193 } 6194 6195 return readMet && writeMet; 6196 } 6197 6198 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6199 ProviderInfo pi = null; 6200 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6201 if (cpr != null) { 6202 pi = cpr.info; 6203 } else { 6204 try { 6205 pi = AppGlobals.getPackageManager().resolveContentProvider( 6206 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6207 } catch (RemoteException ex) { 6208 } 6209 } 6210 return pi; 6211 } 6212 6213 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6214 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6215 if (targetUris != null) { 6216 return targetUris.get(grantUri); 6217 } 6218 return null; 6219 } 6220 6221 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6222 String targetPkg, int targetUid, GrantUri grantUri) { 6223 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6224 if (targetUris == null) { 6225 targetUris = Maps.newArrayMap(); 6226 mGrantedUriPermissions.put(targetUid, targetUris); 6227 } 6228 6229 UriPermission perm = targetUris.get(grantUri); 6230 if (perm == null) { 6231 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6232 targetUris.put(grantUri, perm); 6233 } 6234 6235 return perm; 6236 } 6237 6238 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6239 final int modeFlags) { 6240 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6241 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6242 : UriPermission.STRENGTH_OWNED; 6243 6244 // Root gets to do everything. 6245 if (uid == 0) { 6246 return true; 6247 } 6248 6249 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6250 if (perms == null) return false; 6251 6252 // First look for exact match 6253 final UriPermission exactPerm = perms.get(grantUri); 6254 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6255 return true; 6256 } 6257 6258 // No exact match, look for prefixes 6259 final int N = perms.size(); 6260 for (int i = 0; i < N; i++) { 6261 final UriPermission perm = perms.valueAt(i); 6262 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6263 && perm.getStrength(modeFlags) >= minStrength) { 6264 return true; 6265 } 6266 } 6267 6268 return false; 6269 } 6270 6271 @Override 6272 public int checkUriPermission(Uri uri, int pid, int uid, 6273 final int modeFlags, int userId) { 6274 enforceNotIsolatedCaller("checkUriPermission"); 6275 6276 // Another redirected-binder-call permissions check as in 6277 // {@link checkComponentPermission}. 6278 Identity tlsIdentity = sCallerIdentity.get(); 6279 if (tlsIdentity != null) { 6280 uid = tlsIdentity.uid; 6281 pid = tlsIdentity.pid; 6282 } 6283 6284 // Our own process gets to do everything. 6285 if (pid == MY_PID) { 6286 return PackageManager.PERMISSION_GRANTED; 6287 } 6288 synchronized (this) { 6289 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6290 ? PackageManager.PERMISSION_GRANTED 6291 : PackageManager.PERMISSION_DENIED; 6292 } 6293 } 6294 6295 /** 6296 * Check if the targetPkg can be granted permission to access uri by 6297 * the callingUid using the given modeFlags. Throws a security exception 6298 * if callingUid is not allowed to do this. Returns the uid of the target 6299 * if the URI permission grant should be performed; returns -1 if it is not 6300 * needed (for example targetPkg already has permission to access the URI). 6301 * If you already know the uid of the target, you can supply it in 6302 * lastTargetUid else set that to -1. 6303 */ 6304 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6305 final int modeFlags, int lastTargetUid) { 6306 if (!Intent.isAccessUriMode(modeFlags)) { 6307 return -1; 6308 } 6309 6310 if (targetPkg != null) { 6311 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6312 "Checking grant " + targetPkg + " permission to " + grantUri); 6313 } 6314 6315 final IPackageManager pm = AppGlobals.getPackageManager(); 6316 6317 // If this is not a content: uri, we can't do anything with it. 6318 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6319 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6320 "Can't grant URI permission for non-content URI: " + grantUri); 6321 return -1; 6322 } 6323 6324 final String authority = grantUri.uri.getAuthority(); 6325 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6326 if (pi == null) { 6327 Slog.w(TAG, "No content provider found for permission check: " + 6328 grantUri.uri.toSafeString()); 6329 return -1; 6330 } 6331 6332 int targetUid = lastTargetUid; 6333 if (targetUid < 0 && targetPkg != null) { 6334 try { 6335 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6336 if (targetUid < 0) { 6337 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6338 "Can't grant URI permission no uid for: " + targetPkg); 6339 return -1; 6340 } 6341 } catch (RemoteException ex) { 6342 return -1; 6343 } 6344 } 6345 6346 if (targetUid >= 0) { 6347 // First... does the target actually need this permission? 6348 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6349 // No need to grant the target this permission. 6350 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6351 "Target " + targetPkg + " already has full permission to " + grantUri); 6352 return -1; 6353 } 6354 } else { 6355 // First... there is no target package, so can anyone access it? 6356 boolean allowed = pi.exported; 6357 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6358 if (pi.readPermission != null) { 6359 allowed = false; 6360 } 6361 } 6362 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6363 if (pi.writePermission != null) { 6364 allowed = false; 6365 } 6366 } 6367 if (allowed) { 6368 return -1; 6369 } 6370 } 6371 6372 /* There is a special cross user grant if: 6373 * - The target is on another user. 6374 * - Apps on the current user can access the uri without any uid permissions. 6375 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6376 * grant uri permissions. 6377 */ 6378 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6379 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6380 modeFlags, false /*without considering the uid permissions*/); 6381 6382 // Second... is the provider allowing granting of URI permissions? 6383 if (!specialCrossUserGrant) { 6384 if (!pi.grantUriPermissions) { 6385 throw new SecurityException("Provider " + pi.packageName 6386 + "/" + pi.name 6387 + " does not allow granting of Uri permissions (uri " 6388 + grantUri + ")"); 6389 } 6390 if (pi.uriPermissionPatterns != null) { 6391 final int N = pi.uriPermissionPatterns.length; 6392 boolean allowed = false; 6393 for (int i=0; i<N; i++) { 6394 if (pi.uriPermissionPatterns[i] != null 6395 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6396 allowed = true; 6397 break; 6398 } 6399 } 6400 if (!allowed) { 6401 throw new SecurityException("Provider " + pi.packageName 6402 + "/" + pi.name 6403 + " does not allow granting of permission to path of Uri " 6404 + grantUri); 6405 } 6406 } 6407 } 6408 6409 // Third... does the caller itself have permission to access 6410 // this uri? 6411 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6412 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6413 // Require they hold a strong enough Uri permission 6414 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6415 throw new SecurityException("Uid " + callingUid 6416 + " does not have permission to uri " + grantUri); 6417 } 6418 } 6419 } 6420 return targetUid; 6421 } 6422 6423 @Override 6424 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6425 final int modeFlags, int userId) { 6426 enforceNotIsolatedCaller("checkGrantUriPermission"); 6427 synchronized(this) { 6428 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6429 new GrantUri(userId, uri, false), modeFlags, -1); 6430 } 6431 } 6432 6433 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6434 final int modeFlags, UriPermissionOwner owner) { 6435 if (!Intent.isAccessUriMode(modeFlags)) { 6436 return; 6437 } 6438 6439 // So here we are: the caller has the assumed permission 6440 // to the uri, and the target doesn't. Let's now give this to 6441 // the target. 6442 6443 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6444 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6445 6446 final String authority = grantUri.uri.getAuthority(); 6447 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6448 if (pi == null) { 6449 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6450 return; 6451 } 6452 6453 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6454 grantUri.prefix = true; 6455 } 6456 final UriPermission perm = findOrCreateUriPermissionLocked( 6457 pi.packageName, targetPkg, targetUid, grantUri); 6458 perm.grantModes(modeFlags, owner); 6459 } 6460 6461 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6462 final int modeFlags, UriPermissionOwner owner) { 6463 if (targetPkg == null) { 6464 throw new NullPointerException("targetPkg"); 6465 } 6466 6467 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6468 -1); 6469 if (targetUid < 0) { 6470 return; 6471 } 6472 6473 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6474 owner); 6475 } 6476 6477 static class NeededUriGrants extends ArrayList<GrantUri> { 6478 final String targetPkg; 6479 final int targetUid; 6480 final int flags; 6481 6482 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6483 this.targetPkg = targetPkg; 6484 this.targetUid = targetUid; 6485 this.flags = flags; 6486 } 6487 } 6488 6489 /** 6490 * Like checkGrantUriPermissionLocked, but takes an Intent. 6491 */ 6492 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6493 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6494 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6495 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6496 + " clip=" + (intent != null ? intent.getClipData() : null) 6497 + " from " + intent + "; flags=0x" 6498 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6499 6500 if (targetPkg == null) { 6501 throw new NullPointerException("targetPkg"); 6502 } 6503 6504 if (intent == null) { 6505 return null; 6506 } 6507 Uri data = intent.getData(); 6508 ClipData clip = intent.getClipData(); 6509 if (data == null && clip == null) { 6510 return null; 6511 } 6512 final IPackageManager pm = AppGlobals.getPackageManager(); 6513 int targetUid; 6514 if (needed != null) { 6515 targetUid = needed.targetUid; 6516 } else { 6517 try { 6518 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6519 } catch (RemoteException ex) { 6520 return null; 6521 } 6522 if (targetUid < 0) { 6523 if (DEBUG_URI_PERMISSION) { 6524 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6525 + " on user " + targetUserId); 6526 } 6527 return null; 6528 } 6529 } 6530 if (data != null) { 6531 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6532 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6533 targetUid); 6534 if (targetUid > 0) { 6535 if (needed == null) { 6536 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6537 } 6538 needed.add(grantUri); 6539 } 6540 } 6541 if (clip != null) { 6542 for (int i=0; i<clip.getItemCount(); i++) { 6543 Uri uri = clip.getItemAt(i).getUri(); 6544 if (uri != null) { 6545 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6546 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6547 targetUid); 6548 if (targetUid > 0) { 6549 if (needed == null) { 6550 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6551 } 6552 needed.add(grantUri); 6553 } 6554 } else { 6555 Intent clipIntent = clip.getItemAt(i).getIntent(); 6556 if (clipIntent != null) { 6557 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6558 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6559 if (newNeeded != null) { 6560 needed = newNeeded; 6561 } 6562 } 6563 } 6564 } 6565 } 6566 6567 return needed; 6568 } 6569 6570 /** 6571 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6572 */ 6573 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6574 UriPermissionOwner owner) { 6575 if (needed != null) { 6576 for (int i=0; i<needed.size(); i++) { 6577 GrantUri grantUri = needed.get(i); 6578 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6579 grantUri, needed.flags, owner); 6580 } 6581 } 6582 } 6583 6584 void grantUriPermissionFromIntentLocked(int callingUid, 6585 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6586 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6587 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6588 if (needed == null) { 6589 return; 6590 } 6591 6592 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6593 } 6594 6595 @Override 6596 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6597 final int modeFlags, int userId) { 6598 enforceNotIsolatedCaller("grantUriPermission"); 6599 GrantUri grantUri = new GrantUri(userId, uri, false); 6600 synchronized(this) { 6601 final ProcessRecord r = getRecordForAppLocked(caller); 6602 if (r == null) { 6603 throw new SecurityException("Unable to find app for caller " 6604 + caller 6605 + " when granting permission to uri " + grantUri); 6606 } 6607 if (targetPkg == null) { 6608 throw new IllegalArgumentException("null target"); 6609 } 6610 if (grantUri == null) { 6611 throw new IllegalArgumentException("null uri"); 6612 } 6613 6614 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6615 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6616 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6617 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6618 6619 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6620 } 6621 } 6622 6623 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6624 if (perm.modeFlags == 0) { 6625 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6626 perm.targetUid); 6627 if (perms != null) { 6628 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6629 "Removing " + perm.targetUid + " permission to " + perm.uri); 6630 6631 perms.remove(perm.uri); 6632 if (perms.isEmpty()) { 6633 mGrantedUriPermissions.remove(perm.targetUid); 6634 } 6635 } 6636 } 6637 } 6638 6639 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6640 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6641 6642 final IPackageManager pm = AppGlobals.getPackageManager(); 6643 final String authority = grantUri.uri.getAuthority(); 6644 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6645 if (pi == null) { 6646 Slog.w(TAG, "No content provider found for permission revoke: " 6647 + grantUri.toSafeString()); 6648 return; 6649 } 6650 6651 // Does the caller have this permission on the URI? 6652 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6653 // Right now, if you are not the original owner of the permission, 6654 // you are not allowed to revoke it. 6655 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6656 throw new SecurityException("Uid " + callingUid 6657 + " does not have permission to uri " + grantUri); 6658 //} 6659 } 6660 6661 boolean persistChanged = false; 6662 6663 // Go through all of the permissions and remove any that match. 6664 int N = mGrantedUriPermissions.size(); 6665 for (int i = 0; i < N; i++) { 6666 final int targetUid = mGrantedUriPermissions.keyAt(i); 6667 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6668 6669 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6670 final UriPermission perm = it.next(); 6671 if (perm.uri.sourceUserId == grantUri.sourceUserId 6672 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6673 if (DEBUG_URI_PERMISSION) 6674 Slog.v(TAG, 6675 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6676 persistChanged |= perm.revokeModes( 6677 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6678 if (perm.modeFlags == 0) { 6679 it.remove(); 6680 } 6681 } 6682 } 6683 6684 if (perms.isEmpty()) { 6685 mGrantedUriPermissions.remove(targetUid); 6686 N--; 6687 i--; 6688 } 6689 } 6690 6691 if (persistChanged) { 6692 schedulePersistUriGrants(); 6693 } 6694 } 6695 6696 @Override 6697 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6698 int userId) { 6699 enforceNotIsolatedCaller("revokeUriPermission"); 6700 synchronized(this) { 6701 final ProcessRecord r = getRecordForAppLocked(caller); 6702 if (r == null) { 6703 throw new SecurityException("Unable to find app for caller " 6704 + caller 6705 + " when revoking permission to uri " + uri); 6706 } 6707 if (uri == null) { 6708 Slog.w(TAG, "revokeUriPermission: null uri"); 6709 return; 6710 } 6711 6712 if (!Intent.isAccessUriMode(modeFlags)) { 6713 return; 6714 } 6715 6716 final IPackageManager pm = AppGlobals.getPackageManager(); 6717 final String authority = uri.getAuthority(); 6718 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6719 if (pi == null) { 6720 Slog.w(TAG, "No content provider found for permission revoke: " 6721 + uri.toSafeString()); 6722 return; 6723 } 6724 6725 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6726 } 6727 } 6728 6729 /** 6730 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6731 * given package. 6732 * 6733 * @param packageName Package name to match, or {@code null} to apply to all 6734 * packages. 6735 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6736 * to all users. 6737 * @param persistable If persistable grants should be removed. 6738 */ 6739 private void removeUriPermissionsForPackageLocked( 6740 String packageName, int userHandle, boolean persistable) { 6741 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6742 throw new IllegalArgumentException("Must narrow by either package or user"); 6743 } 6744 6745 boolean persistChanged = false; 6746 6747 int N = mGrantedUriPermissions.size(); 6748 for (int i = 0; i < N; i++) { 6749 final int targetUid = mGrantedUriPermissions.keyAt(i); 6750 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6751 6752 // Only inspect grants matching user 6753 if (userHandle == UserHandle.USER_ALL 6754 || userHandle == UserHandle.getUserId(targetUid)) { 6755 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6756 final UriPermission perm = it.next(); 6757 6758 // Only inspect grants matching package 6759 if (packageName == null || perm.sourcePkg.equals(packageName) 6760 || perm.targetPkg.equals(packageName)) { 6761 persistChanged |= perm.revokeModes( 6762 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6763 6764 // Only remove when no modes remain; any persisted grants 6765 // will keep this alive. 6766 if (perm.modeFlags == 0) { 6767 it.remove(); 6768 } 6769 } 6770 } 6771 6772 if (perms.isEmpty()) { 6773 mGrantedUriPermissions.remove(targetUid); 6774 N--; 6775 i--; 6776 } 6777 } 6778 } 6779 6780 if (persistChanged) { 6781 schedulePersistUriGrants(); 6782 } 6783 } 6784 6785 @Override 6786 public IBinder newUriPermissionOwner(String name) { 6787 enforceNotIsolatedCaller("newUriPermissionOwner"); 6788 synchronized(this) { 6789 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6790 return owner.getExternalTokenLocked(); 6791 } 6792 } 6793 6794 @Override 6795 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6796 final int modeFlags, int userId) { 6797 synchronized(this) { 6798 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6799 if (owner == null) { 6800 throw new IllegalArgumentException("Unknown owner: " + token); 6801 } 6802 if (fromUid != Binder.getCallingUid()) { 6803 if (Binder.getCallingUid() != Process.myUid()) { 6804 // Only system code can grant URI permissions on behalf 6805 // of other users. 6806 throw new SecurityException("nice try"); 6807 } 6808 } 6809 if (targetPkg == null) { 6810 throw new IllegalArgumentException("null target"); 6811 } 6812 if (uri == null) { 6813 throw new IllegalArgumentException("null uri"); 6814 } 6815 6816 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6817 modeFlags, owner); 6818 } 6819 } 6820 6821 @Override 6822 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6823 synchronized(this) { 6824 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6825 if (owner == null) { 6826 throw new IllegalArgumentException("Unknown owner: " + token); 6827 } 6828 6829 if (uri == null) { 6830 owner.removeUriPermissionsLocked(mode); 6831 } else { 6832 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6833 } 6834 } 6835 } 6836 6837 private void schedulePersistUriGrants() { 6838 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6839 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6840 10 * DateUtils.SECOND_IN_MILLIS); 6841 } 6842 } 6843 6844 private void writeGrantedUriPermissions() { 6845 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6846 6847 // Snapshot permissions so we can persist without lock 6848 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6849 synchronized (this) { 6850 final int size = mGrantedUriPermissions.size(); 6851 for (int i = 0; i < size; i++) { 6852 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6853 for (UriPermission perm : perms.values()) { 6854 if (perm.persistedModeFlags != 0) { 6855 persist.add(perm.snapshot()); 6856 } 6857 } 6858 } 6859 } 6860 6861 FileOutputStream fos = null; 6862 try { 6863 fos = mGrantFile.startWrite(); 6864 6865 XmlSerializer out = new FastXmlSerializer(); 6866 out.setOutput(fos, "utf-8"); 6867 out.startDocument(null, true); 6868 out.startTag(null, TAG_URI_GRANTS); 6869 for (UriPermission.Snapshot perm : persist) { 6870 out.startTag(null, TAG_URI_GRANT); 6871 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6872 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6873 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6874 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6875 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6876 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6877 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6878 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6879 out.endTag(null, TAG_URI_GRANT); 6880 } 6881 out.endTag(null, TAG_URI_GRANTS); 6882 out.endDocument(); 6883 6884 mGrantFile.finishWrite(fos); 6885 } catch (IOException e) { 6886 if (fos != null) { 6887 mGrantFile.failWrite(fos); 6888 } 6889 } 6890 } 6891 6892 private void readGrantedUriPermissionsLocked() { 6893 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6894 6895 final long now = System.currentTimeMillis(); 6896 6897 FileInputStream fis = null; 6898 try { 6899 fis = mGrantFile.openRead(); 6900 final XmlPullParser in = Xml.newPullParser(); 6901 in.setInput(fis, null); 6902 6903 int type; 6904 while ((type = in.next()) != END_DOCUMENT) { 6905 final String tag = in.getName(); 6906 if (type == START_TAG) { 6907 if (TAG_URI_GRANT.equals(tag)) { 6908 final int sourceUserId; 6909 final int targetUserId; 6910 final int userHandle = readIntAttribute(in, 6911 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6912 if (userHandle != UserHandle.USER_NULL) { 6913 // For backwards compatibility. 6914 sourceUserId = userHandle; 6915 targetUserId = userHandle; 6916 } else { 6917 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6918 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6919 } 6920 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6921 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6922 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6923 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6924 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6925 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6926 6927 // Sanity check that provider still belongs to source package 6928 final ProviderInfo pi = getProviderInfoLocked( 6929 uri.getAuthority(), sourceUserId); 6930 if (pi != null && sourcePkg.equals(pi.packageName)) { 6931 int targetUid = -1; 6932 try { 6933 targetUid = AppGlobals.getPackageManager() 6934 .getPackageUid(targetPkg, targetUserId); 6935 } catch (RemoteException e) { 6936 } 6937 if (targetUid != -1) { 6938 final UriPermission perm = findOrCreateUriPermissionLocked( 6939 sourcePkg, targetPkg, targetUid, 6940 new GrantUri(sourceUserId, uri, prefix)); 6941 perm.initPersistedModes(modeFlags, createdTime); 6942 } 6943 } else { 6944 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6945 + " but instead found " + pi); 6946 } 6947 } 6948 } 6949 } 6950 } catch (FileNotFoundException e) { 6951 // Missing grants is okay 6952 } catch (IOException e) { 6953 Log.wtf(TAG, "Failed reading Uri grants", e); 6954 } catch (XmlPullParserException e) { 6955 Log.wtf(TAG, "Failed reading Uri grants", e); 6956 } finally { 6957 IoUtils.closeQuietly(fis); 6958 } 6959 } 6960 6961 @Override 6962 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6963 enforceNotIsolatedCaller("takePersistableUriPermission"); 6964 6965 Preconditions.checkFlagsArgument(modeFlags, 6966 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6967 6968 synchronized (this) { 6969 final int callingUid = Binder.getCallingUid(); 6970 boolean persistChanged = false; 6971 GrantUri grantUri = new GrantUri(userId, uri, false); 6972 6973 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6974 new GrantUri(userId, uri, false)); 6975 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6976 new GrantUri(userId, uri, true)); 6977 6978 final boolean exactValid = (exactPerm != null) 6979 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6980 final boolean prefixValid = (prefixPerm != null) 6981 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6982 6983 if (!(exactValid || prefixValid)) { 6984 throw new SecurityException("No persistable permission grants found for UID " 6985 + callingUid + " and Uri " + grantUri.toSafeString()); 6986 } 6987 6988 if (exactValid) { 6989 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6990 } 6991 if (prefixValid) { 6992 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6993 } 6994 6995 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6996 6997 if (persistChanged) { 6998 schedulePersistUriGrants(); 6999 } 7000 } 7001 } 7002 7003 @Override 7004 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7005 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7006 7007 Preconditions.checkFlagsArgument(modeFlags, 7008 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7009 7010 synchronized (this) { 7011 final int callingUid = Binder.getCallingUid(); 7012 boolean persistChanged = false; 7013 7014 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7015 new GrantUri(userId, uri, false)); 7016 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7017 new GrantUri(userId, uri, true)); 7018 if (exactPerm == null && prefixPerm == null) { 7019 throw new SecurityException("No permission grants found for UID " + callingUid 7020 + " and Uri " + uri.toSafeString()); 7021 } 7022 7023 if (exactPerm != null) { 7024 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7025 removeUriPermissionIfNeededLocked(exactPerm); 7026 } 7027 if (prefixPerm != null) { 7028 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7029 removeUriPermissionIfNeededLocked(prefixPerm); 7030 } 7031 7032 if (persistChanged) { 7033 schedulePersistUriGrants(); 7034 } 7035 } 7036 } 7037 7038 /** 7039 * Prune any older {@link UriPermission} for the given UID until outstanding 7040 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7041 * 7042 * @return if any mutations occured that require persisting. 7043 */ 7044 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7045 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7046 if (perms == null) return false; 7047 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7048 7049 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7050 for (UriPermission perm : perms.values()) { 7051 if (perm.persistedModeFlags != 0) { 7052 persisted.add(perm); 7053 } 7054 } 7055 7056 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7057 if (trimCount <= 0) return false; 7058 7059 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7060 for (int i = 0; i < trimCount; i++) { 7061 final UriPermission perm = persisted.get(i); 7062 7063 if (DEBUG_URI_PERMISSION) { 7064 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7065 } 7066 7067 perm.releasePersistableModes(~0); 7068 removeUriPermissionIfNeededLocked(perm); 7069 } 7070 7071 return true; 7072 } 7073 7074 @Override 7075 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7076 String packageName, boolean incoming) { 7077 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7078 Preconditions.checkNotNull(packageName, "packageName"); 7079 7080 final int callingUid = Binder.getCallingUid(); 7081 final IPackageManager pm = AppGlobals.getPackageManager(); 7082 try { 7083 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7084 if (packageUid != callingUid) { 7085 throw new SecurityException( 7086 "Package " + packageName + " does not belong to calling UID " + callingUid); 7087 } 7088 } catch (RemoteException e) { 7089 throw new SecurityException("Failed to verify package name ownership"); 7090 } 7091 7092 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7093 synchronized (this) { 7094 if (incoming) { 7095 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7096 callingUid); 7097 if (perms == null) { 7098 Slog.w(TAG, "No permission grants found for " + packageName); 7099 } else { 7100 for (UriPermission perm : perms.values()) { 7101 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7102 result.add(perm.buildPersistedPublicApiObject()); 7103 } 7104 } 7105 } 7106 } else { 7107 final int size = mGrantedUriPermissions.size(); 7108 for (int i = 0; i < size; i++) { 7109 final ArrayMap<GrantUri, UriPermission> perms = 7110 mGrantedUriPermissions.valueAt(i); 7111 for (UriPermission perm : perms.values()) { 7112 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7113 result.add(perm.buildPersistedPublicApiObject()); 7114 } 7115 } 7116 } 7117 } 7118 } 7119 return new ParceledListSlice<android.content.UriPermission>(result); 7120 } 7121 7122 @Override 7123 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7124 synchronized (this) { 7125 ProcessRecord app = 7126 who != null ? getRecordForAppLocked(who) : null; 7127 if (app == null) return; 7128 7129 Message msg = Message.obtain(); 7130 msg.what = WAIT_FOR_DEBUGGER_MSG; 7131 msg.obj = app; 7132 msg.arg1 = waiting ? 1 : 0; 7133 mHandler.sendMessage(msg); 7134 } 7135 } 7136 7137 @Override 7138 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7139 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7140 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7141 outInfo.availMem = Process.getFreeMemory(); 7142 outInfo.totalMem = Process.getTotalMemory(); 7143 outInfo.threshold = homeAppMem; 7144 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7145 outInfo.hiddenAppThreshold = cachedAppMem; 7146 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7147 ProcessList.SERVICE_ADJ); 7148 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7149 ProcessList.VISIBLE_APP_ADJ); 7150 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7151 ProcessList.FOREGROUND_APP_ADJ); 7152 } 7153 7154 // ========================================================= 7155 // TASK MANAGEMENT 7156 // ========================================================= 7157 7158 @Override 7159 public List<IAppTask> getAppTasks() { 7160 final PackageManager pm = mContext.getPackageManager(); 7161 int callingUid = Binder.getCallingUid(); 7162 long ident = Binder.clearCallingIdentity(); 7163 7164 // Compose the list of packages for this id to test against 7165 HashSet<String> packages = new HashSet<String>(); 7166 String[] uidPackages = pm.getPackagesForUid(callingUid); 7167 for (int i = 0; i < uidPackages.length; i++) { 7168 packages.add(uidPackages[i]); 7169 } 7170 7171 synchronized(this) { 7172 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7173 try { 7174 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7175 7176 final int N = mRecentTasks.size(); 7177 for (int i = 0; i < N; i++) { 7178 TaskRecord tr = mRecentTasks.get(i); 7179 // Skip tasks that are not created by the caller 7180 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7181 ActivityManager.RecentTaskInfo taskInfo = 7182 createRecentTaskInfoFromTaskRecord(tr); 7183 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7184 list.add(taskImpl); 7185 } 7186 } 7187 } finally { 7188 Binder.restoreCallingIdentity(ident); 7189 } 7190 return list; 7191 } 7192 } 7193 7194 @Override 7195 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7196 final int callingUid = Binder.getCallingUid(); 7197 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7198 7199 synchronized(this) { 7200 if (localLOGV) Slog.v( 7201 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7202 7203 final boolean allowed = checkCallingPermission( 7204 android.Manifest.permission.GET_TASKS) 7205 == PackageManager.PERMISSION_GRANTED; 7206 if (!allowed) { 7207 Slog.w(TAG, "getTasks: caller " + callingUid 7208 + " does not hold GET_TASKS; limiting output"); 7209 } 7210 7211 // TODO: Improve with MRU list from all ActivityStacks. 7212 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7213 } 7214 7215 return list; 7216 } 7217 7218 TaskRecord getMostRecentTask() { 7219 return mRecentTasks.get(0); 7220 } 7221 7222 /** 7223 * Creates a new RecentTaskInfo from a TaskRecord. 7224 */ 7225 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7226 // Update the task description to reflect any changes in the task stack 7227 tr.updateTaskDescription(); 7228 7229 // Compose the recent task info 7230 ActivityManager.RecentTaskInfo rti 7231 = new ActivityManager.RecentTaskInfo(); 7232 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7233 rti.persistentId = tr.taskId; 7234 rti.baseIntent = new Intent(tr.getBaseIntent()); 7235 rti.origActivity = tr.origActivity; 7236 rti.description = tr.lastDescription; 7237 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7238 rti.userId = tr.userId; 7239 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7240 rti.lastActiveTime = tr.lastActiveTime; 7241 return rti; 7242 } 7243 7244 @Override 7245 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7246 int flags, int userId) { 7247 final int callingUid = Binder.getCallingUid(); 7248 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7249 false, true, "getRecentTasks", null); 7250 7251 synchronized (this) { 7252 final boolean allowed = checkCallingPermission( 7253 android.Manifest.permission.GET_TASKS) 7254 == PackageManager.PERMISSION_GRANTED; 7255 if (!allowed) { 7256 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7257 + " does not hold GET_TASKS; limiting output"); 7258 } 7259 final boolean detailed = checkCallingPermission( 7260 android.Manifest.permission.GET_DETAILED_TASKS) 7261 == PackageManager.PERMISSION_GRANTED; 7262 7263 IPackageManager pm = AppGlobals.getPackageManager(); 7264 7265 final int N = mRecentTasks.size(); 7266 ArrayList<ActivityManager.RecentTaskInfo> res 7267 = new ArrayList<ActivityManager.RecentTaskInfo>( 7268 maxNum < N ? maxNum : N); 7269 7270 final Set<Integer> includedUsers; 7271 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7272 includedUsers = getProfileIdsLocked(userId); 7273 } else { 7274 includedUsers = new HashSet<Integer>(); 7275 } 7276 includedUsers.add(Integer.valueOf(userId)); 7277 for (int i=0; i<N && maxNum > 0; i++) { 7278 TaskRecord tr = mRecentTasks.get(i); 7279 // Only add calling user or related users recent tasks 7280 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7281 7282 // Return the entry if desired by the caller. We always return 7283 // the first entry, because callers always expect this to be the 7284 // foreground app. We may filter others if the caller has 7285 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7286 // we should exclude the entry. 7287 7288 if (i == 0 7289 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7290 || (tr.intent == null) 7291 || ((tr.intent.getFlags() 7292 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7293 if (!allowed) { 7294 // If the caller doesn't have the GET_TASKS permission, then only 7295 // allow them to see a small subset of tasks -- their own and home. 7296 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7297 continue; 7298 } 7299 } 7300 if (tr.intent != null && 7301 (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) 7302 != 0 && tr.getTopActivity() == null) { 7303 // Don't include auto remove tasks that are finished or finishing. 7304 continue; 7305 } 7306 7307 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7308 if (!detailed) { 7309 rti.baseIntent.replaceExtras((Bundle)null); 7310 } 7311 7312 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7313 // Check whether this activity is currently available. 7314 try { 7315 if (rti.origActivity != null) { 7316 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7317 == null) { 7318 continue; 7319 } 7320 } else if (rti.baseIntent != null) { 7321 if (pm.queryIntentActivities(rti.baseIntent, 7322 null, 0, userId) == null) { 7323 continue; 7324 } 7325 } 7326 } catch (RemoteException e) { 7327 // Will never happen. 7328 } 7329 } 7330 7331 res.add(rti); 7332 maxNum--; 7333 } 7334 } 7335 return res; 7336 } 7337 } 7338 7339 private TaskRecord recentTaskForIdLocked(int id) { 7340 final int N = mRecentTasks.size(); 7341 for (int i=0; i<N; i++) { 7342 TaskRecord tr = mRecentTasks.get(i); 7343 if (tr.taskId == id) { 7344 return tr; 7345 } 7346 } 7347 return null; 7348 } 7349 7350 @Override 7351 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7352 synchronized (this) { 7353 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7354 "getTaskThumbnails()"); 7355 TaskRecord tr = recentTaskForIdLocked(id); 7356 if (tr != null) { 7357 return tr.getTaskThumbnailsLocked(); 7358 } 7359 } 7360 return null; 7361 } 7362 7363 @Override 7364 public Bitmap getTaskTopThumbnail(int id) { 7365 synchronized (this) { 7366 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7367 "getTaskTopThumbnail()"); 7368 TaskRecord tr = recentTaskForIdLocked(id); 7369 if (tr != null) { 7370 return tr.getTaskTopThumbnailLocked(); 7371 } 7372 } 7373 return null; 7374 } 7375 7376 @Override 7377 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7378 synchronized (this) { 7379 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7380 if (r != null) { 7381 r.taskDescription = td; 7382 r.task.updateTaskDescription(); 7383 } 7384 } 7385 } 7386 7387 @Override 7388 public boolean removeSubTask(int taskId, int subTaskIndex) { 7389 synchronized (this) { 7390 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7391 "removeSubTask()"); 7392 long ident = Binder.clearCallingIdentity(); 7393 try { 7394 TaskRecord tr = recentTaskForIdLocked(taskId); 7395 if (tr != null) { 7396 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7397 } 7398 return false; 7399 } finally { 7400 Binder.restoreCallingIdentity(ident); 7401 } 7402 } 7403 } 7404 7405 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7406 if (!pr.killedByAm) { 7407 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7408 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7409 pr.processName, pr.setAdj, reason); 7410 pr.killedByAm = true; 7411 Process.killProcessQuiet(pr.pid); 7412 } 7413 } 7414 7415 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7416 tr.disposeThumbnail(); 7417 mRecentTasks.remove(tr); 7418 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7419 Intent baseIntent = new Intent( 7420 tr.intent != null ? tr.intent : tr.affinityIntent); 7421 ComponentName component = baseIntent.getComponent(); 7422 if (component == null) { 7423 Slog.w(TAG, "Now component for base intent of task: " + tr); 7424 return; 7425 } 7426 7427 // Find any running services associated with this app. 7428 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7429 7430 if (killProcesses) { 7431 // Find any running processes associated with this app. 7432 final String pkg = component.getPackageName(); 7433 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7434 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7435 for (int i=0; i<pmap.size(); i++) { 7436 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7437 for (int j=0; j<uids.size(); j++) { 7438 ProcessRecord proc = uids.valueAt(j); 7439 if (proc.userId != tr.userId) { 7440 continue; 7441 } 7442 if (!proc.pkgList.containsKey(pkg)) { 7443 continue; 7444 } 7445 procs.add(proc); 7446 } 7447 } 7448 7449 // Kill the running processes. 7450 for (int i=0; i<procs.size(); i++) { 7451 ProcessRecord pr = procs.get(i); 7452 if (pr == mHomeProcess) { 7453 // Don't kill the home process along with tasks from the same package. 7454 continue; 7455 } 7456 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7457 killUnneededProcessLocked(pr, "remove task"); 7458 } else { 7459 pr.waitingToKill = "remove task"; 7460 } 7461 } 7462 } 7463 } 7464 7465 /** 7466 * Removes the task with the specified task id. 7467 * 7468 * @param taskId Identifier of the task to be removed. 7469 * @param flags Additional operational flags. May be 0 or 7470 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7471 * @return Returns true if the given task was found and removed. 7472 */ 7473 private boolean removeTaskByIdLocked(int taskId, int flags) { 7474 TaskRecord tr = recentTaskForIdLocked(taskId); 7475 if (tr != null) { 7476 tr.removeTaskActivitiesLocked(-1, false); 7477 cleanUpRemovedTaskLocked(tr, flags); 7478 if (tr.isPersistable) { 7479 notifyTaskPersisterLocked(tr, true); 7480 } 7481 return true; 7482 } 7483 return false; 7484 } 7485 7486 @Override 7487 public boolean removeTask(int taskId, int flags) { 7488 synchronized (this) { 7489 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7490 "removeTask()"); 7491 long ident = Binder.clearCallingIdentity(); 7492 try { 7493 return removeTaskByIdLocked(taskId, flags); 7494 } finally { 7495 Binder.restoreCallingIdentity(ident); 7496 } 7497 } 7498 } 7499 7500 /** 7501 * TODO: Add mController hook 7502 */ 7503 @Override 7504 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7505 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7506 "moveTaskToFront()"); 7507 7508 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7509 synchronized(this) { 7510 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7511 Binder.getCallingUid(), "Task to front")) { 7512 ActivityOptions.abort(options); 7513 return; 7514 } 7515 final long origId = Binder.clearCallingIdentity(); 7516 try { 7517 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7518 if (task == null) { 7519 return; 7520 } 7521 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7522 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7523 return; 7524 } 7525 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7526 if (prev != null && prev.isRecentsActivity()) { 7527 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7528 } 7529 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7530 } finally { 7531 Binder.restoreCallingIdentity(origId); 7532 } 7533 ActivityOptions.abort(options); 7534 } 7535 } 7536 7537 @Override 7538 public void moveTaskToBack(int taskId) { 7539 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7540 "moveTaskToBack()"); 7541 7542 synchronized(this) { 7543 TaskRecord tr = recentTaskForIdLocked(taskId); 7544 if (tr != null) { 7545 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7546 ActivityStack stack = tr.stack; 7547 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7548 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7549 Binder.getCallingUid(), "Task to back")) { 7550 return; 7551 } 7552 } 7553 final long origId = Binder.clearCallingIdentity(); 7554 try { 7555 stack.moveTaskToBackLocked(taskId, null); 7556 } finally { 7557 Binder.restoreCallingIdentity(origId); 7558 } 7559 } 7560 } 7561 } 7562 7563 /** 7564 * Moves an activity, and all of the other activities within the same task, to the bottom 7565 * of the history stack. The activity's order within the task is unchanged. 7566 * 7567 * @param token A reference to the activity we wish to move 7568 * @param nonRoot If false then this only works if the activity is the root 7569 * of a task; if true it will work for any activity in a task. 7570 * @return Returns true if the move completed, false if not. 7571 */ 7572 @Override 7573 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7574 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7575 synchronized(this) { 7576 final long origId = Binder.clearCallingIdentity(); 7577 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7578 if (taskId >= 0) { 7579 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7580 } 7581 Binder.restoreCallingIdentity(origId); 7582 } 7583 return false; 7584 } 7585 7586 @Override 7587 public void moveTaskBackwards(int task) { 7588 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7589 "moveTaskBackwards()"); 7590 7591 synchronized(this) { 7592 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7593 Binder.getCallingUid(), "Task backwards")) { 7594 return; 7595 } 7596 final long origId = Binder.clearCallingIdentity(); 7597 moveTaskBackwardsLocked(task); 7598 Binder.restoreCallingIdentity(origId); 7599 } 7600 } 7601 7602 private final void moveTaskBackwardsLocked(int task) { 7603 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7604 } 7605 7606 @Override 7607 public IBinder getHomeActivityToken() throws RemoteException { 7608 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7609 "getHomeActivityToken()"); 7610 synchronized (this) { 7611 return mStackSupervisor.getHomeActivityToken(); 7612 } 7613 } 7614 7615 @Override 7616 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7617 IActivityContainerCallback callback) throws RemoteException { 7618 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7619 "createActivityContainer()"); 7620 synchronized (this) { 7621 if (parentActivityToken == null) { 7622 throw new IllegalArgumentException("parent token must not be null"); 7623 } 7624 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7625 if (r == null) { 7626 return null; 7627 } 7628 if (callback == null) { 7629 throw new IllegalArgumentException("callback must not be null"); 7630 } 7631 return mStackSupervisor.createActivityContainer(r, callback); 7632 } 7633 } 7634 7635 @Override 7636 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7637 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7638 "deleteActivityContainer()"); 7639 synchronized (this) { 7640 mStackSupervisor.deleteActivityContainer(container); 7641 } 7642 } 7643 7644 @Override 7645 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7646 throws RemoteException { 7647 synchronized (this) { 7648 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7649 if (stack != null) { 7650 return stack.mActivityContainer; 7651 } 7652 return null; 7653 } 7654 } 7655 7656 @Override 7657 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7658 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7659 "moveTaskToStack()"); 7660 if (stackId == HOME_STACK_ID) { 7661 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7662 new RuntimeException("here").fillInStackTrace()); 7663 } 7664 synchronized (this) { 7665 long ident = Binder.clearCallingIdentity(); 7666 try { 7667 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7668 + stackId + " toTop=" + toTop); 7669 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7670 } finally { 7671 Binder.restoreCallingIdentity(ident); 7672 } 7673 } 7674 } 7675 7676 @Override 7677 public void resizeStack(int stackBoxId, Rect bounds) { 7678 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7679 "resizeStackBox()"); 7680 long ident = Binder.clearCallingIdentity(); 7681 try { 7682 mWindowManager.resizeStack(stackBoxId, bounds); 7683 } finally { 7684 Binder.restoreCallingIdentity(ident); 7685 } 7686 } 7687 7688 @Override 7689 public List<StackInfo> getAllStackInfos() { 7690 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7691 "getAllStackInfos()"); 7692 long ident = Binder.clearCallingIdentity(); 7693 try { 7694 synchronized (this) { 7695 return mStackSupervisor.getAllStackInfosLocked(); 7696 } 7697 } finally { 7698 Binder.restoreCallingIdentity(ident); 7699 } 7700 } 7701 7702 @Override 7703 public StackInfo getStackInfo(int stackId) { 7704 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7705 "getStackInfo()"); 7706 long ident = Binder.clearCallingIdentity(); 7707 try { 7708 synchronized (this) { 7709 return mStackSupervisor.getStackInfoLocked(stackId); 7710 } 7711 } finally { 7712 Binder.restoreCallingIdentity(ident); 7713 } 7714 } 7715 7716 @Override 7717 public boolean isInHomeStack(int taskId) { 7718 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7719 "getStackInfo()"); 7720 long ident = Binder.clearCallingIdentity(); 7721 try { 7722 synchronized (this) { 7723 TaskRecord tr = recentTaskForIdLocked(taskId); 7724 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7725 } 7726 } finally { 7727 Binder.restoreCallingIdentity(ident); 7728 } 7729 } 7730 7731 @Override 7732 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7733 synchronized(this) { 7734 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7735 } 7736 } 7737 7738 private boolean isLockTaskAuthorized(String pkg) { 7739 final DevicePolicyManager dpm = (DevicePolicyManager) 7740 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7741 try { 7742 int uid = mContext.getPackageManager().getPackageUid(pkg, 7743 Binder.getCallingUserHandle().getIdentifier()); 7744 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7745 } catch (NameNotFoundException e) { 7746 return false; 7747 } 7748 } 7749 7750 void startLockTaskMode(TaskRecord task) { 7751 final String pkg; 7752 synchronized (this) { 7753 pkg = task.intent.getComponent().getPackageName(); 7754 } 7755 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7756 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7757 final TaskRecord taskRecord = task; 7758 mHandler.post(new Runnable() { 7759 @Override 7760 public void run() { 7761 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7762 } 7763 }); 7764 return; 7765 } 7766 long ident = Binder.clearCallingIdentity(); 7767 try { 7768 synchronized (this) { 7769 // Since we lost lock on task, make sure it is still there. 7770 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7771 if (task != null) { 7772 if (!isSystemInitiated 7773 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7774 throw new IllegalArgumentException("Invalid task, not in foreground"); 7775 } 7776 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated); 7777 } 7778 } 7779 } finally { 7780 Binder.restoreCallingIdentity(ident); 7781 } 7782 } 7783 7784 @Override 7785 public void startLockTaskMode(int taskId) { 7786 final TaskRecord task; 7787 long ident = Binder.clearCallingIdentity(); 7788 try { 7789 synchronized (this) { 7790 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7791 } 7792 } finally { 7793 Binder.restoreCallingIdentity(ident); 7794 } 7795 if (task != null) { 7796 startLockTaskMode(task); 7797 } 7798 } 7799 7800 @Override 7801 public void startLockTaskMode(IBinder token) { 7802 final TaskRecord task; 7803 long ident = Binder.clearCallingIdentity(); 7804 try { 7805 synchronized (this) { 7806 final ActivityRecord r = ActivityRecord.forToken(token); 7807 if (r == null) { 7808 return; 7809 } 7810 task = r.task; 7811 } 7812 } finally { 7813 Binder.restoreCallingIdentity(ident); 7814 } 7815 if (task != null) { 7816 startLockTaskMode(task); 7817 } 7818 } 7819 7820 @Override 7821 public void startLockTaskModeOnCurrent() throws RemoteException { 7822 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7823 ActivityRecord r = null; 7824 synchronized (this) { 7825 r = mStackSupervisor.topRunningActivityLocked(); 7826 } 7827 startLockTaskMode(r.task); 7828 } 7829 7830 @Override 7831 public void stopLockTaskMode() { 7832 // Verify that the user matches the package of the intent for the TaskRecord 7833 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7834 // and stopLockTaskMode. 7835 final int callingUid = Binder.getCallingUid(); 7836 if (callingUid != Process.SYSTEM_UID) { 7837 try { 7838 String pkg = 7839 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7840 int uid = mContext.getPackageManager().getPackageUid(pkg, 7841 Binder.getCallingUserHandle().getIdentifier()); 7842 if (uid != callingUid) { 7843 throw new SecurityException("Invalid uid, expected " + uid); 7844 } 7845 } catch (NameNotFoundException e) { 7846 Log.d(TAG, "stopLockTaskMode " + e); 7847 return; 7848 } 7849 } 7850 long ident = Binder.clearCallingIdentity(); 7851 try { 7852 Log.d(TAG, "stopLockTaskMode"); 7853 // Stop lock task 7854 synchronized (this) { 7855 mStackSupervisor.setLockTaskModeLocked(null, false); 7856 } 7857 } finally { 7858 Binder.restoreCallingIdentity(ident); 7859 } 7860 } 7861 7862 @Override 7863 public void stopLockTaskModeOnCurrent() throws RemoteException { 7864 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7865 long ident = Binder.clearCallingIdentity(); 7866 try { 7867 stopLockTaskMode(); 7868 } finally { 7869 Binder.restoreCallingIdentity(ident); 7870 } 7871 } 7872 7873 @Override 7874 public boolean isInLockTaskMode() { 7875 synchronized (this) { 7876 return mStackSupervisor.isInLockTaskMode(); 7877 } 7878 } 7879 7880 // ========================================================= 7881 // CONTENT PROVIDERS 7882 // ========================================================= 7883 7884 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7885 List<ProviderInfo> providers = null; 7886 try { 7887 providers = AppGlobals.getPackageManager(). 7888 queryContentProviders(app.processName, app.uid, 7889 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7890 } catch (RemoteException ex) { 7891 } 7892 if (DEBUG_MU) 7893 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7894 int userId = app.userId; 7895 if (providers != null) { 7896 int N = providers.size(); 7897 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7898 for (int i=0; i<N; i++) { 7899 ProviderInfo cpi = 7900 (ProviderInfo)providers.get(i); 7901 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7902 cpi.name, cpi.flags); 7903 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7904 // This is a singleton provider, but a user besides the 7905 // default user is asking to initialize a process it runs 7906 // in... well, no, it doesn't actually run in this process, 7907 // it runs in the process of the default user. Get rid of it. 7908 providers.remove(i); 7909 N--; 7910 i--; 7911 continue; 7912 } 7913 7914 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7915 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7916 if (cpr == null) { 7917 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7918 mProviderMap.putProviderByClass(comp, cpr); 7919 } 7920 if (DEBUG_MU) 7921 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7922 app.pubProviders.put(cpi.name, cpr); 7923 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7924 // Don't add this if it is a platform component that is marked 7925 // to run in multiple processes, because this is actually 7926 // part of the framework so doesn't make sense to track as a 7927 // separate apk in the process. 7928 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 7929 mProcessStats); 7930 } 7931 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7932 } 7933 } 7934 return providers; 7935 } 7936 7937 /** 7938 * Check if {@link ProcessRecord} has a possible chance at accessing the 7939 * given {@link ProviderInfo}. Final permission checking is always done 7940 * in {@link ContentProvider}. 7941 */ 7942 private final String checkContentProviderPermissionLocked( 7943 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 7944 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7945 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7946 boolean checkedGrants = false; 7947 if (checkUser) { 7948 // Looking for cross-user grants before enforcing the typical cross-users permissions 7949 if (UserHandle.getUserId(callingUid) != userId) { 7950 if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7951 return null; 7952 } 7953 checkedGrants = true; 7954 } 7955 userId = handleIncomingUser(callingPid, callingUid, userId, 7956 false, true, "checkContentProviderPermissionLocked " + cpi.authority, null); 7957 } 7958 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7959 cpi.applicationInfo.uid, cpi.exported) 7960 == PackageManager.PERMISSION_GRANTED) { 7961 return null; 7962 } 7963 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7964 cpi.applicationInfo.uid, cpi.exported) 7965 == PackageManager.PERMISSION_GRANTED) { 7966 return null; 7967 } 7968 7969 PathPermission[] pps = cpi.pathPermissions; 7970 if (pps != null) { 7971 int i = pps.length; 7972 while (i > 0) { 7973 i--; 7974 PathPermission pp = pps[i]; 7975 String pprperm = pp.getReadPermission(); 7976 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 7977 cpi.applicationInfo.uid, cpi.exported) 7978 == PackageManager.PERMISSION_GRANTED) { 7979 return null; 7980 } 7981 String ppwperm = pp.getWritePermission(); 7982 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 7983 cpi.applicationInfo.uid, cpi.exported) 7984 == PackageManager.PERMISSION_GRANTED) { 7985 return null; 7986 } 7987 } 7988 } 7989 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7990 return null; 7991 } 7992 7993 String msg; 7994 if (!cpi.exported) { 7995 msg = "Permission Denial: opening provider " + cpi.name 7996 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7997 + ", uid=" + callingUid + ") that is not exported from uid " 7998 + cpi.applicationInfo.uid; 7999 } else { 8000 msg = "Permission Denial: opening provider " + cpi.name 8001 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8002 + ", uid=" + callingUid + ") requires " 8003 + cpi.readPermission + " or " + cpi.writePermission; 8004 } 8005 Slog.w(TAG, msg); 8006 return msg; 8007 } 8008 8009 /** 8010 * Returns if the ContentProvider has granted a uri to callingUid 8011 */ 8012 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8013 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8014 if (perms != null) { 8015 for (GrantUri grantUri : perms.keySet()) { 8016 if (grantUri.sourceUserId == userId || !checkUser) { 8017 if (matchesProvider(grantUri.uri, cpi)) { 8018 return true; 8019 } 8020 } 8021 } 8022 } 8023 return false; 8024 } 8025 8026 /** 8027 * Returns true if the uri authority is one of the authorities specified in the provider. 8028 */ 8029 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8030 String uriAuth = uri.getAuthority(); 8031 String cpiAuth = cpi.authority; 8032 if (cpiAuth.indexOf(';') == -1) { 8033 return cpiAuth.equals(uriAuth); 8034 } 8035 String[] cpiAuths = cpiAuth.split(";"); 8036 int length = cpiAuths.length; 8037 for (int i = 0; i < length; i++) { 8038 if (cpiAuths[i].equals(uriAuth)) return true; 8039 } 8040 return false; 8041 } 8042 8043 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8044 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8045 if (r != null) { 8046 for (int i=0; i<r.conProviders.size(); i++) { 8047 ContentProviderConnection conn = r.conProviders.get(i); 8048 if (conn.provider == cpr) { 8049 if (DEBUG_PROVIDER) Slog.v(TAG, 8050 "Adding provider requested by " 8051 + r.processName + " from process " 8052 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8053 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8054 if (stable) { 8055 conn.stableCount++; 8056 conn.numStableIncs++; 8057 } else { 8058 conn.unstableCount++; 8059 conn.numUnstableIncs++; 8060 } 8061 return conn; 8062 } 8063 } 8064 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8065 if (stable) { 8066 conn.stableCount = 1; 8067 conn.numStableIncs = 1; 8068 } else { 8069 conn.unstableCount = 1; 8070 conn.numUnstableIncs = 1; 8071 } 8072 cpr.connections.add(conn); 8073 r.conProviders.add(conn); 8074 return conn; 8075 } 8076 cpr.addExternalProcessHandleLocked(externalProcessToken); 8077 return null; 8078 } 8079 8080 boolean decProviderCountLocked(ContentProviderConnection conn, 8081 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8082 if (conn != null) { 8083 cpr = conn.provider; 8084 if (DEBUG_PROVIDER) Slog.v(TAG, 8085 "Removing provider requested by " 8086 + conn.client.processName + " from process " 8087 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8088 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8089 if (stable) { 8090 conn.stableCount--; 8091 } else { 8092 conn.unstableCount--; 8093 } 8094 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8095 cpr.connections.remove(conn); 8096 conn.client.conProviders.remove(conn); 8097 return true; 8098 } 8099 return false; 8100 } 8101 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8102 return false; 8103 } 8104 8105 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8106 String name, IBinder token, boolean stable, int userId) { 8107 ContentProviderRecord cpr; 8108 ContentProviderConnection conn = null; 8109 ProviderInfo cpi = null; 8110 8111 synchronized(this) { 8112 ProcessRecord r = null; 8113 if (caller != null) { 8114 r = getRecordForAppLocked(caller); 8115 if (r == null) { 8116 throw new SecurityException( 8117 "Unable to find app for caller " + caller 8118 + " (pid=" + Binder.getCallingPid() 8119 + ") when getting content provider " + name); 8120 } 8121 } 8122 8123 boolean checkCrossUser = true; 8124 8125 // First check if this content provider has been published... 8126 cpr = mProviderMap.getProviderByName(name, userId); 8127 // If that didn't work, check if it exists for user 0 and then 8128 // verify that it's a singleton provider before using it. 8129 if (cpr == null && userId != UserHandle.USER_OWNER) { 8130 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8131 if (cpr != null) { 8132 cpi = cpr.info; 8133 if (isSingleton(cpi.processName, cpi.applicationInfo, 8134 cpi.name, cpi.flags) 8135 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8136 userId = UserHandle.USER_OWNER; 8137 checkCrossUser = false; 8138 } else { 8139 cpr = null; 8140 cpi = null; 8141 } 8142 } 8143 } 8144 8145 boolean providerRunning = cpr != null; 8146 if (providerRunning) { 8147 cpi = cpr.info; 8148 String msg; 8149 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8150 != null) { 8151 throw new SecurityException(msg); 8152 } 8153 8154 if (r != null && cpr.canRunHere(r)) { 8155 // This provider has been published or is in the process 8156 // of being published... but it is also allowed to run 8157 // in the caller's process, so don't make a connection 8158 // and just let the caller instantiate its own instance. 8159 ContentProviderHolder holder = cpr.newHolder(null); 8160 // don't give caller the provider object, it needs 8161 // to make its own. 8162 holder.provider = null; 8163 return holder; 8164 } 8165 8166 final long origId = Binder.clearCallingIdentity(); 8167 8168 // In this case the provider instance already exists, so we can 8169 // return it right away. 8170 conn = incProviderCountLocked(r, cpr, token, stable); 8171 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8172 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8173 // If this is a perceptible app accessing the provider, 8174 // make sure to count it as being accessed and thus 8175 // back up on the LRU list. This is good because 8176 // content providers are often expensive to start. 8177 updateLruProcessLocked(cpr.proc, false, null); 8178 } 8179 } 8180 8181 if (cpr.proc != null) { 8182 if (false) { 8183 if (cpr.name.flattenToShortString().equals( 8184 "com.android.providers.calendar/.CalendarProvider2")) { 8185 Slog.v(TAG, "****************** KILLING " 8186 + cpr.name.flattenToShortString()); 8187 Process.killProcess(cpr.proc.pid); 8188 } 8189 } 8190 boolean success = updateOomAdjLocked(cpr.proc); 8191 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8192 // NOTE: there is still a race here where a signal could be 8193 // pending on the process even though we managed to update its 8194 // adj level. Not sure what to do about this, but at least 8195 // the race is now smaller. 8196 if (!success) { 8197 // Uh oh... it looks like the provider's process 8198 // has been killed on us. We need to wait for a new 8199 // process to be started, and make sure its death 8200 // doesn't kill our process. 8201 Slog.i(TAG, 8202 "Existing provider " + cpr.name.flattenToShortString() 8203 + " is crashing; detaching " + r); 8204 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8205 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8206 if (!lastRef) { 8207 // This wasn't the last ref our process had on 8208 // the provider... we have now been killed, bail. 8209 return null; 8210 } 8211 providerRunning = false; 8212 conn = null; 8213 } 8214 } 8215 8216 Binder.restoreCallingIdentity(origId); 8217 } 8218 8219 boolean singleton; 8220 if (!providerRunning) { 8221 try { 8222 cpi = AppGlobals.getPackageManager(). 8223 resolveContentProvider(name, 8224 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8225 } catch (RemoteException ex) { 8226 } 8227 if (cpi == null) { 8228 return null; 8229 } 8230 // If the provider is a singleton AND 8231 // (it's a call within the same user || the provider is a 8232 // privileged app) 8233 // Then allow connecting to the singleton provider 8234 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8235 cpi.name, cpi.flags) 8236 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8237 if (singleton) { 8238 userId = UserHandle.USER_OWNER; 8239 } 8240 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8241 8242 String msg; 8243 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8244 != null) { 8245 throw new SecurityException(msg); 8246 } 8247 8248 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8249 && !cpi.processName.equals("system")) { 8250 // If this content provider does not run in the system 8251 // process, and the system is not yet ready to run other 8252 // processes, then fail fast instead of hanging. 8253 throw new IllegalArgumentException( 8254 "Attempt to launch content provider before system ready"); 8255 } 8256 8257 // Make sure that the user who owns this provider is started. If not, 8258 // we don't want to allow it to run. 8259 if (mStartedUsers.get(userId) == null) { 8260 Slog.w(TAG, "Unable to launch app " 8261 + cpi.applicationInfo.packageName + "/" 8262 + cpi.applicationInfo.uid + " for provider " 8263 + name + ": user " + userId + " is stopped"); 8264 return null; 8265 } 8266 8267 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8268 cpr = mProviderMap.getProviderByClass(comp, userId); 8269 final boolean firstClass = cpr == null; 8270 if (firstClass) { 8271 try { 8272 ApplicationInfo ai = 8273 AppGlobals.getPackageManager(). 8274 getApplicationInfo( 8275 cpi.applicationInfo.packageName, 8276 STOCK_PM_FLAGS, userId); 8277 if (ai == null) { 8278 Slog.w(TAG, "No package info for content provider " 8279 + cpi.name); 8280 return null; 8281 } 8282 ai = getAppInfoForUser(ai, userId); 8283 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8284 } catch (RemoteException ex) { 8285 // pm is in same process, this will never happen. 8286 } 8287 } 8288 8289 if (r != null && cpr.canRunHere(r)) { 8290 // If this is a multiprocess provider, then just return its 8291 // info and allow the caller to instantiate it. Only do 8292 // this if the provider is the same user as the caller's 8293 // process, or can run as root (so can be in any process). 8294 return cpr.newHolder(null); 8295 } 8296 8297 if (DEBUG_PROVIDER) { 8298 RuntimeException e = new RuntimeException("here"); 8299 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8300 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8301 } 8302 8303 // This is single process, and our app is now connecting to it. 8304 // See if we are already in the process of launching this 8305 // provider. 8306 final int N = mLaunchingProviders.size(); 8307 int i; 8308 for (i=0; i<N; i++) { 8309 if (mLaunchingProviders.get(i) == cpr) { 8310 break; 8311 } 8312 } 8313 8314 // If the provider is not already being launched, then get it 8315 // started. 8316 if (i >= N) { 8317 final long origId = Binder.clearCallingIdentity(); 8318 8319 try { 8320 // Content provider is now in use, its package can't be stopped. 8321 try { 8322 AppGlobals.getPackageManager().setPackageStoppedState( 8323 cpr.appInfo.packageName, false, userId); 8324 } catch (RemoteException e) { 8325 } catch (IllegalArgumentException e) { 8326 Slog.w(TAG, "Failed trying to unstop package " 8327 + cpr.appInfo.packageName + ": " + e); 8328 } 8329 8330 // Use existing process if already started 8331 ProcessRecord proc = getProcessRecordLocked( 8332 cpi.processName, cpr.appInfo.uid, false); 8333 if (proc != null && proc.thread != null) { 8334 if (DEBUG_PROVIDER) { 8335 Slog.d(TAG, "Installing in existing process " + proc); 8336 } 8337 proc.pubProviders.put(cpi.name, cpr); 8338 try { 8339 proc.thread.scheduleInstallProvider(cpi); 8340 } catch (RemoteException e) { 8341 } 8342 } else { 8343 proc = startProcessLocked(cpi.processName, 8344 cpr.appInfo, false, 0, "content provider", 8345 new ComponentName(cpi.applicationInfo.packageName, 8346 cpi.name), false, false, false); 8347 if (proc == null) { 8348 Slog.w(TAG, "Unable to launch app " 8349 + cpi.applicationInfo.packageName + "/" 8350 + cpi.applicationInfo.uid + " for provider " 8351 + name + ": process is bad"); 8352 return null; 8353 } 8354 } 8355 cpr.launchingApp = proc; 8356 mLaunchingProviders.add(cpr); 8357 } finally { 8358 Binder.restoreCallingIdentity(origId); 8359 } 8360 } 8361 8362 // Make sure the provider is published (the same provider class 8363 // may be published under multiple names). 8364 if (firstClass) { 8365 mProviderMap.putProviderByClass(comp, cpr); 8366 } 8367 8368 mProviderMap.putProviderByName(name, cpr); 8369 conn = incProviderCountLocked(r, cpr, token, stable); 8370 if (conn != null) { 8371 conn.waiting = true; 8372 } 8373 } 8374 } 8375 8376 // Wait for the provider to be published... 8377 synchronized (cpr) { 8378 while (cpr.provider == null) { 8379 if (cpr.launchingApp == null) { 8380 Slog.w(TAG, "Unable to launch app " 8381 + cpi.applicationInfo.packageName + "/" 8382 + cpi.applicationInfo.uid + " for provider " 8383 + name + ": launching app became null"); 8384 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8385 UserHandle.getUserId(cpi.applicationInfo.uid), 8386 cpi.applicationInfo.packageName, 8387 cpi.applicationInfo.uid, name); 8388 return null; 8389 } 8390 try { 8391 if (DEBUG_MU) { 8392 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8393 + cpr.launchingApp); 8394 } 8395 if (conn != null) { 8396 conn.waiting = true; 8397 } 8398 cpr.wait(); 8399 } catch (InterruptedException ex) { 8400 } finally { 8401 if (conn != null) { 8402 conn.waiting = false; 8403 } 8404 } 8405 } 8406 } 8407 return cpr != null ? cpr.newHolder(conn) : null; 8408 } 8409 8410 @Override 8411 public final ContentProviderHolder getContentProvider( 8412 IApplicationThread caller, String name, int userId, boolean stable) { 8413 enforceNotIsolatedCaller("getContentProvider"); 8414 if (caller == null) { 8415 String msg = "null IApplicationThread when getting content provider " 8416 + name; 8417 Slog.w(TAG, msg); 8418 throw new SecurityException(msg); 8419 } 8420 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8421 // with cross-user grant. 8422 return getContentProviderImpl(caller, name, null, stable, userId); 8423 } 8424 8425 public ContentProviderHolder getContentProviderExternal( 8426 String name, int userId, IBinder token) { 8427 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8428 "Do not have permission in call getContentProviderExternal()"); 8429 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8430 false, true, "getContentProvider", null); 8431 return getContentProviderExternalUnchecked(name, token, userId); 8432 } 8433 8434 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8435 IBinder token, int userId) { 8436 return getContentProviderImpl(null, name, token, true, userId); 8437 } 8438 8439 /** 8440 * Drop a content provider from a ProcessRecord's bookkeeping 8441 */ 8442 public void removeContentProvider(IBinder connection, boolean stable) { 8443 enforceNotIsolatedCaller("removeContentProvider"); 8444 long ident = Binder.clearCallingIdentity(); 8445 try { 8446 synchronized (this) { 8447 ContentProviderConnection conn; 8448 try { 8449 conn = (ContentProviderConnection)connection; 8450 } catch (ClassCastException e) { 8451 String msg ="removeContentProvider: " + connection 8452 + " not a ContentProviderConnection"; 8453 Slog.w(TAG, msg); 8454 throw new IllegalArgumentException(msg); 8455 } 8456 if (conn == null) { 8457 throw new NullPointerException("connection is null"); 8458 } 8459 if (decProviderCountLocked(conn, null, null, stable)) { 8460 updateOomAdjLocked(); 8461 } 8462 } 8463 } finally { 8464 Binder.restoreCallingIdentity(ident); 8465 } 8466 } 8467 8468 public void removeContentProviderExternal(String name, IBinder token) { 8469 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8470 "Do not have permission in call removeContentProviderExternal()"); 8471 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8472 } 8473 8474 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8475 synchronized (this) { 8476 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8477 if(cpr == null) { 8478 //remove from mProvidersByClass 8479 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8480 return; 8481 } 8482 8483 //update content provider record entry info 8484 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8485 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8486 if (localCpr.hasExternalProcessHandles()) { 8487 if (localCpr.removeExternalProcessHandleLocked(token)) { 8488 updateOomAdjLocked(); 8489 } else { 8490 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8491 + " with no external reference for token: " 8492 + token + "."); 8493 } 8494 } else { 8495 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8496 + " with no external references."); 8497 } 8498 } 8499 } 8500 8501 public final void publishContentProviders(IApplicationThread caller, 8502 List<ContentProviderHolder> providers) { 8503 if (providers == null) { 8504 return; 8505 } 8506 8507 enforceNotIsolatedCaller("publishContentProviders"); 8508 synchronized (this) { 8509 final ProcessRecord r = getRecordForAppLocked(caller); 8510 if (DEBUG_MU) 8511 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8512 if (r == null) { 8513 throw new SecurityException( 8514 "Unable to find app for caller " + caller 8515 + " (pid=" + Binder.getCallingPid() 8516 + ") when publishing content providers"); 8517 } 8518 8519 final long origId = Binder.clearCallingIdentity(); 8520 8521 final int N = providers.size(); 8522 for (int i=0; i<N; i++) { 8523 ContentProviderHolder src = providers.get(i); 8524 if (src == null || src.info == null || src.provider == null) { 8525 continue; 8526 } 8527 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8528 if (DEBUG_MU) 8529 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8530 if (dst != null) { 8531 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8532 mProviderMap.putProviderByClass(comp, dst); 8533 String names[] = dst.info.authority.split(";"); 8534 for (int j = 0; j < names.length; j++) { 8535 mProviderMap.putProviderByName(names[j], dst); 8536 } 8537 8538 int NL = mLaunchingProviders.size(); 8539 int j; 8540 for (j=0; j<NL; j++) { 8541 if (mLaunchingProviders.get(j) == dst) { 8542 mLaunchingProviders.remove(j); 8543 j--; 8544 NL--; 8545 } 8546 } 8547 synchronized (dst) { 8548 dst.provider = src.provider; 8549 dst.proc = r; 8550 dst.notifyAll(); 8551 } 8552 updateOomAdjLocked(r); 8553 } 8554 } 8555 8556 Binder.restoreCallingIdentity(origId); 8557 } 8558 } 8559 8560 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8561 ContentProviderConnection conn; 8562 try { 8563 conn = (ContentProviderConnection)connection; 8564 } catch (ClassCastException e) { 8565 String msg ="refContentProvider: " + connection 8566 + " not a ContentProviderConnection"; 8567 Slog.w(TAG, msg); 8568 throw new IllegalArgumentException(msg); 8569 } 8570 if (conn == null) { 8571 throw new NullPointerException("connection is null"); 8572 } 8573 8574 synchronized (this) { 8575 if (stable > 0) { 8576 conn.numStableIncs += stable; 8577 } 8578 stable = conn.stableCount + stable; 8579 if (stable < 0) { 8580 throw new IllegalStateException("stableCount < 0: " + stable); 8581 } 8582 8583 if (unstable > 0) { 8584 conn.numUnstableIncs += unstable; 8585 } 8586 unstable = conn.unstableCount + unstable; 8587 if (unstable < 0) { 8588 throw new IllegalStateException("unstableCount < 0: " + unstable); 8589 } 8590 8591 if ((stable+unstable) <= 0) { 8592 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8593 + stable + " unstable=" + unstable); 8594 } 8595 conn.stableCount = stable; 8596 conn.unstableCount = unstable; 8597 return !conn.dead; 8598 } 8599 } 8600 8601 public void unstableProviderDied(IBinder connection) { 8602 ContentProviderConnection conn; 8603 try { 8604 conn = (ContentProviderConnection)connection; 8605 } catch (ClassCastException e) { 8606 String msg ="refContentProvider: " + connection 8607 + " not a ContentProviderConnection"; 8608 Slog.w(TAG, msg); 8609 throw new IllegalArgumentException(msg); 8610 } 8611 if (conn == null) { 8612 throw new NullPointerException("connection is null"); 8613 } 8614 8615 // Safely retrieve the content provider associated with the connection. 8616 IContentProvider provider; 8617 synchronized (this) { 8618 provider = conn.provider.provider; 8619 } 8620 8621 if (provider == null) { 8622 // Um, yeah, we're way ahead of you. 8623 return; 8624 } 8625 8626 // Make sure the caller is being honest with us. 8627 if (provider.asBinder().pingBinder()) { 8628 // Er, no, still looks good to us. 8629 synchronized (this) { 8630 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8631 + " says " + conn + " died, but we don't agree"); 8632 return; 8633 } 8634 } 8635 8636 // Well look at that! It's dead! 8637 synchronized (this) { 8638 if (conn.provider.provider != provider) { 8639 // But something changed... good enough. 8640 return; 8641 } 8642 8643 ProcessRecord proc = conn.provider.proc; 8644 if (proc == null || proc.thread == null) { 8645 // Seems like the process is already cleaned up. 8646 return; 8647 } 8648 8649 // As far as we're concerned, this is just like receiving a 8650 // death notification... just a bit prematurely. 8651 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8652 + ") early provider death"); 8653 final long ident = Binder.clearCallingIdentity(); 8654 try { 8655 appDiedLocked(proc, proc.pid, proc.thread); 8656 } finally { 8657 Binder.restoreCallingIdentity(ident); 8658 } 8659 } 8660 } 8661 8662 @Override 8663 public void appNotRespondingViaProvider(IBinder connection) { 8664 enforceCallingPermission( 8665 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8666 8667 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8668 if (conn == null) { 8669 Slog.w(TAG, "ContentProviderConnection is null"); 8670 return; 8671 } 8672 8673 final ProcessRecord host = conn.provider.proc; 8674 if (host == null) { 8675 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8676 return; 8677 } 8678 8679 final long token = Binder.clearCallingIdentity(); 8680 try { 8681 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8682 } finally { 8683 Binder.restoreCallingIdentity(token); 8684 } 8685 } 8686 8687 public final void installSystemProviders() { 8688 List<ProviderInfo> providers; 8689 synchronized (this) { 8690 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8691 providers = generateApplicationProvidersLocked(app); 8692 if (providers != null) { 8693 for (int i=providers.size()-1; i>=0; i--) { 8694 ProviderInfo pi = (ProviderInfo)providers.get(i); 8695 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8696 Slog.w(TAG, "Not installing system proc provider " + pi.name 8697 + ": not system .apk"); 8698 providers.remove(i); 8699 } 8700 } 8701 } 8702 } 8703 if (providers != null) { 8704 mSystemThread.installSystemProviders(providers); 8705 } 8706 8707 mCoreSettingsObserver = new CoreSettingsObserver(this); 8708 8709 mUsageStatsService.monitorPackages(); 8710 } 8711 8712 /** 8713 * Allows app to retrieve the MIME type of a URI without having permission 8714 * to access its content provider. 8715 * 8716 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8717 * 8718 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8719 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8720 */ 8721 public String getProviderMimeType(Uri uri, int userId) { 8722 enforceNotIsolatedCaller("getProviderMimeType"); 8723 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8724 userId, false, true, "getProviderMimeType", null); 8725 final String name = uri.getAuthority(); 8726 final long ident = Binder.clearCallingIdentity(); 8727 ContentProviderHolder holder = null; 8728 8729 try { 8730 holder = getContentProviderExternalUnchecked(name, null, userId); 8731 if (holder != null) { 8732 return holder.provider.getType(uri); 8733 } 8734 } catch (RemoteException e) { 8735 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8736 return null; 8737 } finally { 8738 if (holder != null) { 8739 removeContentProviderExternalUnchecked(name, null, userId); 8740 } 8741 Binder.restoreCallingIdentity(ident); 8742 } 8743 8744 return null; 8745 } 8746 8747 // ========================================================= 8748 // GLOBAL MANAGEMENT 8749 // ========================================================= 8750 8751 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8752 boolean isolated) { 8753 String proc = customProcess != null ? customProcess : info.processName; 8754 BatteryStatsImpl.Uid.Proc ps = null; 8755 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8756 int uid = info.uid; 8757 if (isolated) { 8758 int userId = UserHandle.getUserId(uid); 8759 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8760 while (true) { 8761 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8762 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8763 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8764 } 8765 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8766 mNextIsolatedProcessUid++; 8767 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8768 // No process for this uid, use it. 8769 break; 8770 } 8771 stepsLeft--; 8772 if (stepsLeft <= 0) { 8773 return null; 8774 } 8775 } 8776 } 8777 return new ProcessRecord(stats, info, proc, uid); 8778 } 8779 8780 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8781 String abiOverride) { 8782 ProcessRecord app; 8783 if (!isolated) { 8784 app = getProcessRecordLocked(info.processName, info.uid, true); 8785 } else { 8786 app = null; 8787 } 8788 8789 if (app == null) { 8790 app = newProcessRecordLocked(info, null, isolated); 8791 mProcessNames.put(info.processName, app.uid, app); 8792 if (isolated) { 8793 mIsolatedProcesses.put(app.uid, app); 8794 } 8795 updateLruProcessLocked(app, false, null); 8796 updateOomAdjLocked(); 8797 } 8798 8799 // This package really, really can not be stopped. 8800 try { 8801 AppGlobals.getPackageManager().setPackageStoppedState( 8802 info.packageName, false, UserHandle.getUserId(app.uid)); 8803 } catch (RemoteException e) { 8804 } catch (IllegalArgumentException e) { 8805 Slog.w(TAG, "Failed trying to unstop package " 8806 + info.packageName + ": " + e); 8807 } 8808 8809 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8810 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8811 app.persistent = true; 8812 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8813 } 8814 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8815 mPersistentStartingProcesses.add(app); 8816 startProcessLocked(app, "added application", app.processName, 8817 abiOverride); 8818 } 8819 8820 return app; 8821 } 8822 8823 public void unhandledBack() { 8824 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8825 "unhandledBack()"); 8826 8827 synchronized(this) { 8828 final long origId = Binder.clearCallingIdentity(); 8829 try { 8830 getFocusedStack().unhandledBackLocked(); 8831 } finally { 8832 Binder.restoreCallingIdentity(origId); 8833 } 8834 } 8835 } 8836 8837 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8838 enforceNotIsolatedCaller("openContentUri"); 8839 final int userId = UserHandle.getCallingUserId(); 8840 String name = uri.getAuthority(); 8841 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8842 ParcelFileDescriptor pfd = null; 8843 if (cph != null) { 8844 // We record the binder invoker's uid in thread-local storage before 8845 // going to the content provider to open the file. Later, in the code 8846 // that handles all permissions checks, we look for this uid and use 8847 // that rather than the Activity Manager's own uid. The effect is that 8848 // we do the check against the caller's permissions even though it looks 8849 // to the content provider like the Activity Manager itself is making 8850 // the request. 8851 sCallerIdentity.set(new Identity( 8852 Binder.getCallingPid(), Binder.getCallingUid())); 8853 try { 8854 pfd = cph.provider.openFile(null, uri, "r", null); 8855 } catch (FileNotFoundException e) { 8856 // do nothing; pfd will be returned null 8857 } finally { 8858 // Ensure that whatever happens, we clean up the identity state 8859 sCallerIdentity.remove(); 8860 } 8861 8862 // We've got the fd now, so we're done with the provider. 8863 removeContentProviderExternalUnchecked(name, null, userId); 8864 } else { 8865 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8866 } 8867 return pfd; 8868 } 8869 8870 // Actually is sleeping or shutting down or whatever else in the future 8871 // is an inactive state. 8872 public boolean isSleepingOrShuttingDown() { 8873 return mSleeping || mShuttingDown; 8874 } 8875 8876 public boolean isSleeping() { 8877 return mSleeping; 8878 } 8879 8880 void goingToSleep() { 8881 synchronized(this) { 8882 mWentToSleep = true; 8883 updateEventDispatchingLocked(); 8884 goToSleepIfNeededLocked(); 8885 } 8886 } 8887 8888 void finishRunningVoiceLocked() { 8889 if (mRunningVoice) { 8890 mRunningVoice = false; 8891 goToSleepIfNeededLocked(); 8892 } 8893 } 8894 8895 void goToSleepIfNeededLocked() { 8896 if (mWentToSleep && !mRunningVoice) { 8897 if (!mSleeping) { 8898 mSleeping = true; 8899 mStackSupervisor.goingToSleepLocked(); 8900 8901 // Initialize the wake times of all processes. 8902 checkExcessivePowerUsageLocked(false); 8903 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8904 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8905 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8906 } 8907 } 8908 } 8909 8910 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8911 mTaskPersister.notify(task, flush); 8912 } 8913 8914 @Override 8915 public boolean shutdown(int timeout) { 8916 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8917 != PackageManager.PERMISSION_GRANTED) { 8918 throw new SecurityException("Requires permission " 8919 + android.Manifest.permission.SHUTDOWN); 8920 } 8921 8922 boolean timedout = false; 8923 8924 synchronized(this) { 8925 mShuttingDown = true; 8926 updateEventDispatchingLocked(); 8927 timedout = mStackSupervisor.shutdownLocked(timeout); 8928 } 8929 8930 mAppOpsService.shutdown(); 8931 mUsageStatsService.shutdown(); 8932 mBatteryStatsService.shutdown(); 8933 synchronized (this) { 8934 mProcessStats.shutdownLocked(); 8935 } 8936 notifyTaskPersisterLocked(null, true); 8937 8938 return timedout; 8939 } 8940 8941 public final void activitySlept(IBinder token) { 8942 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8943 8944 final long origId = Binder.clearCallingIdentity(); 8945 8946 synchronized (this) { 8947 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8948 if (r != null) { 8949 mStackSupervisor.activitySleptLocked(r); 8950 } 8951 } 8952 8953 Binder.restoreCallingIdentity(origId); 8954 } 8955 8956 void logLockScreen(String msg) { 8957 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8958 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8959 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8960 mStackSupervisor.mDismissKeyguardOnNextActivity); 8961 } 8962 8963 private void comeOutOfSleepIfNeededLocked() { 8964 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8965 if (mSleeping) { 8966 mSleeping = false; 8967 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8968 } 8969 } 8970 } 8971 8972 void wakingUp() { 8973 synchronized(this) { 8974 mWentToSleep = false; 8975 updateEventDispatchingLocked(); 8976 comeOutOfSleepIfNeededLocked(); 8977 } 8978 } 8979 8980 void startRunningVoiceLocked() { 8981 if (!mRunningVoice) { 8982 mRunningVoice = true; 8983 comeOutOfSleepIfNeededLocked(); 8984 } 8985 } 8986 8987 private void updateEventDispatchingLocked() { 8988 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8989 } 8990 8991 public void setLockScreenShown(boolean shown) { 8992 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8993 != PackageManager.PERMISSION_GRANTED) { 8994 throw new SecurityException("Requires permission " 8995 + android.Manifest.permission.DEVICE_POWER); 8996 } 8997 8998 synchronized(this) { 8999 long ident = Binder.clearCallingIdentity(); 9000 try { 9001 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9002 mLockScreenShown = shown; 9003 comeOutOfSleepIfNeededLocked(); 9004 } finally { 9005 Binder.restoreCallingIdentity(ident); 9006 } 9007 } 9008 } 9009 9010 public void stopAppSwitches() { 9011 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9012 != PackageManager.PERMISSION_GRANTED) { 9013 throw new SecurityException("Requires permission " 9014 + android.Manifest.permission.STOP_APP_SWITCHES); 9015 } 9016 9017 synchronized(this) { 9018 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9019 + APP_SWITCH_DELAY_TIME; 9020 mDidAppSwitch = false; 9021 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9022 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9023 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9024 } 9025 } 9026 9027 public void resumeAppSwitches() { 9028 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9029 != PackageManager.PERMISSION_GRANTED) { 9030 throw new SecurityException("Requires permission " 9031 + android.Manifest.permission.STOP_APP_SWITCHES); 9032 } 9033 9034 synchronized(this) { 9035 // Note that we don't execute any pending app switches... we will 9036 // let those wait until either the timeout, or the next start 9037 // activity request. 9038 mAppSwitchesAllowedTime = 0; 9039 } 9040 } 9041 9042 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9043 String name) { 9044 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9045 return true; 9046 } 9047 9048 final int perm = checkComponentPermission( 9049 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9050 callingUid, -1, true); 9051 if (perm == PackageManager.PERMISSION_GRANTED) { 9052 return true; 9053 } 9054 9055 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9056 return false; 9057 } 9058 9059 public void setDebugApp(String packageName, boolean waitForDebugger, 9060 boolean persistent) { 9061 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9062 "setDebugApp()"); 9063 9064 long ident = Binder.clearCallingIdentity(); 9065 try { 9066 // Note that this is not really thread safe if there are multiple 9067 // callers into it at the same time, but that's not a situation we 9068 // care about. 9069 if (persistent) { 9070 final ContentResolver resolver = mContext.getContentResolver(); 9071 Settings.Global.putString( 9072 resolver, Settings.Global.DEBUG_APP, 9073 packageName); 9074 Settings.Global.putInt( 9075 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9076 waitForDebugger ? 1 : 0); 9077 } 9078 9079 synchronized (this) { 9080 if (!persistent) { 9081 mOrigDebugApp = mDebugApp; 9082 mOrigWaitForDebugger = mWaitForDebugger; 9083 } 9084 mDebugApp = packageName; 9085 mWaitForDebugger = waitForDebugger; 9086 mDebugTransient = !persistent; 9087 if (packageName != null) { 9088 forceStopPackageLocked(packageName, -1, false, false, true, true, 9089 false, UserHandle.USER_ALL, "set debug app"); 9090 } 9091 } 9092 } finally { 9093 Binder.restoreCallingIdentity(ident); 9094 } 9095 } 9096 9097 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9098 synchronized (this) { 9099 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9100 if (!isDebuggable) { 9101 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9102 throw new SecurityException("Process not debuggable: " + app.packageName); 9103 } 9104 } 9105 9106 mOpenGlTraceApp = processName; 9107 } 9108 } 9109 9110 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9111 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9112 synchronized (this) { 9113 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9114 if (!isDebuggable) { 9115 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9116 throw new SecurityException("Process not debuggable: " + app.packageName); 9117 } 9118 } 9119 mProfileApp = processName; 9120 mProfileFile = profileFile; 9121 if (mProfileFd != null) { 9122 try { 9123 mProfileFd.close(); 9124 } catch (IOException e) { 9125 } 9126 mProfileFd = null; 9127 } 9128 mProfileFd = profileFd; 9129 mProfileType = 0; 9130 mAutoStopProfiler = autoStopProfiler; 9131 } 9132 } 9133 9134 @Override 9135 public void setAlwaysFinish(boolean enabled) { 9136 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9137 "setAlwaysFinish()"); 9138 9139 Settings.Global.putInt( 9140 mContext.getContentResolver(), 9141 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9142 9143 synchronized (this) { 9144 mAlwaysFinishActivities = enabled; 9145 } 9146 } 9147 9148 @Override 9149 public void setActivityController(IActivityController controller) { 9150 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9151 "setActivityController()"); 9152 synchronized (this) { 9153 mController = controller; 9154 Watchdog.getInstance().setActivityController(controller); 9155 } 9156 } 9157 9158 @Override 9159 public void setUserIsMonkey(boolean userIsMonkey) { 9160 synchronized (this) { 9161 synchronized (mPidsSelfLocked) { 9162 final int callingPid = Binder.getCallingPid(); 9163 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9164 if (precessRecord == null) { 9165 throw new SecurityException("Unknown process: " + callingPid); 9166 } 9167 if (precessRecord.instrumentationUiAutomationConnection == null) { 9168 throw new SecurityException("Only an instrumentation process " 9169 + "with a UiAutomation can call setUserIsMonkey"); 9170 } 9171 } 9172 mUserIsMonkey = userIsMonkey; 9173 } 9174 } 9175 9176 @Override 9177 public boolean isUserAMonkey() { 9178 synchronized (this) { 9179 // If there is a controller also implies the user is a monkey. 9180 return (mUserIsMonkey || mController != null); 9181 } 9182 } 9183 9184 public void requestBugReport() { 9185 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9186 SystemProperties.set("ctl.start", "bugreport"); 9187 } 9188 9189 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9190 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9191 } 9192 9193 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9194 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9195 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9196 } 9197 return KEY_DISPATCHING_TIMEOUT; 9198 } 9199 9200 @Override 9201 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9202 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9203 != PackageManager.PERMISSION_GRANTED) { 9204 throw new SecurityException("Requires permission " 9205 + android.Manifest.permission.FILTER_EVENTS); 9206 } 9207 ProcessRecord proc; 9208 long timeout; 9209 synchronized (this) { 9210 synchronized (mPidsSelfLocked) { 9211 proc = mPidsSelfLocked.get(pid); 9212 } 9213 timeout = getInputDispatchingTimeoutLocked(proc); 9214 } 9215 9216 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9217 return -1; 9218 } 9219 9220 return timeout; 9221 } 9222 9223 /** 9224 * Handle input dispatching timeouts. 9225 * Returns whether input dispatching should be aborted or not. 9226 */ 9227 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9228 final ActivityRecord activity, final ActivityRecord parent, 9229 final boolean aboveSystem, String reason) { 9230 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9231 != PackageManager.PERMISSION_GRANTED) { 9232 throw new SecurityException("Requires permission " 9233 + android.Manifest.permission.FILTER_EVENTS); 9234 } 9235 9236 final String annotation; 9237 if (reason == null) { 9238 annotation = "Input dispatching timed out"; 9239 } else { 9240 annotation = "Input dispatching timed out (" + reason + ")"; 9241 } 9242 9243 if (proc != null) { 9244 synchronized (this) { 9245 if (proc.debugging) { 9246 return false; 9247 } 9248 9249 if (mDidDexOpt) { 9250 // Give more time since we were dexopting. 9251 mDidDexOpt = false; 9252 return false; 9253 } 9254 9255 if (proc.instrumentationClass != null) { 9256 Bundle info = new Bundle(); 9257 info.putString("shortMsg", "keyDispatchingTimedOut"); 9258 info.putString("longMsg", annotation); 9259 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9260 return true; 9261 } 9262 } 9263 mHandler.post(new Runnable() { 9264 @Override 9265 public void run() { 9266 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9267 } 9268 }); 9269 } 9270 9271 return true; 9272 } 9273 9274 public Bundle getAssistContextExtras(int requestType) { 9275 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9276 "getAssistContextExtras()"); 9277 PendingAssistExtras pae; 9278 Bundle extras = new Bundle(); 9279 synchronized (this) { 9280 ActivityRecord activity = getFocusedStack().mResumedActivity; 9281 if (activity == null) { 9282 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9283 return null; 9284 } 9285 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9286 if (activity.app == null || activity.app.thread == null) { 9287 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9288 return extras; 9289 } 9290 if (activity.app.pid == Binder.getCallingPid()) { 9291 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9292 return extras; 9293 } 9294 pae = new PendingAssistExtras(activity); 9295 try { 9296 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9297 requestType); 9298 mPendingAssistExtras.add(pae); 9299 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9300 } catch (RemoteException e) { 9301 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9302 return extras; 9303 } 9304 } 9305 synchronized (pae) { 9306 while (!pae.haveResult) { 9307 try { 9308 pae.wait(); 9309 } catch (InterruptedException e) { 9310 } 9311 } 9312 if (pae.result != null) { 9313 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9314 } 9315 } 9316 synchronized (this) { 9317 mPendingAssistExtras.remove(pae); 9318 mHandler.removeCallbacks(pae); 9319 } 9320 return extras; 9321 } 9322 9323 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9324 PendingAssistExtras pae = (PendingAssistExtras)token; 9325 synchronized (pae) { 9326 pae.result = extras; 9327 pae.haveResult = true; 9328 pae.notifyAll(); 9329 } 9330 } 9331 9332 public void registerProcessObserver(IProcessObserver observer) { 9333 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9334 "registerProcessObserver()"); 9335 synchronized (this) { 9336 mProcessObservers.register(observer); 9337 } 9338 } 9339 9340 @Override 9341 public void unregisterProcessObserver(IProcessObserver observer) { 9342 synchronized (this) { 9343 mProcessObservers.unregister(observer); 9344 } 9345 } 9346 9347 @Override 9348 public boolean convertFromTranslucent(IBinder token) { 9349 final long origId = Binder.clearCallingIdentity(); 9350 try { 9351 synchronized (this) { 9352 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9353 if (r == null) { 9354 return false; 9355 } 9356 if (r.changeWindowTranslucency(true)) { 9357 mWindowManager.setAppFullscreen(token, true); 9358 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9359 return true; 9360 } 9361 return false; 9362 } 9363 } finally { 9364 Binder.restoreCallingIdentity(origId); 9365 } 9366 } 9367 9368 @Override 9369 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9370 final long origId = Binder.clearCallingIdentity(); 9371 try { 9372 synchronized (this) { 9373 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9374 if (r == null) { 9375 return false; 9376 } 9377 if (r.changeWindowTranslucency(false)) { 9378 r.task.stack.convertToTranslucent(r, options); 9379 mWindowManager.setAppFullscreen(token, false); 9380 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9381 return true; 9382 } 9383 return false; 9384 } 9385 } finally { 9386 Binder.restoreCallingIdentity(origId); 9387 } 9388 } 9389 9390 @Override 9391 public ActivityOptions getActivityOptions(IBinder token) { 9392 final long origId = Binder.clearCallingIdentity(); 9393 try { 9394 synchronized (this) { 9395 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9396 if (r != null) { 9397 final ActivityOptions activityOptions = r.pendingOptions; 9398 r.pendingOptions = null; 9399 return activityOptions; 9400 } 9401 return null; 9402 } 9403 } finally { 9404 Binder.restoreCallingIdentity(origId); 9405 } 9406 } 9407 9408 @Override 9409 public void setImmersive(IBinder token, boolean immersive) { 9410 synchronized(this) { 9411 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9412 if (r == null) { 9413 throw new IllegalArgumentException(); 9414 } 9415 r.immersive = immersive; 9416 9417 // update associated state if we're frontmost 9418 if (r == mFocusedActivity) { 9419 if (DEBUG_IMMERSIVE) { 9420 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9421 } 9422 applyUpdateLockStateLocked(r); 9423 } 9424 } 9425 } 9426 9427 @Override 9428 public boolean isImmersive(IBinder token) { 9429 synchronized (this) { 9430 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9431 if (r == null) { 9432 throw new IllegalArgumentException(); 9433 } 9434 return r.immersive; 9435 } 9436 } 9437 9438 public boolean isTopActivityImmersive() { 9439 enforceNotIsolatedCaller("startActivity"); 9440 synchronized (this) { 9441 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9442 return (r != null) ? r.immersive : false; 9443 } 9444 } 9445 9446 public final void enterSafeMode() { 9447 synchronized(this) { 9448 // It only makes sense to do this before the system is ready 9449 // and started launching other packages. 9450 if (!mSystemReady) { 9451 try { 9452 AppGlobals.getPackageManager().enterSafeMode(); 9453 } catch (RemoteException e) { 9454 } 9455 } 9456 9457 mSafeMode = true; 9458 } 9459 } 9460 9461 public final void showSafeModeOverlay() { 9462 View v = LayoutInflater.from(mContext).inflate( 9463 com.android.internal.R.layout.safe_mode, null); 9464 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9465 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9466 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9467 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9468 lp.gravity = Gravity.BOTTOM | Gravity.START; 9469 lp.format = v.getBackground().getOpacity(); 9470 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9471 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9472 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9473 ((WindowManager)mContext.getSystemService( 9474 Context.WINDOW_SERVICE)).addView(v, lp); 9475 } 9476 9477 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9478 if (!(sender instanceof PendingIntentRecord)) { 9479 return; 9480 } 9481 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9482 synchronized (stats) { 9483 if (mBatteryStatsService.isOnBattery()) { 9484 mBatteryStatsService.enforceCallingPermission(); 9485 PendingIntentRecord rec = (PendingIntentRecord)sender; 9486 int MY_UID = Binder.getCallingUid(); 9487 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9488 BatteryStatsImpl.Uid.Pkg pkg = 9489 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9490 sourcePkg != null ? sourcePkg : rec.key.packageName); 9491 pkg.incWakeupsLocked(); 9492 } 9493 } 9494 } 9495 9496 public boolean killPids(int[] pids, String pReason, boolean secure) { 9497 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9498 throw new SecurityException("killPids only available to the system"); 9499 } 9500 String reason = (pReason == null) ? "Unknown" : pReason; 9501 // XXX Note: don't acquire main activity lock here, because the window 9502 // manager calls in with its locks held. 9503 9504 boolean killed = false; 9505 synchronized (mPidsSelfLocked) { 9506 int[] types = new int[pids.length]; 9507 int worstType = 0; 9508 for (int i=0; i<pids.length; i++) { 9509 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9510 if (proc != null) { 9511 int type = proc.setAdj; 9512 types[i] = type; 9513 if (type > worstType) { 9514 worstType = type; 9515 } 9516 } 9517 } 9518 9519 // If the worst oom_adj is somewhere in the cached proc LRU range, 9520 // then constrain it so we will kill all cached procs. 9521 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9522 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9523 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9524 } 9525 9526 // If this is not a secure call, don't let it kill processes that 9527 // are important. 9528 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9529 worstType = ProcessList.SERVICE_ADJ; 9530 } 9531 9532 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9533 for (int i=0; i<pids.length; i++) { 9534 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9535 if (proc == null) { 9536 continue; 9537 } 9538 int adj = proc.setAdj; 9539 if (adj >= worstType && !proc.killedByAm) { 9540 killUnneededProcessLocked(proc, reason); 9541 killed = true; 9542 } 9543 } 9544 } 9545 return killed; 9546 } 9547 9548 @Override 9549 public void killUid(int uid, String reason) { 9550 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9551 throw new SecurityException("killUid only available to the system"); 9552 } 9553 synchronized (this) { 9554 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9555 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9556 reason != null ? reason : "kill uid"); 9557 } 9558 } 9559 9560 @Override 9561 public boolean killProcessesBelowForeground(String reason) { 9562 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9563 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9564 } 9565 9566 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9567 } 9568 9569 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9570 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9571 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9572 } 9573 9574 boolean killed = false; 9575 synchronized (mPidsSelfLocked) { 9576 final int size = mPidsSelfLocked.size(); 9577 for (int i = 0; i < size; i++) { 9578 final int pid = mPidsSelfLocked.keyAt(i); 9579 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9580 if (proc == null) continue; 9581 9582 final int adj = proc.setAdj; 9583 if (adj > belowAdj && !proc.killedByAm) { 9584 killUnneededProcessLocked(proc, reason); 9585 killed = true; 9586 } 9587 } 9588 } 9589 return killed; 9590 } 9591 9592 @Override 9593 public void hang(final IBinder who, boolean allowRestart) { 9594 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9595 != PackageManager.PERMISSION_GRANTED) { 9596 throw new SecurityException("Requires permission " 9597 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9598 } 9599 9600 final IBinder.DeathRecipient death = new DeathRecipient() { 9601 @Override 9602 public void binderDied() { 9603 synchronized (this) { 9604 notifyAll(); 9605 } 9606 } 9607 }; 9608 9609 try { 9610 who.linkToDeath(death, 0); 9611 } catch (RemoteException e) { 9612 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9613 return; 9614 } 9615 9616 synchronized (this) { 9617 Watchdog.getInstance().setAllowRestart(allowRestart); 9618 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9619 synchronized (death) { 9620 while (who.isBinderAlive()) { 9621 try { 9622 death.wait(); 9623 } catch (InterruptedException e) { 9624 } 9625 } 9626 } 9627 Watchdog.getInstance().setAllowRestart(true); 9628 } 9629 } 9630 9631 @Override 9632 public void restart() { 9633 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9634 != PackageManager.PERMISSION_GRANTED) { 9635 throw new SecurityException("Requires permission " 9636 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9637 } 9638 9639 Log.i(TAG, "Sending shutdown broadcast..."); 9640 9641 BroadcastReceiver br = new BroadcastReceiver() { 9642 @Override public void onReceive(Context context, Intent intent) { 9643 // Now the broadcast is done, finish up the low-level shutdown. 9644 Log.i(TAG, "Shutting down activity manager..."); 9645 shutdown(10000); 9646 Log.i(TAG, "Shutdown complete, restarting!"); 9647 Process.killProcess(Process.myPid()); 9648 System.exit(10); 9649 } 9650 }; 9651 9652 // First send the high-level shut down broadcast. 9653 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9654 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9655 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9656 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9657 mContext.sendOrderedBroadcastAsUser(intent, 9658 UserHandle.ALL, null, br, mHandler, 0, null, null); 9659 */ 9660 br.onReceive(mContext, intent); 9661 } 9662 9663 private long getLowRamTimeSinceIdle(long now) { 9664 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9665 } 9666 9667 @Override 9668 public void performIdleMaintenance() { 9669 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9670 != PackageManager.PERMISSION_GRANTED) { 9671 throw new SecurityException("Requires permission " 9672 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9673 } 9674 9675 synchronized (this) { 9676 final long now = SystemClock.uptimeMillis(); 9677 final long timeSinceLastIdle = now - mLastIdleTime; 9678 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9679 mLastIdleTime = now; 9680 mLowRamTimeSinceLastIdle = 0; 9681 if (mLowRamStartTime != 0) { 9682 mLowRamStartTime = now; 9683 } 9684 9685 StringBuilder sb = new StringBuilder(128); 9686 sb.append("Idle maintenance over "); 9687 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9688 sb.append(" low RAM for "); 9689 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9690 Slog.i(TAG, sb.toString()); 9691 9692 // If at least 1/3 of our time since the last idle period has been spent 9693 // with RAM low, then we want to kill processes. 9694 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9695 9696 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9697 ProcessRecord proc = mLruProcesses.get(i); 9698 if (proc.notCachedSinceIdle) { 9699 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9700 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9701 if (doKilling && proc.initialIdlePss != 0 9702 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9703 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9704 + " from " + proc.initialIdlePss + ")"); 9705 } 9706 } 9707 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9708 proc.notCachedSinceIdle = true; 9709 proc.initialIdlePss = 0; 9710 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9711 isSleeping(), now); 9712 } 9713 } 9714 9715 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9716 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9717 } 9718 } 9719 9720 private void retrieveSettings() { 9721 final ContentResolver resolver = mContext.getContentResolver(); 9722 String debugApp = Settings.Global.getString( 9723 resolver, Settings.Global.DEBUG_APP); 9724 boolean waitForDebugger = Settings.Global.getInt( 9725 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9726 boolean alwaysFinishActivities = Settings.Global.getInt( 9727 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9728 boolean forceRtl = Settings.Global.getInt( 9729 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9730 // Transfer any global setting for forcing RTL layout, into a System Property 9731 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9732 9733 Configuration configuration = new Configuration(); 9734 Settings.System.getConfiguration(resolver, configuration); 9735 if (forceRtl) { 9736 // This will take care of setting the correct layout direction flags 9737 configuration.setLayoutDirection(configuration.locale); 9738 } 9739 9740 synchronized (this) { 9741 mDebugApp = mOrigDebugApp = debugApp; 9742 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9743 mAlwaysFinishActivities = alwaysFinishActivities; 9744 // This happens before any activities are started, so we can 9745 // change mConfiguration in-place. 9746 updateConfigurationLocked(configuration, null, false, true); 9747 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9748 } 9749 } 9750 9751 public boolean testIsSystemReady() { 9752 // no need to synchronize(this) just to read & return the value 9753 return mSystemReady; 9754 } 9755 9756 private static File getCalledPreBootReceiversFile() { 9757 File dataDir = Environment.getDataDirectory(); 9758 File systemDir = new File(dataDir, "system"); 9759 File fname = new File(systemDir, "called_pre_boots.dat"); 9760 return fname; 9761 } 9762 9763 static final int LAST_DONE_VERSION = 10000; 9764 9765 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9766 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9767 File file = getCalledPreBootReceiversFile(); 9768 FileInputStream fis = null; 9769 try { 9770 fis = new FileInputStream(file); 9771 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9772 int fvers = dis.readInt(); 9773 if (fvers == LAST_DONE_VERSION) { 9774 String vers = dis.readUTF(); 9775 String codename = dis.readUTF(); 9776 String build = dis.readUTF(); 9777 if (android.os.Build.VERSION.RELEASE.equals(vers) 9778 && android.os.Build.VERSION.CODENAME.equals(codename) 9779 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9780 int num = dis.readInt(); 9781 while (num > 0) { 9782 num--; 9783 String pkg = dis.readUTF(); 9784 String cls = dis.readUTF(); 9785 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9786 } 9787 } 9788 } 9789 } catch (FileNotFoundException e) { 9790 } catch (IOException e) { 9791 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9792 } finally { 9793 if (fis != null) { 9794 try { 9795 fis.close(); 9796 } catch (IOException e) { 9797 } 9798 } 9799 } 9800 return lastDoneReceivers; 9801 } 9802 9803 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9804 File file = getCalledPreBootReceiversFile(); 9805 FileOutputStream fos = null; 9806 DataOutputStream dos = null; 9807 try { 9808 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9809 fos = new FileOutputStream(file); 9810 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9811 dos.writeInt(LAST_DONE_VERSION); 9812 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9813 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9814 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9815 dos.writeInt(list.size()); 9816 for (int i=0; i<list.size(); i++) { 9817 dos.writeUTF(list.get(i).getPackageName()); 9818 dos.writeUTF(list.get(i).getClassName()); 9819 } 9820 } catch (IOException e) { 9821 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9822 file.delete(); 9823 } finally { 9824 FileUtils.sync(fos); 9825 if (dos != null) { 9826 try { 9827 dos.close(); 9828 } catch (IOException e) { 9829 // TODO Auto-generated catch block 9830 e.printStackTrace(); 9831 } 9832 } 9833 } 9834 } 9835 9836 public void systemReady(final Runnable goingCallback) { 9837 synchronized(this) { 9838 if (mSystemReady) { 9839 if (goingCallback != null) goingCallback.run(); 9840 return; 9841 } 9842 9843 if (mRecentTasks == null) { 9844 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9845 if (!mRecentTasks.isEmpty()) { 9846 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9847 } 9848 mTaskPersister.startPersisting(); 9849 } 9850 9851 // Check to see if there are any update receivers to run. 9852 if (!mDidUpdate) { 9853 if (mWaitingUpdate) { 9854 return; 9855 } 9856 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9857 List<ResolveInfo> ris = null; 9858 try { 9859 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9860 intent, null, 0, 0); 9861 } catch (RemoteException e) { 9862 } 9863 if (ris != null) { 9864 for (int i=ris.size()-1; i>=0; i--) { 9865 if ((ris.get(i).activityInfo.applicationInfo.flags 9866 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9867 ris.remove(i); 9868 } 9869 } 9870 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9871 9872 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9873 9874 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9875 for (int i=0; i<ris.size(); i++) { 9876 ActivityInfo ai = ris.get(i).activityInfo; 9877 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9878 if (lastDoneReceivers.contains(comp)) { 9879 // We already did the pre boot receiver for this app with the current 9880 // platform version, so don't do it again... 9881 ris.remove(i); 9882 i--; 9883 // ...however, do keep it as one that has been done, so we don't 9884 // forget about it when rewriting the file of last done receivers. 9885 doneReceivers.add(comp); 9886 } 9887 } 9888 9889 final int[] users = getUsersLocked(); 9890 for (int i=0; i<ris.size(); i++) { 9891 ActivityInfo ai = ris.get(i).activityInfo; 9892 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9893 doneReceivers.add(comp); 9894 intent.setComponent(comp); 9895 for (int j=0; j<users.length; j++) { 9896 IIntentReceiver finisher = null; 9897 if (i == ris.size()-1 && j == users.length-1) { 9898 finisher = new IIntentReceiver.Stub() { 9899 public void performReceive(Intent intent, int resultCode, 9900 String data, Bundle extras, boolean ordered, 9901 boolean sticky, int sendingUser) { 9902 // The raw IIntentReceiver interface is called 9903 // with the AM lock held, so redispatch to 9904 // execute our code without the lock. 9905 mHandler.post(new Runnable() { 9906 public void run() { 9907 synchronized (ActivityManagerService.this) { 9908 mDidUpdate = true; 9909 } 9910 writeLastDonePreBootReceivers(doneReceivers); 9911 showBootMessage(mContext.getText( 9912 R.string.android_upgrading_complete), 9913 false); 9914 systemReady(goingCallback); 9915 } 9916 }); 9917 } 9918 }; 9919 } 9920 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9921 + " for user " + users[j]); 9922 broadcastIntentLocked(null, null, intent, null, finisher, 9923 0, null, null, null, AppOpsManager.OP_NONE, 9924 true, false, MY_PID, Process.SYSTEM_UID, 9925 users[j]); 9926 if (finisher != null) { 9927 mWaitingUpdate = true; 9928 } 9929 } 9930 } 9931 } 9932 if (mWaitingUpdate) { 9933 return; 9934 } 9935 mDidUpdate = true; 9936 } 9937 9938 mAppOpsService.systemReady(); 9939 mUsageStatsService.systemReady(); 9940 mSystemReady = true; 9941 } 9942 9943 ArrayList<ProcessRecord> procsToKill = null; 9944 synchronized(mPidsSelfLocked) { 9945 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9946 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9947 if (!isAllowedWhileBooting(proc.info)){ 9948 if (procsToKill == null) { 9949 procsToKill = new ArrayList<ProcessRecord>(); 9950 } 9951 procsToKill.add(proc); 9952 } 9953 } 9954 } 9955 9956 synchronized(this) { 9957 if (procsToKill != null) { 9958 for (int i=procsToKill.size()-1; i>=0; i--) { 9959 ProcessRecord proc = procsToKill.get(i); 9960 Slog.i(TAG, "Removing system update proc: " + proc); 9961 removeProcessLocked(proc, true, false, "system update done"); 9962 } 9963 } 9964 9965 // Now that we have cleaned up any update processes, we 9966 // are ready to start launching real processes and know that 9967 // we won't trample on them any more. 9968 mProcessesReady = true; 9969 } 9970 9971 Slog.i(TAG, "System now ready"); 9972 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9973 SystemClock.uptimeMillis()); 9974 9975 synchronized(this) { 9976 // Make sure we have no pre-ready processes sitting around. 9977 9978 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9979 ResolveInfo ri = mContext.getPackageManager() 9980 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9981 STOCK_PM_FLAGS); 9982 CharSequence errorMsg = null; 9983 if (ri != null) { 9984 ActivityInfo ai = ri.activityInfo; 9985 ApplicationInfo app = ai.applicationInfo; 9986 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9987 mTopAction = Intent.ACTION_FACTORY_TEST; 9988 mTopData = null; 9989 mTopComponent = new ComponentName(app.packageName, 9990 ai.name); 9991 } else { 9992 errorMsg = mContext.getResources().getText( 9993 com.android.internal.R.string.factorytest_not_system); 9994 } 9995 } else { 9996 errorMsg = mContext.getResources().getText( 9997 com.android.internal.R.string.factorytest_no_action); 9998 } 9999 if (errorMsg != null) { 10000 mTopAction = null; 10001 mTopData = null; 10002 mTopComponent = null; 10003 Message msg = Message.obtain(); 10004 msg.what = SHOW_FACTORY_ERROR_MSG; 10005 msg.getData().putCharSequence("msg", errorMsg); 10006 mHandler.sendMessage(msg); 10007 } 10008 } 10009 } 10010 10011 retrieveSettings(); 10012 10013 synchronized (this) { 10014 readGrantedUriPermissionsLocked(); 10015 } 10016 10017 if (goingCallback != null) goingCallback.run(); 10018 10019 mSystemServiceManager.startUser(mCurrentUserId); 10020 10021 synchronized (this) { 10022 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10023 try { 10024 List apps = AppGlobals.getPackageManager(). 10025 getPersistentApplications(STOCK_PM_FLAGS); 10026 if (apps != null) { 10027 int N = apps.size(); 10028 int i; 10029 for (i=0; i<N; i++) { 10030 ApplicationInfo info 10031 = (ApplicationInfo)apps.get(i); 10032 if (info != null && 10033 !info.packageName.equals("android")) { 10034 addAppLocked(info, false, null /* ABI override */); 10035 } 10036 } 10037 } 10038 } catch (RemoteException ex) { 10039 // pm is in same process, this will never happen. 10040 } 10041 } 10042 10043 // Start up initial activity. 10044 mBooting = true; 10045 10046 try { 10047 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10048 Message msg = Message.obtain(); 10049 msg.what = SHOW_UID_ERROR_MSG; 10050 mHandler.sendMessage(msg); 10051 } 10052 } catch (RemoteException e) { 10053 } 10054 10055 long ident = Binder.clearCallingIdentity(); 10056 try { 10057 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10058 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10059 | Intent.FLAG_RECEIVER_FOREGROUND); 10060 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10061 broadcastIntentLocked(null, null, intent, 10062 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10063 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10064 intent = new Intent(Intent.ACTION_USER_STARTING); 10065 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10066 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10067 broadcastIntentLocked(null, null, intent, 10068 null, new IIntentReceiver.Stub() { 10069 @Override 10070 public void performReceive(Intent intent, int resultCode, String data, 10071 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10072 throws RemoteException { 10073 } 10074 }, 0, null, null, 10075 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10076 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10077 } catch (Throwable t) { 10078 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10079 } finally { 10080 Binder.restoreCallingIdentity(ident); 10081 } 10082 mStackSupervisor.resumeTopActivitiesLocked(); 10083 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10084 } 10085 } 10086 10087 private boolean makeAppCrashingLocked(ProcessRecord app, 10088 String shortMsg, String longMsg, String stackTrace) { 10089 app.crashing = true; 10090 app.crashingReport = generateProcessError(app, 10091 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10092 startAppProblemLocked(app); 10093 app.stopFreezingAllLocked(); 10094 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10095 } 10096 10097 private void makeAppNotRespondingLocked(ProcessRecord app, 10098 String activity, String shortMsg, String longMsg) { 10099 app.notResponding = true; 10100 app.notRespondingReport = generateProcessError(app, 10101 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10102 activity, shortMsg, longMsg, null); 10103 startAppProblemLocked(app); 10104 app.stopFreezingAllLocked(); 10105 } 10106 10107 /** 10108 * Generate a process error record, suitable for attachment to a ProcessRecord. 10109 * 10110 * @param app The ProcessRecord in which the error occurred. 10111 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10112 * ActivityManager.AppErrorStateInfo 10113 * @param activity The activity associated with the crash, if known. 10114 * @param shortMsg Short message describing the crash. 10115 * @param longMsg Long message describing the crash. 10116 * @param stackTrace Full crash stack trace, may be null. 10117 * 10118 * @return Returns a fully-formed AppErrorStateInfo record. 10119 */ 10120 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10121 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10122 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10123 10124 report.condition = condition; 10125 report.processName = app.processName; 10126 report.pid = app.pid; 10127 report.uid = app.info.uid; 10128 report.tag = activity; 10129 report.shortMsg = shortMsg; 10130 report.longMsg = longMsg; 10131 report.stackTrace = stackTrace; 10132 10133 return report; 10134 } 10135 10136 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10137 synchronized (this) { 10138 app.crashing = false; 10139 app.crashingReport = null; 10140 app.notResponding = false; 10141 app.notRespondingReport = null; 10142 if (app.anrDialog == fromDialog) { 10143 app.anrDialog = null; 10144 } 10145 if (app.waitDialog == fromDialog) { 10146 app.waitDialog = null; 10147 } 10148 if (app.pid > 0 && app.pid != MY_PID) { 10149 handleAppCrashLocked(app, null, null, null); 10150 killUnneededProcessLocked(app, "user request after error"); 10151 } 10152 } 10153 } 10154 10155 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10156 String stackTrace) { 10157 long now = SystemClock.uptimeMillis(); 10158 10159 Long crashTime; 10160 if (!app.isolated) { 10161 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10162 } else { 10163 crashTime = null; 10164 } 10165 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10166 // This process loses! 10167 Slog.w(TAG, "Process " + app.info.processName 10168 + " has crashed too many times: killing!"); 10169 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10170 app.userId, app.info.processName, app.uid); 10171 mStackSupervisor.handleAppCrashLocked(app); 10172 if (!app.persistent) { 10173 // We don't want to start this process again until the user 10174 // explicitly does so... but for persistent process, we really 10175 // need to keep it running. If a persistent process is actually 10176 // repeatedly crashing, then badness for everyone. 10177 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10178 app.info.processName); 10179 if (!app.isolated) { 10180 // XXX We don't have a way to mark isolated processes 10181 // as bad, since they don't have a peristent identity. 10182 mBadProcesses.put(app.info.processName, app.uid, 10183 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10184 mProcessCrashTimes.remove(app.info.processName, app.uid); 10185 } 10186 app.bad = true; 10187 app.removed = true; 10188 // Don't let services in this process be restarted and potentially 10189 // annoy the user repeatedly. Unless it is persistent, since those 10190 // processes run critical code. 10191 removeProcessLocked(app, false, false, "crash"); 10192 mStackSupervisor.resumeTopActivitiesLocked(); 10193 return false; 10194 } 10195 mStackSupervisor.resumeTopActivitiesLocked(); 10196 } else { 10197 mStackSupervisor.finishTopRunningActivityLocked(app); 10198 } 10199 10200 // Bump up the crash count of any services currently running in the proc. 10201 for (int i=app.services.size()-1; i>=0; i--) { 10202 // Any services running in the application need to be placed 10203 // back in the pending list. 10204 ServiceRecord sr = app.services.valueAt(i); 10205 sr.crashCount++; 10206 } 10207 10208 // If the crashing process is what we consider to be the "home process" and it has been 10209 // replaced by a third-party app, clear the package preferred activities from packages 10210 // with a home activity running in the process to prevent a repeatedly crashing app 10211 // from blocking the user to manually clear the list. 10212 final ArrayList<ActivityRecord> activities = app.activities; 10213 if (app == mHomeProcess && activities.size() > 0 10214 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10215 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10216 final ActivityRecord r = activities.get(activityNdx); 10217 if (r.isHomeActivity()) { 10218 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10219 try { 10220 ActivityThread.getPackageManager() 10221 .clearPackagePreferredActivities(r.packageName); 10222 } catch (RemoteException c) { 10223 // pm is in same process, this will never happen. 10224 } 10225 } 10226 } 10227 } 10228 10229 if (!app.isolated) { 10230 // XXX Can't keep track of crash times for isolated processes, 10231 // because they don't have a perisistent identity. 10232 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10233 } 10234 10235 return true; 10236 } 10237 10238 void startAppProblemLocked(ProcessRecord app) { 10239 if (app.userId == mCurrentUserId) { 10240 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10241 mContext, app.info.packageName, app.info.flags); 10242 } else { 10243 // If this app is not running under the current user, then we 10244 // can't give it a report button because that would require 10245 // launching the report UI under a different user. 10246 app.errorReportReceiver = null; 10247 } 10248 skipCurrentReceiverLocked(app); 10249 } 10250 10251 void skipCurrentReceiverLocked(ProcessRecord app) { 10252 for (BroadcastQueue queue : mBroadcastQueues) { 10253 queue.skipCurrentReceiverLocked(app); 10254 } 10255 } 10256 10257 /** 10258 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10259 * The application process will exit immediately after this call returns. 10260 * @param app object of the crashing app, null for the system server 10261 * @param crashInfo describing the exception 10262 */ 10263 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10264 ProcessRecord r = findAppProcess(app, "Crash"); 10265 final String processName = app == null ? "system_server" 10266 : (r == null ? "unknown" : r.processName); 10267 10268 handleApplicationCrashInner("crash", r, processName, crashInfo); 10269 } 10270 10271 /* Native crash reporting uses this inner version because it needs to be somewhat 10272 * decoupled from the AM-managed cleanup lifecycle 10273 */ 10274 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10275 ApplicationErrorReport.CrashInfo crashInfo) { 10276 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10277 UserHandle.getUserId(Binder.getCallingUid()), processName, 10278 r == null ? -1 : r.info.flags, 10279 crashInfo.exceptionClassName, 10280 crashInfo.exceptionMessage, 10281 crashInfo.throwFileName, 10282 crashInfo.throwLineNumber); 10283 10284 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10285 10286 crashApplication(r, crashInfo); 10287 } 10288 10289 public void handleApplicationStrictModeViolation( 10290 IBinder app, 10291 int violationMask, 10292 StrictMode.ViolationInfo info) { 10293 ProcessRecord r = findAppProcess(app, "StrictMode"); 10294 if (r == null) { 10295 return; 10296 } 10297 10298 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10299 Integer stackFingerprint = info.hashCode(); 10300 boolean logIt = true; 10301 synchronized (mAlreadyLoggedViolatedStacks) { 10302 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10303 logIt = false; 10304 // TODO: sub-sample into EventLog for these, with 10305 // the info.durationMillis? Then we'd get 10306 // the relative pain numbers, without logging all 10307 // the stack traces repeatedly. We'd want to do 10308 // likewise in the client code, which also does 10309 // dup suppression, before the Binder call. 10310 } else { 10311 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10312 mAlreadyLoggedViolatedStacks.clear(); 10313 } 10314 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10315 } 10316 } 10317 if (logIt) { 10318 logStrictModeViolationToDropBox(r, info); 10319 } 10320 } 10321 10322 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10323 AppErrorResult result = new AppErrorResult(); 10324 synchronized (this) { 10325 final long origId = Binder.clearCallingIdentity(); 10326 10327 Message msg = Message.obtain(); 10328 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10329 HashMap<String, Object> data = new HashMap<String, Object>(); 10330 data.put("result", result); 10331 data.put("app", r); 10332 data.put("violationMask", violationMask); 10333 data.put("info", info); 10334 msg.obj = data; 10335 mHandler.sendMessage(msg); 10336 10337 Binder.restoreCallingIdentity(origId); 10338 } 10339 int res = result.get(); 10340 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10341 } 10342 } 10343 10344 // Depending on the policy in effect, there could be a bunch of 10345 // these in quick succession so we try to batch these together to 10346 // minimize disk writes, number of dropbox entries, and maximize 10347 // compression, by having more fewer, larger records. 10348 private void logStrictModeViolationToDropBox( 10349 ProcessRecord process, 10350 StrictMode.ViolationInfo info) { 10351 if (info == null) { 10352 return; 10353 } 10354 final boolean isSystemApp = process == null || 10355 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10356 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10357 final String processName = process == null ? "unknown" : process.processName; 10358 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10359 final DropBoxManager dbox = (DropBoxManager) 10360 mContext.getSystemService(Context.DROPBOX_SERVICE); 10361 10362 // Exit early if the dropbox isn't configured to accept this report type. 10363 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10364 10365 boolean bufferWasEmpty; 10366 boolean needsFlush; 10367 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10368 synchronized (sb) { 10369 bufferWasEmpty = sb.length() == 0; 10370 appendDropBoxProcessHeaders(process, processName, sb); 10371 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10372 sb.append("System-App: ").append(isSystemApp).append("\n"); 10373 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10374 if (info.violationNumThisLoop != 0) { 10375 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10376 } 10377 if (info.numAnimationsRunning != 0) { 10378 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10379 } 10380 if (info.broadcastIntentAction != null) { 10381 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10382 } 10383 if (info.durationMillis != -1) { 10384 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10385 } 10386 if (info.numInstances != -1) { 10387 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10388 } 10389 if (info.tags != null) { 10390 for (String tag : info.tags) { 10391 sb.append("Span-Tag: ").append(tag).append("\n"); 10392 } 10393 } 10394 sb.append("\n"); 10395 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10396 sb.append(info.crashInfo.stackTrace); 10397 } 10398 sb.append("\n"); 10399 10400 // Only buffer up to ~64k. Various logging bits truncate 10401 // things at 128k. 10402 needsFlush = (sb.length() > 64 * 1024); 10403 } 10404 10405 // Flush immediately if the buffer's grown too large, or this 10406 // is a non-system app. Non-system apps are isolated with a 10407 // different tag & policy and not batched. 10408 // 10409 // Batching is useful during internal testing with 10410 // StrictMode settings turned up high. Without batching, 10411 // thousands of separate files could be created on boot. 10412 if (!isSystemApp || needsFlush) { 10413 new Thread("Error dump: " + dropboxTag) { 10414 @Override 10415 public void run() { 10416 String report; 10417 synchronized (sb) { 10418 report = sb.toString(); 10419 sb.delete(0, sb.length()); 10420 sb.trimToSize(); 10421 } 10422 if (report.length() != 0) { 10423 dbox.addText(dropboxTag, report); 10424 } 10425 } 10426 }.start(); 10427 return; 10428 } 10429 10430 // System app batching: 10431 if (!bufferWasEmpty) { 10432 // An existing dropbox-writing thread is outstanding, so 10433 // we don't need to start it up. The existing thread will 10434 // catch the buffer appends we just did. 10435 return; 10436 } 10437 10438 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10439 // (After this point, we shouldn't access AMS internal data structures.) 10440 new Thread("Error dump: " + dropboxTag) { 10441 @Override 10442 public void run() { 10443 // 5 second sleep to let stacks arrive and be batched together 10444 try { 10445 Thread.sleep(5000); // 5 seconds 10446 } catch (InterruptedException e) {} 10447 10448 String errorReport; 10449 synchronized (mStrictModeBuffer) { 10450 errorReport = mStrictModeBuffer.toString(); 10451 if (errorReport.length() == 0) { 10452 return; 10453 } 10454 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10455 mStrictModeBuffer.trimToSize(); 10456 } 10457 dbox.addText(dropboxTag, errorReport); 10458 } 10459 }.start(); 10460 } 10461 10462 /** 10463 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10464 * @param app object of the crashing app, null for the system server 10465 * @param tag reported by the caller 10466 * @param crashInfo describing the context of the error 10467 * @return true if the process should exit immediately (WTF is fatal) 10468 */ 10469 public boolean handleApplicationWtf(IBinder app, String tag, 10470 ApplicationErrorReport.CrashInfo crashInfo) { 10471 ProcessRecord r = findAppProcess(app, "WTF"); 10472 final String processName = app == null ? "system_server" 10473 : (r == null ? "unknown" : r.processName); 10474 10475 EventLog.writeEvent(EventLogTags.AM_WTF, 10476 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10477 processName, 10478 r == null ? -1 : r.info.flags, 10479 tag, crashInfo.exceptionMessage); 10480 10481 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10482 10483 if (r != null && r.pid != Process.myPid() && 10484 Settings.Global.getInt(mContext.getContentResolver(), 10485 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10486 crashApplication(r, crashInfo); 10487 return true; 10488 } else { 10489 return false; 10490 } 10491 } 10492 10493 /** 10494 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10495 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10496 */ 10497 private ProcessRecord findAppProcess(IBinder app, String reason) { 10498 if (app == null) { 10499 return null; 10500 } 10501 10502 synchronized (this) { 10503 final int NP = mProcessNames.getMap().size(); 10504 for (int ip=0; ip<NP; ip++) { 10505 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10506 final int NA = apps.size(); 10507 for (int ia=0; ia<NA; ia++) { 10508 ProcessRecord p = apps.valueAt(ia); 10509 if (p.thread != null && p.thread.asBinder() == app) { 10510 return p; 10511 } 10512 } 10513 } 10514 10515 Slog.w(TAG, "Can't find mystery application for " + reason 10516 + " from pid=" + Binder.getCallingPid() 10517 + " uid=" + Binder.getCallingUid() + ": " + app); 10518 return null; 10519 } 10520 } 10521 10522 /** 10523 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10524 * to append various headers to the dropbox log text. 10525 */ 10526 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10527 StringBuilder sb) { 10528 // Watchdog thread ends up invoking this function (with 10529 // a null ProcessRecord) to add the stack file to dropbox. 10530 // Do not acquire a lock on this (am) in such cases, as it 10531 // could cause a potential deadlock, if and when watchdog 10532 // is invoked due to unavailability of lock on am and it 10533 // would prevent watchdog from killing system_server. 10534 if (process == null) { 10535 sb.append("Process: ").append(processName).append("\n"); 10536 return; 10537 } 10538 // Note: ProcessRecord 'process' is guarded by the service 10539 // instance. (notably process.pkgList, which could otherwise change 10540 // concurrently during execution of this method) 10541 synchronized (this) { 10542 sb.append("Process: ").append(processName).append("\n"); 10543 int flags = process.info.flags; 10544 IPackageManager pm = AppGlobals.getPackageManager(); 10545 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10546 for (int ip=0; ip<process.pkgList.size(); ip++) { 10547 String pkg = process.pkgList.keyAt(ip); 10548 sb.append("Package: ").append(pkg); 10549 try { 10550 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10551 if (pi != null) { 10552 sb.append(" v").append(pi.versionCode); 10553 if (pi.versionName != null) { 10554 sb.append(" (").append(pi.versionName).append(")"); 10555 } 10556 } 10557 } catch (RemoteException e) { 10558 Slog.e(TAG, "Error getting package info: " + pkg, e); 10559 } 10560 sb.append("\n"); 10561 } 10562 } 10563 } 10564 10565 private static String processClass(ProcessRecord process) { 10566 if (process == null || process.pid == MY_PID) { 10567 return "system_server"; 10568 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10569 return "system_app"; 10570 } else { 10571 return "data_app"; 10572 } 10573 } 10574 10575 /** 10576 * Write a description of an error (crash, WTF, ANR) to the drop box. 10577 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10578 * @param process which caused the error, null means the system server 10579 * @param activity which triggered the error, null if unknown 10580 * @param parent activity related to the error, null if unknown 10581 * @param subject line related to the error, null if absent 10582 * @param report in long form describing the error, null if absent 10583 * @param logFile to include in the report, null if none 10584 * @param crashInfo giving an application stack trace, null if absent 10585 */ 10586 public void addErrorToDropBox(String eventType, 10587 ProcessRecord process, String processName, ActivityRecord activity, 10588 ActivityRecord parent, String subject, 10589 final String report, final File logFile, 10590 final ApplicationErrorReport.CrashInfo crashInfo) { 10591 // NOTE -- this must never acquire the ActivityManagerService lock, 10592 // otherwise the watchdog may be prevented from resetting the system. 10593 10594 final String dropboxTag = processClass(process) + "_" + eventType; 10595 final DropBoxManager dbox = (DropBoxManager) 10596 mContext.getSystemService(Context.DROPBOX_SERVICE); 10597 10598 // Exit early if the dropbox isn't configured to accept this report type. 10599 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10600 10601 final StringBuilder sb = new StringBuilder(1024); 10602 appendDropBoxProcessHeaders(process, processName, sb); 10603 if (activity != null) { 10604 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10605 } 10606 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10607 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10608 } 10609 if (parent != null && parent != activity) { 10610 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10611 } 10612 if (subject != null) { 10613 sb.append("Subject: ").append(subject).append("\n"); 10614 } 10615 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10616 if (Debug.isDebuggerConnected()) { 10617 sb.append("Debugger: Connected\n"); 10618 } 10619 sb.append("\n"); 10620 10621 // Do the rest in a worker thread to avoid blocking the caller on I/O 10622 // (After this point, we shouldn't access AMS internal data structures.) 10623 Thread worker = new Thread("Error dump: " + dropboxTag) { 10624 @Override 10625 public void run() { 10626 if (report != null) { 10627 sb.append(report); 10628 } 10629 if (logFile != null) { 10630 try { 10631 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10632 "\n\n[[TRUNCATED]]")); 10633 } catch (IOException e) { 10634 Slog.e(TAG, "Error reading " + logFile, e); 10635 } 10636 } 10637 if (crashInfo != null && crashInfo.stackTrace != null) { 10638 sb.append(crashInfo.stackTrace); 10639 } 10640 10641 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10642 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10643 if (lines > 0) { 10644 sb.append("\n"); 10645 10646 // Merge several logcat streams, and take the last N lines 10647 InputStreamReader input = null; 10648 try { 10649 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10650 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10651 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10652 10653 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10654 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10655 input = new InputStreamReader(logcat.getInputStream()); 10656 10657 int num; 10658 char[] buf = new char[8192]; 10659 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10660 } catch (IOException e) { 10661 Slog.e(TAG, "Error running logcat", e); 10662 } finally { 10663 if (input != null) try { input.close(); } catch (IOException e) {} 10664 } 10665 } 10666 10667 dbox.addText(dropboxTag, sb.toString()); 10668 } 10669 }; 10670 10671 if (process == null) { 10672 // If process is null, we are being called from some internal code 10673 // and may be about to die -- run this synchronously. 10674 worker.run(); 10675 } else { 10676 worker.start(); 10677 } 10678 } 10679 10680 /** 10681 * Bring up the "unexpected error" dialog box for a crashing app. 10682 * Deal with edge cases (intercepts from instrumented applications, 10683 * ActivityController, error intent receivers, that sort of thing). 10684 * @param r the application crashing 10685 * @param crashInfo describing the failure 10686 */ 10687 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10688 long timeMillis = System.currentTimeMillis(); 10689 String shortMsg = crashInfo.exceptionClassName; 10690 String longMsg = crashInfo.exceptionMessage; 10691 String stackTrace = crashInfo.stackTrace; 10692 if (shortMsg != null && longMsg != null) { 10693 longMsg = shortMsg + ": " + longMsg; 10694 } else if (shortMsg != null) { 10695 longMsg = shortMsg; 10696 } 10697 10698 AppErrorResult result = new AppErrorResult(); 10699 synchronized (this) { 10700 if (mController != null) { 10701 try { 10702 String name = r != null ? r.processName : null; 10703 int pid = r != null ? r.pid : Binder.getCallingPid(); 10704 if (!mController.appCrashed(name, pid, 10705 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10706 Slog.w(TAG, "Force-killing crashed app " + name 10707 + " at watcher's request"); 10708 Process.killProcess(pid); 10709 return; 10710 } 10711 } catch (RemoteException e) { 10712 mController = null; 10713 Watchdog.getInstance().setActivityController(null); 10714 } 10715 } 10716 10717 final long origId = Binder.clearCallingIdentity(); 10718 10719 // If this process is running instrumentation, finish it. 10720 if (r != null && r.instrumentationClass != null) { 10721 Slog.w(TAG, "Error in app " + r.processName 10722 + " running instrumentation " + r.instrumentationClass + ":"); 10723 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10724 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10725 Bundle info = new Bundle(); 10726 info.putString("shortMsg", shortMsg); 10727 info.putString("longMsg", longMsg); 10728 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10729 Binder.restoreCallingIdentity(origId); 10730 return; 10731 } 10732 10733 // If we can't identify the process or it's already exceeded its crash quota, 10734 // quit right away without showing a crash dialog. 10735 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10736 Binder.restoreCallingIdentity(origId); 10737 return; 10738 } 10739 10740 Message msg = Message.obtain(); 10741 msg.what = SHOW_ERROR_MSG; 10742 HashMap data = new HashMap(); 10743 data.put("result", result); 10744 data.put("app", r); 10745 msg.obj = data; 10746 mHandler.sendMessage(msg); 10747 10748 Binder.restoreCallingIdentity(origId); 10749 } 10750 10751 int res = result.get(); 10752 10753 Intent appErrorIntent = null; 10754 synchronized (this) { 10755 if (r != null && !r.isolated) { 10756 // XXX Can't keep track of crash time for isolated processes, 10757 // since they don't have a persistent identity. 10758 mProcessCrashTimes.put(r.info.processName, r.uid, 10759 SystemClock.uptimeMillis()); 10760 } 10761 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10762 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10763 } 10764 } 10765 10766 if (appErrorIntent != null) { 10767 try { 10768 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10769 } catch (ActivityNotFoundException e) { 10770 Slog.w(TAG, "bug report receiver dissappeared", e); 10771 } 10772 } 10773 } 10774 10775 Intent createAppErrorIntentLocked(ProcessRecord r, 10776 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10777 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10778 if (report == null) { 10779 return null; 10780 } 10781 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10782 result.setComponent(r.errorReportReceiver); 10783 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10784 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10785 return result; 10786 } 10787 10788 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10789 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10790 if (r.errorReportReceiver == null) { 10791 return null; 10792 } 10793 10794 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10795 return null; 10796 } 10797 10798 ApplicationErrorReport report = new ApplicationErrorReport(); 10799 report.packageName = r.info.packageName; 10800 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10801 report.processName = r.processName; 10802 report.time = timeMillis; 10803 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10804 10805 if (r.crashing || r.forceCrashReport) { 10806 report.type = ApplicationErrorReport.TYPE_CRASH; 10807 report.crashInfo = crashInfo; 10808 } else if (r.notResponding) { 10809 report.type = ApplicationErrorReport.TYPE_ANR; 10810 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10811 10812 report.anrInfo.activity = r.notRespondingReport.tag; 10813 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10814 report.anrInfo.info = r.notRespondingReport.longMsg; 10815 } 10816 10817 return report; 10818 } 10819 10820 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10821 enforceNotIsolatedCaller("getProcessesInErrorState"); 10822 // assume our apps are happy - lazy create the list 10823 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10824 10825 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10826 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10827 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10828 10829 synchronized (this) { 10830 10831 // iterate across all processes 10832 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10833 ProcessRecord app = mLruProcesses.get(i); 10834 if (!allUsers && app.userId != userId) { 10835 continue; 10836 } 10837 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10838 // This one's in trouble, so we'll generate a report for it 10839 // crashes are higher priority (in case there's a crash *and* an anr) 10840 ActivityManager.ProcessErrorStateInfo report = null; 10841 if (app.crashing) { 10842 report = app.crashingReport; 10843 } else if (app.notResponding) { 10844 report = app.notRespondingReport; 10845 } 10846 10847 if (report != null) { 10848 if (errList == null) { 10849 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10850 } 10851 errList.add(report); 10852 } else { 10853 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10854 " crashing = " + app.crashing + 10855 " notResponding = " + app.notResponding); 10856 } 10857 } 10858 } 10859 } 10860 10861 return errList; 10862 } 10863 10864 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10865 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10866 if (currApp != null) { 10867 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10868 } 10869 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10870 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10871 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10872 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10873 if (currApp != null) { 10874 currApp.lru = 0; 10875 } 10876 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10877 } else if (adj >= ProcessList.SERVICE_ADJ) { 10878 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10879 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10880 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10881 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10882 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10883 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10884 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10885 } else { 10886 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10887 } 10888 } 10889 10890 private void fillInProcMemInfo(ProcessRecord app, 10891 ActivityManager.RunningAppProcessInfo outInfo) { 10892 outInfo.pid = app.pid; 10893 outInfo.uid = app.info.uid; 10894 if (mHeavyWeightProcess == app) { 10895 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10896 } 10897 if (app.persistent) { 10898 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10899 } 10900 if (app.activities.size() > 0) { 10901 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10902 } 10903 outInfo.lastTrimLevel = app.trimMemoryLevel; 10904 int adj = app.curAdj; 10905 outInfo.importance = oomAdjToImportance(adj, outInfo); 10906 outInfo.importanceReasonCode = app.adjTypeCode; 10907 outInfo.processState = app.curProcState; 10908 } 10909 10910 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10911 enforceNotIsolatedCaller("getRunningAppProcesses"); 10912 // Lazy instantiation of list 10913 List<ActivityManager.RunningAppProcessInfo> runList = null; 10914 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10915 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10916 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10917 synchronized (this) { 10918 // Iterate across all processes 10919 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10920 ProcessRecord app = mLruProcesses.get(i); 10921 if (!allUsers && app.userId != userId) { 10922 continue; 10923 } 10924 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10925 // Generate process state info for running application 10926 ActivityManager.RunningAppProcessInfo currApp = 10927 new ActivityManager.RunningAppProcessInfo(app.processName, 10928 app.pid, app.getPackageList()); 10929 fillInProcMemInfo(app, currApp); 10930 if (app.adjSource instanceof ProcessRecord) { 10931 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10932 currApp.importanceReasonImportance = oomAdjToImportance( 10933 app.adjSourceOom, null); 10934 } else if (app.adjSource instanceof ActivityRecord) { 10935 ActivityRecord r = (ActivityRecord)app.adjSource; 10936 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10937 } 10938 if (app.adjTarget instanceof ComponentName) { 10939 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10940 } 10941 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10942 // + " lru=" + currApp.lru); 10943 if (runList == null) { 10944 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10945 } 10946 runList.add(currApp); 10947 } 10948 } 10949 } 10950 return runList; 10951 } 10952 10953 public List<ApplicationInfo> getRunningExternalApplications() { 10954 enforceNotIsolatedCaller("getRunningExternalApplications"); 10955 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10956 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10957 if (runningApps != null && runningApps.size() > 0) { 10958 Set<String> extList = new HashSet<String>(); 10959 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10960 if (app.pkgList != null) { 10961 for (String pkg : app.pkgList) { 10962 extList.add(pkg); 10963 } 10964 } 10965 } 10966 IPackageManager pm = AppGlobals.getPackageManager(); 10967 for (String pkg : extList) { 10968 try { 10969 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10970 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10971 retList.add(info); 10972 } 10973 } catch (RemoteException e) { 10974 } 10975 } 10976 } 10977 return retList; 10978 } 10979 10980 @Override 10981 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10982 enforceNotIsolatedCaller("getMyMemoryState"); 10983 synchronized (this) { 10984 ProcessRecord proc; 10985 synchronized (mPidsSelfLocked) { 10986 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10987 } 10988 fillInProcMemInfo(proc, outInfo); 10989 } 10990 } 10991 10992 @Override 10993 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10994 if (checkCallingPermission(android.Manifest.permission.DUMP) 10995 != PackageManager.PERMISSION_GRANTED) { 10996 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10997 + Binder.getCallingPid() 10998 + ", uid=" + Binder.getCallingUid() 10999 + " without permission " 11000 + android.Manifest.permission.DUMP); 11001 return; 11002 } 11003 11004 boolean dumpAll = false; 11005 boolean dumpClient = false; 11006 String dumpPackage = null; 11007 11008 int opti = 0; 11009 while (opti < args.length) { 11010 String opt = args[opti]; 11011 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11012 break; 11013 } 11014 opti++; 11015 if ("-a".equals(opt)) { 11016 dumpAll = true; 11017 } else if ("-c".equals(opt)) { 11018 dumpClient = true; 11019 } else if ("-h".equals(opt)) { 11020 pw.println("Activity manager dump options:"); 11021 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11022 pw.println(" cmd may be one of:"); 11023 pw.println(" a[ctivities]: activity stack state"); 11024 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11025 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11026 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11027 pw.println(" o[om]: out of memory management"); 11028 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11029 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11030 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11031 pw.println(" service [COMP_SPEC]: service client-side state"); 11032 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11033 pw.println(" all: dump all activities"); 11034 pw.println(" top: dump the top activity"); 11035 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11036 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11037 pw.println(" a partial substring in a component name, a"); 11038 pw.println(" hex object identifier."); 11039 pw.println(" -a: include all available server state."); 11040 pw.println(" -c: include client state."); 11041 return; 11042 } else { 11043 pw.println("Unknown argument: " + opt + "; use -h for help"); 11044 } 11045 } 11046 11047 long origId = Binder.clearCallingIdentity(); 11048 boolean more = false; 11049 // Is the caller requesting to dump a particular piece of data? 11050 if (opti < args.length) { 11051 String cmd = args[opti]; 11052 opti++; 11053 if ("activities".equals(cmd) || "a".equals(cmd)) { 11054 synchronized (this) { 11055 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11056 } 11057 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11058 String[] newArgs; 11059 String name; 11060 if (opti >= args.length) { 11061 name = null; 11062 newArgs = EMPTY_STRING_ARRAY; 11063 } else { 11064 name = args[opti]; 11065 opti++; 11066 newArgs = new String[args.length - opti]; 11067 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11068 args.length - opti); 11069 } 11070 synchronized (this) { 11071 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11072 } 11073 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11074 String[] newArgs; 11075 String name; 11076 if (opti >= args.length) { 11077 name = null; 11078 newArgs = EMPTY_STRING_ARRAY; 11079 } else { 11080 name = args[opti]; 11081 opti++; 11082 newArgs = new String[args.length - opti]; 11083 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11084 args.length - opti); 11085 } 11086 synchronized (this) { 11087 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11088 } 11089 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11090 String[] newArgs; 11091 String name; 11092 if (opti >= args.length) { 11093 name = null; 11094 newArgs = EMPTY_STRING_ARRAY; 11095 } else { 11096 name = args[opti]; 11097 opti++; 11098 newArgs = new String[args.length - opti]; 11099 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11100 args.length - opti); 11101 } 11102 synchronized (this) { 11103 dumpProcessesLocked(fd, pw, args, opti, true, name); 11104 } 11105 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11106 synchronized (this) { 11107 dumpOomLocked(fd, pw, args, opti, true); 11108 } 11109 } else if ("provider".equals(cmd)) { 11110 String[] newArgs; 11111 String name; 11112 if (opti >= args.length) { 11113 name = null; 11114 newArgs = EMPTY_STRING_ARRAY; 11115 } else { 11116 name = args[opti]; 11117 opti++; 11118 newArgs = new String[args.length - opti]; 11119 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11120 } 11121 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11122 pw.println("No providers match: " + name); 11123 pw.println("Use -h for help."); 11124 } 11125 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11126 synchronized (this) { 11127 dumpProvidersLocked(fd, pw, args, opti, true, null); 11128 } 11129 } else if ("service".equals(cmd)) { 11130 String[] newArgs; 11131 String name; 11132 if (opti >= args.length) { 11133 name = null; 11134 newArgs = EMPTY_STRING_ARRAY; 11135 } else { 11136 name = args[opti]; 11137 opti++; 11138 newArgs = new String[args.length - opti]; 11139 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11140 args.length - opti); 11141 } 11142 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11143 pw.println("No services match: " + name); 11144 pw.println("Use -h for help."); 11145 } 11146 } else if ("package".equals(cmd)) { 11147 String[] newArgs; 11148 if (opti >= args.length) { 11149 pw.println("package: no package name specified"); 11150 pw.println("Use -h for help."); 11151 } else { 11152 dumpPackage = args[opti]; 11153 opti++; 11154 newArgs = new String[args.length - opti]; 11155 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11156 args.length - opti); 11157 args = newArgs; 11158 opti = 0; 11159 more = true; 11160 } 11161 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11162 synchronized (this) { 11163 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11164 } 11165 } else { 11166 // Dumping a single activity? 11167 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11168 pw.println("Bad activity command, or no activities match: " + cmd); 11169 pw.println("Use -h for help."); 11170 } 11171 } 11172 if (!more) { 11173 Binder.restoreCallingIdentity(origId); 11174 return; 11175 } 11176 } 11177 11178 // No piece of data specified, dump everything. 11179 synchronized (this) { 11180 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11181 pw.println(); 11182 if (dumpAll) { 11183 pw.println("-------------------------------------------------------------------------------"); 11184 } 11185 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11186 pw.println(); 11187 if (dumpAll) { 11188 pw.println("-------------------------------------------------------------------------------"); 11189 } 11190 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11191 pw.println(); 11192 if (dumpAll) { 11193 pw.println("-------------------------------------------------------------------------------"); 11194 } 11195 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11196 pw.println(); 11197 if (dumpAll) { 11198 pw.println("-------------------------------------------------------------------------------"); 11199 } 11200 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11201 pw.println(); 11202 if (dumpAll) { 11203 pw.println("-------------------------------------------------------------------------------"); 11204 } 11205 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11206 } 11207 Binder.restoreCallingIdentity(origId); 11208 } 11209 11210 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11211 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11212 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11213 11214 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11215 dumpPackage); 11216 boolean needSep = printedAnything; 11217 11218 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11219 dumpPackage, needSep, " mFocusedActivity: "); 11220 if (printed) { 11221 printedAnything = true; 11222 needSep = false; 11223 } 11224 11225 if (dumpPackage == null) { 11226 if (needSep) { 11227 pw.println(); 11228 } 11229 needSep = true; 11230 printedAnything = true; 11231 mStackSupervisor.dump(pw, " "); 11232 } 11233 11234 if (mRecentTasks.size() > 0) { 11235 boolean printedHeader = false; 11236 11237 final int N = mRecentTasks.size(); 11238 for (int i=0; i<N; i++) { 11239 TaskRecord tr = mRecentTasks.get(i); 11240 if (dumpPackage != null) { 11241 if (tr.realActivity == null || 11242 !dumpPackage.equals(tr.realActivity)) { 11243 continue; 11244 } 11245 } 11246 if (!printedHeader) { 11247 if (needSep) { 11248 pw.println(); 11249 } 11250 pw.println(" Recent tasks:"); 11251 printedHeader = true; 11252 printedAnything = true; 11253 } 11254 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11255 pw.println(tr); 11256 if (dumpAll) { 11257 mRecentTasks.get(i).dump(pw, " "); 11258 } 11259 } 11260 } 11261 11262 if (!printedAnything) { 11263 pw.println(" (nothing)"); 11264 } 11265 } 11266 11267 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11268 int opti, boolean dumpAll, String dumpPackage) { 11269 boolean needSep = false; 11270 boolean printedAnything = false; 11271 int numPers = 0; 11272 11273 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11274 11275 if (dumpAll) { 11276 final int NP = mProcessNames.getMap().size(); 11277 for (int ip=0; ip<NP; ip++) { 11278 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11279 final int NA = procs.size(); 11280 for (int ia=0; ia<NA; ia++) { 11281 ProcessRecord r = procs.valueAt(ia); 11282 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11283 continue; 11284 } 11285 if (!needSep) { 11286 pw.println(" All known processes:"); 11287 needSep = true; 11288 printedAnything = true; 11289 } 11290 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11291 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11292 pw.print(" "); pw.println(r); 11293 r.dump(pw, " "); 11294 if (r.persistent) { 11295 numPers++; 11296 } 11297 } 11298 } 11299 } 11300 11301 if (mIsolatedProcesses.size() > 0) { 11302 boolean printed = false; 11303 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11304 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11305 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11306 continue; 11307 } 11308 if (!printed) { 11309 if (needSep) { 11310 pw.println(); 11311 } 11312 pw.println(" Isolated process list (sorted by uid):"); 11313 printedAnything = true; 11314 printed = true; 11315 needSep = true; 11316 } 11317 pw.println(String.format("%sIsolated #%2d: %s", 11318 " ", i, r.toString())); 11319 } 11320 } 11321 11322 if (mLruProcesses.size() > 0) { 11323 if (needSep) { 11324 pw.println(); 11325 } 11326 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11327 pw.print(" total, non-act at "); 11328 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11329 pw.print(", non-svc at "); 11330 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11331 pw.println("):"); 11332 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11333 needSep = true; 11334 printedAnything = true; 11335 } 11336 11337 if (dumpAll || dumpPackage != null) { 11338 synchronized (mPidsSelfLocked) { 11339 boolean printed = false; 11340 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11341 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11342 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11343 continue; 11344 } 11345 if (!printed) { 11346 if (needSep) pw.println(); 11347 needSep = true; 11348 pw.println(" PID mappings:"); 11349 printed = true; 11350 printedAnything = true; 11351 } 11352 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11353 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11354 } 11355 } 11356 } 11357 11358 if (mForegroundProcesses.size() > 0) { 11359 synchronized (mPidsSelfLocked) { 11360 boolean printed = false; 11361 for (int i=0; i<mForegroundProcesses.size(); i++) { 11362 ProcessRecord r = mPidsSelfLocked.get( 11363 mForegroundProcesses.valueAt(i).pid); 11364 if (dumpPackage != null && (r == null 11365 || !r.pkgList.containsKey(dumpPackage))) { 11366 continue; 11367 } 11368 if (!printed) { 11369 if (needSep) pw.println(); 11370 needSep = true; 11371 pw.println(" Foreground Processes:"); 11372 printed = true; 11373 printedAnything = true; 11374 } 11375 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11376 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11377 } 11378 } 11379 } 11380 11381 if (mPersistentStartingProcesses.size() > 0) { 11382 if (needSep) pw.println(); 11383 needSep = true; 11384 printedAnything = true; 11385 pw.println(" Persisent processes that are starting:"); 11386 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11387 "Starting Norm", "Restarting PERS", dumpPackage); 11388 } 11389 11390 if (mRemovedProcesses.size() > 0) { 11391 if (needSep) pw.println(); 11392 needSep = true; 11393 printedAnything = true; 11394 pw.println(" Processes that are being removed:"); 11395 dumpProcessList(pw, this, mRemovedProcesses, " ", 11396 "Removed Norm", "Removed PERS", dumpPackage); 11397 } 11398 11399 if (mProcessesOnHold.size() > 0) { 11400 if (needSep) pw.println(); 11401 needSep = true; 11402 printedAnything = true; 11403 pw.println(" Processes that are on old until the system is ready:"); 11404 dumpProcessList(pw, this, mProcessesOnHold, " ", 11405 "OnHold Norm", "OnHold PERS", dumpPackage); 11406 } 11407 11408 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11409 11410 if (mProcessCrashTimes.getMap().size() > 0) { 11411 boolean printed = false; 11412 long now = SystemClock.uptimeMillis(); 11413 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11414 final int NP = pmap.size(); 11415 for (int ip=0; ip<NP; ip++) { 11416 String pname = pmap.keyAt(ip); 11417 SparseArray<Long> uids = pmap.valueAt(ip); 11418 final int N = uids.size(); 11419 for (int i=0; i<N; i++) { 11420 int puid = uids.keyAt(i); 11421 ProcessRecord r = mProcessNames.get(pname, puid); 11422 if (dumpPackage != null && (r == null 11423 || !r.pkgList.containsKey(dumpPackage))) { 11424 continue; 11425 } 11426 if (!printed) { 11427 if (needSep) pw.println(); 11428 needSep = true; 11429 pw.println(" Time since processes crashed:"); 11430 printed = true; 11431 printedAnything = true; 11432 } 11433 pw.print(" Process "); pw.print(pname); 11434 pw.print(" uid "); pw.print(puid); 11435 pw.print(": last crashed "); 11436 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11437 pw.println(" ago"); 11438 } 11439 } 11440 } 11441 11442 if (mBadProcesses.getMap().size() > 0) { 11443 boolean printed = false; 11444 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11445 final int NP = pmap.size(); 11446 for (int ip=0; ip<NP; ip++) { 11447 String pname = pmap.keyAt(ip); 11448 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11449 final int N = uids.size(); 11450 for (int i=0; i<N; i++) { 11451 int puid = uids.keyAt(i); 11452 ProcessRecord r = mProcessNames.get(pname, puid); 11453 if (dumpPackage != null && (r == null 11454 || !r.pkgList.containsKey(dumpPackage))) { 11455 continue; 11456 } 11457 if (!printed) { 11458 if (needSep) pw.println(); 11459 needSep = true; 11460 pw.println(" Bad processes:"); 11461 printedAnything = true; 11462 } 11463 BadProcessInfo info = uids.valueAt(i); 11464 pw.print(" Bad process "); pw.print(pname); 11465 pw.print(" uid "); pw.print(puid); 11466 pw.print(": crashed at time "); pw.println(info.time); 11467 if (info.shortMsg != null) { 11468 pw.print(" Short msg: "); pw.println(info.shortMsg); 11469 } 11470 if (info.longMsg != null) { 11471 pw.print(" Long msg: "); pw.println(info.longMsg); 11472 } 11473 if (info.stack != null) { 11474 pw.println(" Stack:"); 11475 int lastPos = 0; 11476 for (int pos=0; pos<info.stack.length(); pos++) { 11477 if (info.stack.charAt(pos) == '\n') { 11478 pw.print(" "); 11479 pw.write(info.stack, lastPos, pos-lastPos); 11480 pw.println(); 11481 lastPos = pos+1; 11482 } 11483 } 11484 if (lastPos < info.stack.length()) { 11485 pw.print(" "); 11486 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11487 pw.println(); 11488 } 11489 } 11490 } 11491 } 11492 } 11493 11494 if (dumpPackage == null) { 11495 pw.println(); 11496 needSep = false; 11497 pw.println(" mStartedUsers:"); 11498 for (int i=0; i<mStartedUsers.size(); i++) { 11499 UserStartedState uss = mStartedUsers.valueAt(i); 11500 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11501 pw.print(": "); uss.dump("", pw); 11502 } 11503 pw.print(" mStartedUserArray: ["); 11504 for (int i=0; i<mStartedUserArray.length; i++) { 11505 if (i > 0) pw.print(", "); 11506 pw.print(mStartedUserArray[i]); 11507 } 11508 pw.println("]"); 11509 pw.print(" mUserLru: ["); 11510 for (int i=0; i<mUserLru.size(); i++) { 11511 if (i > 0) pw.print(", "); 11512 pw.print(mUserLru.get(i)); 11513 } 11514 pw.println("]"); 11515 if (dumpAll) { 11516 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11517 } 11518 } 11519 if (mHomeProcess != null && (dumpPackage == null 11520 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11521 if (needSep) { 11522 pw.println(); 11523 needSep = false; 11524 } 11525 pw.println(" mHomeProcess: " + mHomeProcess); 11526 } 11527 if (mPreviousProcess != null && (dumpPackage == null 11528 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11529 if (needSep) { 11530 pw.println(); 11531 needSep = false; 11532 } 11533 pw.println(" mPreviousProcess: " + mPreviousProcess); 11534 } 11535 if (dumpAll) { 11536 StringBuilder sb = new StringBuilder(128); 11537 sb.append(" mPreviousProcessVisibleTime: "); 11538 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11539 pw.println(sb); 11540 } 11541 if (mHeavyWeightProcess != null && (dumpPackage == null 11542 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11543 if (needSep) { 11544 pw.println(); 11545 needSep = false; 11546 } 11547 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11548 } 11549 if (dumpPackage == null) { 11550 pw.println(" mConfiguration: " + mConfiguration); 11551 } 11552 if (dumpAll) { 11553 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11554 if (mCompatModePackages.getPackages().size() > 0) { 11555 boolean printed = false; 11556 for (Map.Entry<String, Integer> entry 11557 : mCompatModePackages.getPackages().entrySet()) { 11558 String pkg = entry.getKey(); 11559 int mode = entry.getValue(); 11560 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11561 continue; 11562 } 11563 if (!printed) { 11564 pw.println(" mScreenCompatPackages:"); 11565 printed = true; 11566 } 11567 pw.print(" "); pw.print(pkg); pw.print(": "); 11568 pw.print(mode); pw.println(); 11569 } 11570 } 11571 } 11572 if (dumpPackage == null) { 11573 if (mSleeping || mWentToSleep || mLockScreenShown) { 11574 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11575 + " mLockScreenShown " + mLockScreenShown); 11576 } 11577 if (mShuttingDown || mRunningVoice) { 11578 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11579 } 11580 } 11581 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11582 || mOrigWaitForDebugger) { 11583 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11584 || dumpPackage.equals(mOrigDebugApp)) { 11585 if (needSep) { 11586 pw.println(); 11587 needSep = false; 11588 } 11589 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11590 + " mDebugTransient=" + mDebugTransient 11591 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11592 } 11593 } 11594 if (mOpenGlTraceApp != null) { 11595 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11596 if (needSep) { 11597 pw.println(); 11598 needSep = false; 11599 } 11600 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11601 } 11602 } 11603 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11604 || mProfileFd != null) { 11605 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11606 if (needSep) { 11607 pw.println(); 11608 needSep = false; 11609 } 11610 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11611 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11612 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11613 + mAutoStopProfiler); 11614 } 11615 } 11616 if (dumpPackage == null) { 11617 if (mAlwaysFinishActivities || mController != null) { 11618 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11619 + " mController=" + mController); 11620 } 11621 if (dumpAll) { 11622 pw.println(" Total persistent processes: " + numPers); 11623 pw.println(" mProcessesReady=" + mProcessesReady 11624 + " mSystemReady=" + mSystemReady); 11625 pw.println(" mBooting=" + mBooting 11626 + " mBooted=" + mBooted 11627 + " mFactoryTest=" + mFactoryTest); 11628 pw.print(" mLastPowerCheckRealtime="); 11629 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11630 pw.println(""); 11631 pw.print(" mLastPowerCheckUptime="); 11632 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11633 pw.println(""); 11634 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11635 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11636 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11637 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11638 + " (" + mLruProcesses.size() + " total)" 11639 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11640 + " mNumServiceProcs=" + mNumServiceProcs 11641 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11642 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11643 + " mLastMemoryLevel" + mLastMemoryLevel 11644 + " mLastNumProcesses" + mLastNumProcesses); 11645 long now = SystemClock.uptimeMillis(); 11646 pw.print(" mLastIdleTime="); 11647 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11648 pw.print(" mLowRamSinceLastIdle="); 11649 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11650 pw.println(); 11651 } 11652 } 11653 11654 if (!printedAnything) { 11655 pw.println(" (nothing)"); 11656 } 11657 } 11658 11659 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11660 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11661 if (mProcessesToGc.size() > 0) { 11662 boolean printed = false; 11663 long now = SystemClock.uptimeMillis(); 11664 for (int i=0; i<mProcessesToGc.size(); i++) { 11665 ProcessRecord proc = mProcessesToGc.get(i); 11666 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11667 continue; 11668 } 11669 if (!printed) { 11670 if (needSep) pw.println(); 11671 needSep = true; 11672 pw.println(" Processes that are waiting to GC:"); 11673 printed = true; 11674 } 11675 pw.print(" Process "); pw.println(proc); 11676 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11677 pw.print(", last gced="); 11678 pw.print(now-proc.lastRequestedGc); 11679 pw.print(" ms ago, last lowMem="); 11680 pw.print(now-proc.lastLowMemory); 11681 pw.println(" ms ago"); 11682 11683 } 11684 } 11685 return needSep; 11686 } 11687 11688 void printOomLevel(PrintWriter pw, String name, int adj) { 11689 pw.print(" "); 11690 if (adj >= 0) { 11691 pw.print(' '); 11692 if (adj < 10) pw.print(' '); 11693 } else { 11694 if (adj > -10) pw.print(' '); 11695 } 11696 pw.print(adj); 11697 pw.print(": "); 11698 pw.print(name); 11699 pw.print(" ("); 11700 pw.print(mProcessList.getMemLevel(adj)/1024); 11701 pw.println(" kB)"); 11702 } 11703 11704 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11705 int opti, boolean dumpAll) { 11706 boolean needSep = false; 11707 11708 if (mLruProcesses.size() > 0) { 11709 if (needSep) pw.println(); 11710 needSep = true; 11711 pw.println(" OOM levels:"); 11712 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11713 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11714 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11715 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11716 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11717 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11718 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11719 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11720 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11721 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11722 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11723 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11724 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11725 11726 if (needSep) pw.println(); 11727 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11728 pw.print(" total, non-act at "); 11729 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11730 pw.print(", non-svc at "); 11731 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11732 pw.println("):"); 11733 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11734 needSep = true; 11735 } 11736 11737 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11738 11739 pw.println(); 11740 pw.println(" mHomeProcess: " + mHomeProcess); 11741 pw.println(" mPreviousProcess: " + mPreviousProcess); 11742 if (mHeavyWeightProcess != null) { 11743 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11744 } 11745 11746 return true; 11747 } 11748 11749 /** 11750 * There are three ways to call this: 11751 * - no provider specified: dump all the providers 11752 * - a flattened component name that matched an existing provider was specified as the 11753 * first arg: dump that one provider 11754 * - the first arg isn't the flattened component name of an existing provider: 11755 * dump all providers whose component contains the first arg as a substring 11756 */ 11757 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11758 int opti, boolean dumpAll) { 11759 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11760 } 11761 11762 static class ItemMatcher { 11763 ArrayList<ComponentName> components; 11764 ArrayList<String> strings; 11765 ArrayList<Integer> objects; 11766 boolean all; 11767 11768 ItemMatcher() { 11769 all = true; 11770 } 11771 11772 void build(String name) { 11773 ComponentName componentName = ComponentName.unflattenFromString(name); 11774 if (componentName != null) { 11775 if (components == null) { 11776 components = new ArrayList<ComponentName>(); 11777 } 11778 components.add(componentName); 11779 all = false; 11780 } else { 11781 int objectId = 0; 11782 // Not a '/' separated full component name; maybe an object ID? 11783 try { 11784 objectId = Integer.parseInt(name, 16); 11785 if (objects == null) { 11786 objects = new ArrayList<Integer>(); 11787 } 11788 objects.add(objectId); 11789 all = false; 11790 } catch (RuntimeException e) { 11791 // Not an integer; just do string match. 11792 if (strings == null) { 11793 strings = new ArrayList<String>(); 11794 } 11795 strings.add(name); 11796 all = false; 11797 } 11798 } 11799 } 11800 11801 int build(String[] args, int opti) { 11802 for (; opti<args.length; opti++) { 11803 String name = args[opti]; 11804 if ("--".equals(name)) { 11805 return opti+1; 11806 } 11807 build(name); 11808 } 11809 return opti; 11810 } 11811 11812 boolean match(Object object, ComponentName comp) { 11813 if (all) { 11814 return true; 11815 } 11816 if (components != null) { 11817 for (int i=0; i<components.size(); i++) { 11818 if (components.get(i).equals(comp)) { 11819 return true; 11820 } 11821 } 11822 } 11823 if (objects != null) { 11824 for (int i=0; i<objects.size(); i++) { 11825 if (System.identityHashCode(object) == objects.get(i)) { 11826 return true; 11827 } 11828 } 11829 } 11830 if (strings != null) { 11831 String flat = comp.flattenToString(); 11832 for (int i=0; i<strings.size(); i++) { 11833 if (flat.contains(strings.get(i))) { 11834 return true; 11835 } 11836 } 11837 } 11838 return false; 11839 } 11840 } 11841 11842 /** 11843 * There are three things that cmd can be: 11844 * - a flattened component name that matches an existing activity 11845 * - the cmd arg isn't the flattened component name of an existing activity: 11846 * dump all activity whose component contains the cmd as a substring 11847 * - A hex number of the ActivityRecord object instance. 11848 */ 11849 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11850 int opti, boolean dumpAll) { 11851 ArrayList<ActivityRecord> activities; 11852 11853 synchronized (this) { 11854 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11855 } 11856 11857 if (activities.size() <= 0) { 11858 return false; 11859 } 11860 11861 String[] newArgs = new String[args.length - opti]; 11862 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11863 11864 TaskRecord lastTask = null; 11865 boolean needSep = false; 11866 for (int i=activities.size()-1; i>=0; i--) { 11867 ActivityRecord r = activities.get(i); 11868 if (needSep) { 11869 pw.println(); 11870 } 11871 needSep = true; 11872 synchronized (this) { 11873 if (lastTask != r.task) { 11874 lastTask = r.task; 11875 pw.print("TASK "); pw.print(lastTask.affinity); 11876 pw.print(" id="); pw.println(lastTask.taskId); 11877 if (dumpAll) { 11878 lastTask.dump(pw, " "); 11879 } 11880 } 11881 } 11882 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11883 } 11884 return true; 11885 } 11886 11887 /** 11888 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11889 * there is a thread associated with the activity. 11890 */ 11891 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11892 final ActivityRecord r, String[] args, boolean dumpAll) { 11893 String innerPrefix = prefix + " "; 11894 synchronized (this) { 11895 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11896 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11897 pw.print(" pid="); 11898 if (r.app != null) pw.println(r.app.pid); 11899 else pw.println("(not running)"); 11900 if (dumpAll) { 11901 r.dump(pw, innerPrefix); 11902 } 11903 } 11904 if (r.app != null && r.app.thread != null) { 11905 // flush anything that is already in the PrintWriter since the thread is going 11906 // to write to the file descriptor directly 11907 pw.flush(); 11908 try { 11909 TransferPipe tp = new TransferPipe(); 11910 try { 11911 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11912 r.appToken, innerPrefix, args); 11913 tp.go(fd); 11914 } finally { 11915 tp.kill(); 11916 } 11917 } catch (IOException e) { 11918 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11919 } catch (RemoteException e) { 11920 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11921 } 11922 } 11923 } 11924 11925 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11926 int opti, boolean dumpAll, String dumpPackage) { 11927 boolean needSep = false; 11928 boolean onlyHistory = false; 11929 boolean printedAnything = false; 11930 11931 if ("history".equals(dumpPackage)) { 11932 if (opti < args.length && "-s".equals(args[opti])) { 11933 dumpAll = false; 11934 } 11935 onlyHistory = true; 11936 dumpPackage = null; 11937 } 11938 11939 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11940 if (!onlyHistory && dumpAll) { 11941 if (mRegisteredReceivers.size() > 0) { 11942 boolean printed = false; 11943 Iterator it = mRegisteredReceivers.values().iterator(); 11944 while (it.hasNext()) { 11945 ReceiverList r = (ReceiverList)it.next(); 11946 if (dumpPackage != null && (r.app == null || 11947 !dumpPackage.equals(r.app.info.packageName))) { 11948 continue; 11949 } 11950 if (!printed) { 11951 pw.println(" Registered Receivers:"); 11952 needSep = true; 11953 printed = true; 11954 printedAnything = true; 11955 } 11956 pw.print(" * "); pw.println(r); 11957 r.dump(pw, " "); 11958 } 11959 } 11960 11961 if (mReceiverResolver.dump(pw, needSep ? 11962 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11963 " ", dumpPackage, false)) { 11964 needSep = true; 11965 printedAnything = true; 11966 } 11967 } 11968 11969 for (BroadcastQueue q : mBroadcastQueues) { 11970 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11971 printedAnything |= needSep; 11972 } 11973 11974 needSep = true; 11975 11976 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11977 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11978 if (needSep) { 11979 pw.println(); 11980 } 11981 needSep = true; 11982 printedAnything = true; 11983 pw.print(" Sticky broadcasts for user "); 11984 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11985 StringBuilder sb = new StringBuilder(128); 11986 for (Map.Entry<String, ArrayList<Intent>> ent 11987 : mStickyBroadcasts.valueAt(user).entrySet()) { 11988 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11989 if (dumpAll) { 11990 pw.println(":"); 11991 ArrayList<Intent> intents = ent.getValue(); 11992 final int N = intents.size(); 11993 for (int i=0; i<N; i++) { 11994 sb.setLength(0); 11995 sb.append(" Intent: "); 11996 intents.get(i).toShortString(sb, false, true, false, false); 11997 pw.println(sb.toString()); 11998 Bundle bundle = intents.get(i).getExtras(); 11999 if (bundle != null) { 12000 pw.print(" "); 12001 pw.println(bundle.toString()); 12002 } 12003 } 12004 } else { 12005 pw.println(""); 12006 } 12007 } 12008 } 12009 } 12010 12011 if (!onlyHistory && dumpAll) { 12012 pw.println(); 12013 for (BroadcastQueue queue : mBroadcastQueues) { 12014 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12015 + queue.mBroadcastsScheduled); 12016 } 12017 pw.println(" mHandler:"); 12018 mHandler.dump(new PrintWriterPrinter(pw), " "); 12019 needSep = true; 12020 printedAnything = true; 12021 } 12022 12023 if (!printedAnything) { 12024 pw.println(" (nothing)"); 12025 } 12026 } 12027 12028 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12029 int opti, boolean dumpAll, String dumpPackage) { 12030 boolean needSep; 12031 boolean printedAnything = false; 12032 12033 ItemMatcher matcher = new ItemMatcher(); 12034 matcher.build(args, opti); 12035 12036 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12037 12038 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12039 printedAnything |= needSep; 12040 12041 if (mLaunchingProviders.size() > 0) { 12042 boolean printed = false; 12043 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12044 ContentProviderRecord r = mLaunchingProviders.get(i); 12045 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12046 continue; 12047 } 12048 if (!printed) { 12049 if (needSep) pw.println(); 12050 needSep = true; 12051 pw.println(" Launching content providers:"); 12052 printed = true; 12053 printedAnything = true; 12054 } 12055 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12056 pw.println(r); 12057 } 12058 } 12059 12060 if (mGrantedUriPermissions.size() > 0) { 12061 boolean printed = false; 12062 int dumpUid = -2; 12063 if (dumpPackage != null) { 12064 try { 12065 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12066 } catch (NameNotFoundException e) { 12067 dumpUid = -1; 12068 } 12069 } 12070 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12071 int uid = mGrantedUriPermissions.keyAt(i); 12072 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12073 continue; 12074 } 12075 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12076 if (!printed) { 12077 if (needSep) pw.println(); 12078 needSep = true; 12079 pw.println(" Granted Uri Permissions:"); 12080 printed = true; 12081 printedAnything = true; 12082 } 12083 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12084 for (UriPermission perm : perms.values()) { 12085 pw.print(" "); pw.println(perm); 12086 if (dumpAll) { 12087 perm.dump(pw, " "); 12088 } 12089 } 12090 } 12091 } 12092 12093 if (!printedAnything) { 12094 pw.println(" (nothing)"); 12095 } 12096 } 12097 12098 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12099 int opti, boolean dumpAll, String dumpPackage) { 12100 boolean printed = false; 12101 12102 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12103 12104 if (mIntentSenderRecords.size() > 0) { 12105 Iterator<WeakReference<PendingIntentRecord>> it 12106 = mIntentSenderRecords.values().iterator(); 12107 while (it.hasNext()) { 12108 WeakReference<PendingIntentRecord> ref = it.next(); 12109 PendingIntentRecord rec = ref != null ? ref.get(): null; 12110 if (dumpPackage != null && (rec == null 12111 || !dumpPackage.equals(rec.key.packageName))) { 12112 continue; 12113 } 12114 printed = true; 12115 if (rec != null) { 12116 pw.print(" * "); pw.println(rec); 12117 if (dumpAll) { 12118 rec.dump(pw, " "); 12119 } 12120 } else { 12121 pw.print(" * "); pw.println(ref); 12122 } 12123 } 12124 } 12125 12126 if (!printed) { 12127 pw.println(" (nothing)"); 12128 } 12129 } 12130 12131 private static final int dumpProcessList(PrintWriter pw, 12132 ActivityManagerService service, List list, 12133 String prefix, String normalLabel, String persistentLabel, 12134 String dumpPackage) { 12135 int numPers = 0; 12136 final int N = list.size()-1; 12137 for (int i=N; i>=0; i--) { 12138 ProcessRecord r = (ProcessRecord)list.get(i); 12139 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12140 continue; 12141 } 12142 pw.println(String.format("%s%s #%2d: %s", 12143 prefix, (r.persistent ? persistentLabel : normalLabel), 12144 i, r.toString())); 12145 if (r.persistent) { 12146 numPers++; 12147 } 12148 } 12149 return numPers; 12150 } 12151 12152 private static final boolean dumpProcessOomList(PrintWriter pw, 12153 ActivityManagerService service, List<ProcessRecord> origList, 12154 String prefix, String normalLabel, String persistentLabel, 12155 boolean inclDetails, String dumpPackage) { 12156 12157 ArrayList<Pair<ProcessRecord, Integer>> list 12158 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12159 for (int i=0; i<origList.size(); i++) { 12160 ProcessRecord r = origList.get(i); 12161 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12162 continue; 12163 } 12164 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12165 } 12166 12167 if (list.size() <= 0) { 12168 return false; 12169 } 12170 12171 Comparator<Pair<ProcessRecord, Integer>> comparator 12172 = new Comparator<Pair<ProcessRecord, Integer>>() { 12173 @Override 12174 public int compare(Pair<ProcessRecord, Integer> object1, 12175 Pair<ProcessRecord, Integer> object2) { 12176 if (object1.first.setAdj != object2.first.setAdj) { 12177 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12178 } 12179 if (object1.second.intValue() != object2.second.intValue()) { 12180 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12181 } 12182 return 0; 12183 } 12184 }; 12185 12186 Collections.sort(list, comparator); 12187 12188 final long curRealtime = SystemClock.elapsedRealtime(); 12189 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12190 final long curUptime = SystemClock.uptimeMillis(); 12191 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12192 12193 for (int i=list.size()-1; i>=0; i--) { 12194 ProcessRecord r = list.get(i).first; 12195 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12196 char schedGroup; 12197 switch (r.setSchedGroup) { 12198 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12199 schedGroup = 'B'; 12200 break; 12201 case Process.THREAD_GROUP_DEFAULT: 12202 schedGroup = 'F'; 12203 break; 12204 default: 12205 schedGroup = '?'; 12206 break; 12207 } 12208 char foreground; 12209 if (r.foregroundActivities) { 12210 foreground = 'A'; 12211 } else if (r.foregroundServices) { 12212 foreground = 'S'; 12213 } else { 12214 foreground = ' '; 12215 } 12216 String procState = ProcessList.makeProcStateString(r.curProcState); 12217 pw.print(prefix); 12218 pw.print(r.persistent ? persistentLabel : normalLabel); 12219 pw.print(" #"); 12220 int num = (origList.size()-1)-list.get(i).second; 12221 if (num < 10) pw.print(' '); 12222 pw.print(num); 12223 pw.print(": "); 12224 pw.print(oomAdj); 12225 pw.print(' '); 12226 pw.print(schedGroup); 12227 pw.print('/'); 12228 pw.print(foreground); 12229 pw.print('/'); 12230 pw.print(procState); 12231 pw.print(" trm:"); 12232 if (r.trimMemoryLevel < 10) pw.print(' '); 12233 pw.print(r.trimMemoryLevel); 12234 pw.print(' '); 12235 pw.print(r.toShortString()); 12236 pw.print(" ("); 12237 pw.print(r.adjType); 12238 pw.println(')'); 12239 if (r.adjSource != null || r.adjTarget != null) { 12240 pw.print(prefix); 12241 pw.print(" "); 12242 if (r.adjTarget instanceof ComponentName) { 12243 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12244 } else if (r.adjTarget != null) { 12245 pw.print(r.adjTarget.toString()); 12246 } else { 12247 pw.print("{null}"); 12248 } 12249 pw.print("<="); 12250 if (r.adjSource instanceof ProcessRecord) { 12251 pw.print("Proc{"); 12252 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12253 pw.println("}"); 12254 } else if (r.adjSource != null) { 12255 pw.println(r.adjSource.toString()); 12256 } else { 12257 pw.println("{null}"); 12258 } 12259 } 12260 if (inclDetails) { 12261 pw.print(prefix); 12262 pw.print(" "); 12263 pw.print("oom: max="); pw.print(r.maxAdj); 12264 pw.print(" curRaw="); pw.print(r.curRawAdj); 12265 pw.print(" setRaw="); pw.print(r.setRawAdj); 12266 pw.print(" cur="); pw.print(r.curAdj); 12267 pw.print(" set="); pw.println(r.setAdj); 12268 pw.print(prefix); 12269 pw.print(" "); 12270 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12271 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12272 pw.print(" lastPss="); pw.print(r.lastPss); 12273 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12274 pw.print(prefix); 12275 pw.print(" "); 12276 pw.print("keeping="); pw.print(r.keeping); 12277 pw.print(" cached="); pw.print(r.cached); 12278 pw.print(" empty="); pw.print(r.empty); 12279 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12280 12281 if (!r.keeping) { 12282 if (r.lastWakeTime != 0) { 12283 long wtime; 12284 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12285 synchronized (stats) { 12286 wtime = stats.getProcessWakeTime(r.info.uid, 12287 r.pid, curRealtime); 12288 } 12289 long timeUsed = wtime - r.lastWakeTime; 12290 pw.print(prefix); 12291 pw.print(" "); 12292 pw.print("keep awake over "); 12293 TimeUtils.formatDuration(realtimeSince, pw); 12294 pw.print(" used "); 12295 TimeUtils.formatDuration(timeUsed, pw); 12296 pw.print(" ("); 12297 pw.print((timeUsed*100)/realtimeSince); 12298 pw.println("%)"); 12299 } 12300 if (r.lastCpuTime != 0) { 12301 long timeUsed = r.curCpuTime - r.lastCpuTime; 12302 pw.print(prefix); 12303 pw.print(" "); 12304 pw.print("run cpu over "); 12305 TimeUtils.formatDuration(uptimeSince, pw); 12306 pw.print(" used "); 12307 TimeUtils.formatDuration(timeUsed, pw); 12308 pw.print(" ("); 12309 pw.print((timeUsed*100)/uptimeSince); 12310 pw.println("%)"); 12311 } 12312 } 12313 } 12314 } 12315 return true; 12316 } 12317 12318 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12319 ArrayList<ProcessRecord> procs; 12320 synchronized (this) { 12321 if (args != null && args.length > start 12322 && args[start].charAt(0) != '-') { 12323 procs = new ArrayList<ProcessRecord>(); 12324 int pid = -1; 12325 try { 12326 pid = Integer.parseInt(args[start]); 12327 } catch (NumberFormatException e) { 12328 } 12329 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12330 ProcessRecord proc = mLruProcesses.get(i); 12331 if (proc.pid == pid) { 12332 procs.add(proc); 12333 } else if (proc.processName.equals(args[start])) { 12334 procs.add(proc); 12335 } 12336 } 12337 if (procs.size() <= 0) { 12338 return null; 12339 } 12340 } else { 12341 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12342 } 12343 } 12344 return procs; 12345 } 12346 12347 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12348 PrintWriter pw, String[] args) { 12349 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12350 if (procs == null) { 12351 pw.println("No process found for: " + args[0]); 12352 return; 12353 } 12354 12355 long uptime = SystemClock.uptimeMillis(); 12356 long realtime = SystemClock.elapsedRealtime(); 12357 pw.println("Applications Graphics Acceleration Info:"); 12358 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12359 12360 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12361 ProcessRecord r = procs.get(i); 12362 if (r.thread != null) { 12363 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12364 pw.flush(); 12365 try { 12366 TransferPipe tp = new TransferPipe(); 12367 try { 12368 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12369 tp.go(fd); 12370 } finally { 12371 tp.kill(); 12372 } 12373 } catch (IOException e) { 12374 pw.println("Failure while dumping the app: " + r); 12375 pw.flush(); 12376 } catch (RemoteException e) { 12377 pw.println("Got a RemoteException while dumping the app " + r); 12378 pw.flush(); 12379 } 12380 } 12381 } 12382 } 12383 12384 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12385 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12386 if (procs == null) { 12387 pw.println("No process found for: " + args[0]); 12388 return; 12389 } 12390 12391 pw.println("Applications Database Info:"); 12392 12393 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12394 ProcessRecord r = procs.get(i); 12395 if (r.thread != null) { 12396 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12397 pw.flush(); 12398 try { 12399 TransferPipe tp = new TransferPipe(); 12400 try { 12401 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12402 tp.go(fd); 12403 } finally { 12404 tp.kill(); 12405 } 12406 } catch (IOException e) { 12407 pw.println("Failure while dumping the app: " + r); 12408 pw.flush(); 12409 } catch (RemoteException e) { 12410 pw.println("Got a RemoteException while dumping the app " + r); 12411 pw.flush(); 12412 } 12413 } 12414 } 12415 } 12416 12417 final static class MemItem { 12418 final boolean isProc; 12419 final String label; 12420 final String shortLabel; 12421 final long pss; 12422 final int id; 12423 final boolean hasActivities; 12424 ArrayList<MemItem> subitems; 12425 12426 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12427 boolean _hasActivities) { 12428 isProc = true; 12429 label = _label; 12430 shortLabel = _shortLabel; 12431 pss = _pss; 12432 id = _id; 12433 hasActivities = _hasActivities; 12434 } 12435 12436 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12437 isProc = false; 12438 label = _label; 12439 shortLabel = _shortLabel; 12440 pss = _pss; 12441 id = _id; 12442 hasActivities = false; 12443 } 12444 } 12445 12446 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12447 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12448 if (sort && !isCompact) { 12449 Collections.sort(items, new Comparator<MemItem>() { 12450 @Override 12451 public int compare(MemItem lhs, MemItem rhs) { 12452 if (lhs.pss < rhs.pss) { 12453 return 1; 12454 } else if (lhs.pss > rhs.pss) { 12455 return -1; 12456 } 12457 return 0; 12458 } 12459 }); 12460 } 12461 12462 for (int i=0; i<items.size(); i++) { 12463 MemItem mi = items.get(i); 12464 if (!isCompact) { 12465 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12466 } else if (mi.isProc) { 12467 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12468 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12469 pw.println(mi.hasActivities ? ",a" : ",e"); 12470 } else { 12471 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12472 pw.println(mi.pss); 12473 } 12474 if (mi.subitems != null) { 12475 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12476 true, isCompact); 12477 } 12478 } 12479 } 12480 12481 // These are in KB. 12482 static final long[] DUMP_MEM_BUCKETS = new long[] { 12483 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12484 120*1024, 160*1024, 200*1024, 12485 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12486 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12487 }; 12488 12489 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12490 boolean stackLike) { 12491 int start = label.lastIndexOf('.'); 12492 if (start >= 0) start++; 12493 else start = 0; 12494 int end = label.length(); 12495 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12496 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12497 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12498 out.append(bucket); 12499 out.append(stackLike ? "MB." : "MB "); 12500 out.append(label, start, end); 12501 return; 12502 } 12503 } 12504 out.append(memKB/1024); 12505 out.append(stackLike ? "MB." : "MB "); 12506 out.append(label, start, end); 12507 } 12508 12509 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12510 ProcessList.NATIVE_ADJ, 12511 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12512 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12513 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12514 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12515 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12516 }; 12517 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12518 "Native", 12519 "System", "Persistent", "Foreground", 12520 "Visible", "Perceptible", 12521 "Heavy Weight", "Backup", 12522 "A Services", "Home", 12523 "Previous", "B Services", "Cached" 12524 }; 12525 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12526 "native", 12527 "sys", "pers", "fore", 12528 "vis", "percept", 12529 "heavy", "backup", 12530 "servicea", "home", 12531 "prev", "serviceb", "cached" 12532 }; 12533 12534 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12535 long realtime, boolean isCheckinRequest, boolean isCompact) { 12536 if (isCheckinRequest || isCompact) { 12537 // short checkin version 12538 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12539 } else { 12540 pw.println("Applications Memory Usage (kB):"); 12541 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12542 } 12543 } 12544 12545 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12546 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12547 boolean dumpDetails = false; 12548 boolean dumpFullDetails = false; 12549 boolean dumpDalvik = false; 12550 boolean oomOnly = false; 12551 boolean isCompact = false; 12552 boolean localOnly = false; 12553 12554 int opti = 0; 12555 while (opti < args.length) { 12556 String opt = args[opti]; 12557 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12558 break; 12559 } 12560 opti++; 12561 if ("-a".equals(opt)) { 12562 dumpDetails = true; 12563 dumpFullDetails = true; 12564 dumpDalvik = true; 12565 } else if ("-d".equals(opt)) { 12566 dumpDalvik = true; 12567 } else if ("-c".equals(opt)) { 12568 isCompact = true; 12569 } else if ("--oom".equals(opt)) { 12570 oomOnly = true; 12571 } else if ("--local".equals(opt)) { 12572 localOnly = true; 12573 } else if ("-h".equals(opt)) { 12574 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12575 pw.println(" -a: include all available information for each process."); 12576 pw.println(" -d: include dalvik details when dumping process details."); 12577 pw.println(" -c: dump in a compact machine-parseable representation."); 12578 pw.println(" --oom: only show processes organized by oom adj."); 12579 pw.println(" --local: only collect details locally, don't call process."); 12580 pw.println("If [process] is specified it can be the name or "); 12581 pw.println("pid of a specific process to dump."); 12582 return; 12583 } else { 12584 pw.println("Unknown argument: " + opt + "; use -h for help"); 12585 } 12586 } 12587 12588 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12589 long uptime = SystemClock.uptimeMillis(); 12590 long realtime = SystemClock.elapsedRealtime(); 12591 final long[] tmpLong = new long[1]; 12592 12593 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12594 if (procs == null) { 12595 // No Java processes. Maybe they want to print a native process. 12596 if (args != null && args.length > opti 12597 && args[opti].charAt(0) != '-') { 12598 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12599 = new ArrayList<ProcessCpuTracker.Stats>(); 12600 updateCpuStatsNow(); 12601 int findPid = -1; 12602 try { 12603 findPid = Integer.parseInt(args[opti]); 12604 } catch (NumberFormatException e) { 12605 } 12606 synchronized (mProcessCpuThread) { 12607 final int N = mProcessCpuTracker.countStats(); 12608 for (int i=0; i<N; i++) { 12609 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12610 if (st.pid == findPid || (st.baseName != null 12611 && st.baseName.equals(args[opti]))) { 12612 nativeProcs.add(st); 12613 } 12614 } 12615 } 12616 if (nativeProcs.size() > 0) { 12617 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12618 isCompact); 12619 Debug.MemoryInfo mi = null; 12620 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12621 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12622 final int pid = r.pid; 12623 if (!isCheckinRequest && dumpDetails) { 12624 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12625 } 12626 if (mi == null) { 12627 mi = new Debug.MemoryInfo(); 12628 } 12629 if (dumpDetails || (!brief && !oomOnly)) { 12630 Debug.getMemoryInfo(pid, mi); 12631 } else { 12632 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12633 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12634 } 12635 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12636 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12637 if (isCheckinRequest) { 12638 pw.println(); 12639 } 12640 } 12641 return; 12642 } 12643 } 12644 pw.println("No process found for: " + args[opti]); 12645 return; 12646 } 12647 12648 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12649 dumpDetails = true; 12650 } 12651 12652 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12653 12654 String[] innerArgs = new String[args.length-opti]; 12655 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12656 12657 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12658 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12659 long nativePss=0, dalvikPss=0, otherPss=0; 12660 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12661 12662 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12663 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12664 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12665 12666 long totalPss = 0; 12667 long cachedPss = 0; 12668 12669 Debug.MemoryInfo mi = null; 12670 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12671 final ProcessRecord r = procs.get(i); 12672 final IApplicationThread thread; 12673 final int pid; 12674 final int oomAdj; 12675 final boolean hasActivities; 12676 synchronized (this) { 12677 thread = r.thread; 12678 pid = r.pid; 12679 oomAdj = r.getSetAdjWithServices(); 12680 hasActivities = r.activities.size() > 0; 12681 } 12682 if (thread != null) { 12683 if (!isCheckinRequest && dumpDetails) { 12684 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12685 } 12686 if (mi == null) { 12687 mi = new Debug.MemoryInfo(); 12688 } 12689 if (dumpDetails || (!brief && !oomOnly)) { 12690 Debug.getMemoryInfo(pid, mi); 12691 } else { 12692 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12693 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12694 } 12695 if (dumpDetails) { 12696 if (localOnly) { 12697 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12698 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12699 if (isCheckinRequest) { 12700 pw.println(); 12701 } 12702 } else { 12703 try { 12704 pw.flush(); 12705 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12706 dumpDalvik, innerArgs); 12707 } catch (RemoteException e) { 12708 if (!isCheckinRequest) { 12709 pw.println("Got RemoteException!"); 12710 pw.flush(); 12711 } 12712 } 12713 } 12714 } 12715 12716 final long myTotalPss = mi.getTotalPss(); 12717 final long myTotalUss = mi.getTotalUss(); 12718 12719 synchronized (this) { 12720 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12721 // Record this for posterity if the process has been stable. 12722 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12723 } 12724 } 12725 12726 if (!isCheckinRequest && mi != null) { 12727 totalPss += myTotalPss; 12728 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12729 (hasActivities ? " / activities)" : ")"), 12730 r.processName, myTotalPss, pid, hasActivities); 12731 procMems.add(pssItem); 12732 procMemsMap.put(pid, pssItem); 12733 12734 nativePss += mi.nativePss; 12735 dalvikPss += mi.dalvikPss; 12736 otherPss += mi.otherPss; 12737 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12738 long mem = mi.getOtherPss(j); 12739 miscPss[j] += mem; 12740 otherPss -= mem; 12741 } 12742 12743 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12744 cachedPss += myTotalPss; 12745 } 12746 12747 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12748 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12749 || oomIndex == (oomPss.length-1)) { 12750 oomPss[oomIndex] += myTotalPss; 12751 if (oomProcs[oomIndex] == null) { 12752 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12753 } 12754 oomProcs[oomIndex].add(pssItem); 12755 break; 12756 } 12757 } 12758 } 12759 } 12760 } 12761 12762 long nativeProcTotalPss = 0; 12763 12764 if (!isCheckinRequest && procs.size() > 1) { 12765 // If we are showing aggregations, also look for native processes to 12766 // include so that our aggregations are more accurate. 12767 updateCpuStatsNow(); 12768 synchronized (mProcessCpuThread) { 12769 final int N = mProcessCpuTracker.countStats(); 12770 for (int i=0; i<N; i++) { 12771 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12772 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12773 if (mi == null) { 12774 mi = new Debug.MemoryInfo(); 12775 } 12776 if (!brief && !oomOnly) { 12777 Debug.getMemoryInfo(st.pid, mi); 12778 } else { 12779 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12780 mi.nativePrivateDirty = (int)tmpLong[0]; 12781 } 12782 12783 final long myTotalPss = mi.getTotalPss(); 12784 totalPss += myTotalPss; 12785 nativeProcTotalPss += myTotalPss; 12786 12787 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12788 st.name, myTotalPss, st.pid, false); 12789 procMems.add(pssItem); 12790 12791 nativePss += mi.nativePss; 12792 dalvikPss += mi.dalvikPss; 12793 otherPss += mi.otherPss; 12794 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12795 long mem = mi.getOtherPss(j); 12796 miscPss[j] += mem; 12797 otherPss -= mem; 12798 } 12799 oomPss[0] += myTotalPss; 12800 if (oomProcs[0] == null) { 12801 oomProcs[0] = new ArrayList<MemItem>(); 12802 } 12803 oomProcs[0].add(pssItem); 12804 } 12805 } 12806 } 12807 12808 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12809 12810 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12811 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12812 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12813 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12814 String label = Debug.MemoryInfo.getOtherLabel(j); 12815 catMems.add(new MemItem(label, label, miscPss[j], j)); 12816 } 12817 12818 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12819 for (int j=0; j<oomPss.length; j++) { 12820 if (oomPss[j] != 0) { 12821 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12822 : DUMP_MEM_OOM_LABEL[j]; 12823 MemItem item = new MemItem(label, label, oomPss[j], 12824 DUMP_MEM_OOM_ADJ[j]); 12825 item.subitems = oomProcs[j]; 12826 oomMems.add(item); 12827 } 12828 } 12829 12830 if (!brief && !oomOnly && !isCompact) { 12831 pw.println(); 12832 pw.println("Total PSS by process:"); 12833 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12834 pw.println(); 12835 } 12836 if (!isCompact) { 12837 pw.println("Total PSS by OOM adjustment:"); 12838 } 12839 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12840 if (!brief && !oomOnly) { 12841 PrintWriter out = categoryPw != null ? categoryPw : pw; 12842 if (!isCompact) { 12843 out.println(); 12844 out.println("Total PSS by category:"); 12845 } 12846 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12847 } 12848 if (!isCompact) { 12849 pw.println(); 12850 } 12851 MemInfoReader memInfo = new MemInfoReader(); 12852 memInfo.readMemInfo(); 12853 if (nativeProcTotalPss > 0) { 12854 synchronized (this) { 12855 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 12856 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 12857 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 12858 nativeProcTotalPss); 12859 } 12860 } 12861 if (!brief) { 12862 if (!isCompact) { 12863 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12864 pw.print(" kB (status "); 12865 switch (mLastMemoryLevel) { 12866 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12867 pw.println("normal)"); 12868 break; 12869 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12870 pw.println("moderate)"); 12871 break; 12872 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12873 pw.println("low)"); 12874 break; 12875 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12876 pw.println("critical)"); 12877 break; 12878 default: 12879 pw.print(mLastMemoryLevel); 12880 pw.println(")"); 12881 break; 12882 } 12883 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12884 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12885 pw.print(cachedPss); pw.print(" cached pss + "); 12886 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12887 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12888 } else { 12889 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12890 pw.print(cachedPss + memInfo.getCachedSizeKb() 12891 + memInfo.getFreeSizeKb()); pw.print(","); 12892 pw.println(totalPss - cachedPss); 12893 } 12894 } 12895 if (!isCompact) { 12896 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12897 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12898 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12899 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12900 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12901 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12902 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12903 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12904 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12905 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12906 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12907 } 12908 if (!brief) { 12909 if (memInfo.getZramTotalSizeKb() != 0) { 12910 if (!isCompact) { 12911 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12912 pw.print(" kB physical used for "); 12913 pw.print(memInfo.getSwapTotalSizeKb() 12914 - memInfo.getSwapFreeSizeKb()); 12915 pw.print(" kB in swap ("); 12916 pw.print(memInfo.getSwapTotalSizeKb()); 12917 pw.println(" kB total swap)"); 12918 } else { 12919 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12920 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12921 pw.println(memInfo.getSwapFreeSizeKb()); 12922 } 12923 } 12924 final int[] SINGLE_LONG_FORMAT = new int[] { 12925 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12926 }; 12927 long[] longOut = new long[1]; 12928 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12929 SINGLE_LONG_FORMAT, null, longOut, null); 12930 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12931 longOut[0] = 0; 12932 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12933 SINGLE_LONG_FORMAT, null, longOut, null); 12934 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12935 longOut[0] = 0; 12936 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12937 SINGLE_LONG_FORMAT, null, longOut, null); 12938 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12939 longOut[0] = 0; 12940 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12941 SINGLE_LONG_FORMAT, null, longOut, null); 12942 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12943 if (!isCompact) { 12944 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12945 pw.print(" KSM: "); pw.print(sharing); 12946 pw.print(" kB saved from shared "); 12947 pw.print(shared); pw.println(" kB"); 12948 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12949 pw.print(voltile); pw.println(" kB volatile"); 12950 } 12951 pw.print(" Tuning: "); 12952 pw.print(ActivityManager.staticGetMemoryClass()); 12953 pw.print(" (large "); 12954 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12955 pw.print("), oom "); 12956 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12957 pw.print(" kB"); 12958 pw.print(", restore limit "); 12959 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12960 pw.print(" kB"); 12961 if (ActivityManager.isLowRamDeviceStatic()) { 12962 pw.print(" (low-ram)"); 12963 } 12964 if (ActivityManager.isHighEndGfx()) { 12965 pw.print(" (high-end-gfx)"); 12966 } 12967 pw.println(); 12968 } else { 12969 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12970 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12971 pw.println(voltile); 12972 pw.print("tuning,"); 12973 pw.print(ActivityManager.staticGetMemoryClass()); 12974 pw.print(','); 12975 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12976 pw.print(','); 12977 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12978 if (ActivityManager.isLowRamDeviceStatic()) { 12979 pw.print(",low-ram"); 12980 } 12981 if (ActivityManager.isHighEndGfx()) { 12982 pw.print(",high-end-gfx"); 12983 } 12984 pw.println(); 12985 } 12986 } 12987 } 12988 } 12989 12990 /** 12991 * Searches array of arguments for the specified string 12992 * @param args array of argument strings 12993 * @param value value to search for 12994 * @return true if the value is contained in the array 12995 */ 12996 private static boolean scanArgs(String[] args, String value) { 12997 if (args != null) { 12998 for (String arg : args) { 12999 if (value.equals(arg)) { 13000 return true; 13001 } 13002 } 13003 } 13004 return false; 13005 } 13006 13007 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13008 ContentProviderRecord cpr, boolean always) { 13009 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13010 13011 if (!inLaunching || always) { 13012 synchronized (cpr) { 13013 cpr.launchingApp = null; 13014 cpr.notifyAll(); 13015 } 13016 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13017 String names[] = cpr.info.authority.split(";"); 13018 for (int j = 0; j < names.length; j++) { 13019 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13020 } 13021 } 13022 13023 for (int i=0; i<cpr.connections.size(); i++) { 13024 ContentProviderConnection conn = cpr.connections.get(i); 13025 if (conn.waiting) { 13026 // If this connection is waiting for the provider, then we don't 13027 // need to mess with its process unless we are always removing 13028 // or for some reason the provider is not currently launching. 13029 if (inLaunching && !always) { 13030 continue; 13031 } 13032 } 13033 ProcessRecord capp = conn.client; 13034 conn.dead = true; 13035 if (conn.stableCount > 0) { 13036 if (!capp.persistent && capp.thread != null 13037 && capp.pid != 0 13038 && capp.pid != MY_PID) { 13039 killUnneededProcessLocked(capp, "depends on provider " 13040 + cpr.name.flattenToShortString() 13041 + " in dying proc " + (proc != null ? proc.processName : "??")); 13042 } 13043 } else if (capp.thread != null && conn.provider.provider != null) { 13044 try { 13045 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13046 } catch (RemoteException e) { 13047 } 13048 // In the protocol here, we don't expect the client to correctly 13049 // clean up this connection, we'll just remove it. 13050 cpr.connections.remove(i); 13051 conn.client.conProviders.remove(conn); 13052 } 13053 } 13054 13055 if (inLaunching && always) { 13056 mLaunchingProviders.remove(cpr); 13057 } 13058 return inLaunching; 13059 } 13060 13061 /** 13062 * Main code for cleaning up a process when it has gone away. This is 13063 * called both as a result of the process dying, or directly when stopping 13064 * a process when running in single process mode. 13065 */ 13066 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13067 boolean restarting, boolean allowRestart, int index) { 13068 if (index >= 0) { 13069 removeLruProcessLocked(app); 13070 ProcessList.remove(app.pid); 13071 } 13072 13073 mProcessesToGc.remove(app); 13074 mPendingPssProcesses.remove(app); 13075 13076 // Dismiss any open dialogs. 13077 if (app.crashDialog != null && !app.forceCrashReport) { 13078 app.crashDialog.dismiss(); 13079 app.crashDialog = null; 13080 } 13081 if (app.anrDialog != null) { 13082 app.anrDialog.dismiss(); 13083 app.anrDialog = null; 13084 } 13085 if (app.waitDialog != null) { 13086 app.waitDialog.dismiss(); 13087 app.waitDialog = null; 13088 } 13089 13090 app.crashing = false; 13091 app.notResponding = false; 13092 13093 app.resetPackageList(mProcessStats); 13094 app.unlinkDeathRecipient(); 13095 app.makeInactive(mProcessStats); 13096 app.forcingToForeground = null; 13097 updateProcessForegroundLocked(app, false, false); 13098 app.foregroundActivities = false; 13099 app.hasShownUi = false; 13100 app.treatLikeActivity = false; 13101 app.hasAboveClient = false; 13102 app.hasClientActivities = false; 13103 13104 mServices.killServicesLocked(app, allowRestart); 13105 13106 boolean restart = false; 13107 13108 // Remove published content providers. 13109 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13110 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13111 final boolean always = app.bad || !allowRestart; 13112 if (removeDyingProviderLocked(app, cpr, always) || always) { 13113 // We left the provider in the launching list, need to 13114 // restart it. 13115 restart = true; 13116 } 13117 13118 cpr.provider = null; 13119 cpr.proc = null; 13120 } 13121 app.pubProviders.clear(); 13122 13123 // Take care of any launching providers waiting for this process. 13124 if (checkAppInLaunchingProvidersLocked(app, false)) { 13125 restart = true; 13126 } 13127 13128 // Unregister from connected content providers. 13129 if (!app.conProviders.isEmpty()) { 13130 for (int i=0; i<app.conProviders.size(); i++) { 13131 ContentProviderConnection conn = app.conProviders.get(i); 13132 conn.provider.connections.remove(conn); 13133 } 13134 app.conProviders.clear(); 13135 } 13136 13137 // At this point there may be remaining entries in mLaunchingProviders 13138 // where we were the only one waiting, so they are no longer of use. 13139 // Look for these and clean up if found. 13140 // XXX Commented out for now. Trying to figure out a way to reproduce 13141 // the actual situation to identify what is actually going on. 13142 if (false) { 13143 for (int i=0; i<mLaunchingProviders.size(); i++) { 13144 ContentProviderRecord cpr = (ContentProviderRecord) 13145 mLaunchingProviders.get(i); 13146 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13147 synchronized (cpr) { 13148 cpr.launchingApp = null; 13149 cpr.notifyAll(); 13150 } 13151 } 13152 } 13153 } 13154 13155 skipCurrentReceiverLocked(app); 13156 13157 // Unregister any receivers. 13158 for (int i=app.receivers.size()-1; i>=0; i--) { 13159 removeReceiverLocked(app.receivers.valueAt(i)); 13160 } 13161 app.receivers.clear(); 13162 13163 // If the app is undergoing backup, tell the backup manager about it 13164 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13165 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13166 + mBackupTarget.appInfo + " died during backup"); 13167 try { 13168 IBackupManager bm = IBackupManager.Stub.asInterface( 13169 ServiceManager.getService(Context.BACKUP_SERVICE)); 13170 bm.agentDisconnected(app.info.packageName); 13171 } catch (RemoteException e) { 13172 // can't happen; backup manager is local 13173 } 13174 } 13175 13176 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13177 ProcessChangeItem item = mPendingProcessChanges.get(i); 13178 if (item.pid == app.pid) { 13179 mPendingProcessChanges.remove(i); 13180 mAvailProcessChanges.add(item); 13181 } 13182 } 13183 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13184 13185 // If the caller is restarting this app, then leave it in its 13186 // current lists and let the caller take care of it. 13187 if (restarting) { 13188 return; 13189 } 13190 13191 if (!app.persistent || app.isolated) { 13192 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13193 "Removing non-persistent process during cleanup: " + app); 13194 mProcessNames.remove(app.processName, app.uid); 13195 mIsolatedProcesses.remove(app.uid); 13196 if (mHeavyWeightProcess == app) { 13197 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13198 mHeavyWeightProcess.userId, 0)); 13199 mHeavyWeightProcess = null; 13200 } 13201 } else if (!app.removed) { 13202 // This app is persistent, so we need to keep its record around. 13203 // If it is not already on the pending app list, add it there 13204 // and start a new process for it. 13205 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13206 mPersistentStartingProcesses.add(app); 13207 restart = true; 13208 } 13209 } 13210 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13211 "Clean-up removing on hold: " + app); 13212 mProcessesOnHold.remove(app); 13213 13214 if (app == mHomeProcess) { 13215 mHomeProcess = null; 13216 } 13217 if (app == mPreviousProcess) { 13218 mPreviousProcess = null; 13219 } 13220 13221 if (restart && !app.isolated) { 13222 // We have components that still need to be running in the 13223 // process, so re-launch it. 13224 mProcessNames.put(app.processName, app.uid, app); 13225 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13226 } else if (app.pid > 0 && app.pid != MY_PID) { 13227 // Goodbye! 13228 boolean removed; 13229 synchronized (mPidsSelfLocked) { 13230 mPidsSelfLocked.remove(app.pid); 13231 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13232 } 13233 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 13234 app.processName, app.info.uid); 13235 if (app.isolated) { 13236 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13237 } 13238 app.setPid(0); 13239 } 13240 } 13241 13242 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13243 // Look through the content providers we are waiting to have launched, 13244 // and if any run in this process then either schedule a restart of 13245 // the process or kill the client waiting for it if this process has 13246 // gone bad. 13247 int NL = mLaunchingProviders.size(); 13248 boolean restart = false; 13249 for (int i=0; i<NL; i++) { 13250 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13251 if (cpr.launchingApp == app) { 13252 if (!alwaysBad && !app.bad) { 13253 restart = true; 13254 } else { 13255 removeDyingProviderLocked(app, cpr, true); 13256 // cpr should have been removed from mLaunchingProviders 13257 NL = mLaunchingProviders.size(); 13258 i--; 13259 } 13260 } 13261 } 13262 return restart; 13263 } 13264 13265 // ========================================================= 13266 // SERVICES 13267 // ========================================================= 13268 13269 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13270 int flags) { 13271 enforceNotIsolatedCaller("getServices"); 13272 synchronized (this) { 13273 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13274 } 13275 } 13276 13277 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13278 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13279 synchronized (this) { 13280 return mServices.getRunningServiceControlPanelLocked(name); 13281 } 13282 } 13283 13284 public ComponentName startService(IApplicationThread caller, Intent service, 13285 String resolvedType, int userId) { 13286 enforceNotIsolatedCaller("startService"); 13287 // Refuse possible leaked file descriptors 13288 if (service != null && service.hasFileDescriptors() == true) { 13289 throw new IllegalArgumentException("File descriptors passed in Intent"); 13290 } 13291 13292 if (DEBUG_SERVICE) 13293 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13294 synchronized(this) { 13295 final int callingPid = Binder.getCallingPid(); 13296 final int callingUid = Binder.getCallingUid(); 13297 final long origId = Binder.clearCallingIdentity(); 13298 ComponentName res = mServices.startServiceLocked(caller, service, 13299 resolvedType, callingPid, callingUid, userId); 13300 Binder.restoreCallingIdentity(origId); 13301 return res; 13302 } 13303 } 13304 13305 ComponentName startServiceInPackage(int uid, 13306 Intent service, String resolvedType, int userId) { 13307 synchronized(this) { 13308 if (DEBUG_SERVICE) 13309 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13310 final long origId = Binder.clearCallingIdentity(); 13311 ComponentName res = mServices.startServiceLocked(null, service, 13312 resolvedType, -1, uid, userId); 13313 Binder.restoreCallingIdentity(origId); 13314 return res; 13315 } 13316 } 13317 13318 public int stopService(IApplicationThread caller, Intent service, 13319 String resolvedType, int userId) { 13320 enforceNotIsolatedCaller("stopService"); 13321 // Refuse possible leaked file descriptors 13322 if (service != null && service.hasFileDescriptors() == true) { 13323 throw new IllegalArgumentException("File descriptors passed in Intent"); 13324 } 13325 13326 synchronized(this) { 13327 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13328 } 13329 } 13330 13331 public IBinder peekService(Intent service, String resolvedType) { 13332 enforceNotIsolatedCaller("peekService"); 13333 // Refuse possible leaked file descriptors 13334 if (service != null && service.hasFileDescriptors() == true) { 13335 throw new IllegalArgumentException("File descriptors passed in Intent"); 13336 } 13337 synchronized(this) { 13338 return mServices.peekServiceLocked(service, resolvedType); 13339 } 13340 } 13341 13342 public boolean stopServiceToken(ComponentName className, IBinder token, 13343 int startId) { 13344 synchronized(this) { 13345 return mServices.stopServiceTokenLocked(className, token, startId); 13346 } 13347 } 13348 13349 public void setServiceForeground(ComponentName className, IBinder token, 13350 int id, Notification notification, boolean removeNotification) { 13351 synchronized(this) { 13352 mServices.setServiceForegroundLocked(className, token, id, notification, 13353 removeNotification); 13354 } 13355 } 13356 13357 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13358 boolean requireFull, String name, String callerPackage) { 13359 final int callingUserId = UserHandle.getUserId(callingUid); 13360 if (callingUserId != userId) { 13361 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13362 if ((requireFull || checkComponentPermission( 13363 android.Manifest.permission.INTERACT_ACROSS_USERS, 13364 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13365 && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, 13366 callingPid, callingUid, -1, true) 13367 != PackageManager.PERMISSION_GRANTED) { 13368 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13369 // In this case, they would like to just execute as their 13370 // owner user instead of failing. 13371 userId = callingUserId; 13372 } else { 13373 StringBuilder builder = new StringBuilder(128); 13374 builder.append("Permission Denial: "); 13375 builder.append(name); 13376 if (callerPackage != null) { 13377 builder.append(" from "); 13378 builder.append(callerPackage); 13379 } 13380 builder.append(" asks to run as user "); 13381 builder.append(userId); 13382 builder.append(" but is calling from user "); 13383 builder.append(UserHandle.getUserId(callingUid)); 13384 builder.append("; this requires "); 13385 builder.append(INTERACT_ACROSS_USERS_FULL); 13386 if (!requireFull) { 13387 builder.append(" or "); 13388 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13389 } 13390 String msg = builder.toString(); 13391 Slog.w(TAG, msg); 13392 throw new SecurityException(msg); 13393 } 13394 } 13395 } 13396 if (userId == UserHandle.USER_CURRENT 13397 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13398 // Note that we may be accessing this outside of a lock... 13399 // shouldn't be a big deal, if this is being called outside 13400 // of a locked context there is intrinsically a race with 13401 // the value the caller will receive and someone else changing it. 13402 userId = mCurrentUserId; 13403 } 13404 if (!allowAll && userId < 0) { 13405 throw new IllegalArgumentException( 13406 "Call does not support special user #" + userId); 13407 } 13408 } 13409 return userId; 13410 } 13411 13412 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13413 String className, int flags) { 13414 boolean result = false; 13415 // For apps that don't have pre-defined UIDs, check for permission 13416 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13417 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13418 if (ActivityManager.checkUidPermission( 13419 android.Manifest.permission.INTERACT_ACROSS_USERS, 13420 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13421 ComponentName comp = new ComponentName(aInfo.packageName, className); 13422 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13423 + " requests FLAG_SINGLE_USER, but app does not hold " 13424 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13425 Slog.w(TAG, msg); 13426 throw new SecurityException(msg); 13427 } 13428 // Permission passed 13429 result = true; 13430 } 13431 } else if ("system".equals(componentProcessName)) { 13432 result = true; 13433 } else { 13434 // App with pre-defined UID, check if it's a persistent app 13435 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13436 } 13437 if (DEBUG_MU) { 13438 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13439 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13440 } 13441 return result; 13442 } 13443 13444 /** 13445 * Checks to see if the caller is in the same app as the singleton 13446 * component, or the component is in a special app. It allows special apps 13447 * to export singleton components but prevents exporting singleton 13448 * components for regular apps. 13449 */ 13450 boolean isValidSingletonCall(int callingUid, int componentUid) { 13451 int componentAppId = UserHandle.getAppId(componentUid); 13452 return UserHandle.isSameApp(callingUid, componentUid) 13453 || componentAppId == Process.SYSTEM_UID 13454 || componentAppId == Process.PHONE_UID 13455 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13456 == PackageManager.PERMISSION_GRANTED; 13457 } 13458 13459 public int bindService(IApplicationThread caller, IBinder token, 13460 Intent service, String resolvedType, 13461 IServiceConnection connection, int flags, int userId) { 13462 enforceNotIsolatedCaller("bindService"); 13463 // Refuse possible leaked file descriptors 13464 if (service != null && service.hasFileDescriptors() == true) { 13465 throw new IllegalArgumentException("File descriptors passed in Intent"); 13466 } 13467 13468 synchronized(this) { 13469 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13470 connection, flags, userId); 13471 } 13472 } 13473 13474 public boolean unbindService(IServiceConnection connection) { 13475 synchronized (this) { 13476 return mServices.unbindServiceLocked(connection); 13477 } 13478 } 13479 13480 public void publishService(IBinder token, Intent intent, IBinder service) { 13481 // Refuse possible leaked file descriptors 13482 if (intent != null && intent.hasFileDescriptors() == true) { 13483 throw new IllegalArgumentException("File descriptors passed in Intent"); 13484 } 13485 13486 synchronized(this) { 13487 if (!(token instanceof ServiceRecord)) { 13488 throw new IllegalArgumentException("Invalid service token"); 13489 } 13490 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13491 } 13492 } 13493 13494 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13495 // Refuse possible leaked file descriptors 13496 if (intent != null && intent.hasFileDescriptors() == true) { 13497 throw new IllegalArgumentException("File descriptors passed in Intent"); 13498 } 13499 13500 synchronized(this) { 13501 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13502 } 13503 } 13504 13505 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13506 synchronized(this) { 13507 if (!(token instanceof ServiceRecord)) { 13508 throw new IllegalArgumentException("Invalid service token"); 13509 } 13510 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13511 } 13512 } 13513 13514 // ========================================================= 13515 // BACKUP AND RESTORE 13516 // ========================================================= 13517 13518 // Cause the target app to be launched if necessary and its backup agent 13519 // instantiated. The backup agent will invoke backupAgentCreated() on the 13520 // activity manager to announce its creation. 13521 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13522 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13523 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13524 13525 synchronized(this) { 13526 // !!! TODO: currently no check here that we're already bound 13527 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13528 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13529 synchronized (stats) { 13530 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13531 } 13532 13533 // Backup agent is now in use, its package can't be stopped. 13534 try { 13535 AppGlobals.getPackageManager().setPackageStoppedState( 13536 app.packageName, false, UserHandle.getUserId(app.uid)); 13537 } catch (RemoteException e) { 13538 } catch (IllegalArgumentException e) { 13539 Slog.w(TAG, "Failed trying to unstop package " 13540 + app.packageName + ": " + e); 13541 } 13542 13543 BackupRecord r = new BackupRecord(ss, app, backupMode); 13544 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13545 ? new ComponentName(app.packageName, app.backupAgentName) 13546 : new ComponentName("android", "FullBackupAgent"); 13547 // startProcessLocked() returns existing proc's record if it's already running 13548 ProcessRecord proc = startProcessLocked(app.processName, app, 13549 false, 0, "backup", hostingName, false, false, false); 13550 if (proc == null) { 13551 Slog.e(TAG, "Unable to start backup agent process " + r); 13552 return false; 13553 } 13554 13555 r.app = proc; 13556 mBackupTarget = r; 13557 mBackupAppName = app.packageName; 13558 13559 // Try not to kill the process during backup 13560 updateOomAdjLocked(proc); 13561 13562 // If the process is already attached, schedule the creation of the backup agent now. 13563 // If it is not yet live, this will be done when it attaches to the framework. 13564 if (proc.thread != null) { 13565 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13566 try { 13567 proc.thread.scheduleCreateBackupAgent(app, 13568 compatibilityInfoForPackageLocked(app), backupMode); 13569 } catch (RemoteException e) { 13570 // Will time out on the backup manager side 13571 } 13572 } else { 13573 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13574 } 13575 // Invariants: at this point, the target app process exists and the application 13576 // is either already running or in the process of coming up. mBackupTarget and 13577 // mBackupAppName describe the app, so that when it binds back to the AM we 13578 // know that it's scheduled for a backup-agent operation. 13579 } 13580 13581 return true; 13582 } 13583 13584 @Override 13585 public void clearPendingBackup() { 13586 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13587 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13588 13589 synchronized (this) { 13590 mBackupTarget = null; 13591 mBackupAppName = null; 13592 } 13593 } 13594 13595 // A backup agent has just come up 13596 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13597 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13598 + " = " + agent); 13599 13600 synchronized(this) { 13601 if (!agentPackageName.equals(mBackupAppName)) { 13602 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13603 return; 13604 } 13605 } 13606 13607 long oldIdent = Binder.clearCallingIdentity(); 13608 try { 13609 IBackupManager bm = IBackupManager.Stub.asInterface( 13610 ServiceManager.getService(Context.BACKUP_SERVICE)); 13611 bm.agentConnected(agentPackageName, agent); 13612 } catch (RemoteException e) { 13613 // can't happen; the backup manager service is local 13614 } catch (Exception e) { 13615 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13616 e.printStackTrace(); 13617 } finally { 13618 Binder.restoreCallingIdentity(oldIdent); 13619 } 13620 } 13621 13622 // done with this agent 13623 public void unbindBackupAgent(ApplicationInfo appInfo) { 13624 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13625 if (appInfo == null) { 13626 Slog.w(TAG, "unbind backup agent for null app"); 13627 return; 13628 } 13629 13630 synchronized(this) { 13631 try { 13632 if (mBackupAppName == null) { 13633 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13634 return; 13635 } 13636 13637 if (!mBackupAppName.equals(appInfo.packageName)) { 13638 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13639 return; 13640 } 13641 13642 // Not backing this app up any more; reset its OOM adjustment 13643 final ProcessRecord proc = mBackupTarget.app; 13644 updateOomAdjLocked(proc); 13645 13646 // If the app crashed during backup, 'thread' will be null here 13647 if (proc.thread != null) { 13648 try { 13649 proc.thread.scheduleDestroyBackupAgent(appInfo, 13650 compatibilityInfoForPackageLocked(appInfo)); 13651 } catch (Exception e) { 13652 Slog.e(TAG, "Exception when unbinding backup agent:"); 13653 e.printStackTrace(); 13654 } 13655 } 13656 } finally { 13657 mBackupTarget = null; 13658 mBackupAppName = null; 13659 } 13660 } 13661 } 13662 // ========================================================= 13663 // BROADCASTS 13664 // ========================================================= 13665 13666 private final List getStickiesLocked(String action, IntentFilter filter, 13667 List cur, int userId) { 13668 final ContentResolver resolver = mContext.getContentResolver(); 13669 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13670 if (stickies == null) { 13671 return cur; 13672 } 13673 final ArrayList<Intent> list = stickies.get(action); 13674 if (list == null) { 13675 return cur; 13676 } 13677 int N = list.size(); 13678 for (int i=0; i<N; i++) { 13679 Intent intent = list.get(i); 13680 if (filter.match(resolver, intent, true, TAG) >= 0) { 13681 if (cur == null) { 13682 cur = new ArrayList<Intent>(); 13683 } 13684 cur.add(intent); 13685 } 13686 } 13687 return cur; 13688 } 13689 13690 boolean isPendingBroadcastProcessLocked(int pid) { 13691 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13692 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13693 } 13694 13695 void skipPendingBroadcastLocked(int pid) { 13696 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13697 for (BroadcastQueue queue : mBroadcastQueues) { 13698 queue.skipPendingBroadcastLocked(pid); 13699 } 13700 } 13701 13702 // The app just attached; send any pending broadcasts that it should receive 13703 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13704 boolean didSomething = false; 13705 for (BroadcastQueue queue : mBroadcastQueues) { 13706 didSomething |= queue.sendPendingBroadcastsLocked(app); 13707 } 13708 return didSomething; 13709 } 13710 13711 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13712 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13713 enforceNotIsolatedCaller("registerReceiver"); 13714 int callingUid; 13715 int callingPid; 13716 synchronized(this) { 13717 ProcessRecord callerApp = null; 13718 if (caller != null) { 13719 callerApp = getRecordForAppLocked(caller); 13720 if (callerApp == null) { 13721 throw new SecurityException( 13722 "Unable to find app for caller " + caller 13723 + " (pid=" + Binder.getCallingPid() 13724 + ") when registering receiver " + receiver); 13725 } 13726 if (callerApp.info.uid != Process.SYSTEM_UID && 13727 !callerApp.pkgList.containsKey(callerPackage) && 13728 !"android".equals(callerPackage)) { 13729 throw new SecurityException("Given caller package " + callerPackage 13730 + " is not running in process " + callerApp); 13731 } 13732 callingUid = callerApp.info.uid; 13733 callingPid = callerApp.pid; 13734 } else { 13735 callerPackage = null; 13736 callingUid = Binder.getCallingUid(); 13737 callingPid = Binder.getCallingPid(); 13738 } 13739 13740 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13741 true, true, "registerReceiver", callerPackage); 13742 13743 List allSticky = null; 13744 13745 // Look for any matching sticky broadcasts... 13746 Iterator actions = filter.actionsIterator(); 13747 if (actions != null) { 13748 while (actions.hasNext()) { 13749 String action = (String)actions.next(); 13750 allSticky = getStickiesLocked(action, filter, allSticky, 13751 UserHandle.USER_ALL); 13752 allSticky = getStickiesLocked(action, filter, allSticky, 13753 UserHandle.getUserId(callingUid)); 13754 } 13755 } else { 13756 allSticky = getStickiesLocked(null, filter, allSticky, 13757 UserHandle.USER_ALL); 13758 allSticky = getStickiesLocked(null, filter, allSticky, 13759 UserHandle.getUserId(callingUid)); 13760 } 13761 13762 // The first sticky in the list is returned directly back to 13763 // the client. 13764 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13765 13766 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13767 + ": " + sticky); 13768 13769 if (receiver == null) { 13770 return sticky; 13771 } 13772 13773 ReceiverList rl 13774 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13775 if (rl == null) { 13776 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13777 userId, receiver); 13778 if (rl.app != null) { 13779 rl.app.receivers.add(rl); 13780 } else { 13781 try { 13782 receiver.asBinder().linkToDeath(rl, 0); 13783 } catch (RemoteException e) { 13784 return sticky; 13785 } 13786 rl.linkedToDeath = true; 13787 } 13788 mRegisteredReceivers.put(receiver.asBinder(), rl); 13789 } else if (rl.uid != callingUid) { 13790 throw new IllegalArgumentException( 13791 "Receiver requested to register for uid " + callingUid 13792 + " was previously registered for uid " + rl.uid); 13793 } else if (rl.pid != callingPid) { 13794 throw new IllegalArgumentException( 13795 "Receiver requested to register for pid " + callingPid 13796 + " was previously registered for pid " + rl.pid); 13797 } else if (rl.userId != userId) { 13798 throw new IllegalArgumentException( 13799 "Receiver requested to register for user " + userId 13800 + " was previously registered for user " + rl.userId); 13801 } 13802 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13803 permission, callingUid, userId); 13804 rl.add(bf); 13805 if (!bf.debugCheck()) { 13806 Slog.w(TAG, "==> For Dynamic broadast"); 13807 } 13808 mReceiverResolver.addFilter(bf); 13809 13810 // Enqueue broadcasts for all existing stickies that match 13811 // this filter. 13812 if (allSticky != null) { 13813 ArrayList receivers = new ArrayList(); 13814 receivers.add(bf); 13815 13816 int N = allSticky.size(); 13817 for (int i=0; i<N; i++) { 13818 Intent intent = (Intent)allSticky.get(i); 13819 BroadcastQueue queue = broadcastQueueForIntent(intent); 13820 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13821 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13822 null, null, false, true, true, -1); 13823 queue.enqueueParallelBroadcastLocked(r); 13824 queue.scheduleBroadcastsLocked(); 13825 } 13826 } 13827 13828 return sticky; 13829 } 13830 } 13831 13832 public void unregisterReceiver(IIntentReceiver receiver) { 13833 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13834 13835 final long origId = Binder.clearCallingIdentity(); 13836 try { 13837 boolean doTrim = false; 13838 13839 synchronized(this) { 13840 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13841 if (rl != null) { 13842 if (rl.curBroadcast != null) { 13843 BroadcastRecord r = rl.curBroadcast; 13844 final boolean doNext = finishReceiverLocked( 13845 receiver.asBinder(), r.resultCode, r.resultData, 13846 r.resultExtras, r.resultAbort); 13847 if (doNext) { 13848 doTrim = true; 13849 r.queue.processNextBroadcast(false); 13850 } 13851 } 13852 13853 if (rl.app != null) { 13854 rl.app.receivers.remove(rl); 13855 } 13856 removeReceiverLocked(rl); 13857 if (rl.linkedToDeath) { 13858 rl.linkedToDeath = false; 13859 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13860 } 13861 } 13862 } 13863 13864 // If we actually concluded any broadcasts, we might now be able 13865 // to trim the recipients' apps from our working set 13866 if (doTrim) { 13867 trimApplications(); 13868 return; 13869 } 13870 13871 } finally { 13872 Binder.restoreCallingIdentity(origId); 13873 } 13874 } 13875 13876 void removeReceiverLocked(ReceiverList rl) { 13877 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13878 int N = rl.size(); 13879 for (int i=0; i<N; i++) { 13880 mReceiverResolver.removeFilter(rl.get(i)); 13881 } 13882 } 13883 13884 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13885 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13886 ProcessRecord r = mLruProcesses.get(i); 13887 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13888 try { 13889 r.thread.dispatchPackageBroadcast(cmd, packages); 13890 } catch (RemoteException ex) { 13891 } 13892 } 13893 } 13894 } 13895 13896 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13897 int[] users) { 13898 List<ResolveInfo> receivers = null; 13899 try { 13900 HashSet<ComponentName> singleUserReceivers = null; 13901 boolean scannedFirstReceivers = false; 13902 for (int user : users) { 13903 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13904 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13905 if (user != 0 && newReceivers != null) { 13906 // If this is not the primary user, we need to check for 13907 // any receivers that should be filtered out. 13908 for (int i=0; i<newReceivers.size(); i++) { 13909 ResolveInfo ri = newReceivers.get(i); 13910 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13911 newReceivers.remove(i); 13912 i--; 13913 } 13914 } 13915 } 13916 if (newReceivers != null && newReceivers.size() == 0) { 13917 newReceivers = null; 13918 } 13919 if (receivers == null) { 13920 receivers = newReceivers; 13921 } else if (newReceivers != null) { 13922 // We need to concatenate the additional receivers 13923 // found with what we have do far. This would be easy, 13924 // but we also need to de-dup any receivers that are 13925 // singleUser. 13926 if (!scannedFirstReceivers) { 13927 // Collect any single user receivers we had already retrieved. 13928 scannedFirstReceivers = true; 13929 for (int i=0; i<receivers.size(); i++) { 13930 ResolveInfo ri = receivers.get(i); 13931 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13932 ComponentName cn = new ComponentName( 13933 ri.activityInfo.packageName, ri.activityInfo.name); 13934 if (singleUserReceivers == null) { 13935 singleUserReceivers = new HashSet<ComponentName>(); 13936 } 13937 singleUserReceivers.add(cn); 13938 } 13939 } 13940 } 13941 // Add the new results to the existing results, tracking 13942 // and de-dupping single user receivers. 13943 for (int i=0; i<newReceivers.size(); i++) { 13944 ResolveInfo ri = newReceivers.get(i); 13945 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13946 ComponentName cn = new ComponentName( 13947 ri.activityInfo.packageName, ri.activityInfo.name); 13948 if (singleUserReceivers == null) { 13949 singleUserReceivers = new HashSet<ComponentName>(); 13950 } 13951 if (!singleUserReceivers.contains(cn)) { 13952 singleUserReceivers.add(cn); 13953 receivers.add(ri); 13954 } 13955 } else { 13956 receivers.add(ri); 13957 } 13958 } 13959 } 13960 } 13961 } catch (RemoteException ex) { 13962 // pm is in same process, this will never happen. 13963 } 13964 return receivers; 13965 } 13966 13967 private final int broadcastIntentLocked(ProcessRecord callerApp, 13968 String callerPackage, Intent intent, String resolvedType, 13969 IIntentReceiver resultTo, int resultCode, String resultData, 13970 Bundle map, String requiredPermission, int appOp, 13971 boolean ordered, boolean sticky, int callingPid, int callingUid, 13972 int userId) { 13973 intent = new Intent(intent); 13974 13975 // By default broadcasts do not go to stopped apps. 13976 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13977 13978 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13979 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13980 + " ordered=" + ordered + " userid=" + userId); 13981 if ((resultTo != null) && !ordered) { 13982 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13983 } 13984 13985 userId = handleIncomingUser(callingPid, callingUid, userId, 13986 true, false, "broadcast", callerPackage); 13987 13988 // Make sure that the user who is receiving this broadcast is started. 13989 // If not, we will just skip it. 13990 13991 13992 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13993 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13994 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13995 Slog.w(TAG, "Skipping broadcast of " + intent 13996 + ": user " + userId + " is stopped"); 13997 return ActivityManager.BROADCAST_SUCCESS; 13998 } 13999 } 14000 14001 /* 14002 * Prevent non-system code (defined here to be non-persistent 14003 * processes) from sending protected broadcasts. 14004 */ 14005 int callingAppId = UserHandle.getAppId(callingUid); 14006 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14007 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14008 || callingAppId == Process.NFC_UID || callingUid == 0) { 14009 // Always okay. 14010 } else if (callerApp == null || !callerApp.persistent) { 14011 try { 14012 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14013 intent.getAction())) { 14014 String msg = "Permission Denial: not allowed to send broadcast " 14015 + intent.getAction() + " from pid=" 14016 + callingPid + ", uid=" + callingUid; 14017 Slog.w(TAG, msg); 14018 throw new SecurityException(msg); 14019 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14020 // Special case for compatibility: we don't want apps to send this, 14021 // but historically it has not been protected and apps may be using it 14022 // to poke their own app widget. So, instead of making it protected, 14023 // just limit it to the caller. 14024 if (callerApp == null) { 14025 String msg = "Permission Denial: not allowed to send broadcast " 14026 + intent.getAction() + " from unknown caller."; 14027 Slog.w(TAG, msg); 14028 throw new SecurityException(msg); 14029 } else if (intent.getComponent() != null) { 14030 // They are good enough to send to an explicit component... verify 14031 // it is being sent to the calling app. 14032 if (!intent.getComponent().getPackageName().equals( 14033 callerApp.info.packageName)) { 14034 String msg = "Permission Denial: not allowed to send broadcast " 14035 + intent.getAction() + " to " 14036 + intent.getComponent().getPackageName() + " from " 14037 + callerApp.info.packageName; 14038 Slog.w(TAG, msg); 14039 throw new SecurityException(msg); 14040 } 14041 } else { 14042 // Limit broadcast to their own package. 14043 intent.setPackage(callerApp.info.packageName); 14044 } 14045 } 14046 } catch (RemoteException e) { 14047 Slog.w(TAG, "Remote exception", e); 14048 return ActivityManager.BROADCAST_SUCCESS; 14049 } 14050 } 14051 14052 // Handle special intents: if this broadcast is from the package 14053 // manager about a package being removed, we need to remove all of 14054 // its activities from the history stack. 14055 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14056 intent.getAction()); 14057 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14058 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14059 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14060 || uidRemoved) { 14061 if (checkComponentPermission( 14062 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14063 callingPid, callingUid, -1, true) 14064 == PackageManager.PERMISSION_GRANTED) { 14065 if (uidRemoved) { 14066 final Bundle intentExtras = intent.getExtras(); 14067 final int uid = intentExtras != null 14068 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14069 if (uid >= 0) { 14070 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14071 synchronized (bs) { 14072 bs.removeUidStatsLocked(uid); 14073 } 14074 mAppOpsService.uidRemoved(uid); 14075 } 14076 } else { 14077 // If resources are unavailable just force stop all 14078 // those packages and flush the attribute cache as well. 14079 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14080 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14081 if (list != null && (list.length > 0)) { 14082 for (String pkg : list) { 14083 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14084 "storage unmount"); 14085 } 14086 sendPackageBroadcastLocked( 14087 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14088 } 14089 } else { 14090 Uri data = intent.getData(); 14091 String ssp; 14092 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14093 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14094 intent.getAction()); 14095 boolean fullUninstall = removed && 14096 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14097 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14098 forceStopPackageLocked(ssp, UserHandle.getAppId( 14099 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14100 false, fullUninstall, userId, 14101 removed ? "pkg removed" : "pkg changed"); 14102 } 14103 if (removed) { 14104 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14105 new String[] {ssp}, userId); 14106 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14107 mAppOpsService.packageRemoved( 14108 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14109 14110 // Remove all permissions granted from/to this package 14111 removeUriPermissionsForPackageLocked(ssp, userId, true); 14112 } 14113 } 14114 } 14115 } 14116 } 14117 } else { 14118 String msg = "Permission Denial: " + intent.getAction() 14119 + " broadcast from " + callerPackage + " (pid=" + callingPid 14120 + ", uid=" + callingUid + ")" 14121 + " requires " 14122 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14123 Slog.w(TAG, msg); 14124 throw new SecurityException(msg); 14125 } 14126 14127 // Special case for adding a package: by default turn on compatibility 14128 // mode. 14129 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14130 Uri data = intent.getData(); 14131 String ssp; 14132 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14133 mCompatModePackages.handlePackageAddedLocked(ssp, 14134 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14135 } 14136 } 14137 14138 /* 14139 * If this is the time zone changed action, queue up a message that will reset the timezone 14140 * of all currently running processes. This message will get queued up before the broadcast 14141 * happens. 14142 */ 14143 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14144 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14145 } 14146 14147 /* 14148 * If the user set the time, let all running processes know. 14149 */ 14150 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14151 final int is24Hour = intent.getBooleanExtra( 14152 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14153 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14154 } 14155 14156 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14157 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14158 } 14159 14160 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14161 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14162 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14163 } 14164 14165 // Add to the sticky list if requested. 14166 if (sticky) { 14167 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14168 callingPid, callingUid) 14169 != PackageManager.PERMISSION_GRANTED) { 14170 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14171 + callingPid + ", uid=" + callingUid 14172 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14173 Slog.w(TAG, msg); 14174 throw new SecurityException(msg); 14175 } 14176 if (requiredPermission != null) { 14177 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14178 + " and enforce permission " + requiredPermission); 14179 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14180 } 14181 if (intent.getComponent() != null) { 14182 throw new SecurityException( 14183 "Sticky broadcasts can't target a specific component"); 14184 } 14185 // We use userId directly here, since the "all" target is maintained 14186 // as a separate set of sticky broadcasts. 14187 if (userId != UserHandle.USER_ALL) { 14188 // But first, if this is not a broadcast to all users, then 14189 // make sure it doesn't conflict with an existing broadcast to 14190 // all users. 14191 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14192 UserHandle.USER_ALL); 14193 if (stickies != null) { 14194 ArrayList<Intent> list = stickies.get(intent.getAction()); 14195 if (list != null) { 14196 int N = list.size(); 14197 int i; 14198 for (i=0; i<N; i++) { 14199 if (intent.filterEquals(list.get(i))) { 14200 throw new IllegalArgumentException( 14201 "Sticky broadcast " + intent + " for user " 14202 + userId + " conflicts with existing global broadcast"); 14203 } 14204 } 14205 } 14206 } 14207 } 14208 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14209 if (stickies == null) { 14210 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14211 mStickyBroadcasts.put(userId, stickies); 14212 } 14213 ArrayList<Intent> list = stickies.get(intent.getAction()); 14214 if (list == null) { 14215 list = new ArrayList<Intent>(); 14216 stickies.put(intent.getAction(), list); 14217 } 14218 int N = list.size(); 14219 int i; 14220 for (i=0; i<N; i++) { 14221 if (intent.filterEquals(list.get(i))) { 14222 // This sticky already exists, replace it. 14223 list.set(i, new Intent(intent)); 14224 break; 14225 } 14226 } 14227 if (i >= N) { 14228 list.add(new Intent(intent)); 14229 } 14230 } 14231 14232 int[] users; 14233 if (userId == UserHandle.USER_ALL) { 14234 // Caller wants broadcast to go to all started users. 14235 users = mStartedUserArray; 14236 } else { 14237 // Caller wants broadcast to go to one specific user. 14238 users = new int[] {userId}; 14239 } 14240 14241 // Figure out who all will receive this broadcast. 14242 List receivers = null; 14243 List<BroadcastFilter> registeredReceivers = null; 14244 // Need to resolve the intent to interested receivers... 14245 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14246 == 0) { 14247 receivers = collectReceiverComponents(intent, resolvedType, users); 14248 } 14249 if (intent.getComponent() == null) { 14250 registeredReceivers = mReceiverResolver.queryIntent(intent, 14251 resolvedType, false, userId); 14252 } 14253 14254 final boolean replacePending = 14255 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14256 14257 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14258 + " replacePending=" + replacePending); 14259 14260 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14261 if (!ordered && NR > 0) { 14262 // If we are not serializing this broadcast, then send the 14263 // registered receivers separately so they don't wait for the 14264 // components to be launched. 14265 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14266 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14267 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14268 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14269 ordered, sticky, false, userId); 14270 if (DEBUG_BROADCAST) Slog.v( 14271 TAG, "Enqueueing parallel broadcast " + r); 14272 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14273 if (!replaced) { 14274 queue.enqueueParallelBroadcastLocked(r); 14275 queue.scheduleBroadcastsLocked(); 14276 } 14277 registeredReceivers = null; 14278 NR = 0; 14279 } 14280 14281 // Merge into one list. 14282 int ir = 0; 14283 if (receivers != null) { 14284 // A special case for PACKAGE_ADDED: do not allow the package 14285 // being added to see this broadcast. This prevents them from 14286 // using this as a back door to get run as soon as they are 14287 // installed. Maybe in the future we want to have a special install 14288 // broadcast or such for apps, but we'd like to deliberately make 14289 // this decision. 14290 String skipPackages[] = null; 14291 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14292 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14293 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14294 Uri data = intent.getData(); 14295 if (data != null) { 14296 String pkgName = data.getSchemeSpecificPart(); 14297 if (pkgName != null) { 14298 skipPackages = new String[] { pkgName }; 14299 } 14300 } 14301 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14302 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14303 } 14304 if (skipPackages != null && (skipPackages.length > 0)) { 14305 for (String skipPackage : skipPackages) { 14306 if (skipPackage != null) { 14307 int NT = receivers.size(); 14308 for (int it=0; it<NT; it++) { 14309 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14310 if (curt.activityInfo.packageName.equals(skipPackage)) { 14311 receivers.remove(it); 14312 it--; 14313 NT--; 14314 } 14315 } 14316 } 14317 } 14318 } 14319 14320 int NT = receivers != null ? receivers.size() : 0; 14321 int it = 0; 14322 ResolveInfo curt = null; 14323 BroadcastFilter curr = null; 14324 while (it < NT && ir < NR) { 14325 if (curt == null) { 14326 curt = (ResolveInfo)receivers.get(it); 14327 } 14328 if (curr == null) { 14329 curr = registeredReceivers.get(ir); 14330 } 14331 if (curr.getPriority() >= curt.priority) { 14332 // Insert this broadcast record into the final list. 14333 receivers.add(it, curr); 14334 ir++; 14335 curr = null; 14336 it++; 14337 NT++; 14338 } else { 14339 // Skip to the next ResolveInfo in the final list. 14340 it++; 14341 curt = null; 14342 } 14343 } 14344 } 14345 while (ir < NR) { 14346 if (receivers == null) { 14347 receivers = new ArrayList(); 14348 } 14349 receivers.add(registeredReceivers.get(ir)); 14350 ir++; 14351 } 14352 14353 if ((receivers != null && receivers.size() > 0) 14354 || resultTo != null) { 14355 BroadcastQueue queue = broadcastQueueForIntent(intent); 14356 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14357 callerPackage, callingPid, callingUid, resolvedType, 14358 requiredPermission, appOp, receivers, resultTo, resultCode, 14359 resultData, map, ordered, sticky, false, userId); 14360 if (DEBUG_BROADCAST) Slog.v( 14361 TAG, "Enqueueing ordered broadcast " + r 14362 + ": prev had " + queue.mOrderedBroadcasts.size()); 14363 if (DEBUG_BROADCAST) { 14364 int seq = r.intent.getIntExtra("seq", -1); 14365 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14366 } 14367 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14368 if (!replaced) { 14369 queue.enqueueOrderedBroadcastLocked(r); 14370 queue.scheduleBroadcastsLocked(); 14371 } 14372 } 14373 14374 return ActivityManager.BROADCAST_SUCCESS; 14375 } 14376 14377 final Intent verifyBroadcastLocked(Intent intent) { 14378 // Refuse possible leaked file descriptors 14379 if (intent != null && intent.hasFileDescriptors() == true) { 14380 throw new IllegalArgumentException("File descriptors passed in Intent"); 14381 } 14382 14383 int flags = intent.getFlags(); 14384 14385 if (!mProcessesReady) { 14386 // if the caller really truly claims to know what they're doing, go 14387 // ahead and allow the broadcast without launching any receivers 14388 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14389 intent = new Intent(intent); 14390 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14391 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14392 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14393 + " before boot completion"); 14394 throw new IllegalStateException("Cannot broadcast before boot completed"); 14395 } 14396 } 14397 14398 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14399 throw new IllegalArgumentException( 14400 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14401 } 14402 14403 return intent; 14404 } 14405 14406 public final int broadcastIntent(IApplicationThread caller, 14407 Intent intent, String resolvedType, IIntentReceiver resultTo, 14408 int resultCode, String resultData, Bundle map, 14409 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14410 enforceNotIsolatedCaller("broadcastIntent"); 14411 synchronized(this) { 14412 intent = verifyBroadcastLocked(intent); 14413 14414 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14415 final int callingPid = Binder.getCallingPid(); 14416 final int callingUid = Binder.getCallingUid(); 14417 final long origId = Binder.clearCallingIdentity(); 14418 int res = broadcastIntentLocked(callerApp, 14419 callerApp != null ? callerApp.info.packageName : null, 14420 intent, resolvedType, resultTo, 14421 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14422 callingPid, callingUid, userId); 14423 Binder.restoreCallingIdentity(origId); 14424 return res; 14425 } 14426 } 14427 14428 int broadcastIntentInPackage(String packageName, int uid, 14429 Intent intent, String resolvedType, IIntentReceiver resultTo, 14430 int resultCode, String resultData, Bundle map, 14431 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14432 synchronized(this) { 14433 intent = verifyBroadcastLocked(intent); 14434 14435 final long origId = Binder.clearCallingIdentity(); 14436 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14437 resultTo, resultCode, resultData, map, requiredPermission, 14438 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14439 Binder.restoreCallingIdentity(origId); 14440 return res; 14441 } 14442 } 14443 14444 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14445 // Refuse possible leaked file descriptors 14446 if (intent != null && intent.hasFileDescriptors() == true) { 14447 throw new IllegalArgumentException("File descriptors passed in Intent"); 14448 } 14449 14450 userId = handleIncomingUser(Binder.getCallingPid(), 14451 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14452 14453 synchronized(this) { 14454 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14455 != PackageManager.PERMISSION_GRANTED) { 14456 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14457 + Binder.getCallingPid() 14458 + ", uid=" + Binder.getCallingUid() 14459 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14460 Slog.w(TAG, msg); 14461 throw new SecurityException(msg); 14462 } 14463 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14464 if (stickies != null) { 14465 ArrayList<Intent> list = stickies.get(intent.getAction()); 14466 if (list != null) { 14467 int N = list.size(); 14468 int i; 14469 for (i=0; i<N; i++) { 14470 if (intent.filterEquals(list.get(i))) { 14471 list.remove(i); 14472 break; 14473 } 14474 } 14475 if (list.size() <= 0) { 14476 stickies.remove(intent.getAction()); 14477 } 14478 } 14479 if (stickies.size() <= 0) { 14480 mStickyBroadcasts.remove(userId); 14481 } 14482 } 14483 } 14484 } 14485 14486 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14487 String resultData, Bundle resultExtras, boolean resultAbort) { 14488 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14489 if (r == null) { 14490 Slog.w(TAG, "finishReceiver called but not found on queue"); 14491 return false; 14492 } 14493 14494 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14495 } 14496 14497 void backgroundServicesFinishedLocked(int userId) { 14498 for (BroadcastQueue queue : mBroadcastQueues) { 14499 queue.backgroundServicesFinishedLocked(userId); 14500 } 14501 } 14502 14503 public void finishReceiver(IBinder who, int resultCode, String resultData, 14504 Bundle resultExtras, boolean resultAbort) { 14505 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14506 14507 // Refuse possible leaked file descriptors 14508 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14509 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14510 } 14511 14512 final long origId = Binder.clearCallingIdentity(); 14513 try { 14514 boolean doNext = false; 14515 BroadcastRecord r; 14516 14517 synchronized(this) { 14518 r = broadcastRecordForReceiverLocked(who); 14519 if (r != null) { 14520 doNext = r.queue.finishReceiverLocked(r, resultCode, 14521 resultData, resultExtras, resultAbort, true); 14522 } 14523 } 14524 14525 if (doNext) { 14526 r.queue.processNextBroadcast(false); 14527 } 14528 trimApplications(); 14529 } finally { 14530 Binder.restoreCallingIdentity(origId); 14531 } 14532 } 14533 14534 // ========================================================= 14535 // INSTRUMENTATION 14536 // ========================================================= 14537 14538 public boolean startInstrumentation(ComponentName className, 14539 String profileFile, int flags, Bundle arguments, 14540 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14541 int userId, String abiOverride) { 14542 enforceNotIsolatedCaller("startInstrumentation"); 14543 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14544 userId, false, true, "startInstrumentation", null); 14545 // Refuse possible leaked file descriptors 14546 if (arguments != null && arguments.hasFileDescriptors()) { 14547 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14548 } 14549 14550 synchronized(this) { 14551 InstrumentationInfo ii = null; 14552 ApplicationInfo ai = null; 14553 try { 14554 ii = mContext.getPackageManager().getInstrumentationInfo( 14555 className, STOCK_PM_FLAGS); 14556 ai = AppGlobals.getPackageManager().getApplicationInfo( 14557 ii.targetPackage, STOCK_PM_FLAGS, userId); 14558 } catch (PackageManager.NameNotFoundException e) { 14559 } catch (RemoteException e) { 14560 } 14561 if (ii == null) { 14562 reportStartInstrumentationFailure(watcher, className, 14563 "Unable to find instrumentation info for: " + className); 14564 return false; 14565 } 14566 if (ai == null) { 14567 reportStartInstrumentationFailure(watcher, className, 14568 "Unable to find instrumentation target package: " + ii.targetPackage); 14569 return false; 14570 } 14571 14572 int match = mContext.getPackageManager().checkSignatures( 14573 ii.targetPackage, ii.packageName); 14574 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14575 String msg = "Permission Denial: starting instrumentation " 14576 + className + " from pid=" 14577 + Binder.getCallingPid() 14578 + ", uid=" + Binder.getCallingPid() 14579 + " not allowed because package " + ii.packageName 14580 + " does not have a signature matching the target " 14581 + ii.targetPackage; 14582 reportStartInstrumentationFailure(watcher, className, msg); 14583 throw new SecurityException(msg); 14584 } 14585 14586 final long origId = Binder.clearCallingIdentity(); 14587 // Instrumentation can kill and relaunch even persistent processes 14588 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14589 "start instr"); 14590 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14591 app.instrumentationClass = className; 14592 app.instrumentationInfo = ai; 14593 app.instrumentationProfileFile = profileFile; 14594 app.instrumentationArguments = arguments; 14595 app.instrumentationWatcher = watcher; 14596 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14597 app.instrumentationResultClass = className; 14598 Binder.restoreCallingIdentity(origId); 14599 } 14600 14601 return true; 14602 } 14603 14604 /** 14605 * Report errors that occur while attempting to start Instrumentation. Always writes the 14606 * error to the logs, but if somebody is watching, send the report there too. This enables 14607 * the "am" command to report errors with more information. 14608 * 14609 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14610 * @param cn The component name of the instrumentation. 14611 * @param report The error report. 14612 */ 14613 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14614 ComponentName cn, String report) { 14615 Slog.w(TAG, report); 14616 try { 14617 if (watcher != null) { 14618 Bundle results = new Bundle(); 14619 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14620 results.putString("Error", report); 14621 watcher.instrumentationStatus(cn, -1, results); 14622 } 14623 } catch (RemoteException e) { 14624 Slog.w(TAG, e); 14625 } 14626 } 14627 14628 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14629 if (app.instrumentationWatcher != null) { 14630 try { 14631 // NOTE: IInstrumentationWatcher *must* be oneway here 14632 app.instrumentationWatcher.instrumentationFinished( 14633 app.instrumentationClass, 14634 resultCode, 14635 results); 14636 } catch (RemoteException e) { 14637 } 14638 } 14639 if (app.instrumentationUiAutomationConnection != null) { 14640 try { 14641 app.instrumentationUiAutomationConnection.shutdown(); 14642 } catch (RemoteException re) { 14643 /* ignore */ 14644 } 14645 // Only a UiAutomation can set this flag and now that 14646 // it is finished we make sure it is reset to its default. 14647 mUserIsMonkey = false; 14648 } 14649 app.instrumentationWatcher = null; 14650 app.instrumentationUiAutomationConnection = null; 14651 app.instrumentationClass = null; 14652 app.instrumentationInfo = null; 14653 app.instrumentationProfileFile = null; 14654 app.instrumentationArguments = null; 14655 14656 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14657 "finished inst"); 14658 } 14659 14660 public void finishInstrumentation(IApplicationThread target, 14661 int resultCode, Bundle results) { 14662 int userId = UserHandle.getCallingUserId(); 14663 // Refuse possible leaked file descriptors 14664 if (results != null && results.hasFileDescriptors()) { 14665 throw new IllegalArgumentException("File descriptors passed in Intent"); 14666 } 14667 14668 synchronized(this) { 14669 ProcessRecord app = getRecordForAppLocked(target); 14670 if (app == null) { 14671 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14672 return; 14673 } 14674 final long origId = Binder.clearCallingIdentity(); 14675 finishInstrumentationLocked(app, resultCode, results); 14676 Binder.restoreCallingIdentity(origId); 14677 } 14678 } 14679 14680 // ========================================================= 14681 // CONFIGURATION 14682 // ========================================================= 14683 14684 public ConfigurationInfo getDeviceConfigurationInfo() { 14685 ConfigurationInfo config = new ConfigurationInfo(); 14686 synchronized (this) { 14687 config.reqTouchScreen = mConfiguration.touchscreen; 14688 config.reqKeyboardType = mConfiguration.keyboard; 14689 config.reqNavigation = mConfiguration.navigation; 14690 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14691 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14692 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14693 } 14694 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14695 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14696 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14697 } 14698 config.reqGlEsVersion = GL_ES_VERSION; 14699 } 14700 return config; 14701 } 14702 14703 ActivityStack getFocusedStack() { 14704 return mStackSupervisor.getFocusedStack(); 14705 } 14706 14707 public Configuration getConfiguration() { 14708 Configuration ci; 14709 synchronized(this) { 14710 ci = new Configuration(mConfiguration); 14711 } 14712 return ci; 14713 } 14714 14715 public void updatePersistentConfiguration(Configuration values) { 14716 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14717 "updateConfiguration()"); 14718 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14719 "updateConfiguration()"); 14720 if (values == null) { 14721 throw new NullPointerException("Configuration must not be null"); 14722 } 14723 14724 synchronized(this) { 14725 final long origId = Binder.clearCallingIdentity(); 14726 updateConfigurationLocked(values, null, true, false); 14727 Binder.restoreCallingIdentity(origId); 14728 } 14729 } 14730 14731 public void updateConfiguration(Configuration values) { 14732 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14733 "updateConfiguration()"); 14734 14735 synchronized(this) { 14736 if (values == null && mWindowManager != null) { 14737 // sentinel: fetch the current configuration from the window manager 14738 values = mWindowManager.computeNewConfiguration(); 14739 } 14740 14741 if (mWindowManager != null) { 14742 mProcessList.applyDisplaySize(mWindowManager); 14743 } 14744 14745 final long origId = Binder.clearCallingIdentity(); 14746 if (values != null) { 14747 Settings.System.clearConfiguration(values); 14748 } 14749 updateConfigurationLocked(values, null, false, false); 14750 Binder.restoreCallingIdentity(origId); 14751 } 14752 } 14753 14754 /** 14755 * Do either or both things: (1) change the current configuration, and (2) 14756 * make sure the given activity is running with the (now) current 14757 * configuration. Returns true if the activity has been left running, or 14758 * false if <var>starting</var> is being destroyed to match the new 14759 * configuration. 14760 * @param persistent TODO 14761 */ 14762 boolean updateConfigurationLocked(Configuration values, 14763 ActivityRecord starting, boolean persistent, boolean initLocale) { 14764 int changes = 0; 14765 14766 if (values != null) { 14767 Configuration newConfig = new Configuration(mConfiguration); 14768 changes = newConfig.updateFrom(values); 14769 if (changes != 0) { 14770 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14771 Slog.i(TAG, "Updating configuration to: " + values); 14772 } 14773 14774 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14775 14776 if (values.locale != null && !initLocale) { 14777 saveLocaleLocked(values.locale, 14778 !values.locale.equals(mConfiguration.locale), 14779 values.userSetLocale); 14780 } 14781 14782 mConfigurationSeq++; 14783 if (mConfigurationSeq <= 0) { 14784 mConfigurationSeq = 1; 14785 } 14786 newConfig.seq = mConfigurationSeq; 14787 mConfiguration = newConfig; 14788 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14789 mUsageStatsService.noteStartConfig(newConfig); 14790 14791 final Configuration configCopy = new Configuration(mConfiguration); 14792 14793 // TODO: If our config changes, should we auto dismiss any currently 14794 // showing dialogs? 14795 mShowDialogs = shouldShowDialogs(newConfig); 14796 14797 AttributeCache ac = AttributeCache.instance(); 14798 if (ac != null) { 14799 ac.updateConfiguration(configCopy); 14800 } 14801 14802 // Make sure all resources in our process are updated 14803 // right now, so that anyone who is going to retrieve 14804 // resource values after we return will be sure to get 14805 // the new ones. This is especially important during 14806 // boot, where the first config change needs to guarantee 14807 // all resources have that config before following boot 14808 // code is executed. 14809 mSystemThread.applyConfigurationToResources(configCopy); 14810 14811 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14812 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14813 msg.obj = new Configuration(configCopy); 14814 mHandler.sendMessage(msg); 14815 } 14816 14817 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14818 ProcessRecord app = mLruProcesses.get(i); 14819 try { 14820 if (app.thread != null) { 14821 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14822 + app.processName + " new config " + mConfiguration); 14823 app.thread.scheduleConfigurationChanged(configCopy); 14824 } 14825 } catch (Exception e) { 14826 } 14827 } 14828 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14829 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14830 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14831 | Intent.FLAG_RECEIVER_FOREGROUND); 14832 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14833 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14834 Process.SYSTEM_UID, UserHandle.USER_ALL); 14835 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14836 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14837 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14838 broadcastIntentLocked(null, null, intent, 14839 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14840 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14841 } 14842 } 14843 } 14844 14845 boolean kept = true; 14846 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14847 // mainStack is null during startup. 14848 if (mainStack != null) { 14849 if (changes != 0 && starting == null) { 14850 // If the configuration changed, and the caller is not already 14851 // in the process of starting an activity, then find the top 14852 // activity to check if its configuration needs to change. 14853 starting = mainStack.topRunningActivityLocked(null); 14854 } 14855 14856 if (starting != null) { 14857 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14858 // And we need to make sure at this point that all other activities 14859 // are made visible with the correct configuration. 14860 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14861 } 14862 } 14863 14864 if (values != null && mWindowManager != null) { 14865 mWindowManager.setNewConfiguration(mConfiguration); 14866 } 14867 14868 return kept; 14869 } 14870 14871 /** 14872 * Decide based on the configuration whether we should shouw the ANR, 14873 * crash, etc dialogs. The idea is that if there is no affordnace to 14874 * press the on-screen buttons, we shouldn't show the dialog. 14875 * 14876 * A thought: SystemUI might also want to get told about this, the Power 14877 * dialog / global actions also might want different behaviors. 14878 */ 14879 private static final boolean shouldShowDialogs(Configuration config) { 14880 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14881 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14882 } 14883 14884 /** 14885 * Save the locale. You must be inside a synchronized (this) block. 14886 */ 14887 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14888 if(isDiff) { 14889 SystemProperties.set("user.language", l.getLanguage()); 14890 SystemProperties.set("user.region", l.getCountry()); 14891 } 14892 14893 if(isPersist) { 14894 SystemProperties.set("persist.sys.language", l.getLanguage()); 14895 SystemProperties.set("persist.sys.country", l.getCountry()); 14896 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14897 } 14898 } 14899 14900 @Override 14901 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14902 ActivityRecord srec = ActivityRecord.forToken(token); 14903 return srec != null && srec.task.affinity != null && 14904 srec.task.affinity.equals(destAffinity); 14905 } 14906 14907 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14908 Intent resultData) { 14909 14910 synchronized (this) { 14911 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14912 if (stack != null) { 14913 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14914 } 14915 return false; 14916 } 14917 } 14918 14919 public int getLaunchedFromUid(IBinder activityToken) { 14920 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14921 if (srec == null) { 14922 return -1; 14923 } 14924 return srec.launchedFromUid; 14925 } 14926 14927 public String getLaunchedFromPackage(IBinder activityToken) { 14928 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14929 if (srec == null) { 14930 return null; 14931 } 14932 return srec.launchedFromPackage; 14933 } 14934 14935 // ========================================================= 14936 // LIFETIME MANAGEMENT 14937 // ========================================================= 14938 14939 // Returns which broadcast queue the app is the current [or imminent] receiver 14940 // on, or 'null' if the app is not an active broadcast recipient. 14941 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14942 BroadcastRecord r = app.curReceiver; 14943 if (r != null) { 14944 return r.queue; 14945 } 14946 14947 // It's not the current receiver, but it might be starting up to become one 14948 synchronized (this) { 14949 for (BroadcastQueue queue : mBroadcastQueues) { 14950 r = queue.mPendingBroadcast; 14951 if (r != null && r.curApp == app) { 14952 // found it; report which queue it's in 14953 return queue; 14954 } 14955 } 14956 } 14957 14958 return null; 14959 } 14960 14961 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14962 boolean doingAll, long now) { 14963 if (mAdjSeq == app.adjSeq) { 14964 // This adjustment has already been computed. 14965 return app.curRawAdj; 14966 } 14967 14968 if (app.thread == null) { 14969 app.adjSeq = mAdjSeq; 14970 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14971 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14972 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14973 } 14974 14975 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14976 app.adjSource = null; 14977 app.adjTarget = null; 14978 app.empty = false; 14979 app.cached = false; 14980 14981 final int activitiesSize = app.activities.size(); 14982 14983 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14984 // The max adjustment doesn't allow this app to be anything 14985 // below foreground, so it is not worth doing work for it. 14986 app.adjType = "fixed"; 14987 app.adjSeq = mAdjSeq; 14988 app.curRawAdj = app.maxAdj; 14989 app.foregroundActivities = false; 14990 app.keeping = true; 14991 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14992 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14993 // System processes can do UI, and when they do we want to have 14994 // them trim their memory after the user leaves the UI. To 14995 // facilitate this, here we need to determine whether or not it 14996 // is currently showing UI. 14997 app.systemNoUi = true; 14998 if (app == TOP_APP) { 14999 app.systemNoUi = false; 15000 } else if (activitiesSize > 0) { 15001 for (int j = 0; j < activitiesSize; j++) { 15002 final ActivityRecord r = app.activities.get(j); 15003 if (r.visible) { 15004 app.systemNoUi = false; 15005 } 15006 } 15007 } 15008 if (!app.systemNoUi) { 15009 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15010 } 15011 return (app.curAdj=app.maxAdj); 15012 } 15013 15014 app.keeping = false; 15015 app.systemNoUi = false; 15016 15017 // Determine the importance of the process, starting with most 15018 // important to least, and assign an appropriate OOM adjustment. 15019 int adj; 15020 int schedGroup; 15021 int procState; 15022 boolean foregroundActivities = false; 15023 BroadcastQueue queue; 15024 if (app == TOP_APP) { 15025 // The last app on the list is the foreground app. 15026 adj = ProcessList.FOREGROUND_APP_ADJ; 15027 schedGroup = Process.THREAD_GROUP_DEFAULT; 15028 app.adjType = "top-activity"; 15029 foregroundActivities = true; 15030 procState = ActivityManager.PROCESS_STATE_TOP; 15031 } else if (app.instrumentationClass != null) { 15032 // Don't want to kill running instrumentation. 15033 adj = ProcessList.FOREGROUND_APP_ADJ; 15034 schedGroup = Process.THREAD_GROUP_DEFAULT; 15035 app.adjType = "instrumentation"; 15036 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15037 } else if ((queue = isReceivingBroadcast(app)) != null) { 15038 // An app that is currently receiving a broadcast also 15039 // counts as being in the foreground for OOM killer purposes. 15040 // It's placed in a sched group based on the nature of the 15041 // broadcast as reflected by which queue it's active in. 15042 adj = ProcessList.FOREGROUND_APP_ADJ; 15043 schedGroup = (queue == mFgBroadcastQueue) 15044 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15045 app.adjType = "broadcast"; 15046 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15047 } else if (app.executingServices.size() > 0) { 15048 // An app that is currently executing a service callback also 15049 // counts as being in the foreground. 15050 adj = ProcessList.FOREGROUND_APP_ADJ; 15051 schedGroup = app.execServicesFg ? 15052 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15053 app.adjType = "exec-service"; 15054 procState = ActivityManager.PROCESS_STATE_SERVICE; 15055 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15056 } else { 15057 // As far as we know the process is empty. We may change our mind later. 15058 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15059 // At this point we don't actually know the adjustment. Use the cached adj 15060 // value that the caller wants us to. 15061 adj = cachedAdj; 15062 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15063 app.cached = true; 15064 app.empty = true; 15065 app.adjType = "cch-empty"; 15066 } 15067 15068 // Examine all activities if not already foreground. 15069 if (!foregroundActivities && activitiesSize > 0) { 15070 for (int j = 0; j < activitiesSize; j++) { 15071 final ActivityRecord r = app.activities.get(j); 15072 if (r.app != app) { 15073 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15074 + app + "?!?"); 15075 continue; 15076 } 15077 if (r.visible) { 15078 // App has a visible activity; only upgrade adjustment. 15079 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15080 adj = ProcessList.VISIBLE_APP_ADJ; 15081 app.adjType = "visible"; 15082 } 15083 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15084 procState = ActivityManager.PROCESS_STATE_TOP; 15085 } 15086 schedGroup = Process.THREAD_GROUP_DEFAULT; 15087 app.cached = false; 15088 app.empty = false; 15089 foregroundActivities = true; 15090 break; 15091 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15092 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15093 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15094 app.adjType = "pausing"; 15095 } 15096 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15097 procState = ActivityManager.PROCESS_STATE_TOP; 15098 } 15099 schedGroup = Process.THREAD_GROUP_DEFAULT; 15100 app.cached = false; 15101 app.empty = false; 15102 foregroundActivities = true; 15103 } else if (r.state == ActivityState.STOPPING) { 15104 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15105 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15106 app.adjType = "stopping"; 15107 } 15108 // For the process state, we will at this point consider the 15109 // process to be cached. It will be cached either as an activity 15110 // or empty depending on whether the activity is finishing. We do 15111 // this so that we can treat the process as cached for purposes of 15112 // memory trimming (determing current memory level, trim command to 15113 // send to process) since there can be an arbitrary number of stopping 15114 // processes and they should soon all go into the cached state. 15115 if (!r.finishing) { 15116 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15117 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15118 } 15119 } 15120 app.cached = false; 15121 app.empty = false; 15122 foregroundActivities = true; 15123 } else { 15124 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15125 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15126 app.adjType = "cch-act"; 15127 } 15128 } 15129 } 15130 } 15131 15132 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15133 if (app.foregroundServices) { 15134 // The user is aware of this app, so make it visible. 15135 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15136 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15137 app.cached = false; 15138 app.adjType = "fg-service"; 15139 schedGroup = Process.THREAD_GROUP_DEFAULT; 15140 } else if (app.forcingToForeground != null) { 15141 // The user is aware of this app, so make it visible. 15142 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15143 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15144 app.cached = false; 15145 app.adjType = "force-fg"; 15146 app.adjSource = app.forcingToForeground; 15147 schedGroup = Process.THREAD_GROUP_DEFAULT; 15148 } 15149 } 15150 15151 if (app == mHeavyWeightProcess) { 15152 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15153 // We don't want to kill the current heavy-weight process. 15154 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15155 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15156 app.cached = false; 15157 app.adjType = "heavy"; 15158 } 15159 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15160 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15161 } 15162 } 15163 15164 if (app == mHomeProcess) { 15165 if (adj > ProcessList.HOME_APP_ADJ) { 15166 // This process is hosting what we currently consider to be the 15167 // home app, so we don't want to let it go into the background. 15168 adj = ProcessList.HOME_APP_ADJ; 15169 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15170 app.cached = false; 15171 app.adjType = "home"; 15172 } 15173 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15174 procState = ActivityManager.PROCESS_STATE_HOME; 15175 } 15176 } 15177 15178 if (app == mPreviousProcess && app.activities.size() > 0) { 15179 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15180 // This was the previous process that showed UI to the user. 15181 // We want to try to keep it around more aggressively, to give 15182 // a good experience around switching between two apps. 15183 adj = ProcessList.PREVIOUS_APP_ADJ; 15184 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15185 app.cached = false; 15186 app.adjType = "previous"; 15187 } 15188 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15189 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15190 } 15191 } 15192 15193 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15194 + " reason=" + app.adjType); 15195 15196 // By default, we use the computed adjustment. It may be changed if 15197 // there are applications dependent on our services or providers, but 15198 // this gives us a baseline and makes sure we don't get into an 15199 // infinite recursion. 15200 app.adjSeq = mAdjSeq; 15201 app.curRawAdj = adj; 15202 app.hasStartedServices = false; 15203 15204 if (mBackupTarget != null && app == mBackupTarget.app) { 15205 // If possible we want to avoid killing apps while they're being backed up 15206 if (adj > ProcessList.BACKUP_APP_ADJ) { 15207 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15208 adj = ProcessList.BACKUP_APP_ADJ; 15209 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15210 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15211 } 15212 app.adjType = "backup"; 15213 app.cached = false; 15214 } 15215 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15216 procState = ActivityManager.PROCESS_STATE_BACKUP; 15217 } 15218 } 15219 15220 boolean mayBeTop = false; 15221 15222 for (int is = app.services.size()-1; 15223 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15224 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15225 || procState > ActivityManager.PROCESS_STATE_TOP); 15226 is--) { 15227 ServiceRecord s = app.services.valueAt(is); 15228 if (s.startRequested) { 15229 app.hasStartedServices = true; 15230 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15231 procState = ActivityManager.PROCESS_STATE_SERVICE; 15232 } 15233 if (app.hasShownUi && app != mHomeProcess) { 15234 // If this process has shown some UI, let it immediately 15235 // go to the LRU list because it may be pretty heavy with 15236 // UI stuff. We'll tag it with a label just to help 15237 // debug and understand what is going on. 15238 if (adj > ProcessList.SERVICE_ADJ) { 15239 app.adjType = "cch-started-ui-services"; 15240 } 15241 } else { 15242 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15243 // This service has seen some activity within 15244 // recent memory, so we will keep its process ahead 15245 // of the background processes. 15246 if (adj > ProcessList.SERVICE_ADJ) { 15247 adj = ProcessList.SERVICE_ADJ; 15248 app.adjType = "started-services"; 15249 app.cached = false; 15250 } 15251 } 15252 // If we have let the service slide into the background 15253 // state, still have some text describing what it is doing 15254 // even though the service no longer has an impact. 15255 if (adj > ProcessList.SERVICE_ADJ) { 15256 app.adjType = "cch-started-services"; 15257 } 15258 } 15259 // Don't kill this process because it is doing work; it 15260 // has said it is doing work. 15261 app.keeping = true; 15262 } 15263 for (int conni = s.connections.size()-1; 15264 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15265 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15266 || procState > ActivityManager.PROCESS_STATE_TOP); 15267 conni--) { 15268 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15269 for (int i = 0; 15270 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15271 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15272 || procState > ActivityManager.PROCESS_STATE_TOP); 15273 i++) { 15274 // XXX should compute this based on the max of 15275 // all connected clients. 15276 ConnectionRecord cr = clist.get(i); 15277 if (cr.binding.client == app) { 15278 // Binding to ourself is not interesting. 15279 continue; 15280 } 15281 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15282 ProcessRecord client = cr.binding.client; 15283 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15284 TOP_APP, doingAll, now); 15285 int clientProcState = client.curProcState; 15286 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15287 // If the other app is cached for any reason, for purposes here 15288 // we are going to consider it empty. The specific cached state 15289 // doesn't propagate except under certain conditions. 15290 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15291 } 15292 String adjType = null; 15293 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15294 // Not doing bind OOM management, so treat 15295 // this guy more like a started service. 15296 if (app.hasShownUi && app != mHomeProcess) { 15297 // If this process has shown some UI, let it immediately 15298 // go to the LRU list because it may be pretty heavy with 15299 // UI stuff. We'll tag it with a label just to help 15300 // debug and understand what is going on. 15301 if (adj > clientAdj) { 15302 adjType = "cch-bound-ui-services"; 15303 } 15304 app.cached = false; 15305 clientAdj = adj; 15306 clientProcState = procState; 15307 } else { 15308 if (now >= (s.lastActivity 15309 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15310 // This service has not seen activity within 15311 // recent memory, so allow it to drop to the 15312 // LRU list if there is no other reason to keep 15313 // it around. We'll also tag it with a label just 15314 // to help debug and undertand what is going on. 15315 if (adj > clientAdj) { 15316 adjType = "cch-bound-services"; 15317 } 15318 clientAdj = adj; 15319 } 15320 } 15321 } 15322 if (adj > clientAdj) { 15323 // If this process has recently shown UI, and 15324 // the process that is binding to it is less 15325 // important than being visible, then we don't 15326 // care about the binding as much as we care 15327 // about letting this process get into the LRU 15328 // list to be killed and restarted if needed for 15329 // memory. 15330 if (app.hasShownUi && app != mHomeProcess 15331 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15332 adjType = "cch-bound-ui-services"; 15333 } else { 15334 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15335 |Context.BIND_IMPORTANT)) != 0) { 15336 adj = clientAdj; 15337 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15338 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15339 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15340 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15341 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15342 adj = clientAdj; 15343 } else { 15344 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15345 adj = ProcessList.VISIBLE_APP_ADJ; 15346 } 15347 } 15348 if (!client.cached) { 15349 app.cached = false; 15350 } 15351 if (client.keeping) { 15352 app.keeping = true; 15353 } 15354 adjType = "service"; 15355 } 15356 } 15357 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15358 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15359 schedGroup = Process.THREAD_GROUP_DEFAULT; 15360 } 15361 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15362 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15363 // Special handling of clients who are in the top state. 15364 // We *may* want to consider this process to be in the 15365 // top state as well, but only if there is not another 15366 // reason for it to be running. Being on the top is a 15367 // special state, meaning you are specifically running 15368 // for the current top app. If the process is already 15369 // running in the background for some other reason, it 15370 // is more important to continue considering it to be 15371 // in the background state. 15372 mayBeTop = true; 15373 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15374 } else { 15375 // Special handling for above-top states (persistent 15376 // processes). These should not bring the current process 15377 // into the top state, since they are not on top. Instead 15378 // give them the best state after that. 15379 clientProcState = 15380 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15381 } 15382 } 15383 } else { 15384 if (clientProcState < 15385 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15386 clientProcState = 15387 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15388 } 15389 } 15390 if (procState > clientProcState) { 15391 procState = clientProcState; 15392 } 15393 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15394 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15395 app.pendingUiClean = true; 15396 } 15397 if (adjType != null) { 15398 app.adjType = adjType; 15399 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15400 .REASON_SERVICE_IN_USE; 15401 app.adjSource = cr.binding.client; 15402 app.adjSourceOom = clientAdj; 15403 app.adjTarget = s.name; 15404 } 15405 } 15406 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15407 app.treatLikeActivity = true; 15408 } 15409 final ActivityRecord a = cr.activity; 15410 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15411 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15412 (a.visible || a.state == ActivityState.RESUMED 15413 || a.state == ActivityState.PAUSING)) { 15414 adj = ProcessList.FOREGROUND_APP_ADJ; 15415 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15416 schedGroup = Process.THREAD_GROUP_DEFAULT; 15417 } 15418 app.cached = false; 15419 app.adjType = "service"; 15420 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15421 .REASON_SERVICE_IN_USE; 15422 app.adjSource = a; 15423 app.adjSourceOom = adj; 15424 app.adjTarget = s.name; 15425 } 15426 } 15427 } 15428 } 15429 } 15430 15431 for (int provi = app.pubProviders.size()-1; 15432 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15433 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15434 || procState > ActivityManager.PROCESS_STATE_TOP); 15435 provi--) { 15436 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15437 for (int i = cpr.connections.size()-1; 15438 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15439 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15440 || procState > ActivityManager.PROCESS_STATE_TOP); 15441 i--) { 15442 ContentProviderConnection conn = cpr.connections.get(i); 15443 ProcessRecord client = conn.client; 15444 if (client == app) { 15445 // Being our own client is not interesting. 15446 continue; 15447 } 15448 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15449 int clientProcState = client.curProcState; 15450 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15451 // If the other app is cached for any reason, for purposes here 15452 // we are going to consider it empty. 15453 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15454 } 15455 if (adj > clientAdj) { 15456 if (app.hasShownUi && app != mHomeProcess 15457 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15458 app.adjType = "cch-ui-provider"; 15459 } else { 15460 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15461 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15462 app.adjType = "provider"; 15463 } 15464 app.cached &= client.cached; 15465 app.keeping |= client.keeping; 15466 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15467 .REASON_PROVIDER_IN_USE; 15468 app.adjSource = client; 15469 app.adjSourceOom = clientAdj; 15470 app.adjTarget = cpr.name; 15471 } 15472 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15473 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15474 // Special handling of clients who are in the top state. 15475 // We *may* want to consider this process to be in the 15476 // top state as well, but only if there is not another 15477 // reason for it to be running. Being on the top is a 15478 // special state, meaning you are specifically running 15479 // for the current top app. If the process is already 15480 // running in the background for some other reason, it 15481 // is more important to continue considering it to be 15482 // in the background state. 15483 mayBeTop = true; 15484 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15485 } else { 15486 // Special handling for above-top states (persistent 15487 // processes). These should not bring the current process 15488 // into the top state, since they are not on top. Instead 15489 // give them the best state after that. 15490 clientProcState = 15491 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15492 } 15493 } 15494 if (procState > clientProcState) { 15495 procState = clientProcState; 15496 } 15497 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15498 schedGroup = Process.THREAD_GROUP_DEFAULT; 15499 } 15500 } 15501 // If the provider has external (non-framework) process 15502 // dependencies, ensure that its adjustment is at least 15503 // FOREGROUND_APP_ADJ. 15504 if (cpr.hasExternalProcessHandles()) { 15505 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15506 adj = ProcessList.FOREGROUND_APP_ADJ; 15507 schedGroup = Process.THREAD_GROUP_DEFAULT; 15508 app.cached = false; 15509 app.keeping = true; 15510 app.adjType = "provider"; 15511 app.adjTarget = cpr.name; 15512 } 15513 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15514 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15515 } 15516 } 15517 } 15518 15519 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15520 // A client of one of our services or providers is in the top state. We 15521 // *may* want to be in the top state, but not if we are already running in 15522 // the background for some other reason. For the decision here, we are going 15523 // to pick out a few specific states that we want to remain in when a client 15524 // is top (states that tend to be longer-term) and otherwise allow it to go 15525 // to the top state. 15526 switch (procState) { 15527 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15528 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15529 case ActivityManager.PROCESS_STATE_SERVICE: 15530 // These all are longer-term states, so pull them up to the top 15531 // of the background states, but not all the way to the top state. 15532 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15533 break; 15534 default: 15535 // Otherwise, top is a better choice, so take it. 15536 procState = ActivityManager.PROCESS_STATE_TOP; 15537 break; 15538 } 15539 } 15540 15541 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15542 if (app.hasClientActivities) { 15543 // This is a cached process, but with client activities. Mark it so. 15544 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15545 app.adjType = "cch-client-act"; 15546 } else if (app.treatLikeActivity) { 15547 // This is a cached process, but somebody wants us to treat it like it has 15548 // an activity, okay! 15549 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15550 app.adjType = "cch-as-act"; 15551 } 15552 } 15553 15554 if (adj == ProcessList.SERVICE_ADJ) { 15555 if (doingAll) { 15556 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15557 mNewNumServiceProcs++; 15558 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15559 if (!app.serviceb) { 15560 // This service isn't far enough down on the LRU list to 15561 // normally be a B service, but if we are low on RAM and it 15562 // is large we want to force it down since we would prefer to 15563 // keep launcher over it. 15564 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15565 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15566 app.serviceHighRam = true; 15567 app.serviceb = true; 15568 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15569 } else { 15570 mNewNumAServiceProcs++; 15571 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15572 } 15573 } else { 15574 app.serviceHighRam = false; 15575 } 15576 } 15577 if (app.serviceb) { 15578 adj = ProcessList.SERVICE_B_ADJ; 15579 } 15580 } 15581 15582 app.curRawAdj = adj; 15583 15584 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15585 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15586 if (adj > app.maxAdj) { 15587 adj = app.maxAdj; 15588 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15589 schedGroup = Process.THREAD_GROUP_DEFAULT; 15590 } 15591 } 15592 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15593 app.keeping = true; 15594 } 15595 15596 // Do final modification to adj. Everything we do between here and applying 15597 // the final setAdj must be done in this function, because we will also use 15598 // it when computing the final cached adj later. Note that we don't need to 15599 // worry about this for max adj above, since max adj will always be used to 15600 // keep it out of the cached vaues. 15601 app.curAdj = app.modifyRawOomAdj(adj); 15602 app.curSchedGroup = schedGroup; 15603 app.curProcState = procState; 15604 app.foregroundActivities = foregroundActivities; 15605 15606 return app.curRawAdj; 15607 } 15608 15609 /** 15610 * Schedule PSS collection of a process. 15611 */ 15612 void requestPssLocked(ProcessRecord proc, int procState) { 15613 if (mPendingPssProcesses.contains(proc)) { 15614 return; 15615 } 15616 if (mPendingPssProcesses.size() == 0) { 15617 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15618 } 15619 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15620 proc.pssProcState = procState; 15621 mPendingPssProcesses.add(proc); 15622 } 15623 15624 /** 15625 * Schedule PSS collection of all processes. 15626 */ 15627 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15628 if (!always) { 15629 if (now < (mLastFullPssTime + 15630 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15631 return; 15632 } 15633 } 15634 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15635 mLastFullPssTime = now; 15636 mFullPssPending = true; 15637 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15638 mPendingPssProcesses.clear(); 15639 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15640 ProcessRecord app = mLruProcesses.get(i); 15641 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15642 app.pssProcState = app.setProcState; 15643 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15644 isSleeping(), now); 15645 mPendingPssProcesses.add(app); 15646 } 15647 } 15648 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15649 } 15650 15651 /** 15652 * Ask a given process to GC right now. 15653 */ 15654 final void performAppGcLocked(ProcessRecord app) { 15655 try { 15656 app.lastRequestedGc = SystemClock.uptimeMillis(); 15657 if (app.thread != null) { 15658 if (app.reportLowMemory) { 15659 app.reportLowMemory = false; 15660 app.thread.scheduleLowMemory(); 15661 } else { 15662 app.thread.processInBackground(); 15663 } 15664 } 15665 } catch (Exception e) { 15666 // whatever. 15667 } 15668 } 15669 15670 /** 15671 * Returns true if things are idle enough to perform GCs. 15672 */ 15673 private final boolean canGcNowLocked() { 15674 boolean processingBroadcasts = false; 15675 for (BroadcastQueue q : mBroadcastQueues) { 15676 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15677 processingBroadcasts = true; 15678 } 15679 } 15680 return !processingBroadcasts 15681 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15682 } 15683 15684 /** 15685 * Perform GCs on all processes that are waiting for it, but only 15686 * if things are idle. 15687 */ 15688 final void performAppGcsLocked() { 15689 final int N = mProcessesToGc.size(); 15690 if (N <= 0) { 15691 return; 15692 } 15693 if (canGcNowLocked()) { 15694 while (mProcessesToGc.size() > 0) { 15695 ProcessRecord proc = mProcessesToGc.remove(0); 15696 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15697 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15698 <= SystemClock.uptimeMillis()) { 15699 // To avoid spamming the system, we will GC processes one 15700 // at a time, waiting a few seconds between each. 15701 performAppGcLocked(proc); 15702 scheduleAppGcsLocked(); 15703 return; 15704 } else { 15705 // It hasn't been long enough since we last GCed this 15706 // process... put it in the list to wait for its time. 15707 addProcessToGcListLocked(proc); 15708 break; 15709 } 15710 } 15711 } 15712 15713 scheduleAppGcsLocked(); 15714 } 15715 } 15716 15717 /** 15718 * If all looks good, perform GCs on all processes waiting for them. 15719 */ 15720 final void performAppGcsIfAppropriateLocked() { 15721 if (canGcNowLocked()) { 15722 performAppGcsLocked(); 15723 return; 15724 } 15725 // Still not idle, wait some more. 15726 scheduleAppGcsLocked(); 15727 } 15728 15729 /** 15730 * Schedule the execution of all pending app GCs. 15731 */ 15732 final void scheduleAppGcsLocked() { 15733 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15734 15735 if (mProcessesToGc.size() > 0) { 15736 // Schedule a GC for the time to the next process. 15737 ProcessRecord proc = mProcessesToGc.get(0); 15738 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15739 15740 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15741 long now = SystemClock.uptimeMillis(); 15742 if (when < (now+GC_TIMEOUT)) { 15743 when = now + GC_TIMEOUT; 15744 } 15745 mHandler.sendMessageAtTime(msg, when); 15746 } 15747 } 15748 15749 /** 15750 * Add a process to the array of processes waiting to be GCed. Keeps the 15751 * list in sorted order by the last GC time. The process can't already be 15752 * on the list. 15753 */ 15754 final void addProcessToGcListLocked(ProcessRecord proc) { 15755 boolean added = false; 15756 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15757 if (mProcessesToGc.get(i).lastRequestedGc < 15758 proc.lastRequestedGc) { 15759 added = true; 15760 mProcessesToGc.add(i+1, proc); 15761 break; 15762 } 15763 } 15764 if (!added) { 15765 mProcessesToGc.add(0, proc); 15766 } 15767 } 15768 15769 /** 15770 * Set up to ask a process to GC itself. This will either do it 15771 * immediately, or put it on the list of processes to gc the next 15772 * time things are idle. 15773 */ 15774 final void scheduleAppGcLocked(ProcessRecord app) { 15775 long now = SystemClock.uptimeMillis(); 15776 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15777 return; 15778 } 15779 if (!mProcessesToGc.contains(app)) { 15780 addProcessToGcListLocked(app); 15781 scheduleAppGcsLocked(); 15782 } 15783 } 15784 15785 final void checkExcessivePowerUsageLocked(boolean doKills) { 15786 updateCpuStatsNow(); 15787 15788 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15789 boolean doWakeKills = doKills; 15790 boolean doCpuKills = doKills; 15791 if (mLastPowerCheckRealtime == 0) { 15792 doWakeKills = false; 15793 } 15794 if (mLastPowerCheckUptime == 0) { 15795 doCpuKills = false; 15796 } 15797 if (stats.isScreenOn()) { 15798 doWakeKills = false; 15799 } 15800 final long curRealtime = SystemClock.elapsedRealtime(); 15801 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15802 final long curUptime = SystemClock.uptimeMillis(); 15803 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15804 mLastPowerCheckRealtime = curRealtime; 15805 mLastPowerCheckUptime = curUptime; 15806 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15807 doWakeKills = false; 15808 } 15809 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15810 doCpuKills = false; 15811 } 15812 int i = mLruProcesses.size(); 15813 while (i > 0) { 15814 i--; 15815 ProcessRecord app = mLruProcesses.get(i); 15816 if (!app.keeping) { 15817 long wtime; 15818 synchronized (stats) { 15819 wtime = stats.getProcessWakeTime(app.info.uid, 15820 app.pid, curRealtime); 15821 } 15822 long wtimeUsed = wtime - app.lastWakeTime; 15823 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15824 if (DEBUG_POWER) { 15825 StringBuilder sb = new StringBuilder(128); 15826 sb.append("Wake for "); 15827 app.toShortString(sb); 15828 sb.append(": over "); 15829 TimeUtils.formatDuration(realtimeSince, sb); 15830 sb.append(" used "); 15831 TimeUtils.formatDuration(wtimeUsed, sb); 15832 sb.append(" ("); 15833 sb.append((wtimeUsed*100)/realtimeSince); 15834 sb.append("%)"); 15835 Slog.i(TAG, sb.toString()); 15836 sb.setLength(0); 15837 sb.append("CPU for "); 15838 app.toShortString(sb); 15839 sb.append(": over "); 15840 TimeUtils.formatDuration(uptimeSince, sb); 15841 sb.append(" used "); 15842 TimeUtils.formatDuration(cputimeUsed, sb); 15843 sb.append(" ("); 15844 sb.append((cputimeUsed*100)/uptimeSince); 15845 sb.append("%)"); 15846 Slog.i(TAG, sb.toString()); 15847 } 15848 // If a process has held a wake lock for more 15849 // than 50% of the time during this period, 15850 // that sounds bad. Kill! 15851 if (doWakeKills && realtimeSince > 0 15852 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15853 synchronized (stats) { 15854 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15855 realtimeSince, wtimeUsed); 15856 } 15857 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15858 + " during " + realtimeSince); 15859 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15860 } else if (doCpuKills && uptimeSince > 0 15861 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15862 synchronized (stats) { 15863 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15864 uptimeSince, cputimeUsed); 15865 } 15866 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15867 + " during " + uptimeSince); 15868 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15869 } else { 15870 app.lastWakeTime = wtime; 15871 app.lastCpuTime = app.curCpuTime; 15872 } 15873 } 15874 } 15875 } 15876 15877 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15878 ProcessRecord TOP_APP, boolean doingAll, long now) { 15879 boolean success = true; 15880 15881 if (app.curRawAdj != app.setRawAdj) { 15882 if (wasKeeping && !app.keeping) { 15883 // This app is no longer something we want to keep. Note 15884 // its current wake lock time to later know to kill it if 15885 // it is not behaving well. 15886 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15887 synchronized (stats) { 15888 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15889 app.pid, SystemClock.elapsedRealtime()); 15890 } 15891 app.lastCpuTime = app.curCpuTime; 15892 } 15893 15894 app.setRawAdj = app.curRawAdj; 15895 } 15896 15897 int changes = 0; 15898 15899 if (app.curAdj != app.setAdj) { 15900 ProcessList.setOomAdj(app.pid, app.curAdj); 15901 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15902 TAG, "Set " + app.pid + " " + app.processName + 15903 " adj " + app.curAdj + ": " + app.adjType); 15904 app.setAdj = app.curAdj; 15905 } 15906 15907 if (app.setSchedGroup != app.curSchedGroup) { 15908 app.setSchedGroup = app.curSchedGroup; 15909 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15910 "Setting process group of " + app.processName 15911 + " to " + app.curSchedGroup); 15912 if (app.waitingToKill != null && 15913 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15914 killUnneededProcessLocked(app, app.waitingToKill); 15915 success = false; 15916 } else { 15917 if (true) { 15918 long oldId = Binder.clearCallingIdentity(); 15919 try { 15920 Process.setProcessGroup(app.pid, app.curSchedGroup); 15921 } catch (Exception e) { 15922 Slog.w(TAG, "Failed setting process group of " + app.pid 15923 + " to " + app.curSchedGroup); 15924 e.printStackTrace(); 15925 } finally { 15926 Binder.restoreCallingIdentity(oldId); 15927 } 15928 } else { 15929 if (app.thread != null) { 15930 try { 15931 app.thread.setSchedulingGroup(app.curSchedGroup); 15932 } catch (RemoteException e) { 15933 } 15934 } 15935 } 15936 Process.setSwappiness(app.pid, 15937 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15938 } 15939 } 15940 if (app.repForegroundActivities != app.foregroundActivities) { 15941 app.repForegroundActivities = app.foregroundActivities; 15942 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15943 } 15944 if (app.repProcState != app.curProcState) { 15945 app.repProcState = app.curProcState; 15946 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15947 if (app.thread != null) { 15948 try { 15949 if (false) { 15950 //RuntimeException h = new RuntimeException("here"); 15951 Slog.i(TAG, "Sending new process state " + app.repProcState 15952 + " to " + app /*, h*/); 15953 } 15954 app.thread.setProcessState(app.repProcState); 15955 } catch (RemoteException e) { 15956 } 15957 } 15958 } 15959 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15960 app.setProcState)) { 15961 app.lastStateTime = now; 15962 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15963 isSleeping(), now); 15964 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15965 + ProcessList.makeProcStateString(app.setProcState) + " to " 15966 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15967 + (app.nextPssTime-now) + ": " + app); 15968 } else { 15969 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15970 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15971 requestPssLocked(app, app.setProcState); 15972 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15973 isSleeping(), now); 15974 } else if (false && DEBUG_PSS) { 15975 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15976 } 15977 } 15978 if (app.setProcState != app.curProcState) { 15979 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15980 "Proc state change of " + app.processName 15981 + " to " + app.curProcState); 15982 app.setProcState = app.curProcState; 15983 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15984 app.notCachedSinceIdle = false; 15985 } 15986 if (!doingAll) { 15987 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15988 } else { 15989 app.procStateChanged = true; 15990 } 15991 } 15992 15993 if (changes != 0) { 15994 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15995 int i = mPendingProcessChanges.size()-1; 15996 ProcessChangeItem item = null; 15997 while (i >= 0) { 15998 item = mPendingProcessChanges.get(i); 15999 if (item.pid == app.pid) { 16000 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16001 break; 16002 } 16003 i--; 16004 } 16005 if (i < 0) { 16006 // No existing item in pending changes; need a new one. 16007 final int NA = mAvailProcessChanges.size(); 16008 if (NA > 0) { 16009 item = mAvailProcessChanges.remove(NA-1); 16010 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16011 } else { 16012 item = new ProcessChangeItem(); 16013 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16014 } 16015 item.changes = 0; 16016 item.pid = app.pid; 16017 item.uid = app.info.uid; 16018 if (mPendingProcessChanges.size() == 0) { 16019 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16020 "*** Enqueueing dispatch processes changed!"); 16021 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16022 } 16023 mPendingProcessChanges.add(item); 16024 } 16025 item.changes |= changes; 16026 item.processState = app.repProcState; 16027 item.foregroundActivities = app.repForegroundActivities; 16028 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16029 + Integer.toHexString(System.identityHashCode(item)) 16030 + " " + app.toShortString() + ": changes=" + item.changes 16031 + " procState=" + item.processState 16032 + " foreground=" + item.foregroundActivities 16033 + " type=" + app.adjType + " source=" + app.adjSource 16034 + " target=" + app.adjTarget); 16035 } 16036 16037 return success; 16038 } 16039 16040 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 16041 if (proc.thread != null && proc.baseProcessTracker != null) { 16042 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16043 } 16044 } 16045 16046 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16047 ProcessRecord TOP_APP, boolean doingAll, long now) { 16048 if (app.thread == null) { 16049 return false; 16050 } 16051 16052 final boolean wasKeeping = app.keeping; 16053 16054 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16055 16056 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 16057 } 16058 16059 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16060 boolean oomAdj) { 16061 if (isForeground != proc.foregroundServices) { 16062 proc.foregroundServices = isForeground; 16063 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16064 proc.info.uid); 16065 if (isForeground) { 16066 if (curProcs == null) { 16067 curProcs = new ArrayList<ProcessRecord>(); 16068 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16069 } 16070 if (!curProcs.contains(proc)) { 16071 curProcs.add(proc); 16072 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16073 proc.info.packageName, proc.info.uid); 16074 } 16075 } else { 16076 if (curProcs != null) { 16077 if (curProcs.remove(proc)) { 16078 mBatteryStatsService.noteEvent( 16079 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16080 proc.info.packageName, proc.info.uid); 16081 if (curProcs.size() <= 0) { 16082 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16083 } 16084 } 16085 } 16086 } 16087 if (oomAdj) { 16088 updateOomAdjLocked(); 16089 } 16090 } 16091 } 16092 16093 private final ActivityRecord resumedAppLocked() { 16094 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16095 String pkg; 16096 int uid; 16097 if (act != null && !act.sleeping) { 16098 pkg = act.packageName; 16099 uid = act.info.applicationInfo.uid; 16100 } else { 16101 pkg = null; 16102 uid = -1; 16103 } 16104 // Has the UID or resumed package name changed? 16105 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16106 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16107 if (mCurResumedPackage != null) { 16108 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16109 mCurResumedPackage, mCurResumedUid); 16110 } 16111 mCurResumedPackage = pkg; 16112 mCurResumedUid = uid; 16113 if (mCurResumedPackage != null) { 16114 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16115 mCurResumedPackage, mCurResumedUid); 16116 } 16117 } 16118 return act; 16119 } 16120 16121 final boolean updateOomAdjLocked(ProcessRecord app) { 16122 final ActivityRecord TOP_ACT = resumedAppLocked(); 16123 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16124 final boolean wasCached = app.cached; 16125 16126 mAdjSeq++; 16127 16128 // This is the desired cached adjusment we want to tell it to use. 16129 // If our app is currently cached, we know it, and that is it. Otherwise, 16130 // we don't know it yet, and it needs to now be cached we will then 16131 // need to do a complete oom adj. 16132 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16133 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16134 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16135 SystemClock.uptimeMillis()); 16136 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16137 // Changed to/from cached state, so apps after it in the LRU 16138 // list may also be changed. 16139 updateOomAdjLocked(); 16140 } 16141 return success; 16142 } 16143 16144 final void updateOomAdjLocked() { 16145 final ActivityRecord TOP_ACT = resumedAppLocked(); 16146 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16147 final long now = SystemClock.uptimeMillis(); 16148 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16149 final int N = mLruProcesses.size(); 16150 16151 if (false) { 16152 RuntimeException e = new RuntimeException(); 16153 e.fillInStackTrace(); 16154 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16155 } 16156 16157 mAdjSeq++; 16158 mNewNumServiceProcs = 0; 16159 mNewNumAServiceProcs = 0; 16160 16161 final int emptyProcessLimit; 16162 final int cachedProcessLimit; 16163 if (mProcessLimit <= 0) { 16164 emptyProcessLimit = cachedProcessLimit = 0; 16165 } else if (mProcessLimit == 1) { 16166 emptyProcessLimit = 1; 16167 cachedProcessLimit = 0; 16168 } else { 16169 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16170 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16171 } 16172 16173 // Let's determine how many processes we have running vs. 16174 // how many slots we have for background processes; we may want 16175 // to put multiple processes in a slot of there are enough of 16176 // them. 16177 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16178 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16179 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16180 if (numEmptyProcs > cachedProcessLimit) { 16181 // If there are more empty processes than our limit on cached 16182 // processes, then use the cached process limit for the factor. 16183 // This ensures that the really old empty processes get pushed 16184 // down to the bottom, so if we are running low on memory we will 16185 // have a better chance at keeping around more cached processes 16186 // instead of a gazillion empty processes. 16187 numEmptyProcs = cachedProcessLimit; 16188 } 16189 int emptyFactor = numEmptyProcs/numSlots; 16190 if (emptyFactor < 1) emptyFactor = 1; 16191 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16192 if (cachedFactor < 1) cachedFactor = 1; 16193 int stepCached = 0; 16194 int stepEmpty = 0; 16195 int numCached = 0; 16196 int numEmpty = 0; 16197 int numTrimming = 0; 16198 16199 mNumNonCachedProcs = 0; 16200 mNumCachedHiddenProcs = 0; 16201 16202 // First update the OOM adjustment for each of the 16203 // application processes based on their current state. 16204 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16205 int nextCachedAdj = curCachedAdj+1; 16206 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16207 int nextEmptyAdj = curEmptyAdj+2; 16208 for (int i=N-1; i>=0; i--) { 16209 ProcessRecord app = mLruProcesses.get(i); 16210 if (!app.killedByAm && app.thread != null) { 16211 app.procStateChanged = false; 16212 final boolean wasKeeping = app.keeping; 16213 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16214 16215 // If we haven't yet assigned the final cached adj 16216 // to the process, do that now. 16217 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16218 switch (app.curProcState) { 16219 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16220 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16221 // This process is a cached process holding activities... 16222 // assign it the next cached value for that type, and then 16223 // step that cached level. 16224 app.curRawAdj = curCachedAdj; 16225 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16226 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16227 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16228 + ")"); 16229 if (curCachedAdj != nextCachedAdj) { 16230 stepCached++; 16231 if (stepCached >= cachedFactor) { 16232 stepCached = 0; 16233 curCachedAdj = nextCachedAdj; 16234 nextCachedAdj += 2; 16235 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16236 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16237 } 16238 } 16239 } 16240 break; 16241 default: 16242 // For everything else, assign next empty cached process 16243 // level and bump that up. Note that this means that 16244 // long-running services that have dropped down to the 16245 // cached level will be treated as empty (since their process 16246 // state is still as a service), which is what we want. 16247 app.curRawAdj = curEmptyAdj; 16248 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16249 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16250 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16251 + ")"); 16252 if (curEmptyAdj != nextEmptyAdj) { 16253 stepEmpty++; 16254 if (stepEmpty >= emptyFactor) { 16255 stepEmpty = 0; 16256 curEmptyAdj = nextEmptyAdj; 16257 nextEmptyAdj += 2; 16258 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16259 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16260 } 16261 } 16262 } 16263 break; 16264 } 16265 } 16266 16267 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16268 16269 // Count the number of process types. 16270 switch (app.curProcState) { 16271 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16272 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16273 mNumCachedHiddenProcs++; 16274 numCached++; 16275 if (numCached > cachedProcessLimit) { 16276 killUnneededProcessLocked(app, "cached #" + numCached); 16277 } 16278 break; 16279 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16280 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16281 && app.lastActivityTime < oldTime) { 16282 killUnneededProcessLocked(app, "empty for " 16283 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16284 / 1000) + "s"); 16285 } else { 16286 numEmpty++; 16287 if (numEmpty > emptyProcessLimit) { 16288 killUnneededProcessLocked(app, "empty #" + numEmpty); 16289 } 16290 } 16291 break; 16292 default: 16293 mNumNonCachedProcs++; 16294 break; 16295 } 16296 16297 if (app.isolated && app.services.size() <= 0) { 16298 // If this is an isolated process, and there are no 16299 // services running in it, then the process is no longer 16300 // needed. We agressively kill these because we can by 16301 // definition not re-use the same process again, and it is 16302 // good to avoid having whatever code was running in them 16303 // left sitting around after no longer needed. 16304 killUnneededProcessLocked(app, "isolated not needed"); 16305 } 16306 16307 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16308 && !app.killedByAm) { 16309 numTrimming++; 16310 } 16311 } 16312 } 16313 16314 mNumServiceProcs = mNewNumServiceProcs; 16315 16316 // Now determine the memory trimming level of background processes. 16317 // Unfortunately we need to start at the back of the list to do this 16318 // properly. We only do this if the number of background apps we 16319 // are managing to keep around is less than half the maximum we desire; 16320 // if we are keeping a good number around, we'll let them use whatever 16321 // memory they want. 16322 final int numCachedAndEmpty = numCached + numEmpty; 16323 int memFactor; 16324 if (numCached <= ProcessList.TRIM_CACHED_APPS 16325 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16326 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16327 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16328 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16329 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16330 } else { 16331 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16332 } 16333 } else { 16334 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16335 } 16336 // We always allow the memory level to go up (better). We only allow it to go 16337 // down if we are in a state where that is allowed, *and* the total number of processes 16338 // has gone down since last time. 16339 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16340 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16341 + " last=" + mLastNumProcesses); 16342 if (memFactor > mLastMemoryLevel) { 16343 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16344 memFactor = mLastMemoryLevel; 16345 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16346 } 16347 } 16348 mLastMemoryLevel = memFactor; 16349 mLastNumProcesses = mLruProcesses.size(); 16350 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16351 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16352 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16353 if (mLowRamStartTime == 0) { 16354 mLowRamStartTime = now; 16355 } 16356 int step = 0; 16357 int fgTrimLevel; 16358 switch (memFactor) { 16359 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16360 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16361 break; 16362 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16363 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16364 break; 16365 default: 16366 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16367 break; 16368 } 16369 int factor = numTrimming/3; 16370 int minFactor = 2; 16371 if (mHomeProcess != null) minFactor++; 16372 if (mPreviousProcess != null) minFactor++; 16373 if (factor < minFactor) factor = minFactor; 16374 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16375 for (int i=N-1; i>=0; i--) { 16376 ProcessRecord app = mLruProcesses.get(i); 16377 if (allChanged || app.procStateChanged) { 16378 setProcessTrackerState(app, trackerMemFactor, now); 16379 app.procStateChanged = false; 16380 } 16381 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16382 && !app.killedByAm) { 16383 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16384 try { 16385 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16386 "Trimming memory of " + app.processName 16387 + " to " + curLevel); 16388 app.thread.scheduleTrimMemory(curLevel); 16389 } catch (RemoteException e) { 16390 } 16391 if (false) { 16392 // For now we won't do this; our memory trimming seems 16393 // to be good enough at this point that destroying 16394 // activities causes more harm than good. 16395 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16396 && app != mHomeProcess && app != mPreviousProcess) { 16397 // Need to do this on its own message because the stack may not 16398 // be in a consistent state at this point. 16399 // For these apps we will also finish their activities 16400 // to help them free memory. 16401 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16402 } 16403 } 16404 } 16405 app.trimMemoryLevel = curLevel; 16406 step++; 16407 if (step >= factor) { 16408 step = 0; 16409 switch (curLevel) { 16410 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16411 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16412 break; 16413 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16414 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16415 break; 16416 } 16417 } 16418 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16419 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16420 && app.thread != null) { 16421 try { 16422 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16423 "Trimming memory of heavy-weight " + app.processName 16424 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16425 app.thread.scheduleTrimMemory( 16426 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16427 } catch (RemoteException e) { 16428 } 16429 } 16430 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16431 } else { 16432 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16433 || app.systemNoUi) && app.pendingUiClean) { 16434 // If this application is now in the background and it 16435 // had done UI, then give it the special trim level to 16436 // have it free UI resources. 16437 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16438 if (app.trimMemoryLevel < level && app.thread != null) { 16439 try { 16440 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16441 "Trimming memory of bg-ui " + app.processName 16442 + " to " + level); 16443 app.thread.scheduleTrimMemory(level); 16444 } catch (RemoteException e) { 16445 } 16446 } 16447 app.pendingUiClean = false; 16448 } 16449 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16450 try { 16451 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16452 "Trimming memory of fg " + app.processName 16453 + " to " + fgTrimLevel); 16454 app.thread.scheduleTrimMemory(fgTrimLevel); 16455 } catch (RemoteException e) { 16456 } 16457 } 16458 app.trimMemoryLevel = fgTrimLevel; 16459 } 16460 } 16461 } else { 16462 if (mLowRamStartTime != 0) { 16463 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16464 mLowRamStartTime = 0; 16465 } 16466 for (int i=N-1; i>=0; i--) { 16467 ProcessRecord app = mLruProcesses.get(i); 16468 if (allChanged || app.procStateChanged) { 16469 setProcessTrackerState(app, trackerMemFactor, now); 16470 app.procStateChanged = false; 16471 } 16472 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16473 || app.systemNoUi) && app.pendingUiClean) { 16474 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16475 && app.thread != null) { 16476 try { 16477 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16478 "Trimming memory of ui hidden " + app.processName 16479 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16480 app.thread.scheduleTrimMemory( 16481 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16482 } catch (RemoteException e) { 16483 } 16484 } 16485 app.pendingUiClean = false; 16486 } 16487 app.trimMemoryLevel = 0; 16488 } 16489 } 16490 16491 if (mAlwaysFinishActivities) { 16492 // Need to do this on its own message because the stack may not 16493 // be in a consistent state at this point. 16494 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16495 } 16496 16497 if (allChanged) { 16498 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16499 } 16500 16501 if (mProcessStats.shouldWriteNowLocked(now)) { 16502 mHandler.post(new Runnable() { 16503 @Override public void run() { 16504 synchronized (ActivityManagerService.this) { 16505 mProcessStats.writeStateAsyncLocked(); 16506 } 16507 } 16508 }); 16509 } 16510 16511 if (DEBUG_OOM_ADJ) { 16512 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16513 } 16514 } 16515 16516 final void trimApplications() { 16517 synchronized (this) { 16518 int i; 16519 16520 // First remove any unused application processes whose package 16521 // has been removed. 16522 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16523 final ProcessRecord app = mRemovedProcesses.get(i); 16524 if (app.activities.size() == 0 16525 && app.curReceiver == null && app.services.size() == 0) { 16526 Slog.i( 16527 TAG, "Exiting empty application process " 16528 + app.processName + " (" 16529 + (app.thread != null ? app.thread.asBinder() : null) 16530 + ")\n"); 16531 if (app.pid > 0 && app.pid != MY_PID) { 16532 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16533 app.processName, app.setAdj, "empty"); 16534 app.killedByAm = true; 16535 Process.killProcessQuiet(app.pid); 16536 } else { 16537 try { 16538 app.thread.scheduleExit(); 16539 } catch (Exception e) { 16540 // Ignore exceptions. 16541 } 16542 } 16543 cleanUpApplicationRecordLocked(app, false, true, -1); 16544 mRemovedProcesses.remove(i); 16545 16546 if (app.persistent) { 16547 if (app.persistent) { 16548 addAppLocked(app.info, false, null /* ABI override */); 16549 } 16550 } 16551 } 16552 } 16553 16554 // Now update the oom adj for all processes. 16555 updateOomAdjLocked(); 16556 } 16557 } 16558 16559 /** This method sends the specified signal to each of the persistent apps */ 16560 public void signalPersistentProcesses(int sig) throws RemoteException { 16561 if (sig != Process.SIGNAL_USR1) { 16562 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16563 } 16564 16565 synchronized (this) { 16566 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16567 != PackageManager.PERMISSION_GRANTED) { 16568 throw new SecurityException("Requires permission " 16569 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16570 } 16571 16572 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16573 ProcessRecord r = mLruProcesses.get(i); 16574 if (r.thread != null && r.persistent) { 16575 Process.sendSignal(r.pid, sig); 16576 } 16577 } 16578 } 16579 } 16580 16581 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16582 if (proc == null || proc == mProfileProc) { 16583 proc = mProfileProc; 16584 path = mProfileFile; 16585 profileType = mProfileType; 16586 clearProfilerLocked(); 16587 } 16588 if (proc == null) { 16589 return; 16590 } 16591 try { 16592 proc.thread.profilerControl(false, path, null, profileType); 16593 } catch (RemoteException e) { 16594 throw new IllegalStateException("Process disappeared"); 16595 } 16596 } 16597 16598 private void clearProfilerLocked() { 16599 if (mProfileFd != null) { 16600 try { 16601 mProfileFd.close(); 16602 } catch (IOException e) { 16603 } 16604 } 16605 mProfileApp = null; 16606 mProfileProc = null; 16607 mProfileFile = null; 16608 mProfileType = 0; 16609 mAutoStopProfiler = false; 16610 } 16611 16612 public boolean profileControl(String process, int userId, boolean start, 16613 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16614 16615 try { 16616 synchronized (this) { 16617 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16618 // its own permission. 16619 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16620 != PackageManager.PERMISSION_GRANTED) { 16621 throw new SecurityException("Requires permission " 16622 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16623 } 16624 16625 if (start && fd == null) { 16626 throw new IllegalArgumentException("null fd"); 16627 } 16628 16629 ProcessRecord proc = null; 16630 if (process != null) { 16631 proc = findProcessLocked(process, userId, "profileControl"); 16632 } 16633 16634 if (start && (proc == null || proc.thread == null)) { 16635 throw new IllegalArgumentException("Unknown process: " + process); 16636 } 16637 16638 if (start) { 16639 stopProfilerLocked(null, null, 0); 16640 setProfileApp(proc.info, proc.processName, path, fd, false); 16641 mProfileProc = proc; 16642 mProfileType = profileType; 16643 try { 16644 fd = fd.dup(); 16645 } catch (IOException e) { 16646 fd = null; 16647 } 16648 proc.thread.profilerControl(start, path, fd, profileType); 16649 fd = null; 16650 mProfileFd = null; 16651 } else { 16652 stopProfilerLocked(proc, path, profileType); 16653 if (fd != null) { 16654 try { 16655 fd.close(); 16656 } catch (IOException e) { 16657 } 16658 } 16659 } 16660 16661 return true; 16662 } 16663 } catch (RemoteException e) { 16664 throw new IllegalStateException("Process disappeared"); 16665 } finally { 16666 if (fd != null) { 16667 try { 16668 fd.close(); 16669 } catch (IOException e) { 16670 } 16671 } 16672 } 16673 } 16674 16675 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16676 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16677 userId, true, true, callName, null); 16678 ProcessRecord proc = null; 16679 try { 16680 int pid = Integer.parseInt(process); 16681 synchronized (mPidsSelfLocked) { 16682 proc = mPidsSelfLocked.get(pid); 16683 } 16684 } catch (NumberFormatException e) { 16685 } 16686 16687 if (proc == null) { 16688 ArrayMap<String, SparseArray<ProcessRecord>> all 16689 = mProcessNames.getMap(); 16690 SparseArray<ProcessRecord> procs = all.get(process); 16691 if (procs != null && procs.size() > 0) { 16692 proc = procs.valueAt(0); 16693 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16694 for (int i=1; i<procs.size(); i++) { 16695 ProcessRecord thisProc = procs.valueAt(i); 16696 if (thisProc.userId == userId) { 16697 proc = thisProc; 16698 break; 16699 } 16700 } 16701 } 16702 } 16703 } 16704 16705 return proc; 16706 } 16707 16708 public boolean dumpHeap(String process, int userId, boolean managed, 16709 String path, ParcelFileDescriptor fd) throws RemoteException { 16710 16711 try { 16712 synchronized (this) { 16713 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16714 // its own permission (same as profileControl). 16715 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16716 != PackageManager.PERMISSION_GRANTED) { 16717 throw new SecurityException("Requires permission " 16718 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16719 } 16720 16721 if (fd == null) { 16722 throw new IllegalArgumentException("null fd"); 16723 } 16724 16725 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16726 if (proc == null || proc.thread == null) { 16727 throw new IllegalArgumentException("Unknown process: " + process); 16728 } 16729 16730 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16731 if (!isDebuggable) { 16732 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16733 throw new SecurityException("Process not debuggable: " + proc); 16734 } 16735 } 16736 16737 proc.thread.dumpHeap(managed, path, fd); 16738 fd = null; 16739 return true; 16740 } 16741 } catch (RemoteException e) { 16742 throw new IllegalStateException("Process disappeared"); 16743 } finally { 16744 if (fd != null) { 16745 try { 16746 fd.close(); 16747 } catch (IOException e) { 16748 } 16749 } 16750 } 16751 } 16752 16753 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16754 public void monitor() { 16755 synchronized (this) { } 16756 } 16757 16758 void onCoreSettingsChange(Bundle settings) { 16759 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16760 ProcessRecord processRecord = mLruProcesses.get(i); 16761 try { 16762 if (processRecord.thread != null) { 16763 processRecord.thread.setCoreSettings(settings); 16764 } 16765 } catch (RemoteException re) { 16766 /* ignore */ 16767 } 16768 } 16769 } 16770 16771 // Multi-user methods 16772 16773 /** 16774 * Start user, if its not already running, but don't bring it to foreground. 16775 */ 16776 @Override 16777 public boolean startUserInBackground(final int userId) { 16778 return startUser(userId, /* foreground */ false); 16779 } 16780 16781 /** 16782 * Refreshes the list of users related to the current user when either a 16783 * user switch happens or when a new related user is started in the 16784 * background. 16785 */ 16786 private void updateCurrentProfileIdsLocked() { 16787 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16788 mCurrentUserId, false /* enabledOnly */); 16789 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16790 for (int i = 0; i < currentProfileIds.length; i++) { 16791 currentProfileIds[i] = profiles.get(i).id; 16792 } 16793 mCurrentProfileIds = currentProfileIds; 16794 } 16795 16796 private Set getProfileIdsLocked(int userId) { 16797 Set userIds = new HashSet<Integer>(); 16798 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16799 userId, false /* enabledOnly */); 16800 for (UserInfo user : profiles) { 16801 userIds.add(Integer.valueOf(user.id)); 16802 } 16803 return userIds; 16804 } 16805 16806 @Override 16807 public boolean switchUser(final int userId) { 16808 return startUser(userId, /* foregound */ true); 16809 } 16810 16811 private boolean startUser(final int userId, boolean foreground) { 16812 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16813 != PackageManager.PERMISSION_GRANTED) { 16814 String msg = "Permission Denial: switchUser() from pid=" 16815 + Binder.getCallingPid() 16816 + ", uid=" + Binder.getCallingUid() 16817 + " requires " + INTERACT_ACROSS_USERS_FULL; 16818 Slog.w(TAG, msg); 16819 throw new SecurityException(msg); 16820 } 16821 16822 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16823 16824 final long ident = Binder.clearCallingIdentity(); 16825 try { 16826 synchronized (this) { 16827 final int oldUserId = mCurrentUserId; 16828 if (oldUserId == userId) { 16829 return true; 16830 } 16831 16832 mStackSupervisor.setLockTaskModeLocked(null, false); 16833 16834 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16835 if (userInfo == null) { 16836 Slog.w(TAG, "No user info for user #" + userId); 16837 return false; 16838 } 16839 16840 if (foreground) { 16841 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16842 R.anim.screen_user_enter); 16843 } 16844 16845 boolean needStart = false; 16846 16847 // If the user we are switching to is not currently started, then 16848 // we need to start it now. 16849 if (mStartedUsers.get(userId) == null) { 16850 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16851 updateStartedUserArrayLocked(); 16852 needStart = true; 16853 } 16854 16855 final Integer userIdInt = Integer.valueOf(userId); 16856 mUserLru.remove(userIdInt); 16857 mUserLru.add(userIdInt); 16858 16859 if (foreground) { 16860 mCurrentUserId = userId; 16861 updateCurrentProfileIdsLocked(); 16862 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16863 // Once the internal notion of the active user has switched, we lock the device 16864 // with the option to show the user switcher on the keyguard. 16865 mWindowManager.lockNow(null); 16866 } else { 16867 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16868 updateCurrentProfileIdsLocked(); 16869 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16870 mUserLru.remove(currentUserIdInt); 16871 mUserLru.add(currentUserIdInt); 16872 } 16873 16874 final UserStartedState uss = mStartedUsers.get(userId); 16875 16876 // Make sure user is in the started state. If it is currently 16877 // stopping, we need to knock that off. 16878 if (uss.mState == UserStartedState.STATE_STOPPING) { 16879 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16880 // so we can just fairly silently bring the user back from 16881 // the almost-dead. 16882 uss.mState = UserStartedState.STATE_RUNNING; 16883 updateStartedUserArrayLocked(); 16884 needStart = true; 16885 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16886 // This means ACTION_SHUTDOWN has been sent, so we will 16887 // need to treat this as a new boot of the user. 16888 uss.mState = UserStartedState.STATE_BOOTING; 16889 updateStartedUserArrayLocked(); 16890 needStart = true; 16891 } 16892 16893 if (uss.mState == UserStartedState.STATE_BOOTING) { 16894 // Booting up a new user, need to tell system services about it. 16895 // Note that this is on the same handler as scheduling of broadcasts, 16896 // which is important because it needs to go first. 16897 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16898 } 16899 16900 if (foreground) { 16901 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16902 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16903 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16904 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16905 oldUserId, userId, uss)); 16906 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16907 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16908 } 16909 16910 if (needStart) { 16911 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16912 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16913 | Intent.FLAG_RECEIVER_FOREGROUND); 16914 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16915 broadcastIntentLocked(null, null, intent, 16916 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16917 false, false, MY_PID, Process.SYSTEM_UID, userId); 16918 } 16919 16920 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16921 if (userId != UserHandle.USER_OWNER) { 16922 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16923 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16924 broadcastIntentLocked(null, null, intent, null, 16925 new IIntentReceiver.Stub() { 16926 public void performReceive(Intent intent, int resultCode, 16927 String data, Bundle extras, boolean ordered, 16928 boolean sticky, int sendingUser) { 16929 userInitialized(uss, userId); 16930 } 16931 }, 0, null, null, null, AppOpsManager.OP_NONE, 16932 true, false, MY_PID, Process.SYSTEM_UID, 16933 userId); 16934 uss.initializing = true; 16935 } else { 16936 getUserManagerLocked().makeInitialized(userInfo.id); 16937 } 16938 } 16939 16940 if (foreground) { 16941 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16942 if (homeInFront) { 16943 startHomeActivityLocked(userId); 16944 } else { 16945 mStackSupervisor.resumeTopActivitiesLocked(); 16946 } 16947 EventLogTags.writeAmSwitchUser(userId); 16948 getUserManagerLocked().userForeground(userId); 16949 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16950 } else { 16951 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16952 } 16953 16954 if (needStart) { 16955 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16956 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16957 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16958 broadcastIntentLocked(null, null, intent, 16959 null, new IIntentReceiver.Stub() { 16960 @Override 16961 public void performReceive(Intent intent, int resultCode, String data, 16962 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16963 throws RemoteException { 16964 } 16965 }, 0, null, null, 16966 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16967 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16968 } 16969 } 16970 } finally { 16971 Binder.restoreCallingIdentity(ident); 16972 } 16973 16974 return true; 16975 } 16976 16977 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16978 long ident = Binder.clearCallingIdentity(); 16979 try { 16980 Intent intent; 16981 if (oldUserId >= 0) { 16982 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16983 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16984 | Intent.FLAG_RECEIVER_FOREGROUND); 16985 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16986 broadcastIntentLocked(null, null, intent, 16987 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16988 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16989 } 16990 if (newUserId >= 0) { 16991 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16992 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16993 | Intent.FLAG_RECEIVER_FOREGROUND); 16994 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16995 broadcastIntentLocked(null, null, intent, 16996 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16997 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16998 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16999 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17000 | Intent.FLAG_RECEIVER_FOREGROUND); 17001 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17002 broadcastIntentLocked(null, null, intent, 17003 null, null, 0, null, null, 17004 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17005 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17006 } 17007 } finally { 17008 Binder.restoreCallingIdentity(ident); 17009 } 17010 } 17011 17012 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17013 final int newUserId) { 17014 final int N = mUserSwitchObservers.beginBroadcast(); 17015 if (N > 0) { 17016 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17017 int mCount = 0; 17018 @Override 17019 public void sendResult(Bundle data) throws RemoteException { 17020 synchronized (ActivityManagerService.this) { 17021 if (mCurUserSwitchCallback == this) { 17022 mCount++; 17023 if (mCount == N) { 17024 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17025 } 17026 } 17027 } 17028 } 17029 }; 17030 synchronized (this) { 17031 uss.switching = true; 17032 mCurUserSwitchCallback = callback; 17033 } 17034 for (int i=0; i<N; i++) { 17035 try { 17036 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17037 newUserId, callback); 17038 } catch (RemoteException e) { 17039 } 17040 } 17041 } else { 17042 synchronized (this) { 17043 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17044 } 17045 } 17046 mUserSwitchObservers.finishBroadcast(); 17047 } 17048 17049 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17050 synchronized (this) { 17051 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17052 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17053 } 17054 } 17055 17056 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17057 mCurUserSwitchCallback = null; 17058 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17059 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17060 oldUserId, newUserId, uss)); 17061 } 17062 17063 void userInitialized(UserStartedState uss, int newUserId) { 17064 completeSwitchAndInitalize(uss, newUserId, true, false); 17065 } 17066 17067 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17068 completeSwitchAndInitalize(uss, newUserId, false, true); 17069 } 17070 17071 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17072 boolean clearInitializing, boolean clearSwitching) { 17073 boolean unfrozen = false; 17074 synchronized (this) { 17075 if (clearInitializing) { 17076 uss.initializing = false; 17077 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17078 } 17079 if (clearSwitching) { 17080 uss.switching = false; 17081 } 17082 if (!uss.switching && !uss.initializing) { 17083 mWindowManager.stopFreezingScreen(); 17084 unfrozen = true; 17085 } 17086 } 17087 if (unfrozen) { 17088 final int N = mUserSwitchObservers.beginBroadcast(); 17089 for (int i=0; i<N; i++) { 17090 try { 17091 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17092 } catch (RemoteException e) { 17093 } 17094 } 17095 mUserSwitchObservers.finishBroadcast(); 17096 } 17097 } 17098 17099 void scheduleStartProfilesLocked() { 17100 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17101 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17102 DateUtils.SECOND_IN_MILLIS); 17103 } 17104 } 17105 17106 void startProfilesLocked() { 17107 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17108 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17109 mCurrentUserId, false /* enabledOnly */); 17110 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17111 for (UserInfo user : profiles) { 17112 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17113 && user.id != mCurrentUserId) { 17114 toStart.add(user); 17115 } 17116 } 17117 final int n = toStart.size(); 17118 int i = 0; 17119 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17120 startUserInBackground(toStart.get(i).id); 17121 } 17122 if (i < n) { 17123 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17124 } 17125 } 17126 17127 void finishUserBoot(UserStartedState uss) { 17128 synchronized (this) { 17129 if (uss.mState == UserStartedState.STATE_BOOTING 17130 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17131 uss.mState = UserStartedState.STATE_RUNNING; 17132 final int userId = uss.mHandle.getIdentifier(); 17133 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17134 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17135 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17136 broadcastIntentLocked(null, null, intent, 17137 null, null, 0, null, null, 17138 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17139 true, false, MY_PID, Process.SYSTEM_UID, userId); 17140 } 17141 } 17142 } 17143 17144 void finishUserSwitch(UserStartedState uss) { 17145 synchronized (this) { 17146 finishUserBoot(uss); 17147 17148 startProfilesLocked(); 17149 17150 int num = mUserLru.size(); 17151 int i = 0; 17152 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17153 Integer oldUserId = mUserLru.get(i); 17154 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17155 if (oldUss == null) { 17156 // Shouldn't happen, but be sane if it does. 17157 mUserLru.remove(i); 17158 num--; 17159 continue; 17160 } 17161 if (oldUss.mState == UserStartedState.STATE_STOPPING 17162 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17163 // This user is already stopping, doesn't count. 17164 num--; 17165 i++; 17166 continue; 17167 } 17168 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17169 // Owner and current can't be stopped, but count as running. 17170 i++; 17171 continue; 17172 } 17173 // This is a user to be stopped. 17174 stopUserLocked(oldUserId, null); 17175 num--; 17176 i++; 17177 } 17178 } 17179 } 17180 17181 @Override 17182 public int stopUser(final int userId, final IStopUserCallback callback) { 17183 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17184 != PackageManager.PERMISSION_GRANTED) { 17185 String msg = "Permission Denial: switchUser() from pid=" 17186 + Binder.getCallingPid() 17187 + ", uid=" + Binder.getCallingUid() 17188 + " requires " + INTERACT_ACROSS_USERS_FULL; 17189 Slog.w(TAG, msg); 17190 throw new SecurityException(msg); 17191 } 17192 if (userId <= 0) { 17193 throw new IllegalArgumentException("Can't stop primary user " + userId); 17194 } 17195 synchronized (this) { 17196 return stopUserLocked(userId, callback); 17197 } 17198 } 17199 17200 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17201 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17202 if (mCurrentUserId == userId) { 17203 return ActivityManager.USER_OP_IS_CURRENT; 17204 } 17205 17206 final UserStartedState uss = mStartedUsers.get(userId); 17207 if (uss == null) { 17208 // User is not started, nothing to do... but we do need to 17209 // callback if requested. 17210 if (callback != null) { 17211 mHandler.post(new Runnable() { 17212 @Override 17213 public void run() { 17214 try { 17215 callback.userStopped(userId); 17216 } catch (RemoteException e) { 17217 } 17218 } 17219 }); 17220 } 17221 return ActivityManager.USER_OP_SUCCESS; 17222 } 17223 17224 if (callback != null) { 17225 uss.mStopCallbacks.add(callback); 17226 } 17227 17228 if (uss.mState != UserStartedState.STATE_STOPPING 17229 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17230 uss.mState = UserStartedState.STATE_STOPPING; 17231 updateStartedUserArrayLocked(); 17232 17233 long ident = Binder.clearCallingIdentity(); 17234 try { 17235 // We are going to broadcast ACTION_USER_STOPPING and then 17236 // once that is done send a final ACTION_SHUTDOWN and then 17237 // stop the user. 17238 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17239 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17240 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17241 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17242 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17243 // This is the result receiver for the final shutdown broadcast. 17244 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17245 @Override 17246 public void performReceive(Intent intent, int resultCode, String data, 17247 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17248 finishUserStop(uss); 17249 } 17250 }; 17251 // This is the result receiver for the initial stopping broadcast. 17252 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17253 @Override 17254 public void performReceive(Intent intent, int resultCode, String data, 17255 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17256 // On to the next. 17257 synchronized (ActivityManagerService.this) { 17258 if (uss.mState != UserStartedState.STATE_STOPPING) { 17259 // Whoops, we are being started back up. Abort, abort! 17260 return; 17261 } 17262 uss.mState = UserStartedState.STATE_SHUTDOWN; 17263 } 17264 mSystemServiceManager.stopUser(userId); 17265 broadcastIntentLocked(null, null, shutdownIntent, 17266 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17267 true, false, MY_PID, Process.SYSTEM_UID, userId); 17268 } 17269 }; 17270 // Kick things off. 17271 broadcastIntentLocked(null, null, stoppingIntent, 17272 null, stoppingReceiver, 0, null, null, 17273 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17274 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17275 } finally { 17276 Binder.restoreCallingIdentity(ident); 17277 } 17278 } 17279 17280 return ActivityManager.USER_OP_SUCCESS; 17281 } 17282 17283 void finishUserStop(UserStartedState uss) { 17284 final int userId = uss.mHandle.getIdentifier(); 17285 boolean stopped; 17286 ArrayList<IStopUserCallback> callbacks; 17287 synchronized (this) { 17288 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17289 if (mStartedUsers.get(userId) != uss) { 17290 stopped = false; 17291 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17292 stopped = false; 17293 } else { 17294 stopped = true; 17295 // User can no longer run. 17296 mStartedUsers.remove(userId); 17297 mUserLru.remove(Integer.valueOf(userId)); 17298 updateStartedUserArrayLocked(); 17299 17300 // Clean up all state and processes associated with the user. 17301 // Kill all the processes for the user. 17302 forceStopUserLocked(userId, "finish user"); 17303 } 17304 } 17305 17306 for (int i=0; i<callbacks.size(); i++) { 17307 try { 17308 if (stopped) callbacks.get(i).userStopped(userId); 17309 else callbacks.get(i).userStopAborted(userId); 17310 } catch (RemoteException e) { 17311 } 17312 } 17313 17314 if (stopped) { 17315 mSystemServiceManager.cleanupUser(userId); 17316 synchronized (this) { 17317 mStackSupervisor.removeUserLocked(userId); 17318 } 17319 } 17320 } 17321 17322 @Override 17323 public UserInfo getCurrentUser() { 17324 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17325 != PackageManager.PERMISSION_GRANTED) && ( 17326 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17327 != PackageManager.PERMISSION_GRANTED)) { 17328 String msg = "Permission Denial: getCurrentUser() from pid=" 17329 + Binder.getCallingPid() 17330 + ", uid=" + Binder.getCallingUid() 17331 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17332 Slog.w(TAG, msg); 17333 throw new SecurityException(msg); 17334 } 17335 synchronized (this) { 17336 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17337 } 17338 } 17339 17340 int getCurrentUserIdLocked() { 17341 return mCurrentUserId; 17342 } 17343 17344 @Override 17345 public boolean isUserRunning(int userId, boolean orStopped) { 17346 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17347 != PackageManager.PERMISSION_GRANTED) { 17348 String msg = "Permission Denial: isUserRunning() from pid=" 17349 + Binder.getCallingPid() 17350 + ", uid=" + Binder.getCallingUid() 17351 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17352 Slog.w(TAG, msg); 17353 throw new SecurityException(msg); 17354 } 17355 synchronized (this) { 17356 return isUserRunningLocked(userId, orStopped); 17357 } 17358 } 17359 17360 boolean isUserRunningLocked(int userId, boolean orStopped) { 17361 UserStartedState state = mStartedUsers.get(userId); 17362 if (state == null) { 17363 return false; 17364 } 17365 if (orStopped) { 17366 return true; 17367 } 17368 return state.mState != UserStartedState.STATE_STOPPING 17369 && state.mState != UserStartedState.STATE_SHUTDOWN; 17370 } 17371 17372 @Override 17373 public int[] getRunningUserIds() { 17374 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17375 != PackageManager.PERMISSION_GRANTED) { 17376 String msg = "Permission Denial: isUserRunning() from pid=" 17377 + Binder.getCallingPid() 17378 + ", uid=" + Binder.getCallingUid() 17379 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17380 Slog.w(TAG, msg); 17381 throw new SecurityException(msg); 17382 } 17383 synchronized (this) { 17384 return mStartedUserArray; 17385 } 17386 } 17387 17388 private void updateStartedUserArrayLocked() { 17389 int num = 0; 17390 for (int i=0; i<mStartedUsers.size(); i++) { 17391 UserStartedState uss = mStartedUsers.valueAt(i); 17392 // This list does not include stopping users. 17393 if (uss.mState != UserStartedState.STATE_STOPPING 17394 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17395 num++; 17396 } 17397 } 17398 mStartedUserArray = new int[num]; 17399 num = 0; 17400 for (int i=0; i<mStartedUsers.size(); i++) { 17401 UserStartedState uss = mStartedUsers.valueAt(i); 17402 if (uss.mState != UserStartedState.STATE_STOPPING 17403 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17404 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17405 num++; 17406 } 17407 } 17408 } 17409 17410 @Override 17411 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17412 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17413 != PackageManager.PERMISSION_GRANTED) { 17414 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17415 + Binder.getCallingPid() 17416 + ", uid=" + Binder.getCallingUid() 17417 + " requires " + INTERACT_ACROSS_USERS_FULL; 17418 Slog.w(TAG, msg); 17419 throw new SecurityException(msg); 17420 } 17421 17422 mUserSwitchObservers.register(observer); 17423 } 17424 17425 @Override 17426 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17427 mUserSwitchObservers.unregister(observer); 17428 } 17429 17430 private boolean userExists(int userId) { 17431 if (userId == 0) { 17432 return true; 17433 } 17434 UserManagerService ums = getUserManagerLocked(); 17435 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17436 } 17437 17438 int[] getUsersLocked() { 17439 UserManagerService ums = getUserManagerLocked(); 17440 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17441 } 17442 17443 UserManagerService getUserManagerLocked() { 17444 if (mUserManager == null) { 17445 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17446 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17447 } 17448 return mUserManager; 17449 } 17450 17451 private int applyUserId(int uid, int userId) { 17452 return UserHandle.getUid(userId, uid); 17453 } 17454 17455 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17456 if (info == null) return null; 17457 ApplicationInfo newInfo = new ApplicationInfo(info); 17458 newInfo.uid = applyUserId(info.uid, userId); 17459 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17460 + info.packageName; 17461 return newInfo; 17462 } 17463 17464 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17465 if (aInfo == null 17466 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17467 return aInfo; 17468 } 17469 17470 ActivityInfo info = new ActivityInfo(aInfo); 17471 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17472 return info; 17473 } 17474 17475 private final class LocalService extends ActivityManagerInternal { 17476 @Override 17477 public void goingToSleep() { 17478 ActivityManagerService.this.goingToSleep(); 17479 } 17480 17481 @Override 17482 public void wakingUp() { 17483 ActivityManagerService.this.wakingUp(); 17484 } 17485 } 17486 17487 /** 17488 * An implementation of IAppTask, that allows an app to manage its own tasks via 17489 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17490 * only the process that calls getAppTasks() can call the AppTask methods. 17491 */ 17492 class AppTaskImpl extends IAppTask.Stub { 17493 private int mTaskId; 17494 private int mCallingUid; 17495 17496 public AppTaskImpl(int taskId, int callingUid) { 17497 mTaskId = taskId; 17498 mCallingUid = callingUid; 17499 } 17500 17501 @Override 17502 public void finishAndRemoveTask() { 17503 // Ensure that we are called from the same process that created this AppTask 17504 if (mCallingUid != Binder.getCallingUid()) { 17505 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17506 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17507 return; 17508 } 17509 17510 synchronized (ActivityManagerService.this) { 17511 long origId = Binder.clearCallingIdentity(); 17512 try { 17513 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17514 if (tr != null) { 17515 // Only kill the process if we are not a new document 17516 int flags = tr.getBaseIntent().getFlags(); 17517 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17518 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17519 removeTaskByIdLocked(mTaskId, 17520 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17521 } 17522 } finally { 17523 Binder.restoreCallingIdentity(origId); 17524 } 17525 } 17526 } 17527 17528 @Override 17529 public ActivityManager.RecentTaskInfo getTaskInfo() { 17530 // Ensure that we are called from the same process that created this AppTask 17531 if (mCallingUid != Binder.getCallingUid()) { 17532 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17533 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17534 return null; 17535 } 17536 17537 synchronized (ActivityManagerService.this) { 17538 long origId = Binder.clearCallingIdentity(); 17539 try { 17540 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17541 if (tr != null) { 17542 return createRecentTaskInfoFromTaskRecord(tr); 17543 } 17544 } finally { 17545 Binder.restoreCallingIdentity(origId); 17546 } 17547 return null; 17548 } 17549 } 17550 } 17551} 17552