ActivityManagerService.java revision d908edd810dd22d8ec512a19c32637df464e9d0a
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 20import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21import static com.android.internal.util.XmlUtils.readBooleanAttribute; 22import static com.android.internal.util.XmlUtils.readIntAttribute; 23import static com.android.internal.util.XmlUtils.readLongAttribute; 24import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 25import static com.android.internal.util.XmlUtils.writeIntAttribute; 26import static com.android.internal.util.XmlUtils.writeLongAttribute; 27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 29import static org.xmlpull.v1.XmlPullParser.START_TAG; 30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 31 32import android.Manifest; 33import android.app.AppOpsManager; 34import android.app.IActivityContainer; 35import android.app.IActivityContainerCallback; 36import android.app.IAppTask; 37import android.app.admin.DevicePolicyManager; 38import android.appwidget.AppWidgetManager; 39import android.graphics.Rect; 40import android.os.BatteryStats; 41import android.os.PersistableBundle; 42import android.service.voice.IVoiceInteractionSession; 43import android.util.ArrayMap; 44 45import com.android.internal.R; 46import com.android.internal.annotations.GuardedBy; 47import com.android.internal.app.IAppOpsService; 48import com.android.internal.app.IVoiceInteractor; 49import com.android.internal.app.ProcessMap; 50import com.android.internal.app.ProcessStats; 51import com.android.internal.content.PackageMonitor; 52import com.android.internal.os.BackgroundThread; 53import com.android.internal.os.BatteryStatsImpl; 54import com.android.internal.os.ProcessCpuTracker; 55import com.android.internal.os.TransferPipe; 56import com.android.internal.os.Zygote; 57import com.android.internal.util.FastPrintWriter; 58import com.android.internal.util.FastXmlSerializer; 59import com.android.internal.util.MemInfoReader; 60import com.android.internal.util.Preconditions; 61import com.android.server.AppOpsService; 62import com.android.server.AttributeCache; 63import com.android.server.IntentResolver; 64import com.android.server.LocalServices; 65import com.android.server.ServiceThread; 66import com.android.server.SystemService; 67import com.android.server.SystemServiceManager; 68import com.android.server.Watchdog; 69import com.android.server.am.ActivityStack.ActivityState; 70import com.android.server.firewall.IntentFirewall; 71import com.android.server.pm.UserManagerService; 72import com.android.server.wm.AppTransition; 73import com.android.server.wm.WindowManagerService; 74import com.google.android.collect.Lists; 75import com.google.android.collect.Maps; 76 77import libcore.io.IoUtils; 78 79import org.xmlpull.v1.XmlPullParser; 80import org.xmlpull.v1.XmlPullParserException; 81import org.xmlpull.v1.XmlSerializer; 82 83import android.app.Activity; 84import android.app.ActivityManager; 85import android.app.ActivityManager.RunningTaskInfo; 86import android.app.ActivityManager.StackInfo; 87import android.app.ActivityManagerInternal; 88import android.app.ActivityManagerNative; 89import android.app.ActivityOptions; 90import android.app.ActivityThread; 91import android.app.AlertDialog; 92import android.app.AppGlobals; 93import android.app.ApplicationErrorReport; 94import android.app.Dialog; 95import android.app.IActivityController; 96import android.app.IApplicationThread; 97import android.app.IInstrumentationWatcher; 98import android.app.INotificationManager; 99import android.app.IProcessObserver; 100import android.app.IServiceConnection; 101import android.app.IStopUserCallback; 102import android.app.IUiAutomationConnection; 103import android.app.IUserSwitchObserver; 104import android.app.Instrumentation; 105import android.app.Notification; 106import android.app.NotificationManager; 107import android.app.PendingIntent; 108import android.app.backup.IBackupManager; 109import android.content.ActivityNotFoundException; 110import android.content.BroadcastReceiver; 111import android.content.ClipData; 112import android.content.ComponentCallbacks2; 113import android.content.ComponentName; 114import android.content.ContentProvider; 115import android.content.ContentResolver; 116import android.content.Context; 117import android.content.DialogInterface; 118import android.content.IContentProvider; 119import android.content.IIntentReceiver; 120import android.content.IIntentSender; 121import android.content.Intent; 122import android.content.IntentFilter; 123import android.content.IntentSender; 124import android.content.pm.ActivityInfo; 125import android.content.pm.ApplicationInfo; 126import android.content.pm.ConfigurationInfo; 127import android.content.pm.IPackageDataObserver; 128import android.content.pm.IPackageManager; 129import android.content.pm.InstrumentationInfo; 130import android.content.pm.PackageInfo; 131import android.content.pm.PackageManager; 132import android.content.pm.ParceledListSlice; 133import android.content.pm.UserInfo; 134import android.content.pm.PackageManager.NameNotFoundException; 135import android.content.pm.PathPermission; 136import android.content.pm.ProviderInfo; 137import android.content.pm.ResolveInfo; 138import android.content.pm.ServiceInfo; 139import android.content.res.CompatibilityInfo; 140import android.content.res.Configuration; 141import android.graphics.Bitmap; 142import android.net.Proxy; 143import android.net.ProxyInfo; 144import android.net.Uri; 145import android.os.Binder; 146import android.os.Build; 147import android.os.Bundle; 148import android.os.Debug; 149import android.os.DropBoxManager; 150import android.os.Environment; 151import android.os.FactoryTest; 152import android.os.FileObserver; 153import android.os.FileUtils; 154import android.os.Handler; 155import android.os.IBinder; 156import android.os.IPermissionController; 157import android.os.IRemoteCallback; 158import android.os.IUserManager; 159import android.os.Looper; 160import android.os.Message; 161import android.os.Parcel; 162import android.os.ParcelFileDescriptor; 163import android.os.Process; 164import android.os.RemoteCallbackList; 165import android.os.RemoteException; 166import android.os.SELinux; 167import android.os.ServiceManager; 168import android.os.StrictMode; 169import android.os.SystemClock; 170import android.os.SystemProperties; 171import android.os.UpdateLock; 172import android.os.UserHandle; 173import android.provider.Settings; 174import android.text.format.DateUtils; 175import android.text.format.Time; 176import android.util.AtomicFile; 177import android.util.EventLog; 178import android.util.Log; 179import android.util.Pair; 180import android.util.PrintWriterPrinter; 181import android.util.Slog; 182import android.util.SparseArray; 183import android.util.TimeUtils; 184import android.util.Xml; 185import android.view.Gravity; 186import android.view.LayoutInflater; 187import android.view.View; 188import android.view.WindowManager; 189 190import java.io.BufferedInputStream; 191import java.io.BufferedOutputStream; 192import java.io.DataInputStream; 193import java.io.DataOutputStream; 194import java.io.File; 195import java.io.FileDescriptor; 196import java.io.FileInputStream; 197import java.io.FileNotFoundException; 198import java.io.FileOutputStream; 199import java.io.IOException; 200import java.io.InputStreamReader; 201import java.io.PrintWriter; 202import java.io.StringWriter; 203import java.lang.ref.WeakReference; 204import java.util.ArrayList; 205import java.util.Arrays; 206import java.util.Collections; 207import java.util.Comparator; 208import java.util.HashMap; 209import java.util.HashSet; 210import java.util.Iterator; 211import java.util.List; 212import java.util.Locale; 213import java.util.Map; 214import java.util.Set; 215import java.util.concurrent.atomic.AtomicBoolean; 216import java.util.concurrent.atomic.AtomicLong; 217 218public final class ActivityManagerService extends ActivityManagerNative 219 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 220 private static final String USER_DATA_DIR = "/data/user/"; 221 static final String TAG = "ActivityManager"; 222 static final String TAG_MU = "ActivityManagerServiceMU"; 223 static final boolean DEBUG = false; 224 static final boolean localLOGV = DEBUG; 225 static final boolean DEBUG_BACKUP = localLOGV || false; 226 static final boolean DEBUG_BROADCAST = localLOGV || false; 227 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 229 static final boolean DEBUG_CLEANUP = localLOGV || false; 230 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 231 static final boolean DEBUG_FOCUS = false; 232 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 233 static final boolean DEBUG_MU = localLOGV || false; 234 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 235 static final boolean DEBUG_LRU = localLOGV || false; 236 static final boolean DEBUG_PAUSE = localLOGV || false; 237 static final boolean DEBUG_POWER = localLOGV || false; 238 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 239 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 240 static final boolean DEBUG_PROCESSES = localLOGV || false; 241 static final boolean DEBUG_PROVIDER = localLOGV || false; 242 static final boolean DEBUG_RESULTS = localLOGV || false; 243 static final boolean DEBUG_SERVICE = localLOGV || false; 244 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 245 static final boolean DEBUG_STACK = localLOGV || false; 246 static final boolean DEBUG_SWITCH = localLOGV || false; 247 static final boolean DEBUG_TASKS = localLOGV || false; 248 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 249 static final boolean DEBUG_TRANSITION = localLOGV || false; 250 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 251 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 252 static final boolean DEBUG_VISBILITY = localLOGV || false; 253 static final boolean DEBUG_PSS = localLOGV || false; 254 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 255 static final boolean VALIDATE_TOKENS = false; 256 static final boolean SHOW_ACTIVITY_START_TIME = true; 257 258 // Control over CPU and battery monitoring. 259 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 260 static final boolean MONITOR_CPU_USAGE = true; 261 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 262 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 263 static final boolean MONITOR_THREAD_CPU_USAGE = false; 264 265 // The flags that are set for all calls we make to the package manager. 266 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 267 268 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 269 270 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 271 272 // Maximum number of recent tasks that we can remember. 273 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200; 274 275 // Maximum number recent bitmaps to keep in memory. 276 static final int MAX_RECENT_BITMAPS = 5; 277 278 // Amount of time after a call to stopAppSwitches() during which we will 279 // prevent further untrusted switches from happening. 280 static final long APP_SWITCH_DELAY_TIME = 5*1000; 281 282 // How long we wait for a launched process to attach to the activity manager 283 // before we decide it's never going to come up for real. 284 static final int PROC_START_TIMEOUT = 10*1000; 285 286 // How long we wait for a launched process to attach to the activity manager 287 // before we decide it's never going to come up for real, when the process was 288 // started with a wrapper for instrumentation (such as Valgrind) because it 289 // could take much longer than usual. 290 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 291 292 // How long to wait after going idle before forcing apps to GC. 293 static final int GC_TIMEOUT = 5*1000; 294 295 // The minimum amount of time between successive GC requests for a process. 296 static final int GC_MIN_INTERVAL = 60*1000; 297 298 // The minimum amount of time between successive PSS requests for a process. 299 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 300 301 // The minimum amount of time between successive PSS requests for a process 302 // when the request is due to the memory state being lowered. 303 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 304 305 // The rate at which we check for apps using excessive power -- 15 mins. 306 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 307 308 // The minimum sample duration we will allow before deciding we have 309 // enough data on wake locks to start killing things. 310 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 311 312 // The minimum sample duration we will allow before deciding we have 313 // enough data on CPU usage to start killing things. 314 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 315 316 // How long we allow a receiver to run before giving up on it. 317 static final int BROADCAST_FG_TIMEOUT = 10*1000; 318 static final int BROADCAST_BG_TIMEOUT = 60*1000; 319 320 // How long we wait until we timeout on key dispatching. 321 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 322 323 // How long we wait until we timeout on key dispatching during instrumentation. 324 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 325 326 // Amount of time we wait for observers to handle a user switch before 327 // giving up on them and unfreezing the screen. 328 static final int USER_SWITCH_TIMEOUT = 2*1000; 329 330 // Maximum number of users we allow to be running at a time. 331 static final int MAX_RUNNING_USERS = 3; 332 333 // How long to wait in getAssistContextExtras for the activity and foreground services 334 // to respond with the result. 335 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 336 337 // Maximum number of persisted Uri grants a package is allowed 338 static final int MAX_PERSISTED_URI_GRANTS = 128; 339 340 static final int MY_PID = Process.myPid(); 341 342 static final String[] EMPTY_STRING_ARRAY = new String[0]; 343 344 // How many bytes to write into the dropbox log before truncating 345 static final int DROPBOX_MAX_SIZE = 256 * 1024; 346 347 /** All system services */ 348 SystemServiceManager mSystemServiceManager; 349 350 /** Run all ActivityStacks through this */ 351 ActivityStackSupervisor mStackSupervisor; 352 353 public IntentFirewall mIntentFirewall; 354 355 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 356 // default actuion automatically. Important for devices without direct input 357 // devices. 358 private boolean mShowDialogs = true; 359 360 /** 361 * Description of a request to start a new activity, which has been held 362 * due to app switches being disabled. 363 */ 364 static class PendingActivityLaunch { 365 final ActivityRecord r; 366 final ActivityRecord sourceRecord; 367 final int startFlags; 368 final ActivityStack stack; 369 370 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 371 int _startFlags, ActivityStack _stack) { 372 r = _r; 373 sourceRecord = _sourceRecord; 374 startFlags = _startFlags; 375 stack = _stack; 376 } 377 } 378 379 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 380 = new ArrayList<PendingActivityLaunch>(); 381 382 BroadcastQueue mFgBroadcastQueue; 383 BroadcastQueue mBgBroadcastQueue; 384 // Convenient for easy iteration over the queues. Foreground is first 385 // so that dispatch of foreground broadcasts gets precedence. 386 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 387 388 BroadcastQueue broadcastQueueForIntent(Intent intent) { 389 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 390 if (DEBUG_BACKGROUND_BROADCAST) { 391 Slog.i(TAG, "Broadcast intent " + intent + " on " 392 + (isFg ? "foreground" : "background") 393 + " queue"); 394 } 395 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 396 } 397 398 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 399 for (BroadcastQueue queue : mBroadcastQueues) { 400 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 401 if (r != null) { 402 return r; 403 } 404 } 405 return null; 406 } 407 408 /** 409 * Activity we have told the window manager to have key focus. 410 */ 411 ActivityRecord mFocusedActivity = null; 412 413 /** 414 * List of intents that were used to start the most recent tasks. 415 */ 416 ArrayList<TaskRecord> mRecentTasks; 417 418 public class PendingAssistExtras extends Binder implements Runnable { 419 public final ActivityRecord activity; 420 public boolean haveResult = false; 421 public Bundle result = null; 422 public PendingAssistExtras(ActivityRecord _activity) { 423 activity = _activity; 424 } 425 @Override 426 public void run() { 427 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 428 synchronized (this) { 429 haveResult = true; 430 notifyAll(); 431 } 432 } 433 } 434 435 final ArrayList<PendingAssistExtras> mPendingAssistExtras 436 = new ArrayList<PendingAssistExtras>(); 437 438 /** 439 * Process management. 440 */ 441 final ProcessList mProcessList = new ProcessList(); 442 443 /** 444 * All of the applications we currently have running organized by name. 445 * The keys are strings of the application package name (as 446 * returned by the package manager), and the keys are ApplicationRecord 447 * objects. 448 */ 449 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 450 451 /** 452 * Tracking long-term execution of processes to look for abuse and other 453 * bad app behavior. 454 */ 455 final ProcessStatsService mProcessStats; 456 457 /** 458 * The currently running isolated processes. 459 */ 460 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 461 462 /** 463 * Counter for assigning isolated process uids, to avoid frequently reusing the 464 * same ones. 465 */ 466 int mNextIsolatedProcessUid = 0; 467 468 /** 469 * The currently running heavy-weight process, if any. 470 */ 471 ProcessRecord mHeavyWeightProcess = null; 472 473 /** 474 * The last time that various processes have crashed. 475 */ 476 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 477 478 /** 479 * Information about a process that is currently marked as bad. 480 */ 481 static final class BadProcessInfo { 482 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 483 this.time = time; 484 this.shortMsg = shortMsg; 485 this.longMsg = longMsg; 486 this.stack = stack; 487 } 488 489 final long time; 490 final String shortMsg; 491 final String longMsg; 492 final String stack; 493 } 494 495 /** 496 * Set of applications that we consider to be bad, and will reject 497 * incoming broadcasts from (which the user has no control over). 498 * Processes are added to this set when they have crashed twice within 499 * a minimum amount of time; they are removed from it when they are 500 * later restarted (hopefully due to some user action). The value is the 501 * time it was added to the list. 502 */ 503 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 504 505 /** 506 * All of the processes we currently have running organized by pid. 507 * The keys are the pid running the application. 508 * 509 * <p>NOTE: This object is protected by its own lock, NOT the global 510 * activity manager lock! 511 */ 512 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 513 514 /** 515 * All of the processes that have been forced to be foreground. The key 516 * is the pid of the caller who requested it (we hold a death 517 * link on it). 518 */ 519 abstract class ForegroundToken implements IBinder.DeathRecipient { 520 int pid; 521 IBinder token; 522 } 523 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 524 525 /** 526 * List of records for processes that someone had tried to start before the 527 * system was ready. We don't start them at that point, but ensure they 528 * are started by the time booting is complete. 529 */ 530 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 531 532 /** 533 * List of persistent applications that are in the process 534 * of being started. 535 */ 536 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 537 538 /** 539 * Processes that are being forcibly torn down. 540 */ 541 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 542 543 /** 544 * List of running applications, sorted by recent usage. 545 * The first entry in the list is the least recently used. 546 */ 547 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 548 549 /** 550 * Where in mLruProcesses that the processes hosting activities start. 551 */ 552 int mLruProcessActivityStart = 0; 553 554 /** 555 * Where in mLruProcesses that the processes hosting services start. 556 * This is after (lower index) than mLruProcessesActivityStart. 557 */ 558 int mLruProcessServiceStart = 0; 559 560 /** 561 * List of processes that should gc as soon as things are idle. 562 */ 563 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 564 565 /** 566 * Processes we want to collect PSS data from. 567 */ 568 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 569 570 /** 571 * Last time we requested PSS data of all processes. 572 */ 573 long mLastFullPssTime = SystemClock.uptimeMillis(); 574 575 /** 576 * If set, the next time we collect PSS data we should do a full collection 577 * with data from native processes and the kernel. 578 */ 579 boolean mFullPssPending = false; 580 581 /** 582 * This is the process holding what we currently consider to be 583 * the "home" activity. 584 */ 585 ProcessRecord mHomeProcess; 586 587 /** 588 * This is the process holding the activity the user last visited that 589 * is in a different process from the one they are currently in. 590 */ 591 ProcessRecord mPreviousProcess; 592 593 /** 594 * The time at which the previous process was last visible. 595 */ 596 long mPreviousProcessVisibleTime; 597 598 /** 599 * Which uses have been started, so are allowed to run code. 600 */ 601 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 602 603 /** 604 * LRU list of history of current users. Most recently current is at the end. 605 */ 606 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 607 608 /** 609 * Constant array of the users that are currently started. 610 */ 611 int[] mStartedUserArray = new int[] { 0 }; 612 613 /** 614 * Registered observers of the user switching mechanics. 615 */ 616 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 617 = new RemoteCallbackList<IUserSwitchObserver>(); 618 619 /** 620 * Currently active user switch. 621 */ 622 Object mCurUserSwitchCallback; 623 624 /** 625 * Packages that the user has asked to have run in screen size 626 * compatibility mode instead of filling the screen. 627 */ 628 final CompatModePackages mCompatModePackages; 629 630 /** 631 * Set of IntentSenderRecord objects that are currently active. 632 */ 633 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 634 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 635 636 /** 637 * Fingerprints (hashCode()) of stack traces that we've 638 * already logged DropBox entries for. Guarded by itself. If 639 * something (rogue user app) forces this over 640 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 641 */ 642 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 643 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 644 645 /** 646 * Strict Mode background batched logging state. 647 * 648 * The string buffer is guarded by itself, and its lock is also 649 * used to determine if another batched write is already 650 * in-flight. 651 */ 652 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 653 654 /** 655 * Keeps track of all IIntentReceivers that have been registered for 656 * broadcasts. Hash keys are the receiver IBinder, hash value is 657 * a ReceiverList. 658 */ 659 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 660 new HashMap<IBinder, ReceiverList>(); 661 662 /** 663 * Resolver for broadcast intents to registered receivers. 664 * Holds BroadcastFilter (subclass of IntentFilter). 665 */ 666 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 667 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 668 @Override 669 protected boolean allowFilterResult( 670 BroadcastFilter filter, List<BroadcastFilter> dest) { 671 IBinder target = filter.receiverList.receiver.asBinder(); 672 for (int i=dest.size()-1; i>=0; i--) { 673 if (dest.get(i).receiverList.receiver.asBinder() == target) { 674 return false; 675 } 676 } 677 return true; 678 } 679 680 @Override 681 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 682 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 683 || userId == filter.owningUserId) { 684 return super.newResult(filter, match, userId); 685 } 686 return null; 687 } 688 689 @Override 690 protected BroadcastFilter[] newArray(int size) { 691 return new BroadcastFilter[size]; 692 } 693 694 @Override 695 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 696 return packageName.equals(filter.packageName); 697 } 698 }; 699 700 /** 701 * State of all active sticky broadcasts per user. Keys are the action of the 702 * sticky Intent, values are an ArrayList of all broadcasted intents with 703 * that action (which should usually be one). The SparseArray is keyed 704 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 705 * for stickies that are sent to all users. 706 */ 707 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 708 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 709 710 final ActiveServices mServices; 711 712 /** 713 * Backup/restore process management 714 */ 715 String mBackupAppName = null; 716 BackupRecord mBackupTarget = null; 717 718 final ProviderMap mProviderMap; 719 720 /** 721 * List of content providers who have clients waiting for them. The 722 * application is currently being launched and the provider will be 723 * removed from this list once it is published. 724 */ 725 final ArrayList<ContentProviderRecord> mLaunchingProviders 726 = new ArrayList<ContentProviderRecord>(); 727 728 /** 729 * File storing persisted {@link #mGrantedUriPermissions}. 730 */ 731 private final AtomicFile mGrantFile; 732 733 /** XML constants used in {@link #mGrantFile} */ 734 private static final String TAG_URI_GRANTS = "uri-grants"; 735 private static final String TAG_URI_GRANT = "uri-grant"; 736 private static final String ATTR_USER_HANDLE = "userHandle"; 737 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 738 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 739 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 740 private static final String ATTR_TARGET_PKG = "targetPkg"; 741 private static final String ATTR_URI = "uri"; 742 private static final String ATTR_MODE_FLAGS = "modeFlags"; 743 private static final String ATTR_CREATED_TIME = "createdTime"; 744 private static final String ATTR_PREFIX = "prefix"; 745 746 /** 747 * Global set of specific {@link Uri} permissions that have been granted. 748 * This optimized lookup structure maps from {@link UriPermission#targetUid} 749 * to {@link UriPermission#uri} to {@link UriPermission}. 750 */ 751 @GuardedBy("this") 752 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 753 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 754 755 public static class GrantUri { 756 public final int sourceUserId; 757 public final Uri uri; 758 public boolean prefix; 759 760 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 761 this.sourceUserId = sourceUserId; 762 this.uri = uri; 763 this.prefix = prefix; 764 } 765 766 @Override 767 public int hashCode() { 768 return toString().hashCode(); 769 } 770 771 @Override 772 public boolean equals(Object o) { 773 if (o instanceof GrantUri) { 774 GrantUri other = (GrantUri) o; 775 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 776 && prefix == other.prefix; 777 } 778 return false; 779 } 780 781 @Override 782 public String toString() { 783 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 784 if (prefix) result += " [prefix]"; 785 return result; 786 } 787 788 public String toSafeString() { 789 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 790 if (prefix) result += " [prefix]"; 791 return result; 792 } 793 794 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 795 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 796 ContentProvider.getUriWithoutUserId(uri), false); 797 } 798 } 799 800 CoreSettingsObserver mCoreSettingsObserver; 801 802 /** 803 * Thread-local storage used to carry caller permissions over through 804 * indirect content-provider access. 805 */ 806 private class Identity { 807 public int pid; 808 public int uid; 809 810 Identity(int _pid, int _uid) { 811 pid = _pid; 812 uid = _uid; 813 } 814 } 815 816 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 817 818 /** 819 * All information we have collected about the runtime performance of 820 * any user id that can impact battery performance. 821 */ 822 final BatteryStatsService mBatteryStatsService; 823 824 /** 825 * Information about component usage 826 */ 827 final UsageStatsService mUsageStatsService; 828 829 /** 830 * Information about and control over application operations 831 */ 832 final AppOpsService mAppOpsService; 833 834 /** 835 * Save recent tasks information across reboots. 836 */ 837 final TaskPersister mTaskPersister; 838 839 /** 840 * Current configuration information. HistoryRecord objects are given 841 * a reference to this object to indicate which configuration they are 842 * currently running in, so this object must be kept immutable. 843 */ 844 Configuration mConfiguration = new Configuration(); 845 846 /** 847 * Current sequencing integer of the configuration, for skipping old 848 * configurations. 849 */ 850 int mConfigurationSeq = 0; 851 852 /** 853 * Hardware-reported OpenGLES version. 854 */ 855 final int GL_ES_VERSION; 856 857 /** 858 * List of initialization arguments to pass to all processes when binding applications to them. 859 * For example, references to the commonly used services. 860 */ 861 HashMap<String, IBinder> mAppBindArgs; 862 863 /** 864 * Temporary to avoid allocations. Protected by main lock. 865 */ 866 final StringBuilder mStringBuilder = new StringBuilder(256); 867 868 /** 869 * Used to control how we initialize the service. 870 */ 871 ComponentName mTopComponent; 872 String mTopAction = Intent.ACTION_MAIN; 873 String mTopData; 874 boolean mProcessesReady = false; 875 boolean mSystemReady = false; 876 boolean mBooting = false; 877 boolean mWaitingUpdate = false; 878 boolean mDidUpdate = false; 879 boolean mOnBattery = false; 880 boolean mLaunchWarningShown = false; 881 882 Context mContext; 883 884 int mFactoryTest; 885 886 boolean mCheckedForSetup; 887 888 /** 889 * The time at which we will allow normal application switches again, 890 * after a call to {@link #stopAppSwitches()}. 891 */ 892 long mAppSwitchesAllowedTime; 893 894 /** 895 * This is set to true after the first switch after mAppSwitchesAllowedTime 896 * is set; any switches after that will clear the time. 897 */ 898 boolean mDidAppSwitch; 899 900 /** 901 * Last time (in realtime) at which we checked for power usage. 902 */ 903 long mLastPowerCheckRealtime; 904 905 /** 906 * Last time (in uptime) at which we checked for power usage. 907 */ 908 long mLastPowerCheckUptime; 909 910 /** 911 * Set while we are wanting to sleep, to prevent any 912 * activities from being started/resumed. 913 */ 914 private boolean mSleeping = false; 915 916 /** 917 * Set while we are running a voice interaction. This overrides 918 * sleeping while it is active. 919 */ 920 private boolean mRunningVoice = false; 921 922 /** 923 * State of external calls telling us if the device is asleep. 924 */ 925 private boolean mWentToSleep = false; 926 927 /** 928 * State of external call telling us if the lock screen is shown. 929 */ 930 private boolean mLockScreenShown = false; 931 932 /** 933 * Set if we are shutting down the system, similar to sleeping. 934 */ 935 boolean mShuttingDown = false; 936 937 /** 938 * Current sequence id for oom_adj computation traversal. 939 */ 940 int mAdjSeq = 0; 941 942 /** 943 * Current sequence id for process LRU updating. 944 */ 945 int mLruSeq = 0; 946 947 /** 948 * Keep track of the non-cached/empty process we last found, to help 949 * determine how to distribute cached/empty processes next time. 950 */ 951 int mNumNonCachedProcs = 0; 952 953 /** 954 * Keep track of the number of cached hidden procs, to balance oom adj 955 * distribution between those and empty procs. 956 */ 957 int mNumCachedHiddenProcs = 0; 958 959 /** 960 * Keep track of the number of service processes we last found, to 961 * determine on the next iteration which should be B services. 962 */ 963 int mNumServiceProcs = 0; 964 int mNewNumAServiceProcs = 0; 965 int mNewNumServiceProcs = 0; 966 967 /** 968 * Allow the current computed overall memory level of the system to go down? 969 * This is set to false when we are killing processes for reasons other than 970 * memory management, so that the now smaller process list will not be taken as 971 * an indication that memory is tighter. 972 */ 973 boolean mAllowLowerMemLevel = false; 974 975 /** 976 * The last computed memory level, for holding when we are in a state that 977 * processes are going away for other reasons. 978 */ 979 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 980 981 /** 982 * The last total number of process we have, to determine if changes actually look 983 * like a shrinking number of process due to lower RAM. 984 */ 985 int mLastNumProcesses; 986 987 /** 988 * The uptime of the last time we performed idle maintenance. 989 */ 990 long mLastIdleTime = SystemClock.uptimeMillis(); 991 992 /** 993 * Total time spent with RAM that has been added in the past since the last idle time. 994 */ 995 long mLowRamTimeSinceLastIdle = 0; 996 997 /** 998 * If RAM is currently low, when that horrible situation started. 999 */ 1000 long mLowRamStartTime = 0; 1001 1002 /** 1003 * For reporting to battery stats the current top application. 1004 */ 1005 private String mCurResumedPackage = null; 1006 private int mCurResumedUid = -1; 1007 1008 /** 1009 * For reporting to battery stats the apps currently running foreground 1010 * service. The ProcessMap is package/uid tuples; each of these contain 1011 * an array of the currently foreground processes. 1012 */ 1013 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1014 = new ProcessMap<ArrayList<ProcessRecord>>(); 1015 1016 /** 1017 * This is set if we had to do a delayed dexopt of an app before launching 1018 * it, to increase the ANR timeouts in that case. 1019 */ 1020 boolean mDidDexOpt; 1021 1022 /** 1023 * Set if the systemServer made a call to enterSafeMode. 1024 */ 1025 boolean mSafeMode; 1026 1027 String mDebugApp = null; 1028 boolean mWaitForDebugger = false; 1029 boolean mDebugTransient = false; 1030 String mOrigDebugApp = null; 1031 boolean mOrigWaitForDebugger = false; 1032 boolean mAlwaysFinishActivities = false; 1033 IActivityController mController = null; 1034 String mProfileApp = null; 1035 ProcessRecord mProfileProc = null; 1036 String mProfileFile; 1037 ParcelFileDescriptor mProfileFd; 1038 int mProfileType = 0; 1039 boolean mAutoStopProfiler = false; 1040 String mOpenGlTraceApp = null; 1041 1042 static class ProcessChangeItem { 1043 static final int CHANGE_ACTIVITIES = 1<<0; 1044 static final int CHANGE_PROCESS_STATE = 1<<1; 1045 int changes; 1046 int uid; 1047 int pid; 1048 int processState; 1049 boolean foregroundActivities; 1050 } 1051 1052 final RemoteCallbackList<IProcessObserver> mProcessObservers 1053 = new RemoteCallbackList<IProcessObserver>(); 1054 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1055 1056 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1057 = new ArrayList<ProcessChangeItem>(); 1058 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1059 = new ArrayList<ProcessChangeItem>(); 1060 1061 /** 1062 * Runtime CPU use collection thread. This object's lock is used to 1063 * protect all related state. 1064 */ 1065 final Thread mProcessCpuThread; 1066 1067 /** 1068 * Used to collect process stats when showing not responding dialog. 1069 * Protected by mProcessCpuThread. 1070 */ 1071 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1072 MONITOR_THREAD_CPU_USAGE); 1073 final AtomicLong mLastCpuTime = new AtomicLong(0); 1074 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1075 1076 long mLastWriteTime = 0; 1077 1078 /** 1079 * Used to retain an update lock when the foreground activity is in 1080 * immersive mode. 1081 */ 1082 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1083 1084 /** 1085 * Set to true after the system has finished booting. 1086 */ 1087 boolean mBooted = false; 1088 1089 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1090 int mProcessLimitOverride = -1; 1091 1092 WindowManagerService mWindowManager; 1093 1094 final ActivityThread mSystemThread; 1095 1096 int mCurrentUserId = 0; 1097 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1098 private UserManagerService mUserManager; 1099 1100 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1101 final ProcessRecord mApp; 1102 final int mPid; 1103 final IApplicationThread mAppThread; 1104 1105 AppDeathRecipient(ProcessRecord app, int pid, 1106 IApplicationThread thread) { 1107 if (localLOGV) Slog.v( 1108 TAG, "New death recipient " + this 1109 + " for thread " + thread.asBinder()); 1110 mApp = app; 1111 mPid = pid; 1112 mAppThread = thread; 1113 } 1114 1115 @Override 1116 public void binderDied() { 1117 if (localLOGV) Slog.v( 1118 TAG, "Death received in " + this 1119 + " for thread " + mAppThread.asBinder()); 1120 synchronized(ActivityManagerService.this) { 1121 appDiedLocked(mApp, mPid, mAppThread); 1122 } 1123 } 1124 } 1125 1126 static final int SHOW_ERROR_MSG = 1; 1127 static final int SHOW_NOT_RESPONDING_MSG = 2; 1128 static final int SHOW_FACTORY_ERROR_MSG = 3; 1129 static final int UPDATE_CONFIGURATION_MSG = 4; 1130 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1131 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1132 static final int SERVICE_TIMEOUT_MSG = 12; 1133 static final int UPDATE_TIME_ZONE = 13; 1134 static final int SHOW_UID_ERROR_MSG = 14; 1135 static final int IM_FEELING_LUCKY_MSG = 15; 1136 static final int PROC_START_TIMEOUT_MSG = 20; 1137 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1138 static final int KILL_APPLICATION_MSG = 22; 1139 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1140 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1141 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1142 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1143 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1144 static final int CLEAR_DNS_CACHE_MSG = 28; 1145 static final int UPDATE_HTTP_PROXY_MSG = 29; 1146 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1147 static final int DISPATCH_PROCESSES_CHANGED = 31; 1148 static final int DISPATCH_PROCESS_DIED = 32; 1149 static final int REPORT_MEM_USAGE_MSG = 33; 1150 static final int REPORT_USER_SWITCH_MSG = 34; 1151 static final int CONTINUE_USER_SWITCH_MSG = 35; 1152 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1153 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1154 static final int PERSIST_URI_GRANTS_MSG = 38; 1155 static final int REQUEST_ALL_PSS_MSG = 39; 1156 static final int START_PROFILES_MSG = 40; 1157 static final int UPDATE_TIME = 41; 1158 static final int SYSTEM_USER_START_MSG = 42; 1159 static final int SYSTEM_USER_CURRENT_MSG = 43; 1160 1161 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1162 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1163 static final int FIRST_COMPAT_MODE_MSG = 300; 1164 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1165 1166 AlertDialog mUidAlert; 1167 CompatModeDialog mCompatModeDialog; 1168 long mLastMemUsageReportTime = 0; 1169 1170 private LockToAppRequestDialog mLockToAppRequest; 1171 1172 /** 1173 * Flag whether the current user is a "monkey", i.e. whether 1174 * the UI is driven by a UI automation tool. 1175 */ 1176 private boolean mUserIsMonkey; 1177 1178 final ServiceThread mHandlerThread; 1179 final MainHandler mHandler; 1180 1181 final class MainHandler extends Handler { 1182 public MainHandler(Looper looper) { 1183 super(looper, null, true); 1184 } 1185 1186 @Override 1187 public void handleMessage(Message msg) { 1188 switch (msg.what) { 1189 case SHOW_ERROR_MSG: { 1190 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1191 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1192 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1193 synchronized (ActivityManagerService.this) { 1194 ProcessRecord proc = (ProcessRecord)data.get("app"); 1195 AppErrorResult res = (AppErrorResult) data.get("result"); 1196 if (proc != null && proc.crashDialog != null) { 1197 Slog.e(TAG, "App already has crash dialog: " + proc); 1198 if (res != null) { 1199 res.set(0); 1200 } 1201 return; 1202 } 1203 if (!showBackground && UserHandle.getAppId(proc.uid) 1204 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1205 && proc.pid != MY_PID) { 1206 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1207 if (res != null) { 1208 res.set(0); 1209 } 1210 return; 1211 } 1212 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1213 Dialog d = new AppErrorDialog(mContext, 1214 ActivityManagerService.this, res, proc); 1215 d.show(); 1216 proc.crashDialog = d; 1217 } else { 1218 // The device is asleep, so just pretend that the user 1219 // saw a crash dialog and hit "force quit". 1220 if (res != null) { 1221 res.set(0); 1222 } 1223 } 1224 } 1225 1226 ensureBootCompleted(); 1227 } break; 1228 case SHOW_NOT_RESPONDING_MSG: { 1229 synchronized (ActivityManagerService.this) { 1230 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1231 ProcessRecord proc = (ProcessRecord)data.get("app"); 1232 if (proc != null && proc.anrDialog != null) { 1233 Slog.e(TAG, "App already has anr dialog: " + proc); 1234 return; 1235 } 1236 1237 Intent intent = new Intent("android.intent.action.ANR"); 1238 if (!mProcessesReady) { 1239 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1240 | Intent.FLAG_RECEIVER_FOREGROUND); 1241 } 1242 broadcastIntentLocked(null, null, intent, 1243 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1244 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1245 1246 if (mShowDialogs) { 1247 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1248 mContext, proc, (ActivityRecord)data.get("activity"), 1249 msg.arg1 != 0); 1250 d.show(); 1251 proc.anrDialog = d; 1252 } else { 1253 // Just kill the app if there is no dialog to be shown. 1254 killAppAtUsersRequest(proc, null); 1255 } 1256 } 1257 1258 ensureBootCompleted(); 1259 } break; 1260 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1261 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1262 synchronized (ActivityManagerService.this) { 1263 ProcessRecord proc = (ProcessRecord) data.get("app"); 1264 if (proc == null) { 1265 Slog.e(TAG, "App not found when showing strict mode dialog."); 1266 break; 1267 } 1268 if (proc.crashDialog != null) { 1269 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1270 return; 1271 } 1272 AppErrorResult res = (AppErrorResult) data.get("result"); 1273 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1274 Dialog d = new StrictModeViolationDialog(mContext, 1275 ActivityManagerService.this, res, proc); 1276 d.show(); 1277 proc.crashDialog = d; 1278 } else { 1279 // The device is asleep, so just pretend that the user 1280 // saw a crash dialog and hit "force quit". 1281 res.set(0); 1282 } 1283 } 1284 ensureBootCompleted(); 1285 } break; 1286 case SHOW_FACTORY_ERROR_MSG: { 1287 Dialog d = new FactoryErrorDialog( 1288 mContext, msg.getData().getCharSequence("msg")); 1289 d.show(); 1290 ensureBootCompleted(); 1291 } break; 1292 case UPDATE_CONFIGURATION_MSG: { 1293 final ContentResolver resolver = mContext.getContentResolver(); 1294 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1295 } break; 1296 case GC_BACKGROUND_PROCESSES_MSG: { 1297 synchronized (ActivityManagerService.this) { 1298 performAppGcsIfAppropriateLocked(); 1299 } 1300 } break; 1301 case WAIT_FOR_DEBUGGER_MSG: { 1302 synchronized (ActivityManagerService.this) { 1303 ProcessRecord app = (ProcessRecord)msg.obj; 1304 if (msg.arg1 != 0) { 1305 if (!app.waitedForDebugger) { 1306 Dialog d = new AppWaitingForDebuggerDialog( 1307 ActivityManagerService.this, 1308 mContext, app); 1309 app.waitDialog = d; 1310 app.waitedForDebugger = true; 1311 d.show(); 1312 } 1313 } else { 1314 if (app.waitDialog != null) { 1315 app.waitDialog.dismiss(); 1316 app.waitDialog = null; 1317 } 1318 } 1319 } 1320 } break; 1321 case SERVICE_TIMEOUT_MSG: { 1322 if (mDidDexOpt) { 1323 mDidDexOpt = false; 1324 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1325 nmsg.obj = msg.obj; 1326 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1327 return; 1328 } 1329 mServices.serviceTimeout((ProcessRecord)msg.obj); 1330 } break; 1331 case UPDATE_TIME_ZONE: { 1332 synchronized (ActivityManagerService.this) { 1333 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1334 ProcessRecord r = mLruProcesses.get(i); 1335 if (r.thread != null) { 1336 try { 1337 r.thread.updateTimeZone(); 1338 } catch (RemoteException ex) { 1339 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1340 } 1341 } 1342 } 1343 } 1344 } break; 1345 case CLEAR_DNS_CACHE_MSG: { 1346 synchronized (ActivityManagerService.this) { 1347 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1348 ProcessRecord r = mLruProcesses.get(i); 1349 if (r.thread != null) { 1350 try { 1351 r.thread.clearDnsCache(); 1352 } catch (RemoteException ex) { 1353 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1354 } 1355 } 1356 } 1357 } 1358 } break; 1359 case UPDATE_HTTP_PROXY_MSG: { 1360 ProxyInfo proxy = (ProxyInfo)msg.obj; 1361 String host = ""; 1362 String port = ""; 1363 String exclList = ""; 1364 Uri pacFileUrl = Uri.EMPTY; 1365 if (proxy != null) { 1366 host = proxy.getHost(); 1367 port = Integer.toString(proxy.getPort()); 1368 exclList = proxy.getExclusionListAsString(); 1369 pacFileUrl = proxy.getPacFileUrl(); 1370 } 1371 synchronized (ActivityManagerService.this) { 1372 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1373 ProcessRecord r = mLruProcesses.get(i); 1374 if (r.thread != null) { 1375 try { 1376 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1377 } catch (RemoteException ex) { 1378 Slog.w(TAG, "Failed to update http proxy for: " + 1379 r.info.processName); 1380 } 1381 } 1382 } 1383 } 1384 } break; 1385 case SHOW_UID_ERROR_MSG: { 1386 String title = "System UIDs Inconsistent"; 1387 String text = "UIDs on the system are inconsistent, you need to wipe your" 1388 + " data partition or your device will be unstable."; 1389 Log.e(TAG, title + ": " + text); 1390 if (mShowDialogs) { 1391 // XXX This is a temporary dialog, no need to localize. 1392 AlertDialog d = new BaseErrorDialog(mContext); 1393 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1394 d.setCancelable(false); 1395 d.setTitle(title); 1396 d.setMessage(text); 1397 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1398 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1399 mUidAlert = d; 1400 d.show(); 1401 } 1402 } break; 1403 case IM_FEELING_LUCKY_MSG: { 1404 if (mUidAlert != null) { 1405 mUidAlert.dismiss(); 1406 mUidAlert = null; 1407 } 1408 } break; 1409 case PROC_START_TIMEOUT_MSG: { 1410 if (mDidDexOpt) { 1411 mDidDexOpt = false; 1412 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1413 nmsg.obj = msg.obj; 1414 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1415 return; 1416 } 1417 ProcessRecord app = (ProcessRecord)msg.obj; 1418 synchronized (ActivityManagerService.this) { 1419 processStartTimedOutLocked(app); 1420 } 1421 } break; 1422 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1423 synchronized (ActivityManagerService.this) { 1424 doPendingActivityLaunchesLocked(true); 1425 } 1426 } break; 1427 case KILL_APPLICATION_MSG: { 1428 synchronized (ActivityManagerService.this) { 1429 int appid = msg.arg1; 1430 boolean restart = (msg.arg2 == 1); 1431 Bundle bundle = (Bundle)msg.obj; 1432 String pkg = bundle.getString("pkg"); 1433 String reason = bundle.getString("reason"); 1434 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1435 false, UserHandle.USER_ALL, reason); 1436 } 1437 } break; 1438 case FINALIZE_PENDING_INTENT_MSG: { 1439 ((PendingIntentRecord)msg.obj).completeFinalize(); 1440 } break; 1441 case POST_HEAVY_NOTIFICATION_MSG: { 1442 INotificationManager inm = NotificationManager.getService(); 1443 if (inm == null) { 1444 return; 1445 } 1446 1447 ActivityRecord root = (ActivityRecord)msg.obj; 1448 ProcessRecord process = root.app; 1449 if (process == null) { 1450 return; 1451 } 1452 1453 try { 1454 Context context = mContext.createPackageContext(process.info.packageName, 0); 1455 String text = mContext.getString(R.string.heavy_weight_notification, 1456 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1457 Notification notification = new Notification(); 1458 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1459 notification.when = 0; 1460 notification.flags = Notification.FLAG_ONGOING_EVENT; 1461 notification.tickerText = text; 1462 notification.defaults = 0; // please be quiet 1463 notification.sound = null; 1464 notification.vibrate = null; 1465 notification.setLatestEventInfo(context, text, 1466 mContext.getText(R.string.heavy_weight_notification_detail), 1467 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1468 PendingIntent.FLAG_CANCEL_CURRENT, null, 1469 new UserHandle(root.userId))); 1470 1471 try { 1472 int[] outId = new int[1]; 1473 inm.enqueueNotificationWithTag("android", "android", null, 1474 R.string.heavy_weight_notification, 1475 notification, outId, root.userId); 1476 } catch (RuntimeException e) { 1477 Slog.w(ActivityManagerService.TAG, 1478 "Error showing notification for heavy-weight app", e); 1479 } catch (RemoteException e) { 1480 } 1481 } catch (NameNotFoundException e) { 1482 Slog.w(TAG, "Unable to create context for heavy notification", e); 1483 } 1484 } break; 1485 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1486 INotificationManager inm = NotificationManager.getService(); 1487 if (inm == null) { 1488 return; 1489 } 1490 try { 1491 inm.cancelNotificationWithTag("android", null, 1492 R.string.heavy_weight_notification, msg.arg1); 1493 } catch (RuntimeException e) { 1494 Slog.w(ActivityManagerService.TAG, 1495 "Error canceling notification for service", e); 1496 } catch (RemoteException e) { 1497 } 1498 } break; 1499 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1500 synchronized (ActivityManagerService.this) { 1501 checkExcessivePowerUsageLocked(true); 1502 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1503 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1504 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1505 } 1506 } break; 1507 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1508 synchronized (ActivityManagerService.this) { 1509 ActivityRecord ar = (ActivityRecord)msg.obj; 1510 if (mCompatModeDialog != null) { 1511 if (mCompatModeDialog.mAppInfo.packageName.equals( 1512 ar.info.applicationInfo.packageName)) { 1513 return; 1514 } 1515 mCompatModeDialog.dismiss(); 1516 mCompatModeDialog = null; 1517 } 1518 if (ar != null && false) { 1519 if (mCompatModePackages.getPackageAskCompatModeLocked( 1520 ar.packageName)) { 1521 int mode = mCompatModePackages.computeCompatModeLocked( 1522 ar.info.applicationInfo); 1523 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1524 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1525 mCompatModeDialog = new CompatModeDialog( 1526 ActivityManagerService.this, mContext, 1527 ar.info.applicationInfo); 1528 mCompatModeDialog.show(); 1529 } 1530 } 1531 } 1532 } 1533 break; 1534 } 1535 case DISPATCH_PROCESSES_CHANGED: { 1536 dispatchProcessesChanged(); 1537 break; 1538 } 1539 case DISPATCH_PROCESS_DIED: { 1540 final int pid = msg.arg1; 1541 final int uid = msg.arg2; 1542 dispatchProcessDied(pid, uid); 1543 break; 1544 } 1545 case REPORT_MEM_USAGE_MSG: { 1546 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1547 Thread thread = new Thread() { 1548 @Override public void run() { 1549 final SparseArray<ProcessMemInfo> infoMap 1550 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1551 for (int i=0, N=memInfos.size(); i<N; i++) { 1552 ProcessMemInfo mi = memInfos.get(i); 1553 infoMap.put(mi.pid, mi); 1554 } 1555 updateCpuStatsNow(); 1556 synchronized (mProcessCpuThread) { 1557 final int N = mProcessCpuTracker.countStats(); 1558 for (int i=0; i<N; i++) { 1559 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1560 if (st.vsize > 0) { 1561 long pss = Debug.getPss(st.pid, null); 1562 if (pss > 0) { 1563 if (infoMap.indexOfKey(st.pid) < 0) { 1564 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1565 ProcessList.NATIVE_ADJ, -1, "native", null); 1566 mi.pss = pss; 1567 memInfos.add(mi); 1568 } 1569 } 1570 } 1571 } 1572 } 1573 1574 long totalPss = 0; 1575 for (int i=0, N=memInfos.size(); i<N; i++) { 1576 ProcessMemInfo mi = memInfos.get(i); 1577 if (mi.pss == 0) { 1578 mi.pss = Debug.getPss(mi.pid, null); 1579 } 1580 totalPss += mi.pss; 1581 } 1582 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1583 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1584 if (lhs.oomAdj != rhs.oomAdj) { 1585 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1586 } 1587 if (lhs.pss != rhs.pss) { 1588 return lhs.pss < rhs.pss ? 1 : -1; 1589 } 1590 return 0; 1591 } 1592 }); 1593 1594 StringBuilder tag = new StringBuilder(128); 1595 StringBuilder stack = new StringBuilder(128); 1596 tag.append("Low on memory -- "); 1597 appendMemBucket(tag, totalPss, "total", false); 1598 appendMemBucket(stack, totalPss, "total", true); 1599 1600 StringBuilder logBuilder = new StringBuilder(1024); 1601 logBuilder.append("Low on memory:\n"); 1602 1603 boolean firstLine = true; 1604 int lastOomAdj = Integer.MIN_VALUE; 1605 for (int i=0, N=memInfos.size(); i<N; i++) { 1606 ProcessMemInfo mi = memInfos.get(i); 1607 1608 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1609 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1610 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1611 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1612 if (lastOomAdj != mi.oomAdj) { 1613 lastOomAdj = mi.oomAdj; 1614 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1615 tag.append(" / "); 1616 } 1617 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1618 if (firstLine) { 1619 stack.append(":"); 1620 firstLine = false; 1621 } 1622 stack.append("\n\t at "); 1623 } else { 1624 stack.append("$"); 1625 } 1626 } else { 1627 tag.append(" "); 1628 stack.append("$"); 1629 } 1630 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1631 appendMemBucket(tag, mi.pss, mi.name, false); 1632 } 1633 appendMemBucket(stack, mi.pss, mi.name, true); 1634 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1635 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1636 stack.append("("); 1637 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1638 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1639 stack.append(DUMP_MEM_OOM_LABEL[k]); 1640 stack.append(":"); 1641 stack.append(DUMP_MEM_OOM_ADJ[k]); 1642 } 1643 } 1644 stack.append(")"); 1645 } 1646 } 1647 1648 logBuilder.append(" "); 1649 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1650 logBuilder.append(' '); 1651 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1652 logBuilder.append(' '); 1653 ProcessList.appendRamKb(logBuilder, mi.pss); 1654 logBuilder.append(" kB: "); 1655 logBuilder.append(mi.name); 1656 logBuilder.append(" ("); 1657 logBuilder.append(mi.pid); 1658 logBuilder.append(") "); 1659 logBuilder.append(mi.adjType); 1660 logBuilder.append('\n'); 1661 if (mi.adjReason != null) { 1662 logBuilder.append(" "); 1663 logBuilder.append(mi.adjReason); 1664 logBuilder.append('\n'); 1665 } 1666 } 1667 1668 logBuilder.append(" "); 1669 ProcessList.appendRamKb(logBuilder, totalPss); 1670 logBuilder.append(" kB: TOTAL\n"); 1671 1672 long[] infos = new long[Debug.MEMINFO_COUNT]; 1673 Debug.getMemInfo(infos); 1674 logBuilder.append(" MemInfo: "); 1675 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1676 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1677 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1678 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1679 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1680 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1681 logBuilder.append(" ZRAM: "); 1682 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1683 logBuilder.append(" kB RAM, "); 1684 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1685 logBuilder.append(" kB swap total, "); 1686 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1687 logBuilder.append(" kB swap free\n"); 1688 } 1689 Slog.i(TAG, logBuilder.toString()); 1690 1691 StringBuilder dropBuilder = new StringBuilder(1024); 1692 /* 1693 StringWriter oomSw = new StringWriter(); 1694 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1695 StringWriter catSw = new StringWriter(); 1696 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1697 String[] emptyArgs = new String[] { }; 1698 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1699 oomPw.flush(); 1700 String oomString = oomSw.toString(); 1701 */ 1702 dropBuilder.append(stack); 1703 dropBuilder.append('\n'); 1704 dropBuilder.append('\n'); 1705 dropBuilder.append(logBuilder); 1706 dropBuilder.append('\n'); 1707 /* 1708 dropBuilder.append(oomString); 1709 dropBuilder.append('\n'); 1710 */ 1711 StringWriter catSw = new StringWriter(); 1712 synchronized (ActivityManagerService.this) { 1713 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1714 String[] emptyArgs = new String[] { }; 1715 catPw.println(); 1716 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1717 catPw.println(); 1718 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1719 false, false, null); 1720 catPw.println(); 1721 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1722 catPw.flush(); 1723 } 1724 dropBuilder.append(catSw.toString()); 1725 addErrorToDropBox("lowmem", null, "system_server", null, 1726 null, tag.toString(), dropBuilder.toString(), null, null); 1727 //Slog.i(TAG, "Sent to dropbox:"); 1728 //Slog.i(TAG, dropBuilder.toString()); 1729 synchronized (ActivityManagerService.this) { 1730 long now = SystemClock.uptimeMillis(); 1731 if (mLastMemUsageReportTime < now) { 1732 mLastMemUsageReportTime = now; 1733 } 1734 } 1735 } 1736 }; 1737 thread.start(); 1738 break; 1739 } 1740 case REPORT_USER_SWITCH_MSG: { 1741 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1742 break; 1743 } 1744 case CONTINUE_USER_SWITCH_MSG: { 1745 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1746 break; 1747 } 1748 case USER_SWITCH_TIMEOUT_MSG: { 1749 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1750 break; 1751 } 1752 case IMMERSIVE_MODE_LOCK_MSG: { 1753 final boolean nextState = (msg.arg1 != 0); 1754 if (mUpdateLock.isHeld() != nextState) { 1755 if (DEBUG_IMMERSIVE) { 1756 final ActivityRecord r = (ActivityRecord) msg.obj; 1757 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1758 } 1759 if (nextState) { 1760 mUpdateLock.acquire(); 1761 } else { 1762 mUpdateLock.release(); 1763 } 1764 } 1765 break; 1766 } 1767 case PERSIST_URI_GRANTS_MSG: { 1768 writeGrantedUriPermissions(); 1769 break; 1770 } 1771 case REQUEST_ALL_PSS_MSG: { 1772 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1773 break; 1774 } 1775 case START_PROFILES_MSG: { 1776 synchronized (ActivityManagerService.this) { 1777 startProfilesLocked(); 1778 } 1779 break; 1780 } 1781 case UPDATE_TIME: { 1782 synchronized (ActivityManagerService.this) { 1783 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1784 ProcessRecord r = mLruProcesses.get(i); 1785 if (r.thread != null) { 1786 try { 1787 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1788 } catch (RemoteException ex) { 1789 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1790 } 1791 } 1792 } 1793 } 1794 break; 1795 } 1796 case SYSTEM_USER_START_MSG: { 1797 mSystemServiceManager.startUser(msg.arg1); 1798 break; 1799 } 1800 case SYSTEM_USER_CURRENT_MSG: { 1801 mSystemServiceManager.switchUser(msg.arg1); 1802 break; 1803 } 1804 } 1805 } 1806 }; 1807 1808 static final int COLLECT_PSS_BG_MSG = 1; 1809 1810 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1811 @Override 1812 public void handleMessage(Message msg) { 1813 switch (msg.what) { 1814 case COLLECT_PSS_BG_MSG: { 1815 long start = SystemClock.uptimeMillis(); 1816 MemInfoReader memInfo = null; 1817 synchronized (ActivityManagerService.this) { 1818 if (mFullPssPending) { 1819 mFullPssPending = false; 1820 memInfo = new MemInfoReader(); 1821 } 1822 } 1823 if (memInfo != null) { 1824 updateCpuStatsNow(); 1825 long nativeTotalPss = 0; 1826 synchronized (mProcessCpuThread) { 1827 final int N = mProcessCpuTracker.countStats(); 1828 for (int j=0; j<N; j++) { 1829 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1830 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1831 // This is definitely an application process; skip it. 1832 continue; 1833 } 1834 synchronized (mPidsSelfLocked) { 1835 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1836 // This is one of our own processes; skip it. 1837 continue; 1838 } 1839 } 1840 nativeTotalPss += Debug.getPss(st.pid, null); 1841 } 1842 } 1843 memInfo.readMemInfo(); 1844 synchronized (this) { 1845 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1846 + (SystemClock.uptimeMillis()-start) + "ms"); 1847 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1848 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1849 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1850 +memInfo.getSlabSizeKb(), 1851 nativeTotalPss); 1852 } 1853 } 1854 1855 int i=0, num=0; 1856 long[] tmp = new long[1]; 1857 do { 1858 ProcessRecord proc; 1859 int procState; 1860 int pid; 1861 synchronized (ActivityManagerService.this) { 1862 if (i >= mPendingPssProcesses.size()) { 1863 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1864 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1865 mPendingPssProcesses.clear(); 1866 return; 1867 } 1868 proc = mPendingPssProcesses.get(i); 1869 procState = proc.pssProcState; 1870 if (proc.thread != null && procState == proc.setProcState) { 1871 pid = proc.pid; 1872 } else { 1873 proc = null; 1874 pid = 0; 1875 } 1876 i++; 1877 } 1878 if (proc != null) { 1879 long pss = Debug.getPss(pid, tmp); 1880 synchronized (ActivityManagerService.this) { 1881 if (proc.thread != null && proc.setProcState == procState 1882 && proc.pid == pid) { 1883 num++; 1884 proc.lastPssTime = SystemClock.uptimeMillis(); 1885 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1886 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1887 + ": " + pss + " lastPss=" + proc.lastPss 1888 + " state=" + ProcessList.makeProcStateString(procState)); 1889 if (proc.initialIdlePss == 0) { 1890 proc.initialIdlePss = pss; 1891 } 1892 proc.lastPss = pss; 1893 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1894 proc.lastCachedPss = pss; 1895 } 1896 } 1897 } 1898 } 1899 } while (true); 1900 } 1901 } 1902 } 1903 }; 1904 1905 /** 1906 * Monitor for package changes and update our internal state. 1907 */ 1908 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1909 @Override 1910 public void onPackageRemoved(String packageName, int uid) { 1911 // Remove all tasks with activities in the specified package from the list of recent tasks 1912 synchronized (ActivityManagerService.this) { 1913 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1914 TaskRecord tr = mRecentTasks.get(i); 1915 ComponentName cn = tr.intent.getComponent(); 1916 if (cn != null && cn.getPackageName().equals(packageName)) { 1917 // If the package name matches, remove the task and kill the process 1918 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1919 } 1920 } 1921 } 1922 } 1923 1924 @Override 1925 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1926 onPackageModified(packageName); 1927 return true; 1928 } 1929 1930 @Override 1931 public void onPackageModified(String packageName) { 1932 final PackageManager pm = mContext.getPackageManager(); 1933 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1934 new ArrayList<Pair<Intent, Integer>>(); 1935 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1936 // Copy the list of recent tasks so that we don't hold onto the lock on 1937 // ActivityManagerService for long periods while checking if components exist. 1938 synchronized (ActivityManagerService.this) { 1939 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1940 TaskRecord tr = mRecentTasks.get(i); 1941 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1942 } 1943 } 1944 // Check the recent tasks and filter out all tasks with components that no longer exist. 1945 Intent tmpI = new Intent(); 1946 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1947 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1948 ComponentName cn = p.first.getComponent(); 1949 if (cn != null && cn.getPackageName().equals(packageName)) { 1950 try { 1951 // Add the task to the list to remove if the component no longer exists 1952 tmpI.setComponent(cn); 1953 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1954 tasksToRemove.add(p.second); 1955 } 1956 } catch (Exception e) {} 1957 } 1958 } 1959 // Prune all the tasks with removed components from the list of recent tasks 1960 synchronized (ActivityManagerService.this) { 1961 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1962 // Remove the task but don't kill the process (since other components in that 1963 // package may still be running and in the background) 1964 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1965 } 1966 } 1967 } 1968 1969 @Override 1970 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1971 // Force stop the specified packages 1972 if (packages != null) { 1973 for (String pkg : packages) { 1974 synchronized (ActivityManagerService.this) { 1975 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1976 "finished booting")) { 1977 return true; 1978 } 1979 } 1980 } 1981 } 1982 return false; 1983 } 1984 }; 1985 1986 public void setSystemProcess() { 1987 try { 1988 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1989 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1990 ServiceManager.addService("meminfo", new MemBinder(this)); 1991 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1992 ServiceManager.addService("dbinfo", new DbBinder(this)); 1993 if (MONITOR_CPU_USAGE) { 1994 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1995 } 1996 ServiceManager.addService("permission", new PermissionController(this)); 1997 1998 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1999 "android", STOCK_PM_FLAGS); 2000 mSystemThread.installSystemApplicationInfo(info); 2001 2002 synchronized (this) { 2003 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2004 app.persistent = true; 2005 app.pid = MY_PID; 2006 app.maxAdj = ProcessList.SYSTEM_ADJ; 2007 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2008 mProcessNames.put(app.processName, app.uid, app); 2009 synchronized (mPidsSelfLocked) { 2010 mPidsSelfLocked.put(app.pid, app); 2011 } 2012 updateLruProcessLocked(app, false, null); 2013 updateOomAdjLocked(); 2014 } 2015 } catch (PackageManager.NameNotFoundException e) { 2016 throw new RuntimeException( 2017 "Unable to find android system package", e); 2018 } 2019 } 2020 2021 public void setWindowManager(WindowManagerService wm) { 2022 mWindowManager = wm; 2023 mStackSupervisor.setWindowManager(wm); 2024 } 2025 2026 public void startObservingNativeCrashes() { 2027 final NativeCrashListener ncl = new NativeCrashListener(this); 2028 ncl.start(); 2029 } 2030 2031 public IAppOpsService getAppOpsService() { 2032 return mAppOpsService; 2033 } 2034 2035 static class MemBinder extends Binder { 2036 ActivityManagerService mActivityManagerService; 2037 MemBinder(ActivityManagerService activityManagerService) { 2038 mActivityManagerService = activityManagerService; 2039 } 2040 2041 @Override 2042 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2043 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2044 != PackageManager.PERMISSION_GRANTED) { 2045 pw.println("Permission Denial: can't dump meminfo from from pid=" 2046 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2047 + " without permission " + android.Manifest.permission.DUMP); 2048 return; 2049 } 2050 2051 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2052 } 2053 } 2054 2055 static class GraphicsBinder extends Binder { 2056 ActivityManagerService mActivityManagerService; 2057 GraphicsBinder(ActivityManagerService activityManagerService) { 2058 mActivityManagerService = activityManagerService; 2059 } 2060 2061 @Override 2062 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2063 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2064 != PackageManager.PERMISSION_GRANTED) { 2065 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2066 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2067 + " without permission " + android.Manifest.permission.DUMP); 2068 return; 2069 } 2070 2071 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2072 } 2073 } 2074 2075 static class DbBinder extends Binder { 2076 ActivityManagerService mActivityManagerService; 2077 DbBinder(ActivityManagerService activityManagerService) { 2078 mActivityManagerService = activityManagerService; 2079 } 2080 2081 @Override 2082 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2083 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2084 != PackageManager.PERMISSION_GRANTED) { 2085 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2086 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2087 + " without permission " + android.Manifest.permission.DUMP); 2088 return; 2089 } 2090 2091 mActivityManagerService.dumpDbInfo(fd, pw, args); 2092 } 2093 } 2094 2095 static class CpuBinder extends Binder { 2096 ActivityManagerService mActivityManagerService; 2097 CpuBinder(ActivityManagerService activityManagerService) { 2098 mActivityManagerService = activityManagerService; 2099 } 2100 2101 @Override 2102 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2103 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2104 != PackageManager.PERMISSION_GRANTED) { 2105 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2106 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2107 + " without permission " + android.Manifest.permission.DUMP); 2108 return; 2109 } 2110 2111 synchronized (mActivityManagerService.mProcessCpuThread) { 2112 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2113 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2114 SystemClock.uptimeMillis())); 2115 } 2116 } 2117 } 2118 2119 public static final class Lifecycle extends SystemService { 2120 private final ActivityManagerService mService; 2121 2122 public Lifecycle(Context context) { 2123 super(context); 2124 mService = new ActivityManagerService(context); 2125 } 2126 2127 @Override 2128 public void onStart() { 2129 mService.start(); 2130 } 2131 2132 public ActivityManagerService getService() { 2133 return mService; 2134 } 2135 } 2136 2137 // Note: This method is invoked on the main thread but may need to attach various 2138 // handlers to other threads. So take care to be explicit about the looper. 2139 public ActivityManagerService(Context systemContext) { 2140 mContext = systemContext; 2141 mFactoryTest = FactoryTest.getMode(); 2142 mSystemThread = ActivityThread.currentActivityThread(); 2143 2144 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2145 2146 mHandlerThread = new ServiceThread(TAG, 2147 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2148 mHandlerThread.start(); 2149 mHandler = new MainHandler(mHandlerThread.getLooper()); 2150 2151 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2152 "foreground", BROADCAST_FG_TIMEOUT, false); 2153 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2154 "background", BROADCAST_BG_TIMEOUT, true); 2155 mBroadcastQueues[0] = mFgBroadcastQueue; 2156 mBroadcastQueues[1] = mBgBroadcastQueue; 2157 2158 mServices = new ActiveServices(this); 2159 mProviderMap = new ProviderMap(this); 2160 2161 // TODO: Move creation of battery stats service outside of activity manager service. 2162 File dataDir = Environment.getDataDirectory(); 2163 File systemDir = new File(dataDir, "system"); 2164 systemDir.mkdirs(); 2165 mBatteryStatsService = new BatteryStatsService(new File( 2166 systemDir, "batterystats.bin").toString(), mHandler); 2167 mBatteryStatsService.getActiveStatistics().readLocked(); 2168 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2169 mOnBattery = DEBUG_POWER ? true 2170 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2171 mBatteryStatsService.getActiveStatistics().setCallback(this); 2172 2173 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2174 2175 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2176 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2177 2178 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2179 2180 // User 0 is the first and only user that runs at boot. 2181 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2182 mUserLru.add(Integer.valueOf(0)); 2183 updateStartedUserArrayLocked(); 2184 2185 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2186 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2187 2188 mConfiguration.setToDefaults(); 2189 mConfiguration.setLocale(Locale.getDefault()); 2190 2191 mConfigurationSeq = mConfiguration.seq = 1; 2192 mProcessCpuTracker.init(); 2193 2194 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2195 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2196 mStackSupervisor = new ActivityStackSupervisor(this); 2197 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2198 2199 mProcessCpuThread = new Thread("CpuTracker") { 2200 @Override 2201 public void run() { 2202 while (true) { 2203 try { 2204 try { 2205 synchronized(this) { 2206 final long now = SystemClock.uptimeMillis(); 2207 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2208 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2209 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2210 // + ", write delay=" + nextWriteDelay); 2211 if (nextWriteDelay < nextCpuDelay) { 2212 nextCpuDelay = nextWriteDelay; 2213 } 2214 if (nextCpuDelay > 0) { 2215 mProcessCpuMutexFree.set(true); 2216 this.wait(nextCpuDelay); 2217 } 2218 } 2219 } catch (InterruptedException e) { 2220 } 2221 updateCpuStatsNow(); 2222 } catch (Exception e) { 2223 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2224 } 2225 } 2226 } 2227 }; 2228 2229 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2230 2231 Watchdog.getInstance().addMonitor(this); 2232 Watchdog.getInstance().addThread(mHandler); 2233 } 2234 2235 public void setSystemServiceManager(SystemServiceManager mgr) { 2236 mSystemServiceManager = mgr; 2237 } 2238 2239 private void start() { 2240 mProcessCpuThread.start(); 2241 2242 mBatteryStatsService.publish(mContext); 2243 mUsageStatsService.publish(mContext); 2244 mAppOpsService.publish(mContext); 2245 Slog.d("AppOps", "AppOpsService published"); 2246 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2247 } 2248 2249 public void initPowerManagement() { 2250 mStackSupervisor.initPowerManagement(); 2251 mBatteryStatsService.initPowerManagement(); 2252 } 2253 2254 @Override 2255 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2256 throws RemoteException { 2257 if (code == SYSPROPS_TRANSACTION) { 2258 // We need to tell all apps about the system property change. 2259 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2260 synchronized(this) { 2261 final int NP = mProcessNames.getMap().size(); 2262 for (int ip=0; ip<NP; ip++) { 2263 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2264 final int NA = apps.size(); 2265 for (int ia=0; ia<NA; ia++) { 2266 ProcessRecord app = apps.valueAt(ia); 2267 if (app.thread != null) { 2268 procs.add(app.thread.asBinder()); 2269 } 2270 } 2271 } 2272 } 2273 2274 int N = procs.size(); 2275 for (int i=0; i<N; i++) { 2276 Parcel data2 = Parcel.obtain(); 2277 try { 2278 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2279 } catch (RemoteException e) { 2280 } 2281 data2.recycle(); 2282 } 2283 } 2284 try { 2285 return super.onTransact(code, data, reply, flags); 2286 } catch (RuntimeException e) { 2287 // The activity manager only throws security exceptions, so let's 2288 // log all others. 2289 if (!(e instanceof SecurityException)) { 2290 Slog.wtf(TAG, "Activity Manager Crash", e); 2291 } 2292 throw e; 2293 } 2294 } 2295 2296 void updateCpuStats() { 2297 final long now = SystemClock.uptimeMillis(); 2298 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2299 return; 2300 } 2301 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2302 synchronized (mProcessCpuThread) { 2303 mProcessCpuThread.notify(); 2304 } 2305 } 2306 } 2307 2308 void updateCpuStatsNow() { 2309 synchronized (mProcessCpuThread) { 2310 mProcessCpuMutexFree.set(false); 2311 final long now = SystemClock.uptimeMillis(); 2312 boolean haveNewCpuStats = false; 2313 2314 if (MONITOR_CPU_USAGE && 2315 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2316 mLastCpuTime.set(now); 2317 haveNewCpuStats = true; 2318 mProcessCpuTracker.update(); 2319 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2320 //Slog.i(TAG, "Total CPU usage: " 2321 // + mProcessCpu.getTotalCpuPercent() + "%"); 2322 2323 // Slog the cpu usage if the property is set. 2324 if ("true".equals(SystemProperties.get("events.cpu"))) { 2325 int user = mProcessCpuTracker.getLastUserTime(); 2326 int system = mProcessCpuTracker.getLastSystemTime(); 2327 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2328 int irq = mProcessCpuTracker.getLastIrqTime(); 2329 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2330 int idle = mProcessCpuTracker.getLastIdleTime(); 2331 2332 int total = user + system + iowait + irq + softIrq + idle; 2333 if (total == 0) total = 1; 2334 2335 EventLog.writeEvent(EventLogTags.CPU, 2336 ((user+system+iowait+irq+softIrq) * 100) / total, 2337 (user * 100) / total, 2338 (system * 100) / total, 2339 (iowait * 100) / total, 2340 (irq * 100) / total, 2341 (softIrq * 100) / total); 2342 } 2343 } 2344 2345 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2346 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2347 synchronized(bstats) { 2348 synchronized(mPidsSelfLocked) { 2349 if (haveNewCpuStats) { 2350 if (mOnBattery) { 2351 int perc = bstats.startAddingCpuLocked(); 2352 int totalUTime = 0; 2353 int totalSTime = 0; 2354 final int N = mProcessCpuTracker.countStats(); 2355 for (int i=0; i<N; i++) { 2356 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2357 if (!st.working) { 2358 continue; 2359 } 2360 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2361 int otherUTime = (st.rel_utime*perc)/100; 2362 int otherSTime = (st.rel_stime*perc)/100; 2363 totalUTime += otherUTime; 2364 totalSTime += otherSTime; 2365 if (pr != null) { 2366 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2367 if (ps == null || !ps.isActive()) { 2368 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2369 pr.info.uid, pr.processName); 2370 } 2371 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2372 st.rel_stime-otherSTime); 2373 ps.addSpeedStepTimes(cpuSpeedTimes); 2374 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2375 } else { 2376 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2377 if (ps == null || !ps.isActive()) { 2378 st.batteryStats = ps = bstats.getProcessStatsLocked( 2379 bstats.mapUid(st.uid), st.name); 2380 } 2381 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2382 st.rel_stime-otherSTime); 2383 ps.addSpeedStepTimes(cpuSpeedTimes); 2384 } 2385 } 2386 bstats.finishAddingCpuLocked(perc, totalUTime, 2387 totalSTime, cpuSpeedTimes); 2388 } 2389 } 2390 } 2391 2392 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2393 mLastWriteTime = now; 2394 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2395 } 2396 } 2397 } 2398 } 2399 2400 @Override 2401 public void batteryNeedsCpuUpdate() { 2402 updateCpuStatsNow(); 2403 } 2404 2405 @Override 2406 public void batteryPowerChanged(boolean onBattery) { 2407 // When plugging in, update the CPU stats first before changing 2408 // the plug state. 2409 updateCpuStatsNow(); 2410 synchronized (this) { 2411 synchronized(mPidsSelfLocked) { 2412 mOnBattery = DEBUG_POWER ? true : onBattery; 2413 } 2414 } 2415 } 2416 2417 /** 2418 * Initialize the application bind args. These are passed to each 2419 * process when the bindApplication() IPC is sent to the process. They're 2420 * lazily setup to make sure the services are running when they're asked for. 2421 */ 2422 private HashMap<String, IBinder> getCommonServicesLocked() { 2423 if (mAppBindArgs == null) { 2424 mAppBindArgs = new HashMap<String, IBinder>(); 2425 2426 // Setup the application init args 2427 mAppBindArgs.put("package", ServiceManager.getService("package")); 2428 mAppBindArgs.put("window", ServiceManager.getService("window")); 2429 mAppBindArgs.put(Context.ALARM_SERVICE, 2430 ServiceManager.getService(Context.ALARM_SERVICE)); 2431 } 2432 return mAppBindArgs; 2433 } 2434 2435 final void setFocusedActivityLocked(ActivityRecord r) { 2436 if (mFocusedActivity != r) { 2437 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2438 mFocusedActivity = r; 2439 if (r.task != null && r.task.voiceInteractor != null) { 2440 startRunningVoiceLocked(); 2441 } else { 2442 finishRunningVoiceLocked(); 2443 } 2444 mStackSupervisor.setFocusedStack(r); 2445 if (r != null) { 2446 mWindowManager.setFocusedApp(r.appToken, true); 2447 } 2448 applyUpdateLockStateLocked(r); 2449 } 2450 } 2451 2452 final void clearFocusedActivity(ActivityRecord r) { 2453 if (mFocusedActivity == r) { 2454 mFocusedActivity = null; 2455 } 2456 } 2457 2458 @Override 2459 public void setFocusedStack(int stackId) { 2460 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2461 synchronized (ActivityManagerService.this) { 2462 ActivityStack stack = mStackSupervisor.getStack(stackId); 2463 if (stack != null) { 2464 ActivityRecord r = stack.topRunningActivityLocked(null); 2465 if (r != null) { 2466 setFocusedActivityLocked(r); 2467 } 2468 } 2469 } 2470 } 2471 2472 @Override 2473 public void notifyActivityDrawn(IBinder token) { 2474 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2475 synchronized (this) { 2476 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2477 if (r != null) { 2478 r.task.stack.notifyActivityDrawnLocked(r); 2479 } 2480 } 2481 } 2482 2483 final void applyUpdateLockStateLocked(ActivityRecord r) { 2484 // Modifications to the UpdateLock state are done on our handler, outside 2485 // the activity manager's locks. The new state is determined based on the 2486 // state *now* of the relevant activity record. The object is passed to 2487 // the handler solely for logging detail, not to be consulted/modified. 2488 final boolean nextState = r != null && r.immersive; 2489 mHandler.sendMessage( 2490 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2491 } 2492 2493 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2494 Message msg = Message.obtain(); 2495 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2496 msg.obj = r.task.askedCompatMode ? null : r; 2497 mHandler.sendMessage(msg); 2498 } 2499 2500 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2501 String what, Object obj, ProcessRecord srcApp) { 2502 app.lastActivityTime = now; 2503 2504 if (app.activities.size() > 0) { 2505 // Don't want to touch dependent processes that are hosting activities. 2506 return index; 2507 } 2508 2509 int lrui = mLruProcesses.lastIndexOf(app); 2510 if (lrui < 0) { 2511 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2512 + what + " " + obj + " from " + srcApp); 2513 return index; 2514 } 2515 2516 if (lrui >= index) { 2517 // Don't want to cause this to move dependent processes *back* in the 2518 // list as if they were less frequently used. 2519 return index; 2520 } 2521 2522 if (lrui >= mLruProcessActivityStart) { 2523 // Don't want to touch dependent processes that are hosting activities. 2524 return index; 2525 } 2526 2527 mLruProcesses.remove(lrui); 2528 if (index > 0) { 2529 index--; 2530 } 2531 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2532 + " in LRU list: " + app); 2533 mLruProcesses.add(index, app); 2534 return index; 2535 } 2536 2537 final void removeLruProcessLocked(ProcessRecord app) { 2538 int lrui = mLruProcesses.lastIndexOf(app); 2539 if (lrui >= 0) { 2540 if (lrui <= mLruProcessActivityStart) { 2541 mLruProcessActivityStart--; 2542 } 2543 if (lrui <= mLruProcessServiceStart) { 2544 mLruProcessServiceStart--; 2545 } 2546 mLruProcesses.remove(lrui); 2547 } 2548 } 2549 2550 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2551 ProcessRecord client) { 2552 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2553 || app.treatLikeActivity; 2554 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2555 if (!activityChange && hasActivity) { 2556 // The process has activities, so we are only allowing activity-based adjustments 2557 // to move it. It should be kept in the front of the list with other 2558 // processes that have activities, and we don't want those to change their 2559 // order except due to activity operations. 2560 return; 2561 } 2562 2563 mLruSeq++; 2564 final long now = SystemClock.uptimeMillis(); 2565 app.lastActivityTime = now; 2566 2567 // First a quick reject: if the app is already at the position we will 2568 // put it, then there is nothing to do. 2569 if (hasActivity) { 2570 final int N = mLruProcesses.size(); 2571 if (N > 0 && mLruProcesses.get(N-1) == app) { 2572 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2573 return; 2574 } 2575 } else { 2576 if (mLruProcessServiceStart > 0 2577 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2578 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2579 return; 2580 } 2581 } 2582 2583 int lrui = mLruProcesses.lastIndexOf(app); 2584 2585 if (app.persistent && lrui >= 0) { 2586 // We don't care about the position of persistent processes, as long as 2587 // they are in the list. 2588 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2589 return; 2590 } 2591 2592 /* In progress: compute new position first, so we can avoid doing work 2593 if the process is not actually going to move. Not yet working. 2594 int addIndex; 2595 int nextIndex; 2596 boolean inActivity = false, inService = false; 2597 if (hasActivity) { 2598 // Process has activities, put it at the very tipsy-top. 2599 addIndex = mLruProcesses.size(); 2600 nextIndex = mLruProcessServiceStart; 2601 inActivity = true; 2602 } else if (hasService) { 2603 // Process has services, put it at the top of the service list. 2604 addIndex = mLruProcessActivityStart; 2605 nextIndex = mLruProcessServiceStart; 2606 inActivity = true; 2607 inService = true; 2608 } else { 2609 // Process not otherwise of interest, it goes to the top of the non-service area. 2610 addIndex = mLruProcessServiceStart; 2611 if (client != null) { 2612 int clientIndex = mLruProcesses.lastIndexOf(client); 2613 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2614 + app); 2615 if (clientIndex >= 0 && addIndex > clientIndex) { 2616 addIndex = clientIndex; 2617 } 2618 } 2619 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2620 } 2621 2622 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2623 + mLruProcessActivityStart + "): " + app); 2624 */ 2625 2626 if (lrui >= 0) { 2627 if (lrui < mLruProcessActivityStart) { 2628 mLruProcessActivityStart--; 2629 } 2630 if (lrui < mLruProcessServiceStart) { 2631 mLruProcessServiceStart--; 2632 } 2633 /* 2634 if (addIndex > lrui) { 2635 addIndex--; 2636 } 2637 if (nextIndex > lrui) { 2638 nextIndex--; 2639 } 2640 */ 2641 mLruProcesses.remove(lrui); 2642 } 2643 2644 /* 2645 mLruProcesses.add(addIndex, app); 2646 if (inActivity) { 2647 mLruProcessActivityStart++; 2648 } 2649 if (inService) { 2650 mLruProcessActivityStart++; 2651 } 2652 */ 2653 2654 int nextIndex; 2655 if (hasActivity) { 2656 final int N = mLruProcesses.size(); 2657 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2658 // Process doesn't have activities, but has clients with 2659 // activities... move it up, but one below the top (the top 2660 // should always have a real activity). 2661 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2662 mLruProcesses.add(N-1, app); 2663 // To keep it from spamming the LRU list (by making a bunch of clients), 2664 // we will push down any other entries owned by the app. 2665 final int uid = app.info.uid; 2666 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2667 ProcessRecord subProc = mLruProcesses.get(i); 2668 if (subProc.info.uid == uid) { 2669 // We want to push this one down the list. If the process after 2670 // it is for the same uid, however, don't do so, because we don't 2671 // want them internally to be re-ordered. 2672 if (mLruProcesses.get(i-1).info.uid != uid) { 2673 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2674 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2675 ProcessRecord tmp = mLruProcesses.get(i); 2676 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2677 mLruProcesses.set(i-1, tmp); 2678 i--; 2679 } 2680 } else { 2681 // A gap, we can stop here. 2682 break; 2683 } 2684 } 2685 } else { 2686 // Process has activities, put it at the very tipsy-top. 2687 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2688 mLruProcesses.add(app); 2689 } 2690 nextIndex = mLruProcessServiceStart; 2691 } else if (hasService) { 2692 // Process has services, put it at the top of the service list. 2693 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2694 mLruProcesses.add(mLruProcessActivityStart, app); 2695 nextIndex = mLruProcessServiceStart; 2696 mLruProcessActivityStart++; 2697 } else { 2698 // Process not otherwise of interest, it goes to the top of the non-service area. 2699 int index = mLruProcessServiceStart; 2700 if (client != null) { 2701 // If there is a client, don't allow the process to be moved up higher 2702 // in the list than that client. 2703 int clientIndex = mLruProcesses.lastIndexOf(client); 2704 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2705 + " when updating " + app); 2706 if (clientIndex <= lrui) { 2707 // Don't allow the client index restriction to push it down farther in the 2708 // list than it already is. 2709 clientIndex = lrui; 2710 } 2711 if (clientIndex >= 0 && index > clientIndex) { 2712 index = clientIndex; 2713 } 2714 } 2715 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2716 mLruProcesses.add(index, app); 2717 nextIndex = index-1; 2718 mLruProcessActivityStart++; 2719 mLruProcessServiceStart++; 2720 } 2721 2722 // If the app is currently using a content provider or service, 2723 // bump those processes as well. 2724 for (int j=app.connections.size()-1; j>=0; j--) { 2725 ConnectionRecord cr = app.connections.valueAt(j); 2726 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2727 && cr.binding.service.app != null 2728 && cr.binding.service.app.lruSeq != mLruSeq 2729 && !cr.binding.service.app.persistent) { 2730 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2731 "service connection", cr, app); 2732 } 2733 } 2734 for (int j=app.conProviders.size()-1; j>=0; j--) { 2735 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2736 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2737 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2738 "provider reference", cpr, app); 2739 } 2740 } 2741 } 2742 2743 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2744 if (uid == Process.SYSTEM_UID) { 2745 // The system gets to run in any process. If there are multiple 2746 // processes with the same uid, just pick the first (this 2747 // should never happen). 2748 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2749 if (procs == null) return null; 2750 final int N = procs.size(); 2751 for (int i = 0; i < N; i++) { 2752 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2753 } 2754 } 2755 ProcessRecord proc = mProcessNames.get(processName, uid); 2756 if (false && proc != null && !keepIfLarge 2757 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2758 && proc.lastCachedPss >= 4000) { 2759 // Turn this condition on to cause killing to happen regularly, for testing. 2760 if (proc.baseProcessTracker != null) { 2761 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2762 } 2763 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2764 + "k from cached"); 2765 } else if (proc != null && !keepIfLarge 2766 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2767 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2768 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2769 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2770 if (proc.baseProcessTracker != null) { 2771 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2772 } 2773 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2774 + "k from cached"); 2775 } 2776 } 2777 return proc; 2778 } 2779 2780 void ensurePackageDexOpt(String packageName) { 2781 IPackageManager pm = AppGlobals.getPackageManager(); 2782 try { 2783 if (pm.performDexOpt(packageName)) { 2784 mDidDexOpt = true; 2785 } 2786 } catch (RemoteException e) { 2787 } 2788 } 2789 2790 boolean isNextTransitionForward() { 2791 int transit = mWindowManager.getPendingAppTransition(); 2792 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2793 || transit == AppTransition.TRANSIT_TASK_OPEN 2794 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2795 } 2796 2797 final ProcessRecord startProcessLocked(String processName, 2798 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2799 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2800 boolean isolated, boolean keepIfLarge) { 2801 ProcessRecord app; 2802 if (!isolated) { 2803 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2804 } else { 2805 // If this is an isolated process, it can't re-use an existing process. 2806 app = null; 2807 } 2808 // We don't have to do anything more if: 2809 // (1) There is an existing application record; and 2810 // (2) The caller doesn't think it is dead, OR there is no thread 2811 // object attached to it so we know it couldn't have crashed; and 2812 // (3) There is a pid assigned to it, so it is either starting or 2813 // already running. 2814 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2815 + " app=" + app + " knownToBeDead=" + knownToBeDead 2816 + " thread=" + (app != null ? app.thread : null) 2817 + " pid=" + (app != null ? app.pid : -1)); 2818 if (app != null && app.pid > 0) { 2819 if (!knownToBeDead || app.thread == null) { 2820 // We already have the app running, or are waiting for it to 2821 // come up (we have a pid but not yet its thread), so keep it. 2822 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2823 // If this is a new package in the process, add the package to the list 2824 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2825 return app; 2826 } 2827 2828 // An application record is attached to a previous process, 2829 // clean it up now. 2830 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2831 handleAppDiedLocked(app, true, true); 2832 } 2833 2834 String hostingNameStr = hostingName != null 2835 ? hostingName.flattenToShortString() : null; 2836 2837 if (!isolated) { 2838 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2839 // If we are in the background, then check to see if this process 2840 // is bad. If so, we will just silently fail. 2841 if (mBadProcesses.get(info.processName, info.uid) != null) { 2842 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2843 + "/" + info.processName); 2844 return null; 2845 } 2846 } else { 2847 // When the user is explicitly starting a process, then clear its 2848 // crash count so that we won't make it bad until they see at 2849 // least one crash dialog again, and make the process good again 2850 // if it had been bad. 2851 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2852 + "/" + info.processName); 2853 mProcessCrashTimes.remove(info.processName, info.uid); 2854 if (mBadProcesses.get(info.processName, info.uid) != null) { 2855 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2856 UserHandle.getUserId(info.uid), info.uid, 2857 info.processName); 2858 mBadProcesses.remove(info.processName, info.uid); 2859 if (app != null) { 2860 app.bad = false; 2861 } 2862 } 2863 } 2864 } 2865 2866 if (app == null) { 2867 app = newProcessRecordLocked(info, processName, isolated); 2868 if (app == null) { 2869 Slog.w(TAG, "Failed making new process record for " 2870 + processName + "/" + info.uid + " isolated=" + isolated); 2871 return null; 2872 } 2873 mProcessNames.put(processName, app.uid, app); 2874 if (isolated) { 2875 mIsolatedProcesses.put(app.uid, app); 2876 } 2877 } else { 2878 // If this is a new package in the process, add the package to the list 2879 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2880 } 2881 2882 // If the system is not ready yet, then hold off on starting this 2883 // process until it is. 2884 if (!mProcessesReady 2885 && !isAllowedWhileBooting(info) 2886 && !allowWhileBooting) { 2887 if (!mProcessesOnHold.contains(app)) { 2888 mProcessesOnHold.add(app); 2889 } 2890 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2891 return app; 2892 } 2893 2894 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2895 return (app.pid != 0) ? app : null; 2896 } 2897 2898 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2899 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2900 } 2901 2902 private final void startProcessLocked(ProcessRecord app, 2903 String hostingType, String hostingNameStr, String abiOverride) { 2904 if (app.pid > 0 && app.pid != MY_PID) { 2905 synchronized (mPidsSelfLocked) { 2906 mPidsSelfLocked.remove(app.pid); 2907 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2908 } 2909 app.setPid(0); 2910 } 2911 2912 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2913 "startProcessLocked removing on hold: " + app); 2914 mProcessesOnHold.remove(app); 2915 2916 updateCpuStats(); 2917 2918 try { 2919 int uid = app.uid; 2920 2921 int[] gids = null; 2922 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2923 if (!app.isolated) { 2924 int[] permGids = null; 2925 try { 2926 final PackageManager pm = mContext.getPackageManager(); 2927 permGids = pm.getPackageGids(app.info.packageName); 2928 2929 if (Environment.isExternalStorageEmulated()) { 2930 if (pm.checkPermission( 2931 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2932 app.info.packageName) == PERMISSION_GRANTED) { 2933 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2934 } else { 2935 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2936 } 2937 } 2938 } catch (PackageManager.NameNotFoundException e) { 2939 Slog.w(TAG, "Unable to retrieve gids", e); 2940 } 2941 2942 /* 2943 * Add shared application and profile GIDs so applications can share some 2944 * resources like shared libraries and access user-wide resources 2945 */ 2946 if (permGids == null) { 2947 gids = new int[2]; 2948 } else { 2949 gids = new int[permGids.length + 2]; 2950 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2951 } 2952 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2953 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2954 } 2955 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2956 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2957 && mTopComponent != null 2958 && app.processName.equals(mTopComponent.getPackageName())) { 2959 uid = 0; 2960 } 2961 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2962 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2963 uid = 0; 2964 } 2965 } 2966 int debugFlags = 0; 2967 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2968 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2969 // Also turn on CheckJNI for debuggable apps. It's quite 2970 // awkward to turn on otherwise. 2971 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2972 } 2973 // Run the app in safe mode if its manifest requests so or the 2974 // system is booted in safe mode. 2975 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2976 mSafeMode == true) { 2977 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2978 } 2979 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2980 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2981 } 2982 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2983 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2984 } 2985 if ("1".equals(SystemProperties.get("debug.assert"))) { 2986 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2987 } 2988 2989 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi; 2990 if (requiredAbi == null) { 2991 requiredAbi = Build.SUPPORTED_ABIS[0]; 2992 } 2993 2994 // Start the process. It will either succeed and return a result containing 2995 // the PID of the new process, or else throw a RuntimeException. 2996 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2997 app.processName, uid, uid, gids, debugFlags, mountExternal, 2998 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2999 3000 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 3001 synchronized (bs) { 3002 if (bs.isOnBattery()) { 3003 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 3004 } 3005 } 3006 3007 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3008 UserHandle.getUserId(uid), startResult.pid, uid, 3009 app.processName, hostingType, 3010 hostingNameStr != null ? hostingNameStr : ""); 3011 3012 if (app.persistent) { 3013 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3014 } 3015 3016 StringBuilder buf = mStringBuilder; 3017 buf.setLength(0); 3018 buf.append("Start proc "); 3019 buf.append(app.processName); 3020 buf.append(" for "); 3021 buf.append(hostingType); 3022 if (hostingNameStr != null) { 3023 buf.append(" "); 3024 buf.append(hostingNameStr); 3025 } 3026 buf.append(": pid="); 3027 buf.append(startResult.pid); 3028 buf.append(" uid="); 3029 buf.append(uid); 3030 buf.append(" gids={"); 3031 if (gids != null) { 3032 for (int gi=0; gi<gids.length; gi++) { 3033 if (gi != 0) buf.append(", "); 3034 buf.append(gids[gi]); 3035 3036 } 3037 } 3038 buf.append("}"); 3039 if (requiredAbi != null) { 3040 buf.append(" abi="); 3041 buf.append(requiredAbi); 3042 } 3043 Slog.i(TAG, buf.toString()); 3044 app.setPid(startResult.pid); 3045 app.usingWrapper = startResult.usingWrapper; 3046 app.removed = false; 3047 app.killedByAm = false; 3048 synchronized (mPidsSelfLocked) { 3049 this.mPidsSelfLocked.put(startResult.pid, app); 3050 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3051 msg.obj = app; 3052 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3053 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3054 } 3055 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 3056 app.processName, app.info.uid); 3057 if (app.isolated) { 3058 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3059 } 3060 } catch (RuntimeException e) { 3061 // XXX do better error recovery. 3062 app.setPid(0); 3063 Slog.e(TAG, "Failure starting process " + app.processName, e); 3064 } 3065 } 3066 3067 void updateUsageStats(ActivityRecord component, boolean resumed) { 3068 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3069 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3070 if (resumed) { 3071 mUsageStatsService.noteResumeComponent(component.realActivity); 3072 synchronized (stats) { 3073 stats.noteActivityResumedLocked(component.app.uid); 3074 } 3075 } else { 3076 mUsageStatsService.notePauseComponent(component.realActivity); 3077 synchronized (stats) { 3078 stats.noteActivityPausedLocked(component.app.uid); 3079 } 3080 } 3081 } 3082 3083 Intent getHomeIntent() { 3084 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3085 intent.setComponent(mTopComponent); 3086 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3087 intent.addCategory(Intent.CATEGORY_HOME); 3088 } 3089 return intent; 3090 } 3091 3092 boolean startHomeActivityLocked(int userId) { 3093 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3094 && mTopAction == null) { 3095 // We are running in factory test mode, but unable to find 3096 // the factory test app, so just sit around displaying the 3097 // error message and don't try to start anything. 3098 return false; 3099 } 3100 Intent intent = getHomeIntent(); 3101 ActivityInfo aInfo = 3102 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3103 if (aInfo != null) { 3104 intent.setComponent(new ComponentName( 3105 aInfo.applicationInfo.packageName, aInfo.name)); 3106 // Don't do this if the home app is currently being 3107 // instrumented. 3108 aInfo = new ActivityInfo(aInfo); 3109 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3110 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3111 aInfo.applicationInfo.uid, true); 3112 if (app == null || app.instrumentationClass == null) { 3113 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3114 mStackSupervisor.startHomeActivity(intent, aInfo); 3115 } 3116 } 3117 3118 return true; 3119 } 3120 3121 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3122 ActivityInfo ai = null; 3123 ComponentName comp = intent.getComponent(); 3124 try { 3125 if (comp != null) { 3126 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3127 } else { 3128 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3129 intent, 3130 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3131 flags, userId); 3132 3133 if (info != null) { 3134 ai = info.activityInfo; 3135 } 3136 } 3137 } catch (RemoteException e) { 3138 // ignore 3139 } 3140 3141 return ai; 3142 } 3143 3144 /** 3145 * Starts the "new version setup screen" if appropriate. 3146 */ 3147 void startSetupActivityLocked() { 3148 // Only do this once per boot. 3149 if (mCheckedForSetup) { 3150 return; 3151 } 3152 3153 // We will show this screen if the current one is a different 3154 // version than the last one shown, and we are not running in 3155 // low-level factory test mode. 3156 final ContentResolver resolver = mContext.getContentResolver(); 3157 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3158 Settings.Global.getInt(resolver, 3159 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3160 mCheckedForSetup = true; 3161 3162 // See if we should be showing the platform update setup UI. 3163 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3164 List<ResolveInfo> ris = mContext.getPackageManager() 3165 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3166 3167 // We don't allow third party apps to replace this. 3168 ResolveInfo ri = null; 3169 for (int i=0; ris != null && i<ris.size(); i++) { 3170 if ((ris.get(i).activityInfo.applicationInfo.flags 3171 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3172 ri = ris.get(i); 3173 break; 3174 } 3175 } 3176 3177 if (ri != null) { 3178 String vers = ri.activityInfo.metaData != null 3179 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3180 : null; 3181 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3182 vers = ri.activityInfo.applicationInfo.metaData.getString( 3183 Intent.METADATA_SETUP_VERSION); 3184 } 3185 String lastVers = Settings.Secure.getString( 3186 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3187 if (vers != null && !vers.equals(lastVers)) { 3188 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3189 intent.setComponent(new ComponentName( 3190 ri.activityInfo.packageName, ri.activityInfo.name)); 3191 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3192 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3193 } 3194 } 3195 } 3196 } 3197 3198 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3199 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3200 } 3201 3202 void enforceNotIsolatedCaller(String caller) { 3203 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3204 throw new SecurityException("Isolated process not allowed to call " + caller); 3205 } 3206 } 3207 3208 @Override 3209 public int getFrontActivityScreenCompatMode() { 3210 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3211 synchronized (this) { 3212 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3213 } 3214 } 3215 3216 @Override 3217 public void setFrontActivityScreenCompatMode(int mode) { 3218 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3219 "setFrontActivityScreenCompatMode"); 3220 synchronized (this) { 3221 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3222 } 3223 } 3224 3225 @Override 3226 public int getPackageScreenCompatMode(String packageName) { 3227 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3228 synchronized (this) { 3229 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3230 } 3231 } 3232 3233 @Override 3234 public void setPackageScreenCompatMode(String packageName, int mode) { 3235 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3236 "setPackageScreenCompatMode"); 3237 synchronized (this) { 3238 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3239 } 3240 } 3241 3242 @Override 3243 public boolean getPackageAskScreenCompat(String packageName) { 3244 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3245 synchronized (this) { 3246 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3247 } 3248 } 3249 3250 @Override 3251 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3252 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3253 "setPackageAskScreenCompat"); 3254 synchronized (this) { 3255 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3256 } 3257 } 3258 3259 private void dispatchProcessesChanged() { 3260 int N; 3261 synchronized (this) { 3262 N = mPendingProcessChanges.size(); 3263 if (mActiveProcessChanges.length < N) { 3264 mActiveProcessChanges = new ProcessChangeItem[N]; 3265 } 3266 mPendingProcessChanges.toArray(mActiveProcessChanges); 3267 mAvailProcessChanges.addAll(mPendingProcessChanges); 3268 mPendingProcessChanges.clear(); 3269 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3270 } 3271 3272 int i = mProcessObservers.beginBroadcast(); 3273 while (i > 0) { 3274 i--; 3275 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3276 if (observer != null) { 3277 try { 3278 for (int j=0; j<N; j++) { 3279 ProcessChangeItem item = mActiveProcessChanges[j]; 3280 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3281 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3282 + item.pid + " uid=" + item.uid + ": " 3283 + item.foregroundActivities); 3284 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3285 item.foregroundActivities); 3286 } 3287 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3289 + item.pid + " uid=" + item.uid + ": " + item.processState); 3290 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3291 } 3292 } 3293 } catch (RemoteException e) { 3294 } 3295 } 3296 } 3297 mProcessObservers.finishBroadcast(); 3298 } 3299 3300 private void dispatchProcessDied(int pid, int uid) { 3301 int i = mProcessObservers.beginBroadcast(); 3302 while (i > 0) { 3303 i--; 3304 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3305 if (observer != null) { 3306 try { 3307 observer.onProcessDied(pid, uid); 3308 } catch (RemoteException e) { 3309 } 3310 } 3311 } 3312 mProcessObservers.finishBroadcast(); 3313 } 3314 3315 final void doPendingActivityLaunchesLocked(boolean doResume) { 3316 final int N = mPendingActivityLaunches.size(); 3317 if (N <= 0) { 3318 return; 3319 } 3320 for (int i=0; i<N; i++) { 3321 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3322 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3323 doResume && i == (N-1), null); 3324 } 3325 mPendingActivityLaunches.clear(); 3326 } 3327 3328 @Override 3329 public final int startActivity(IApplicationThread caller, String callingPackage, 3330 Intent intent, String resolvedType, IBinder resultTo, 3331 String resultWho, int requestCode, int startFlags, 3332 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3333 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3334 resultWho, requestCode, 3335 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3336 } 3337 3338 @Override 3339 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3340 Intent intent, String resolvedType, IBinder resultTo, 3341 String resultWho, int requestCode, int startFlags, 3342 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3343 enforceNotIsolatedCaller("startActivity"); 3344 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3345 false, true, "startActivity", null); 3346 // TODO: Switch to user app stacks here. 3347 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3348 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3349 null, null, options, userId, null); 3350 } 3351 3352 @Override 3353 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3354 Intent intent, String resolvedType, IBinder resultTo, 3355 String resultWho, int requestCode, int startFlags, String profileFile, 3356 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3357 enforceNotIsolatedCaller("startActivityAndWait"); 3358 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3359 false, true, "startActivityAndWait", null); 3360 WaitResult res = new WaitResult(); 3361 // TODO: Switch to user app stacks here. 3362 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3363 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3364 res, null, options, UserHandle.getCallingUserId(), null); 3365 return res; 3366 } 3367 3368 @Override 3369 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3370 Intent intent, String resolvedType, IBinder resultTo, 3371 String resultWho, int requestCode, int startFlags, Configuration config, 3372 Bundle options, int userId) { 3373 enforceNotIsolatedCaller("startActivityWithConfig"); 3374 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3375 false, true, "startActivityWithConfig", null); 3376 // TODO: Switch to user app stacks here. 3377 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3378 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3379 null, null, null, config, options, userId, null); 3380 return ret; 3381 } 3382 3383 @Override 3384 public int startActivityIntentSender(IApplicationThread caller, 3385 IntentSender intent, Intent fillInIntent, String resolvedType, 3386 IBinder resultTo, String resultWho, int requestCode, 3387 int flagsMask, int flagsValues, Bundle options) { 3388 enforceNotIsolatedCaller("startActivityIntentSender"); 3389 // Refuse possible leaked file descriptors 3390 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3391 throw new IllegalArgumentException("File descriptors passed in Intent"); 3392 } 3393 3394 IIntentSender sender = intent.getTarget(); 3395 if (!(sender instanceof PendingIntentRecord)) { 3396 throw new IllegalArgumentException("Bad PendingIntent object"); 3397 } 3398 3399 PendingIntentRecord pir = (PendingIntentRecord)sender; 3400 3401 synchronized (this) { 3402 // If this is coming from the currently resumed activity, it is 3403 // effectively saying that app switches are allowed at this point. 3404 final ActivityStack stack = getFocusedStack(); 3405 if (stack.mResumedActivity != null && 3406 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3407 mAppSwitchesAllowedTime = 0; 3408 } 3409 } 3410 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3411 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3412 return ret; 3413 } 3414 3415 @Override 3416 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3417 Intent intent, String resolvedType, IVoiceInteractionSession session, 3418 IVoiceInteractor interactor, int startFlags, String profileFile, 3419 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3420 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3421 != PackageManager.PERMISSION_GRANTED) { 3422 String msg = "Permission Denial: startVoiceActivity() from pid=" 3423 + Binder.getCallingPid() 3424 + ", uid=" + Binder.getCallingUid() 3425 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3426 Slog.w(TAG, msg); 3427 throw new SecurityException(msg); 3428 } 3429 if (session == null || interactor == null) { 3430 throw new NullPointerException("null session or interactor"); 3431 } 3432 userId = handleIncomingUser(callingPid, callingUid, userId, 3433 false, true, "startVoiceActivity", null); 3434 // TODO: Switch to user app stacks here. 3435 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3436 resolvedType, session, interactor, null, null, 0, startFlags, 3437 profileFile, profileFd, null, null, options, userId, null); 3438 } 3439 3440 @Override 3441 public boolean startNextMatchingActivity(IBinder callingActivity, 3442 Intent intent, Bundle options) { 3443 // Refuse possible leaked file descriptors 3444 if (intent != null && intent.hasFileDescriptors() == true) { 3445 throw new IllegalArgumentException("File descriptors passed in Intent"); 3446 } 3447 3448 synchronized (this) { 3449 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3450 if (r == null) { 3451 ActivityOptions.abort(options); 3452 return false; 3453 } 3454 if (r.app == null || r.app.thread == null) { 3455 // The caller is not running... d'oh! 3456 ActivityOptions.abort(options); 3457 return false; 3458 } 3459 intent = new Intent(intent); 3460 // The caller is not allowed to change the data. 3461 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3462 // And we are resetting to find the next component... 3463 intent.setComponent(null); 3464 3465 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3466 3467 ActivityInfo aInfo = null; 3468 try { 3469 List<ResolveInfo> resolves = 3470 AppGlobals.getPackageManager().queryIntentActivities( 3471 intent, r.resolvedType, 3472 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3473 UserHandle.getCallingUserId()); 3474 3475 // Look for the original activity in the list... 3476 final int N = resolves != null ? resolves.size() : 0; 3477 for (int i=0; i<N; i++) { 3478 ResolveInfo rInfo = resolves.get(i); 3479 if (rInfo.activityInfo.packageName.equals(r.packageName) 3480 && rInfo.activityInfo.name.equals(r.info.name)) { 3481 // We found the current one... the next matching is 3482 // after it. 3483 i++; 3484 if (i<N) { 3485 aInfo = resolves.get(i).activityInfo; 3486 } 3487 if (debug) { 3488 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3489 + "/" + r.info.name); 3490 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3491 + "/" + aInfo.name); 3492 } 3493 break; 3494 } 3495 } 3496 } catch (RemoteException e) { 3497 } 3498 3499 if (aInfo == null) { 3500 // Nobody who is next! 3501 ActivityOptions.abort(options); 3502 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3503 return false; 3504 } 3505 3506 intent.setComponent(new ComponentName( 3507 aInfo.applicationInfo.packageName, aInfo.name)); 3508 intent.setFlags(intent.getFlags()&~( 3509 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3510 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3511 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3512 Intent.FLAG_ACTIVITY_NEW_TASK)); 3513 3514 // Okay now we need to start the new activity, replacing the 3515 // currently running activity. This is a little tricky because 3516 // we want to start the new one as if the current one is finished, 3517 // but not finish the current one first so that there is no flicker. 3518 // And thus... 3519 final boolean wasFinishing = r.finishing; 3520 r.finishing = true; 3521 3522 // Propagate reply information over to the new activity. 3523 final ActivityRecord resultTo = r.resultTo; 3524 final String resultWho = r.resultWho; 3525 final int requestCode = r.requestCode; 3526 r.resultTo = null; 3527 if (resultTo != null) { 3528 resultTo.removeResultsLocked(r, resultWho, requestCode); 3529 } 3530 3531 final long origId = Binder.clearCallingIdentity(); 3532 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3533 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3534 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3535 options, false, null, null); 3536 Binder.restoreCallingIdentity(origId); 3537 3538 r.finishing = wasFinishing; 3539 if (res != ActivityManager.START_SUCCESS) { 3540 return false; 3541 } 3542 return true; 3543 } 3544 } 3545 3546 final int startActivityInPackage(int uid, String callingPackage, 3547 Intent intent, String resolvedType, IBinder resultTo, 3548 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3549 IActivityContainer container) { 3550 3551 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3552 false, true, "startActivityInPackage", null); 3553 3554 // TODO: Switch to user app stacks here. 3555 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3556 null, null, resultTo, resultWho, requestCode, startFlags, 3557 null, null, null, null, options, userId, container); 3558 return ret; 3559 } 3560 3561 @Override 3562 public final int startActivities(IApplicationThread caller, String callingPackage, 3563 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3564 int userId) { 3565 enforceNotIsolatedCaller("startActivities"); 3566 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3567 false, true, "startActivity", null); 3568 // TODO: Switch to user app stacks here. 3569 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3570 resolvedTypes, resultTo, options, userId); 3571 return ret; 3572 } 3573 3574 final int startActivitiesInPackage(int uid, String callingPackage, 3575 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3576 Bundle options, int userId) { 3577 3578 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3579 false, true, "startActivityInPackage", null); 3580 // TODO: Switch to user app stacks here. 3581 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3582 resultTo, options, userId); 3583 return ret; 3584 } 3585 3586 final void addRecentTaskLocked(TaskRecord task) { 3587 int N = mRecentTasks.size(); 3588 // Quick case: check if the top-most recent task is the same. 3589 if (N > 0 && mRecentTasks.get(0) == task) { 3590 return; 3591 } 3592 // Another quick case: never add voice sessions. 3593 if (task.voiceSession != null) { 3594 return; 3595 } 3596 // Remove any existing entries that are the same kind of task. 3597 final Intent intent = task.intent; 3598 final boolean document = intent != null && intent.isDocument(); 3599 final ComponentName comp = intent.getComponent(); 3600 3601 int maxRecents = task.maxRecents - 1; 3602 for (int i=0; i<N; i++) { 3603 TaskRecord tr = mRecentTasks.get(i); 3604 if (task != tr) { 3605 if (task.userId != tr.userId) { 3606 continue; 3607 } 3608 if (i > MAX_RECENT_BITMAPS) { 3609 tr.freeLastThumbnail(); 3610 } 3611 final Intent trIntent = tr.intent; 3612 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3613 (intent == null || !intent.filterEquals(trIntent))) { 3614 continue; 3615 } 3616 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3617 if (document && trIsDocument) { 3618 // These are the same document activity (not necessarily the same doc). 3619 if (maxRecents > 0) { 3620 --maxRecents; 3621 continue; 3622 } 3623 // Hit the maximum number of documents for this task. Fall through 3624 // and remove this document from recents. 3625 } else if (document || trIsDocument) { 3626 // Only one of these is a document. Not the droid we're looking for. 3627 continue; 3628 } 3629 } 3630 3631 // Either task and tr are the same or, their affinities match or their intents match 3632 // and neither of them is a document, or they are documents using the same activity 3633 // and their maxRecents has been reached. 3634 tr.disposeThumbnail(); 3635 mRecentTasks.remove(i); 3636 i--; 3637 N--; 3638 if (task.intent == null) { 3639 // If the new recent task we are adding is not fully 3640 // specified, then replace it with the existing recent task. 3641 task = tr; 3642 } 3643 mTaskPersister.notify(tr, false); 3644 } 3645 if (N >= MAX_RECENT_TASKS) { 3646 mRecentTasks.remove(N-1).disposeThumbnail(); 3647 } 3648 mRecentTasks.add(0, task); 3649 } 3650 3651 @Override 3652 public void reportActivityFullyDrawn(IBinder token) { 3653 synchronized (this) { 3654 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3655 if (r == null) { 3656 return; 3657 } 3658 r.reportFullyDrawnLocked(); 3659 } 3660 } 3661 3662 @Override 3663 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3664 synchronized (this) { 3665 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3666 if (r == null) { 3667 return; 3668 } 3669 final long origId = Binder.clearCallingIdentity(); 3670 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3671 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3672 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3673 if (config != null) { 3674 r.frozenBeforeDestroy = true; 3675 if (!updateConfigurationLocked(config, r, false, false)) { 3676 mStackSupervisor.resumeTopActivitiesLocked(); 3677 } 3678 } 3679 Binder.restoreCallingIdentity(origId); 3680 } 3681 } 3682 3683 @Override 3684 public int getRequestedOrientation(IBinder token) { 3685 synchronized (this) { 3686 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3687 if (r == null) { 3688 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3689 } 3690 return mWindowManager.getAppOrientation(r.appToken); 3691 } 3692 } 3693 3694 /** 3695 * This is the internal entry point for handling Activity.finish(). 3696 * 3697 * @param token The Binder token referencing the Activity we want to finish. 3698 * @param resultCode Result code, if any, from this Activity. 3699 * @param resultData Result data (Intent), if any, from this Activity. 3700 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3701 * the root Activity in the task. 3702 * 3703 * @return Returns true if the activity successfully finished, or false if it is still running. 3704 */ 3705 @Override 3706 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3707 boolean finishTask) { 3708 // Refuse possible leaked file descriptors 3709 if (resultData != null && resultData.hasFileDescriptors() == true) { 3710 throw new IllegalArgumentException("File descriptors passed in Intent"); 3711 } 3712 3713 synchronized(this) { 3714 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3715 if (r == null) { 3716 return true; 3717 } 3718 // Keep track of the root activity of the task before we finish it 3719 TaskRecord tr = r.task; 3720 ActivityRecord rootR = tr.getRootActivity(); 3721 // Do not allow task to finish in Lock Task mode. 3722 if (tr == mStackSupervisor.mLockTaskModeTask) { 3723 if (rootR == r) { 3724 mStackSupervisor.showLockTaskToast(); 3725 return false; 3726 } 3727 } 3728 if (mController != null) { 3729 // Find the first activity that is not finishing. 3730 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3731 if (next != null) { 3732 // ask watcher if this is allowed 3733 boolean resumeOK = true; 3734 try { 3735 resumeOK = mController.activityResuming(next.packageName); 3736 } catch (RemoteException e) { 3737 mController = null; 3738 Watchdog.getInstance().setActivityController(null); 3739 } 3740 3741 if (!resumeOK) { 3742 return false; 3743 } 3744 } 3745 } 3746 final long origId = Binder.clearCallingIdentity(); 3747 try { 3748 boolean res; 3749 if (finishTask && r == rootR) { 3750 // If requested, remove the task that is associated to this activity only if it 3751 // was the root activity in the task. The result code and data is ignored because 3752 // we don't support returning them across task boundaries. 3753 res = removeTaskByIdLocked(tr.taskId, 0); 3754 } else { 3755 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3756 resultData, "app-request", true); 3757 } 3758 return res; 3759 } finally { 3760 Binder.restoreCallingIdentity(origId); 3761 } 3762 } 3763 } 3764 3765 @Override 3766 public final void finishHeavyWeightApp() { 3767 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3768 != PackageManager.PERMISSION_GRANTED) { 3769 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3770 + Binder.getCallingPid() 3771 + ", uid=" + Binder.getCallingUid() 3772 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3773 Slog.w(TAG, msg); 3774 throw new SecurityException(msg); 3775 } 3776 3777 synchronized(this) { 3778 if (mHeavyWeightProcess == null) { 3779 return; 3780 } 3781 3782 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3783 mHeavyWeightProcess.activities); 3784 for (int i=0; i<activities.size(); i++) { 3785 ActivityRecord r = activities.get(i); 3786 if (!r.finishing) { 3787 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3788 null, "finish-heavy", true); 3789 } 3790 } 3791 3792 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3793 mHeavyWeightProcess.userId, 0)); 3794 mHeavyWeightProcess = null; 3795 } 3796 } 3797 3798 @Override 3799 public void crashApplication(int uid, int initialPid, String packageName, 3800 String message) { 3801 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3802 != PackageManager.PERMISSION_GRANTED) { 3803 String msg = "Permission Denial: crashApplication() from pid=" 3804 + Binder.getCallingPid() 3805 + ", uid=" + Binder.getCallingUid() 3806 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3807 Slog.w(TAG, msg); 3808 throw new SecurityException(msg); 3809 } 3810 3811 synchronized(this) { 3812 ProcessRecord proc = null; 3813 3814 // Figure out which process to kill. We don't trust that initialPid 3815 // still has any relation to current pids, so must scan through the 3816 // list. 3817 synchronized (mPidsSelfLocked) { 3818 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3819 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3820 if (p.uid != uid) { 3821 continue; 3822 } 3823 if (p.pid == initialPid) { 3824 proc = p; 3825 break; 3826 } 3827 if (p.pkgList.containsKey(packageName)) { 3828 proc = p; 3829 } 3830 } 3831 } 3832 3833 if (proc == null) { 3834 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3835 + " initialPid=" + initialPid 3836 + " packageName=" + packageName); 3837 return; 3838 } 3839 3840 if (proc.thread != null) { 3841 if (proc.pid == Process.myPid()) { 3842 Log.w(TAG, "crashApplication: trying to crash self!"); 3843 return; 3844 } 3845 long ident = Binder.clearCallingIdentity(); 3846 try { 3847 proc.thread.scheduleCrash(message); 3848 } catch (RemoteException e) { 3849 } 3850 Binder.restoreCallingIdentity(ident); 3851 } 3852 } 3853 } 3854 3855 @Override 3856 public final void finishSubActivity(IBinder token, String resultWho, 3857 int requestCode) { 3858 synchronized(this) { 3859 final long origId = Binder.clearCallingIdentity(); 3860 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3861 if (r != null) { 3862 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3863 } 3864 Binder.restoreCallingIdentity(origId); 3865 } 3866 } 3867 3868 @Override 3869 public boolean finishActivityAffinity(IBinder token) { 3870 synchronized(this) { 3871 final long origId = Binder.clearCallingIdentity(); 3872 try { 3873 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3874 3875 ActivityRecord rootR = r.task.getRootActivity(); 3876 // Do not allow task to finish in Lock Task mode. 3877 if (r.task == mStackSupervisor.mLockTaskModeTask) { 3878 if (rootR == r) { 3879 mStackSupervisor.showLockTaskToast(); 3880 return false; 3881 } 3882 } 3883 boolean res = false; 3884 if (r != null) { 3885 res = r.task.stack.finishActivityAffinityLocked(r); 3886 } 3887 return res; 3888 } finally { 3889 Binder.restoreCallingIdentity(origId); 3890 } 3891 } 3892 } 3893 3894 @Override 3895 public void finishVoiceTask(IVoiceInteractionSession session) { 3896 synchronized(this) { 3897 final long origId = Binder.clearCallingIdentity(); 3898 try { 3899 mStackSupervisor.finishVoiceTask(session); 3900 } finally { 3901 Binder.restoreCallingIdentity(origId); 3902 } 3903 } 3904 3905 } 3906 3907 @Override 3908 public boolean willActivityBeVisible(IBinder token) { 3909 synchronized(this) { 3910 ActivityStack stack = ActivityRecord.getStackLocked(token); 3911 if (stack != null) { 3912 return stack.willActivityBeVisibleLocked(token); 3913 } 3914 return false; 3915 } 3916 } 3917 3918 @Override 3919 public void overridePendingTransition(IBinder token, String packageName, 3920 int enterAnim, int exitAnim) { 3921 synchronized(this) { 3922 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3923 if (self == null) { 3924 return; 3925 } 3926 3927 final long origId = Binder.clearCallingIdentity(); 3928 3929 if (self.state == ActivityState.RESUMED 3930 || self.state == ActivityState.PAUSING) { 3931 mWindowManager.overridePendingAppTransition(packageName, 3932 enterAnim, exitAnim, null); 3933 } 3934 3935 Binder.restoreCallingIdentity(origId); 3936 } 3937 } 3938 3939 /** 3940 * Main function for removing an existing process from the activity manager 3941 * as a result of that process going away. Clears out all connections 3942 * to the process. 3943 */ 3944 private final void handleAppDiedLocked(ProcessRecord app, 3945 boolean restarting, boolean allowRestart) { 3946 int pid = app.pid; 3947 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3948 if (!restarting) { 3949 removeLruProcessLocked(app); 3950 if (pid > 0) { 3951 ProcessList.remove(pid); 3952 } 3953 } 3954 3955 if (mProfileProc == app) { 3956 clearProfilerLocked(); 3957 } 3958 3959 // Remove this application's activities from active lists. 3960 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3961 3962 app.activities.clear(); 3963 3964 if (app.instrumentationClass != null) { 3965 Slog.w(TAG, "Crash of app " + app.processName 3966 + " running instrumentation " + app.instrumentationClass); 3967 Bundle info = new Bundle(); 3968 info.putString("shortMsg", "Process crashed."); 3969 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3970 } 3971 3972 if (!restarting) { 3973 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3974 // If there was nothing to resume, and we are not already 3975 // restarting this process, but there is a visible activity that 3976 // is hosted by the process... then make sure all visible 3977 // activities are running, taking care of restarting this 3978 // process. 3979 if (hasVisibleActivities) { 3980 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3981 } 3982 } 3983 } 3984 } 3985 3986 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3987 IBinder threadBinder = thread.asBinder(); 3988 // Find the application record. 3989 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3990 ProcessRecord rec = mLruProcesses.get(i); 3991 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3992 return i; 3993 } 3994 } 3995 return -1; 3996 } 3997 3998 final ProcessRecord getRecordForAppLocked( 3999 IApplicationThread thread) { 4000 if (thread == null) { 4001 return null; 4002 } 4003 4004 int appIndex = getLRURecordIndexForAppLocked(thread); 4005 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4006 } 4007 4008 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4009 // If there are no longer any background processes running, 4010 // and the app that died was not running instrumentation, 4011 // then tell everyone we are now low on memory. 4012 boolean haveBg = false; 4013 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4014 ProcessRecord rec = mLruProcesses.get(i); 4015 if (rec.thread != null 4016 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4017 haveBg = true; 4018 break; 4019 } 4020 } 4021 4022 if (!haveBg) { 4023 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4024 if (doReport) { 4025 long now = SystemClock.uptimeMillis(); 4026 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4027 doReport = false; 4028 } else { 4029 mLastMemUsageReportTime = now; 4030 } 4031 } 4032 final ArrayList<ProcessMemInfo> memInfos 4033 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4034 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4035 long now = SystemClock.uptimeMillis(); 4036 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4037 ProcessRecord rec = mLruProcesses.get(i); 4038 if (rec == dyingProc || rec.thread == null) { 4039 continue; 4040 } 4041 if (doReport) { 4042 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4043 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4044 } 4045 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4046 // The low memory report is overriding any current 4047 // state for a GC request. Make sure to do 4048 // heavy/important/visible/foreground processes first. 4049 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4050 rec.lastRequestedGc = 0; 4051 } else { 4052 rec.lastRequestedGc = rec.lastLowMemory; 4053 } 4054 rec.reportLowMemory = true; 4055 rec.lastLowMemory = now; 4056 mProcessesToGc.remove(rec); 4057 addProcessToGcListLocked(rec); 4058 } 4059 } 4060 if (doReport) { 4061 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4062 mHandler.sendMessage(msg); 4063 } 4064 scheduleAppGcsLocked(); 4065 } 4066 } 4067 4068 final void appDiedLocked(ProcessRecord app, int pid, 4069 IApplicationThread thread) { 4070 4071 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4072 synchronized (stats) { 4073 stats.noteProcessDiedLocked(app.info.uid, pid); 4074 } 4075 4076 // Clean up already done if the process has been re-started. 4077 if (app.pid == pid && app.thread != null && 4078 app.thread.asBinder() == thread.asBinder()) { 4079 boolean doLowMem = app.instrumentationClass == null; 4080 boolean doOomAdj = doLowMem; 4081 if (!app.killedByAm) { 4082 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4083 + ") has died."); 4084 mAllowLowerMemLevel = true; 4085 } else { 4086 // Note that we always want to do oom adj to update our state with the 4087 // new number of procs. 4088 mAllowLowerMemLevel = false; 4089 doLowMem = false; 4090 } 4091 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4092 if (DEBUG_CLEANUP) Slog.v( 4093 TAG, "Dying app: " + app + ", pid: " + pid 4094 + ", thread: " + thread.asBinder()); 4095 handleAppDiedLocked(app, false, true); 4096 4097 if (doOomAdj) { 4098 updateOomAdjLocked(); 4099 } 4100 if (doLowMem) { 4101 doLowMemReportIfNeededLocked(app); 4102 } 4103 } else if (app.pid != pid) { 4104 // A new process has already been started. 4105 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4106 + ") has died and restarted (pid " + app.pid + ")."); 4107 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4108 } else if (DEBUG_PROCESSES) { 4109 Slog.d(TAG, "Received spurious death notification for thread " 4110 + thread.asBinder()); 4111 } 4112 } 4113 4114 /** 4115 * If a stack trace dump file is configured, dump process stack traces. 4116 * @param clearTraces causes the dump file to be erased prior to the new 4117 * traces being written, if true; when false, the new traces will be 4118 * appended to any existing file content. 4119 * @param firstPids of dalvik VM processes to dump stack traces for first 4120 * @param lastPids of dalvik VM processes to dump stack traces for last 4121 * @param nativeProcs optional list of native process names to dump stack crawls 4122 * @return file containing stack traces, or null if no dump file is configured 4123 */ 4124 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4125 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4126 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4127 if (tracesPath == null || tracesPath.length() == 0) { 4128 return null; 4129 } 4130 4131 File tracesFile = new File(tracesPath); 4132 try { 4133 File tracesDir = tracesFile.getParentFile(); 4134 if (!tracesDir.exists()) { 4135 tracesFile.mkdirs(); 4136 if (!SELinux.restorecon(tracesDir)) { 4137 return null; 4138 } 4139 } 4140 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4141 4142 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4143 tracesFile.createNewFile(); 4144 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4145 } catch (IOException e) { 4146 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4147 return null; 4148 } 4149 4150 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4151 return tracesFile; 4152 } 4153 4154 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4155 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4156 // Use a FileObserver to detect when traces finish writing. 4157 // The order of traces is considered important to maintain for legibility. 4158 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4159 @Override 4160 public synchronized void onEvent(int event, String path) { notify(); } 4161 }; 4162 4163 try { 4164 observer.startWatching(); 4165 4166 // First collect all of the stacks of the most important pids. 4167 if (firstPids != null) { 4168 try { 4169 int num = firstPids.size(); 4170 for (int i = 0; i < num; i++) { 4171 synchronized (observer) { 4172 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4173 observer.wait(200); // Wait for write-close, give up after 200msec 4174 } 4175 } 4176 } catch (InterruptedException e) { 4177 Log.wtf(TAG, e); 4178 } 4179 } 4180 4181 // Next collect the stacks of the native pids 4182 if (nativeProcs != null) { 4183 int[] pids = Process.getPidsForCommands(nativeProcs); 4184 if (pids != null) { 4185 for (int pid : pids) { 4186 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4187 } 4188 } 4189 } 4190 4191 // Lastly, measure CPU usage. 4192 if (processCpuTracker != null) { 4193 processCpuTracker.init(); 4194 System.gc(); 4195 processCpuTracker.update(); 4196 try { 4197 synchronized (processCpuTracker) { 4198 processCpuTracker.wait(500); // measure over 1/2 second. 4199 } 4200 } catch (InterruptedException e) { 4201 } 4202 processCpuTracker.update(); 4203 4204 // We'll take the stack crawls of just the top apps using CPU. 4205 final int N = processCpuTracker.countWorkingStats(); 4206 int numProcs = 0; 4207 for (int i=0; i<N && numProcs<5; i++) { 4208 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4209 if (lastPids.indexOfKey(stats.pid) >= 0) { 4210 numProcs++; 4211 try { 4212 synchronized (observer) { 4213 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4214 observer.wait(200); // Wait for write-close, give up after 200msec 4215 } 4216 } catch (InterruptedException e) { 4217 Log.wtf(TAG, e); 4218 } 4219 4220 } 4221 } 4222 } 4223 } finally { 4224 observer.stopWatching(); 4225 } 4226 } 4227 4228 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4229 if (true || IS_USER_BUILD) { 4230 return; 4231 } 4232 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4233 if (tracesPath == null || tracesPath.length() == 0) { 4234 return; 4235 } 4236 4237 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4238 StrictMode.allowThreadDiskWrites(); 4239 try { 4240 final File tracesFile = new File(tracesPath); 4241 final File tracesDir = tracesFile.getParentFile(); 4242 final File tracesTmp = new File(tracesDir, "__tmp__"); 4243 try { 4244 if (!tracesDir.exists()) { 4245 tracesFile.mkdirs(); 4246 if (!SELinux.restorecon(tracesDir.getPath())) { 4247 return; 4248 } 4249 } 4250 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4251 4252 if (tracesFile.exists()) { 4253 tracesTmp.delete(); 4254 tracesFile.renameTo(tracesTmp); 4255 } 4256 StringBuilder sb = new StringBuilder(); 4257 Time tobj = new Time(); 4258 tobj.set(System.currentTimeMillis()); 4259 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4260 sb.append(": "); 4261 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4262 sb.append(" since "); 4263 sb.append(msg); 4264 FileOutputStream fos = new FileOutputStream(tracesFile); 4265 fos.write(sb.toString().getBytes()); 4266 if (app == null) { 4267 fos.write("\n*** No application process!".getBytes()); 4268 } 4269 fos.close(); 4270 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4271 } catch (IOException e) { 4272 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4273 return; 4274 } 4275 4276 if (app != null) { 4277 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4278 firstPids.add(app.pid); 4279 dumpStackTraces(tracesPath, firstPids, null, null, null); 4280 } 4281 4282 File lastTracesFile = null; 4283 File curTracesFile = null; 4284 for (int i=9; i>=0; i--) { 4285 String name = String.format(Locale.US, "slow%02d.txt", i); 4286 curTracesFile = new File(tracesDir, name); 4287 if (curTracesFile.exists()) { 4288 if (lastTracesFile != null) { 4289 curTracesFile.renameTo(lastTracesFile); 4290 } else { 4291 curTracesFile.delete(); 4292 } 4293 } 4294 lastTracesFile = curTracesFile; 4295 } 4296 tracesFile.renameTo(curTracesFile); 4297 if (tracesTmp.exists()) { 4298 tracesTmp.renameTo(tracesFile); 4299 } 4300 } finally { 4301 StrictMode.setThreadPolicy(oldPolicy); 4302 } 4303 } 4304 4305 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4306 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4307 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4308 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4309 4310 if (mController != null) { 4311 try { 4312 // 0 == continue, -1 = kill process immediately 4313 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4314 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4315 } catch (RemoteException e) { 4316 mController = null; 4317 Watchdog.getInstance().setActivityController(null); 4318 } 4319 } 4320 4321 long anrTime = SystemClock.uptimeMillis(); 4322 if (MONITOR_CPU_USAGE) { 4323 updateCpuStatsNow(); 4324 } 4325 4326 synchronized (this) { 4327 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4328 if (mShuttingDown) { 4329 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4330 return; 4331 } else if (app.notResponding) { 4332 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4333 return; 4334 } else if (app.crashing) { 4335 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4336 return; 4337 } 4338 4339 // In case we come through here for the same app before completing 4340 // this one, mark as anring now so we will bail out. 4341 app.notResponding = true; 4342 4343 // Log the ANR to the event log. 4344 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4345 app.processName, app.info.flags, annotation); 4346 4347 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4348 firstPids.add(app.pid); 4349 4350 int parentPid = app.pid; 4351 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4352 if (parentPid != app.pid) firstPids.add(parentPid); 4353 4354 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4355 4356 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4357 ProcessRecord r = mLruProcesses.get(i); 4358 if (r != null && r.thread != null) { 4359 int pid = r.pid; 4360 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4361 if (r.persistent) { 4362 firstPids.add(pid); 4363 } else { 4364 lastPids.put(pid, Boolean.TRUE); 4365 } 4366 } 4367 } 4368 } 4369 } 4370 4371 // Log the ANR to the main log. 4372 StringBuilder info = new StringBuilder(); 4373 info.setLength(0); 4374 info.append("ANR in ").append(app.processName); 4375 if (activity != null && activity.shortComponentName != null) { 4376 info.append(" (").append(activity.shortComponentName).append(")"); 4377 } 4378 info.append("\n"); 4379 info.append("PID: ").append(app.pid).append("\n"); 4380 if (annotation != null) { 4381 info.append("Reason: ").append(annotation).append("\n"); 4382 } 4383 if (parent != null && parent != activity) { 4384 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4385 } 4386 4387 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4388 4389 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4390 NATIVE_STACKS_OF_INTEREST); 4391 4392 String cpuInfo = null; 4393 if (MONITOR_CPU_USAGE) { 4394 updateCpuStatsNow(); 4395 synchronized (mProcessCpuThread) { 4396 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4397 } 4398 info.append(processCpuTracker.printCurrentLoad()); 4399 info.append(cpuInfo); 4400 } 4401 4402 info.append(processCpuTracker.printCurrentState(anrTime)); 4403 4404 Slog.e(TAG, info.toString()); 4405 if (tracesFile == null) { 4406 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4407 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4408 } 4409 4410 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4411 cpuInfo, tracesFile, null); 4412 4413 if (mController != null) { 4414 try { 4415 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4416 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4417 if (res != 0) { 4418 if (res < 0 && app.pid != MY_PID) { 4419 Process.killProcess(app.pid); 4420 } else { 4421 synchronized (this) { 4422 mServices.scheduleServiceTimeoutLocked(app); 4423 } 4424 } 4425 return; 4426 } 4427 } catch (RemoteException e) { 4428 mController = null; 4429 Watchdog.getInstance().setActivityController(null); 4430 } 4431 } 4432 4433 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4434 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4435 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4436 4437 synchronized (this) { 4438 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4439 killUnneededProcessLocked(app, "background ANR"); 4440 return; 4441 } 4442 4443 // Set the app's notResponding state, and look up the errorReportReceiver 4444 makeAppNotRespondingLocked(app, 4445 activity != null ? activity.shortComponentName : null, 4446 annotation != null ? "ANR " + annotation : "ANR", 4447 info.toString()); 4448 4449 // Bring up the infamous App Not Responding dialog 4450 Message msg = Message.obtain(); 4451 HashMap<String, Object> map = new HashMap<String, Object>(); 4452 msg.what = SHOW_NOT_RESPONDING_MSG; 4453 msg.obj = map; 4454 msg.arg1 = aboveSystem ? 1 : 0; 4455 map.put("app", app); 4456 if (activity != null) { 4457 map.put("activity", activity); 4458 } 4459 4460 mHandler.sendMessage(msg); 4461 } 4462 } 4463 4464 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4465 if (!mLaunchWarningShown) { 4466 mLaunchWarningShown = true; 4467 mHandler.post(new Runnable() { 4468 @Override 4469 public void run() { 4470 synchronized (ActivityManagerService.this) { 4471 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4472 d.show(); 4473 mHandler.postDelayed(new Runnable() { 4474 @Override 4475 public void run() { 4476 synchronized (ActivityManagerService.this) { 4477 d.dismiss(); 4478 mLaunchWarningShown = false; 4479 } 4480 } 4481 }, 4000); 4482 } 4483 } 4484 }); 4485 } 4486 } 4487 4488 @Override 4489 public boolean clearApplicationUserData(final String packageName, 4490 final IPackageDataObserver observer, int userId) { 4491 enforceNotIsolatedCaller("clearApplicationUserData"); 4492 int uid = Binder.getCallingUid(); 4493 int pid = Binder.getCallingPid(); 4494 userId = handleIncomingUser(pid, uid, 4495 userId, false, true, "clearApplicationUserData", null); 4496 long callingId = Binder.clearCallingIdentity(); 4497 try { 4498 IPackageManager pm = AppGlobals.getPackageManager(); 4499 int pkgUid = -1; 4500 synchronized(this) { 4501 try { 4502 pkgUid = pm.getPackageUid(packageName, userId); 4503 } catch (RemoteException e) { 4504 } 4505 if (pkgUid == -1) { 4506 Slog.w(TAG, "Invalid packageName: " + packageName); 4507 if (observer != null) { 4508 try { 4509 observer.onRemoveCompleted(packageName, false); 4510 } catch (RemoteException e) { 4511 Slog.i(TAG, "Observer no longer exists."); 4512 } 4513 } 4514 return false; 4515 } 4516 if (uid == pkgUid || checkComponentPermission( 4517 android.Manifest.permission.CLEAR_APP_USER_DATA, 4518 pid, uid, -1, true) 4519 == PackageManager.PERMISSION_GRANTED) { 4520 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4521 } else { 4522 throw new SecurityException("PID " + pid + " does not have permission " 4523 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4524 + " of package " + packageName); 4525 } 4526 } 4527 4528 try { 4529 // Clear application user data 4530 pm.clearApplicationUserData(packageName, observer, userId); 4531 4532 // Remove all permissions granted from/to this package 4533 removeUriPermissionsForPackageLocked(packageName, userId, true); 4534 4535 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4536 Uri.fromParts("package", packageName, null)); 4537 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4538 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4539 null, null, 0, null, null, null, false, false, userId); 4540 } catch (RemoteException e) { 4541 } 4542 } finally { 4543 Binder.restoreCallingIdentity(callingId); 4544 } 4545 return true; 4546 } 4547 4548 @Override 4549 public void killBackgroundProcesses(final String packageName, int userId) { 4550 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4551 != PackageManager.PERMISSION_GRANTED && 4552 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4553 != PackageManager.PERMISSION_GRANTED) { 4554 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4555 + Binder.getCallingPid() 4556 + ", uid=" + Binder.getCallingUid() 4557 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4558 Slog.w(TAG, msg); 4559 throw new SecurityException(msg); 4560 } 4561 4562 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4563 userId, true, true, "killBackgroundProcesses", null); 4564 long callingId = Binder.clearCallingIdentity(); 4565 try { 4566 IPackageManager pm = AppGlobals.getPackageManager(); 4567 synchronized(this) { 4568 int appId = -1; 4569 try { 4570 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4571 } catch (RemoteException e) { 4572 } 4573 if (appId == -1) { 4574 Slog.w(TAG, "Invalid packageName: " + packageName); 4575 return; 4576 } 4577 killPackageProcessesLocked(packageName, appId, userId, 4578 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4579 } 4580 } finally { 4581 Binder.restoreCallingIdentity(callingId); 4582 } 4583 } 4584 4585 @Override 4586 public void killAllBackgroundProcesses() { 4587 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4588 != PackageManager.PERMISSION_GRANTED) { 4589 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4590 + Binder.getCallingPid() 4591 + ", uid=" + Binder.getCallingUid() 4592 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4593 Slog.w(TAG, msg); 4594 throw new SecurityException(msg); 4595 } 4596 4597 long callingId = Binder.clearCallingIdentity(); 4598 try { 4599 synchronized(this) { 4600 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4601 final int NP = mProcessNames.getMap().size(); 4602 for (int ip=0; ip<NP; ip++) { 4603 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4604 final int NA = apps.size(); 4605 for (int ia=0; ia<NA; ia++) { 4606 ProcessRecord app = apps.valueAt(ia); 4607 if (app.persistent) { 4608 // we don't kill persistent processes 4609 continue; 4610 } 4611 if (app.removed) { 4612 procs.add(app); 4613 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4614 app.removed = true; 4615 procs.add(app); 4616 } 4617 } 4618 } 4619 4620 int N = procs.size(); 4621 for (int i=0; i<N; i++) { 4622 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4623 } 4624 mAllowLowerMemLevel = true; 4625 updateOomAdjLocked(); 4626 doLowMemReportIfNeededLocked(null); 4627 } 4628 } finally { 4629 Binder.restoreCallingIdentity(callingId); 4630 } 4631 } 4632 4633 @Override 4634 public void forceStopPackage(final String packageName, int userId) { 4635 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4636 != PackageManager.PERMISSION_GRANTED) { 4637 String msg = "Permission Denial: forceStopPackage() from pid=" 4638 + Binder.getCallingPid() 4639 + ", uid=" + Binder.getCallingUid() 4640 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4641 Slog.w(TAG, msg); 4642 throw new SecurityException(msg); 4643 } 4644 final int callingPid = Binder.getCallingPid(); 4645 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4646 userId, true, true, "forceStopPackage", null); 4647 long callingId = Binder.clearCallingIdentity(); 4648 try { 4649 IPackageManager pm = AppGlobals.getPackageManager(); 4650 synchronized(this) { 4651 int[] users = userId == UserHandle.USER_ALL 4652 ? getUsersLocked() : new int[] { userId }; 4653 for (int user : users) { 4654 int pkgUid = -1; 4655 try { 4656 pkgUid = pm.getPackageUid(packageName, user); 4657 } catch (RemoteException e) { 4658 } 4659 if (pkgUid == -1) { 4660 Slog.w(TAG, "Invalid packageName: " + packageName); 4661 continue; 4662 } 4663 try { 4664 pm.setPackageStoppedState(packageName, true, user); 4665 } catch (RemoteException e) { 4666 } catch (IllegalArgumentException e) { 4667 Slog.w(TAG, "Failed trying to unstop package " 4668 + packageName + ": " + e); 4669 } 4670 if (isUserRunningLocked(user, false)) { 4671 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4672 } 4673 } 4674 } 4675 } finally { 4676 Binder.restoreCallingIdentity(callingId); 4677 } 4678 } 4679 4680 /* 4681 * The pkg name and app id have to be specified. 4682 */ 4683 @Override 4684 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4685 if (pkg == null) { 4686 return; 4687 } 4688 // Make sure the uid is valid. 4689 if (appid < 0) { 4690 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4691 return; 4692 } 4693 int callerUid = Binder.getCallingUid(); 4694 // Only the system server can kill an application 4695 if (callerUid == Process.SYSTEM_UID) { 4696 // Post an aysnc message to kill the application 4697 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4698 msg.arg1 = appid; 4699 msg.arg2 = 0; 4700 Bundle bundle = new Bundle(); 4701 bundle.putString("pkg", pkg); 4702 bundle.putString("reason", reason); 4703 msg.obj = bundle; 4704 mHandler.sendMessage(msg); 4705 } else { 4706 throw new SecurityException(callerUid + " cannot kill pkg: " + 4707 pkg); 4708 } 4709 } 4710 4711 @Override 4712 public void closeSystemDialogs(String reason) { 4713 enforceNotIsolatedCaller("closeSystemDialogs"); 4714 4715 final int pid = Binder.getCallingPid(); 4716 final int uid = Binder.getCallingUid(); 4717 final long origId = Binder.clearCallingIdentity(); 4718 try { 4719 synchronized (this) { 4720 // Only allow this from foreground processes, so that background 4721 // applications can't abuse it to prevent system UI from being shown. 4722 if (uid >= Process.FIRST_APPLICATION_UID) { 4723 ProcessRecord proc; 4724 synchronized (mPidsSelfLocked) { 4725 proc = mPidsSelfLocked.get(pid); 4726 } 4727 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4728 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4729 + " from background process " + proc); 4730 return; 4731 } 4732 } 4733 closeSystemDialogsLocked(reason); 4734 } 4735 } finally { 4736 Binder.restoreCallingIdentity(origId); 4737 } 4738 } 4739 4740 void closeSystemDialogsLocked(String reason) { 4741 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4742 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4743 | Intent.FLAG_RECEIVER_FOREGROUND); 4744 if (reason != null) { 4745 intent.putExtra("reason", reason); 4746 } 4747 mWindowManager.closeSystemDialogs(reason); 4748 4749 mStackSupervisor.closeSystemDialogsLocked(); 4750 4751 broadcastIntentLocked(null, null, intent, null, 4752 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4753 Process.SYSTEM_UID, UserHandle.USER_ALL); 4754 } 4755 4756 @Override 4757 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4758 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4759 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4760 for (int i=pids.length-1; i>=0; i--) { 4761 ProcessRecord proc; 4762 int oomAdj; 4763 synchronized (this) { 4764 synchronized (mPidsSelfLocked) { 4765 proc = mPidsSelfLocked.get(pids[i]); 4766 oomAdj = proc != null ? proc.setAdj : 0; 4767 } 4768 } 4769 infos[i] = new Debug.MemoryInfo(); 4770 Debug.getMemoryInfo(pids[i], infos[i]); 4771 if (proc != null) { 4772 synchronized (this) { 4773 if (proc.thread != null && proc.setAdj == oomAdj) { 4774 // Record this for posterity if the process has been stable. 4775 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4776 infos[i].getTotalUss(), false, proc.pkgList); 4777 } 4778 } 4779 } 4780 } 4781 return infos; 4782 } 4783 4784 @Override 4785 public long[] getProcessPss(int[] pids) { 4786 enforceNotIsolatedCaller("getProcessPss"); 4787 long[] pss = new long[pids.length]; 4788 for (int i=pids.length-1; i>=0; i--) { 4789 ProcessRecord proc; 4790 int oomAdj; 4791 synchronized (this) { 4792 synchronized (mPidsSelfLocked) { 4793 proc = mPidsSelfLocked.get(pids[i]); 4794 oomAdj = proc != null ? proc.setAdj : 0; 4795 } 4796 } 4797 long[] tmpUss = new long[1]; 4798 pss[i] = Debug.getPss(pids[i], tmpUss); 4799 if (proc != null) { 4800 synchronized (this) { 4801 if (proc.thread != null && proc.setAdj == oomAdj) { 4802 // Record this for posterity if the process has been stable. 4803 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4804 } 4805 } 4806 } 4807 } 4808 return pss; 4809 } 4810 4811 @Override 4812 public void killApplicationProcess(String processName, int uid) { 4813 if (processName == null) { 4814 return; 4815 } 4816 4817 int callerUid = Binder.getCallingUid(); 4818 // Only the system server can kill an application 4819 if (callerUid == Process.SYSTEM_UID) { 4820 synchronized (this) { 4821 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4822 if (app != null && app.thread != null) { 4823 try { 4824 app.thread.scheduleSuicide(); 4825 } catch (RemoteException e) { 4826 // If the other end already died, then our work here is done. 4827 } 4828 } else { 4829 Slog.w(TAG, "Process/uid not found attempting kill of " 4830 + processName + " / " + uid); 4831 } 4832 } 4833 } else { 4834 throw new SecurityException(callerUid + " cannot kill app process: " + 4835 processName); 4836 } 4837 } 4838 4839 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4840 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4841 false, true, false, false, UserHandle.getUserId(uid), reason); 4842 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4843 Uri.fromParts("package", packageName, null)); 4844 if (!mProcessesReady) { 4845 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4846 | Intent.FLAG_RECEIVER_FOREGROUND); 4847 } 4848 intent.putExtra(Intent.EXTRA_UID, uid); 4849 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4850 broadcastIntentLocked(null, null, intent, 4851 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4852 false, false, 4853 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4854 } 4855 4856 private void forceStopUserLocked(int userId, String reason) { 4857 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4858 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4859 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4860 | Intent.FLAG_RECEIVER_FOREGROUND); 4861 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4862 broadcastIntentLocked(null, null, intent, 4863 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4864 false, false, 4865 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4866 } 4867 4868 private final boolean killPackageProcessesLocked(String packageName, int appId, 4869 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4870 boolean doit, boolean evenPersistent, String reason) { 4871 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4872 4873 // Remove all processes this package may have touched: all with the 4874 // same UID (except for the system or root user), and all whose name 4875 // matches the package name. 4876 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4877 final int NP = mProcessNames.getMap().size(); 4878 for (int ip=0; ip<NP; ip++) { 4879 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4880 final int NA = apps.size(); 4881 for (int ia=0; ia<NA; ia++) { 4882 ProcessRecord app = apps.valueAt(ia); 4883 if (app.persistent && !evenPersistent) { 4884 // we don't kill persistent processes 4885 continue; 4886 } 4887 if (app.removed) { 4888 if (doit) { 4889 procs.add(app); 4890 } 4891 continue; 4892 } 4893 4894 // Skip process if it doesn't meet our oom adj requirement. 4895 if (app.setAdj < minOomAdj) { 4896 continue; 4897 } 4898 4899 // If no package is specified, we call all processes under the 4900 // give user id. 4901 if (packageName == null) { 4902 if (app.userId != userId) { 4903 continue; 4904 } 4905 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4906 continue; 4907 } 4908 // Package has been specified, we want to hit all processes 4909 // that match it. We need to qualify this by the processes 4910 // that are running under the specified app and user ID. 4911 } else { 4912 if (UserHandle.getAppId(app.uid) != appId) { 4913 continue; 4914 } 4915 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4916 continue; 4917 } 4918 if (!app.pkgList.containsKey(packageName)) { 4919 continue; 4920 } 4921 } 4922 4923 // Process has passed all conditions, kill it! 4924 if (!doit) { 4925 return true; 4926 } 4927 app.removed = true; 4928 procs.add(app); 4929 } 4930 } 4931 4932 int N = procs.size(); 4933 for (int i=0; i<N; i++) { 4934 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4935 } 4936 updateOomAdjLocked(); 4937 return N > 0; 4938 } 4939 4940 private final boolean forceStopPackageLocked(String name, int appId, 4941 boolean callerWillRestart, boolean purgeCache, boolean doit, 4942 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4943 int i; 4944 int N; 4945 4946 if (userId == UserHandle.USER_ALL && name == null) { 4947 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4948 } 4949 4950 if (appId < 0 && name != null) { 4951 try { 4952 appId = UserHandle.getAppId( 4953 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4954 } catch (RemoteException e) { 4955 } 4956 } 4957 4958 if (doit) { 4959 if (name != null) { 4960 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4961 + " user=" + userId + ": " + reason); 4962 } else { 4963 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4964 } 4965 4966 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4967 for (int ip=pmap.size()-1; ip>=0; ip--) { 4968 SparseArray<Long> ba = pmap.valueAt(ip); 4969 for (i=ba.size()-1; i>=0; i--) { 4970 boolean remove = false; 4971 final int entUid = ba.keyAt(i); 4972 if (name != null) { 4973 if (userId == UserHandle.USER_ALL) { 4974 if (UserHandle.getAppId(entUid) == appId) { 4975 remove = true; 4976 } 4977 } else { 4978 if (entUid == UserHandle.getUid(userId, appId)) { 4979 remove = true; 4980 } 4981 } 4982 } else if (UserHandle.getUserId(entUid) == userId) { 4983 remove = true; 4984 } 4985 if (remove) { 4986 ba.removeAt(i); 4987 } 4988 } 4989 if (ba.size() == 0) { 4990 pmap.removeAt(ip); 4991 } 4992 } 4993 } 4994 4995 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4996 -100, callerWillRestart, true, doit, evenPersistent, 4997 name == null ? ("stop user " + userId) : ("stop " + name)); 4998 4999 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5000 if (!doit) { 5001 return true; 5002 } 5003 didSomething = true; 5004 } 5005 5006 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5007 if (!doit) { 5008 return true; 5009 } 5010 didSomething = true; 5011 } 5012 5013 if (name == null) { 5014 // Remove all sticky broadcasts from this user. 5015 mStickyBroadcasts.remove(userId); 5016 } 5017 5018 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5019 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5020 userId, providers)) { 5021 if (!doit) { 5022 return true; 5023 } 5024 didSomething = true; 5025 } 5026 N = providers.size(); 5027 for (i=0; i<N; i++) { 5028 removeDyingProviderLocked(null, providers.get(i), true); 5029 } 5030 5031 // Remove transient permissions granted from/to this package/user 5032 removeUriPermissionsForPackageLocked(name, userId, false); 5033 5034 if (name == null || uninstalling) { 5035 // Remove pending intents. For now we only do this when force 5036 // stopping users, because we have some problems when doing this 5037 // for packages -- app widgets are not currently cleaned up for 5038 // such packages, so they can be left with bad pending intents. 5039 if (mIntentSenderRecords.size() > 0) { 5040 Iterator<WeakReference<PendingIntentRecord>> it 5041 = mIntentSenderRecords.values().iterator(); 5042 while (it.hasNext()) { 5043 WeakReference<PendingIntentRecord> wpir = it.next(); 5044 if (wpir == null) { 5045 it.remove(); 5046 continue; 5047 } 5048 PendingIntentRecord pir = wpir.get(); 5049 if (pir == null) { 5050 it.remove(); 5051 continue; 5052 } 5053 if (name == null) { 5054 // Stopping user, remove all objects for the user. 5055 if (pir.key.userId != userId) { 5056 // Not the same user, skip it. 5057 continue; 5058 } 5059 } else { 5060 if (UserHandle.getAppId(pir.uid) != appId) { 5061 // Different app id, skip it. 5062 continue; 5063 } 5064 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5065 // Different user, skip it. 5066 continue; 5067 } 5068 if (!pir.key.packageName.equals(name)) { 5069 // Different package, skip it. 5070 continue; 5071 } 5072 } 5073 if (!doit) { 5074 return true; 5075 } 5076 didSomething = true; 5077 it.remove(); 5078 pir.canceled = true; 5079 if (pir.key.activity != null) { 5080 pir.key.activity.pendingResults.remove(pir.ref); 5081 } 5082 } 5083 } 5084 } 5085 5086 if (doit) { 5087 if (purgeCache && name != null) { 5088 AttributeCache ac = AttributeCache.instance(); 5089 if (ac != null) { 5090 ac.removePackage(name); 5091 } 5092 } 5093 if (mBooted) { 5094 mStackSupervisor.resumeTopActivitiesLocked(); 5095 mStackSupervisor.scheduleIdleLocked(); 5096 } 5097 } 5098 5099 return didSomething; 5100 } 5101 5102 private final boolean removeProcessLocked(ProcessRecord app, 5103 boolean callerWillRestart, boolean allowRestart, String reason) { 5104 final String name = app.processName; 5105 final int uid = app.uid; 5106 if (DEBUG_PROCESSES) Slog.d( 5107 TAG, "Force removing proc " + app.toShortString() + " (" + name 5108 + "/" + uid + ")"); 5109 5110 mProcessNames.remove(name, uid); 5111 mIsolatedProcesses.remove(app.uid); 5112 if (mHeavyWeightProcess == app) { 5113 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5114 mHeavyWeightProcess.userId, 0)); 5115 mHeavyWeightProcess = null; 5116 } 5117 boolean needRestart = false; 5118 if (app.pid > 0 && app.pid != MY_PID) { 5119 int pid = app.pid; 5120 synchronized (mPidsSelfLocked) { 5121 mPidsSelfLocked.remove(pid); 5122 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5123 } 5124 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5125 app.processName, app.info.uid); 5126 if (app.isolated) { 5127 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5128 } 5129 killUnneededProcessLocked(app, reason); 5130 handleAppDiedLocked(app, true, allowRestart); 5131 removeLruProcessLocked(app); 5132 5133 if (app.persistent && !app.isolated) { 5134 if (!callerWillRestart) { 5135 addAppLocked(app.info, false, null /* ABI override */); 5136 } else { 5137 needRestart = true; 5138 } 5139 } 5140 } else { 5141 mRemovedProcesses.add(app); 5142 } 5143 5144 return needRestart; 5145 } 5146 5147 private final void processStartTimedOutLocked(ProcessRecord app) { 5148 final int pid = app.pid; 5149 boolean gone = false; 5150 synchronized (mPidsSelfLocked) { 5151 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5152 if (knownApp != null && knownApp.thread == null) { 5153 mPidsSelfLocked.remove(pid); 5154 gone = true; 5155 } 5156 } 5157 5158 if (gone) { 5159 Slog.w(TAG, "Process " + app + " failed to attach"); 5160 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5161 pid, app.uid, app.processName); 5162 mProcessNames.remove(app.processName, app.uid); 5163 mIsolatedProcesses.remove(app.uid); 5164 if (mHeavyWeightProcess == app) { 5165 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5166 mHeavyWeightProcess.userId, 0)); 5167 mHeavyWeightProcess = null; 5168 } 5169 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5170 app.processName, app.info.uid); 5171 if (app.isolated) { 5172 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5173 } 5174 // Take care of any launching providers waiting for this process. 5175 checkAppInLaunchingProvidersLocked(app, true); 5176 // Take care of any services that are waiting for the process. 5177 mServices.processStartTimedOutLocked(app); 5178 killUnneededProcessLocked(app, "start timeout"); 5179 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5180 Slog.w(TAG, "Unattached app died before backup, skipping"); 5181 try { 5182 IBackupManager bm = IBackupManager.Stub.asInterface( 5183 ServiceManager.getService(Context.BACKUP_SERVICE)); 5184 bm.agentDisconnected(app.info.packageName); 5185 } catch (RemoteException e) { 5186 // Can't happen; the backup manager is local 5187 } 5188 } 5189 if (isPendingBroadcastProcessLocked(pid)) { 5190 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5191 skipPendingBroadcastLocked(pid); 5192 } 5193 } else { 5194 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5195 } 5196 } 5197 5198 private final boolean attachApplicationLocked(IApplicationThread thread, 5199 int pid) { 5200 5201 // Find the application record that is being attached... either via 5202 // the pid if we are running in multiple processes, or just pull the 5203 // next app record if we are emulating process with anonymous threads. 5204 ProcessRecord app; 5205 if (pid != MY_PID && pid >= 0) { 5206 synchronized (mPidsSelfLocked) { 5207 app = mPidsSelfLocked.get(pid); 5208 } 5209 } else { 5210 app = null; 5211 } 5212 5213 if (app == null) { 5214 Slog.w(TAG, "No pending application record for pid " + pid 5215 + " (IApplicationThread " + thread + "); dropping process"); 5216 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5217 if (pid > 0 && pid != MY_PID) { 5218 Process.killProcessQuiet(pid); 5219 } else { 5220 try { 5221 thread.scheduleExit(); 5222 } catch (Exception e) { 5223 // Ignore exceptions. 5224 } 5225 } 5226 return false; 5227 } 5228 5229 // If this application record is still attached to a previous 5230 // process, clean it up now. 5231 if (app.thread != null) { 5232 handleAppDiedLocked(app, true, true); 5233 } 5234 5235 // Tell the process all about itself. 5236 5237 if (localLOGV) Slog.v( 5238 TAG, "Binding process pid " + pid + " to record " + app); 5239 5240 final String processName = app.processName; 5241 try { 5242 AppDeathRecipient adr = new AppDeathRecipient( 5243 app, pid, thread); 5244 thread.asBinder().linkToDeath(adr, 0); 5245 app.deathRecipient = adr; 5246 } catch (RemoteException e) { 5247 app.resetPackageList(mProcessStats); 5248 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5249 return false; 5250 } 5251 5252 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5253 5254 app.makeActive(thread, mProcessStats); 5255 app.curAdj = app.setAdj = -100; 5256 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5257 app.forcingToForeground = null; 5258 updateProcessForegroundLocked(app, false, false); 5259 app.hasShownUi = false; 5260 app.debugging = false; 5261 app.cached = false; 5262 5263 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5264 5265 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5266 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5267 5268 if (!normalMode) { 5269 Slog.i(TAG, "Launching preboot mode app: " + app); 5270 } 5271 5272 if (localLOGV) Slog.v( 5273 TAG, "New app record " + app 5274 + " thread=" + thread.asBinder() + " pid=" + pid); 5275 try { 5276 int testMode = IApplicationThread.DEBUG_OFF; 5277 if (mDebugApp != null && mDebugApp.equals(processName)) { 5278 testMode = mWaitForDebugger 5279 ? IApplicationThread.DEBUG_WAIT 5280 : IApplicationThread.DEBUG_ON; 5281 app.debugging = true; 5282 if (mDebugTransient) { 5283 mDebugApp = mOrigDebugApp; 5284 mWaitForDebugger = mOrigWaitForDebugger; 5285 } 5286 } 5287 String profileFile = app.instrumentationProfileFile; 5288 ParcelFileDescriptor profileFd = null; 5289 boolean profileAutoStop = false; 5290 if (mProfileApp != null && mProfileApp.equals(processName)) { 5291 mProfileProc = app; 5292 profileFile = mProfileFile; 5293 profileFd = mProfileFd; 5294 profileAutoStop = mAutoStopProfiler; 5295 } 5296 boolean enableOpenGlTrace = false; 5297 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5298 enableOpenGlTrace = true; 5299 mOpenGlTraceApp = null; 5300 } 5301 5302 // If the app is being launched for restore or full backup, set it up specially 5303 boolean isRestrictedBackupMode = false; 5304 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5305 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5306 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5307 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5308 } 5309 5310 ensurePackageDexOpt(app.instrumentationInfo != null 5311 ? app.instrumentationInfo.packageName 5312 : app.info.packageName); 5313 if (app.instrumentationClass != null) { 5314 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5315 } 5316 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5317 + processName + " with config " + mConfiguration); 5318 ApplicationInfo appInfo = app.instrumentationInfo != null 5319 ? app.instrumentationInfo : app.info; 5320 app.compat = compatibilityInfoForPackageLocked(appInfo); 5321 if (profileFd != null) { 5322 profileFd = profileFd.dup(); 5323 } 5324 thread.bindApplication(processName, appInfo, providers, 5325 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5326 app.instrumentationArguments, app.instrumentationWatcher, 5327 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5328 isRestrictedBackupMode || !normalMode, app.persistent, 5329 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5330 mCoreSettingsObserver.getCoreSettingsLocked()); 5331 updateLruProcessLocked(app, false, null); 5332 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5333 } catch (Exception e) { 5334 // todo: Yikes! What should we do? For now we will try to 5335 // start another process, but that could easily get us in 5336 // an infinite loop of restarting processes... 5337 Slog.w(TAG, "Exception thrown during bind!", e); 5338 5339 app.resetPackageList(mProcessStats); 5340 app.unlinkDeathRecipient(); 5341 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5342 return false; 5343 } 5344 5345 // Remove this record from the list of starting applications. 5346 mPersistentStartingProcesses.remove(app); 5347 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5348 "Attach application locked removing on hold: " + app); 5349 mProcessesOnHold.remove(app); 5350 5351 boolean badApp = false; 5352 boolean didSomething = false; 5353 5354 // See if the top visible activity is waiting to run in this process... 5355 if (normalMode) { 5356 try { 5357 if (mStackSupervisor.attachApplicationLocked(app)) { 5358 didSomething = true; 5359 } 5360 } catch (Exception e) { 5361 badApp = true; 5362 } 5363 } 5364 5365 // Find any services that should be running in this process... 5366 if (!badApp) { 5367 try { 5368 didSomething |= mServices.attachApplicationLocked(app, processName); 5369 } catch (Exception e) { 5370 badApp = true; 5371 } 5372 } 5373 5374 // Check if a next-broadcast receiver is in this process... 5375 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5376 try { 5377 didSomething |= sendPendingBroadcastsLocked(app); 5378 } catch (Exception e) { 5379 // If the app died trying to launch the receiver we declare it 'bad' 5380 badApp = true; 5381 } 5382 } 5383 5384 // Check whether the next backup agent is in this process... 5385 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5386 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5387 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5388 try { 5389 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5390 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5391 mBackupTarget.backupMode); 5392 } catch (Exception e) { 5393 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5394 e.printStackTrace(); 5395 } 5396 } 5397 5398 if (badApp) { 5399 // todo: Also need to kill application to deal with all 5400 // kinds of exceptions. 5401 handleAppDiedLocked(app, false, true); 5402 return false; 5403 } 5404 5405 if (!didSomething) { 5406 updateOomAdjLocked(); 5407 } 5408 5409 return true; 5410 } 5411 5412 @Override 5413 public final void attachApplication(IApplicationThread thread) { 5414 synchronized (this) { 5415 int callingPid = Binder.getCallingPid(); 5416 final long origId = Binder.clearCallingIdentity(); 5417 attachApplicationLocked(thread, callingPid); 5418 Binder.restoreCallingIdentity(origId); 5419 } 5420 } 5421 5422 @Override 5423 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5424 final long origId = Binder.clearCallingIdentity(); 5425 synchronized (this) { 5426 ActivityStack stack = ActivityRecord.getStackLocked(token); 5427 if (stack != null) { 5428 ActivityRecord r = 5429 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5430 if (stopProfiling) { 5431 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5432 try { 5433 mProfileFd.close(); 5434 } catch (IOException e) { 5435 } 5436 clearProfilerLocked(); 5437 } 5438 } 5439 } 5440 } 5441 Binder.restoreCallingIdentity(origId); 5442 } 5443 5444 void enableScreenAfterBoot() { 5445 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5446 SystemClock.uptimeMillis()); 5447 mWindowManager.enableScreenAfterBoot(); 5448 5449 synchronized (this) { 5450 updateEventDispatchingLocked(); 5451 } 5452 } 5453 5454 @Override 5455 public void showBootMessage(final CharSequence msg, final boolean always) { 5456 enforceNotIsolatedCaller("showBootMessage"); 5457 mWindowManager.showBootMessage(msg, always); 5458 } 5459 5460 @Override 5461 public void dismissKeyguardOnNextActivity() { 5462 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5463 final long token = Binder.clearCallingIdentity(); 5464 try { 5465 synchronized (this) { 5466 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5467 if (mLockScreenShown) { 5468 mLockScreenShown = false; 5469 comeOutOfSleepIfNeededLocked(); 5470 } 5471 mStackSupervisor.setDismissKeyguard(true); 5472 } 5473 } finally { 5474 Binder.restoreCallingIdentity(token); 5475 } 5476 } 5477 5478 final void finishBooting() { 5479 // Register receivers to handle package update events 5480 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5481 5482 synchronized (this) { 5483 // Ensure that any processes we had put on hold are now started 5484 // up. 5485 final int NP = mProcessesOnHold.size(); 5486 if (NP > 0) { 5487 ArrayList<ProcessRecord> procs = 5488 new ArrayList<ProcessRecord>(mProcessesOnHold); 5489 for (int ip=0; ip<NP; ip++) { 5490 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5491 + procs.get(ip)); 5492 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5493 } 5494 } 5495 5496 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5497 // Start looking for apps that are abusing wake locks. 5498 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5499 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5500 // Tell anyone interested that we are done booting! 5501 SystemProperties.set("sys.boot_completed", "1"); 5502 SystemProperties.set("dev.bootcomplete", "1"); 5503 for (int i=0; i<mStartedUsers.size(); i++) { 5504 UserStartedState uss = mStartedUsers.valueAt(i); 5505 if (uss.mState == UserStartedState.STATE_BOOTING) { 5506 uss.mState = UserStartedState.STATE_RUNNING; 5507 final int userId = mStartedUsers.keyAt(i); 5508 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5509 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5510 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5511 broadcastIntentLocked(null, null, intent, null, 5512 new IIntentReceiver.Stub() { 5513 @Override 5514 public void performReceive(Intent intent, int resultCode, 5515 String data, Bundle extras, boolean ordered, 5516 boolean sticky, int sendingUser) { 5517 synchronized (ActivityManagerService.this) { 5518 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5519 true, false); 5520 } 5521 } 5522 }, 5523 0, null, null, 5524 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5525 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5526 userId); 5527 } 5528 } 5529 scheduleStartProfilesLocked(); 5530 } 5531 } 5532 } 5533 5534 final void ensureBootCompleted() { 5535 boolean booting; 5536 boolean enableScreen; 5537 synchronized (this) { 5538 booting = mBooting; 5539 mBooting = false; 5540 enableScreen = !mBooted; 5541 mBooted = true; 5542 } 5543 5544 if (booting) { 5545 finishBooting(); 5546 } 5547 5548 if (enableScreen) { 5549 enableScreenAfterBoot(); 5550 } 5551 } 5552 5553 @Override 5554 public final void activityResumed(IBinder token) { 5555 final long origId = Binder.clearCallingIdentity(); 5556 synchronized(this) { 5557 ActivityStack stack = ActivityRecord.getStackLocked(token); 5558 if (stack != null) { 5559 ActivityRecord.activityResumedLocked(token); 5560 } 5561 } 5562 Binder.restoreCallingIdentity(origId); 5563 } 5564 5565 @Override 5566 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5567 final long origId = Binder.clearCallingIdentity(); 5568 synchronized(this) { 5569 ActivityStack stack = ActivityRecord.getStackLocked(token); 5570 if (stack != null) { 5571 stack.activityPausedLocked(token, false, persistentState); 5572 } 5573 } 5574 Binder.restoreCallingIdentity(origId); 5575 } 5576 5577 @Override 5578 public final void activityStopped(IBinder token, Bundle icicle, 5579 PersistableBundle persistentState, CharSequence description) { 5580 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5581 5582 // Refuse possible leaked file descriptors 5583 if (icicle != null && icicle.hasFileDescriptors()) { 5584 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5585 } 5586 5587 final long origId = Binder.clearCallingIdentity(); 5588 5589 synchronized (this) { 5590 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5591 if (r != null) { 5592 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5593 } 5594 } 5595 5596 trimApplications(); 5597 5598 Binder.restoreCallingIdentity(origId); 5599 } 5600 5601 @Override 5602 public final void activityDestroyed(IBinder token) { 5603 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5604 synchronized (this) { 5605 ActivityStack stack = ActivityRecord.getStackLocked(token); 5606 if (stack != null) { 5607 stack.activityDestroyedLocked(token); 5608 } 5609 } 5610 } 5611 5612 @Override 5613 public final void mediaResourcesReleased(IBinder token) { 5614 final long origId = Binder.clearCallingIdentity(); 5615 try { 5616 synchronized (this) { 5617 ActivityStack stack = ActivityRecord.getStackLocked(token); 5618 if (stack != null) { 5619 stack.mediaResourcesReleased(token); 5620 } 5621 } 5622 } finally { 5623 Binder.restoreCallingIdentity(origId); 5624 } 5625 } 5626 5627 @Override 5628 public String getCallingPackage(IBinder token) { 5629 synchronized (this) { 5630 ActivityRecord r = getCallingRecordLocked(token); 5631 return r != null ? r.info.packageName : null; 5632 } 5633 } 5634 5635 @Override 5636 public ComponentName getCallingActivity(IBinder token) { 5637 synchronized (this) { 5638 ActivityRecord r = getCallingRecordLocked(token); 5639 return r != null ? r.intent.getComponent() : null; 5640 } 5641 } 5642 5643 private ActivityRecord getCallingRecordLocked(IBinder token) { 5644 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5645 if (r == null) { 5646 return null; 5647 } 5648 return r.resultTo; 5649 } 5650 5651 @Override 5652 public ComponentName getActivityClassForToken(IBinder token) { 5653 synchronized(this) { 5654 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5655 if (r == null) { 5656 return null; 5657 } 5658 return r.intent.getComponent(); 5659 } 5660 } 5661 5662 @Override 5663 public String getPackageForToken(IBinder token) { 5664 synchronized(this) { 5665 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5666 if (r == null) { 5667 return null; 5668 } 5669 return r.packageName; 5670 } 5671 } 5672 5673 @Override 5674 public IIntentSender getIntentSender(int type, 5675 String packageName, IBinder token, String resultWho, 5676 int requestCode, Intent[] intents, String[] resolvedTypes, 5677 int flags, Bundle options, int userId) { 5678 enforceNotIsolatedCaller("getIntentSender"); 5679 // Refuse possible leaked file descriptors 5680 if (intents != null) { 5681 if (intents.length < 1) { 5682 throw new IllegalArgumentException("Intents array length must be >= 1"); 5683 } 5684 for (int i=0; i<intents.length; i++) { 5685 Intent intent = intents[i]; 5686 if (intent != null) { 5687 if (intent.hasFileDescriptors()) { 5688 throw new IllegalArgumentException("File descriptors passed in Intent"); 5689 } 5690 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5691 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5692 throw new IllegalArgumentException( 5693 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5694 } 5695 intents[i] = new Intent(intent); 5696 } 5697 } 5698 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5699 throw new IllegalArgumentException( 5700 "Intent array length does not match resolvedTypes length"); 5701 } 5702 } 5703 if (options != null) { 5704 if (options.hasFileDescriptors()) { 5705 throw new IllegalArgumentException("File descriptors passed in options"); 5706 } 5707 } 5708 5709 synchronized(this) { 5710 int callingUid = Binder.getCallingUid(); 5711 int origUserId = userId; 5712 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5713 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5714 "getIntentSender", null); 5715 if (origUserId == UserHandle.USER_CURRENT) { 5716 // We don't want to evaluate this until the pending intent is 5717 // actually executed. However, we do want to always do the 5718 // security checking for it above. 5719 userId = UserHandle.USER_CURRENT; 5720 } 5721 try { 5722 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5723 int uid = AppGlobals.getPackageManager() 5724 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5725 if (!UserHandle.isSameApp(callingUid, uid)) { 5726 String msg = "Permission Denial: getIntentSender() from pid=" 5727 + Binder.getCallingPid() 5728 + ", uid=" + Binder.getCallingUid() 5729 + ", (need uid=" + uid + ")" 5730 + " is not allowed to send as package " + packageName; 5731 Slog.w(TAG, msg); 5732 throw new SecurityException(msg); 5733 } 5734 } 5735 5736 return getIntentSenderLocked(type, packageName, callingUid, userId, 5737 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5738 5739 } catch (RemoteException e) { 5740 throw new SecurityException(e); 5741 } 5742 } 5743 } 5744 5745 IIntentSender getIntentSenderLocked(int type, String packageName, 5746 int callingUid, int userId, IBinder token, String resultWho, 5747 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5748 Bundle options) { 5749 if (DEBUG_MU) 5750 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5751 ActivityRecord activity = null; 5752 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5753 activity = ActivityRecord.isInStackLocked(token); 5754 if (activity == null) { 5755 return null; 5756 } 5757 if (activity.finishing) { 5758 return null; 5759 } 5760 } 5761 5762 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5763 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5764 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5765 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5766 |PendingIntent.FLAG_UPDATE_CURRENT); 5767 5768 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5769 type, packageName, activity, resultWho, 5770 requestCode, intents, resolvedTypes, flags, options, userId); 5771 WeakReference<PendingIntentRecord> ref; 5772 ref = mIntentSenderRecords.get(key); 5773 PendingIntentRecord rec = ref != null ? ref.get() : null; 5774 if (rec != null) { 5775 if (!cancelCurrent) { 5776 if (updateCurrent) { 5777 if (rec.key.requestIntent != null) { 5778 rec.key.requestIntent.replaceExtras(intents != null ? 5779 intents[intents.length - 1] : null); 5780 } 5781 if (intents != null) { 5782 intents[intents.length-1] = rec.key.requestIntent; 5783 rec.key.allIntents = intents; 5784 rec.key.allResolvedTypes = resolvedTypes; 5785 } else { 5786 rec.key.allIntents = null; 5787 rec.key.allResolvedTypes = null; 5788 } 5789 } 5790 return rec; 5791 } 5792 rec.canceled = true; 5793 mIntentSenderRecords.remove(key); 5794 } 5795 if (noCreate) { 5796 return rec; 5797 } 5798 rec = new PendingIntentRecord(this, key, callingUid); 5799 mIntentSenderRecords.put(key, rec.ref); 5800 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5801 if (activity.pendingResults == null) { 5802 activity.pendingResults 5803 = new HashSet<WeakReference<PendingIntentRecord>>(); 5804 } 5805 activity.pendingResults.add(rec.ref); 5806 } 5807 return rec; 5808 } 5809 5810 @Override 5811 public void cancelIntentSender(IIntentSender sender) { 5812 if (!(sender instanceof PendingIntentRecord)) { 5813 return; 5814 } 5815 synchronized(this) { 5816 PendingIntentRecord rec = (PendingIntentRecord)sender; 5817 try { 5818 int uid = AppGlobals.getPackageManager() 5819 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5820 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5821 String msg = "Permission Denial: cancelIntentSender() from pid=" 5822 + Binder.getCallingPid() 5823 + ", uid=" + Binder.getCallingUid() 5824 + " is not allowed to cancel packges " 5825 + rec.key.packageName; 5826 Slog.w(TAG, msg); 5827 throw new SecurityException(msg); 5828 } 5829 } catch (RemoteException e) { 5830 throw new SecurityException(e); 5831 } 5832 cancelIntentSenderLocked(rec, true); 5833 } 5834 } 5835 5836 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5837 rec.canceled = true; 5838 mIntentSenderRecords.remove(rec.key); 5839 if (cleanActivity && rec.key.activity != null) { 5840 rec.key.activity.pendingResults.remove(rec.ref); 5841 } 5842 } 5843 5844 @Override 5845 public String getPackageForIntentSender(IIntentSender pendingResult) { 5846 if (!(pendingResult instanceof PendingIntentRecord)) { 5847 return null; 5848 } 5849 try { 5850 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5851 return res.key.packageName; 5852 } catch (ClassCastException e) { 5853 } 5854 return null; 5855 } 5856 5857 @Override 5858 public int getUidForIntentSender(IIntentSender sender) { 5859 if (sender instanceof PendingIntentRecord) { 5860 try { 5861 PendingIntentRecord res = (PendingIntentRecord)sender; 5862 return res.uid; 5863 } catch (ClassCastException e) { 5864 } 5865 } 5866 return -1; 5867 } 5868 5869 @Override 5870 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5871 if (!(pendingResult instanceof PendingIntentRecord)) { 5872 return false; 5873 } 5874 try { 5875 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5876 if (res.key.allIntents == null) { 5877 return false; 5878 } 5879 for (int i=0; i<res.key.allIntents.length; i++) { 5880 Intent intent = res.key.allIntents[i]; 5881 if (intent.getPackage() != null && intent.getComponent() != null) { 5882 return false; 5883 } 5884 } 5885 return true; 5886 } catch (ClassCastException e) { 5887 } 5888 return false; 5889 } 5890 5891 @Override 5892 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5893 if (!(pendingResult instanceof PendingIntentRecord)) { 5894 return false; 5895 } 5896 try { 5897 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5898 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5899 return true; 5900 } 5901 return false; 5902 } catch (ClassCastException e) { 5903 } 5904 return false; 5905 } 5906 5907 @Override 5908 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5909 if (!(pendingResult instanceof PendingIntentRecord)) { 5910 return null; 5911 } 5912 try { 5913 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5914 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5915 } catch (ClassCastException e) { 5916 } 5917 return null; 5918 } 5919 5920 @Override 5921 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5922 if (!(pendingResult instanceof PendingIntentRecord)) { 5923 return null; 5924 } 5925 try { 5926 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5927 Intent intent = res.key.requestIntent; 5928 if (intent != null) { 5929 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5930 || res.lastTagPrefix.equals(prefix))) { 5931 return res.lastTag; 5932 } 5933 res.lastTagPrefix = prefix; 5934 StringBuilder sb = new StringBuilder(128); 5935 if (prefix != null) { 5936 sb.append(prefix); 5937 } 5938 if (intent.getAction() != null) { 5939 sb.append(intent.getAction()); 5940 } else if (intent.getComponent() != null) { 5941 intent.getComponent().appendShortString(sb); 5942 } else { 5943 sb.append("?"); 5944 } 5945 return res.lastTag = sb.toString(); 5946 } 5947 } catch (ClassCastException e) { 5948 } 5949 return null; 5950 } 5951 5952 @Override 5953 public void setProcessLimit(int max) { 5954 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5955 "setProcessLimit()"); 5956 synchronized (this) { 5957 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5958 mProcessLimitOverride = max; 5959 } 5960 trimApplications(); 5961 } 5962 5963 @Override 5964 public int getProcessLimit() { 5965 synchronized (this) { 5966 return mProcessLimitOverride; 5967 } 5968 } 5969 5970 void foregroundTokenDied(ForegroundToken token) { 5971 synchronized (ActivityManagerService.this) { 5972 synchronized (mPidsSelfLocked) { 5973 ForegroundToken cur 5974 = mForegroundProcesses.get(token.pid); 5975 if (cur != token) { 5976 return; 5977 } 5978 mForegroundProcesses.remove(token.pid); 5979 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5980 if (pr == null) { 5981 return; 5982 } 5983 pr.forcingToForeground = null; 5984 updateProcessForegroundLocked(pr, false, false); 5985 } 5986 updateOomAdjLocked(); 5987 } 5988 } 5989 5990 @Override 5991 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5992 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5993 "setProcessForeground()"); 5994 synchronized(this) { 5995 boolean changed = false; 5996 5997 synchronized (mPidsSelfLocked) { 5998 ProcessRecord pr = mPidsSelfLocked.get(pid); 5999 if (pr == null && isForeground) { 6000 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6001 return; 6002 } 6003 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6004 if (oldToken != null) { 6005 oldToken.token.unlinkToDeath(oldToken, 0); 6006 mForegroundProcesses.remove(pid); 6007 if (pr != null) { 6008 pr.forcingToForeground = null; 6009 } 6010 changed = true; 6011 } 6012 if (isForeground && token != null) { 6013 ForegroundToken newToken = new ForegroundToken() { 6014 @Override 6015 public void binderDied() { 6016 foregroundTokenDied(this); 6017 } 6018 }; 6019 newToken.pid = pid; 6020 newToken.token = token; 6021 try { 6022 token.linkToDeath(newToken, 0); 6023 mForegroundProcesses.put(pid, newToken); 6024 pr.forcingToForeground = token; 6025 changed = true; 6026 } catch (RemoteException e) { 6027 // If the process died while doing this, we will later 6028 // do the cleanup with the process death link. 6029 } 6030 } 6031 } 6032 6033 if (changed) { 6034 updateOomAdjLocked(); 6035 } 6036 } 6037 } 6038 6039 // ========================================================= 6040 // PERMISSIONS 6041 // ========================================================= 6042 6043 static class PermissionController extends IPermissionController.Stub { 6044 ActivityManagerService mActivityManagerService; 6045 PermissionController(ActivityManagerService activityManagerService) { 6046 mActivityManagerService = activityManagerService; 6047 } 6048 6049 @Override 6050 public boolean checkPermission(String permission, int pid, int uid) { 6051 return mActivityManagerService.checkPermission(permission, pid, 6052 uid) == PackageManager.PERMISSION_GRANTED; 6053 } 6054 } 6055 6056 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6057 @Override 6058 public int checkComponentPermission(String permission, int pid, int uid, 6059 int owningUid, boolean exported) { 6060 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6061 owningUid, exported); 6062 } 6063 6064 @Override 6065 public Object getAMSLock() { 6066 return ActivityManagerService.this; 6067 } 6068 } 6069 6070 /** 6071 * This can be called with or without the global lock held. 6072 */ 6073 int checkComponentPermission(String permission, int pid, int uid, 6074 int owningUid, boolean exported) { 6075 // We might be performing an operation on behalf of an indirect binder 6076 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6077 // client identity accordingly before proceeding. 6078 Identity tlsIdentity = sCallerIdentity.get(); 6079 if (tlsIdentity != null) { 6080 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6081 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6082 uid = tlsIdentity.uid; 6083 pid = tlsIdentity.pid; 6084 } 6085 6086 if (pid == MY_PID) { 6087 return PackageManager.PERMISSION_GRANTED; 6088 } 6089 6090 return ActivityManager.checkComponentPermission(permission, uid, 6091 owningUid, exported); 6092 } 6093 6094 /** 6095 * As the only public entry point for permissions checking, this method 6096 * can enforce the semantic that requesting a check on a null global 6097 * permission is automatically denied. (Internally a null permission 6098 * string is used when calling {@link #checkComponentPermission} in cases 6099 * when only uid-based security is needed.) 6100 * 6101 * This can be called with or without the global lock held. 6102 */ 6103 @Override 6104 public int checkPermission(String permission, int pid, int uid) { 6105 if (permission == null) { 6106 return PackageManager.PERMISSION_DENIED; 6107 } 6108 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6109 } 6110 6111 /** 6112 * Binder IPC calls go through the public entry point. 6113 * This can be called with or without the global lock held. 6114 */ 6115 int checkCallingPermission(String permission) { 6116 return checkPermission(permission, 6117 Binder.getCallingPid(), 6118 UserHandle.getAppId(Binder.getCallingUid())); 6119 } 6120 6121 /** 6122 * This can be called with or without the global lock held. 6123 */ 6124 void enforceCallingPermission(String permission, String func) { 6125 if (checkCallingPermission(permission) 6126 == PackageManager.PERMISSION_GRANTED) { 6127 return; 6128 } 6129 6130 String msg = "Permission Denial: " + func + " from pid=" 6131 + Binder.getCallingPid() 6132 + ", uid=" + Binder.getCallingUid() 6133 + " requires " + permission; 6134 Slog.w(TAG, msg); 6135 throw new SecurityException(msg); 6136 } 6137 6138 /** 6139 * Determine if UID is holding permissions required to access {@link Uri} in 6140 * the given {@link ProviderInfo}. Final permission checking is always done 6141 * in {@link ContentProvider}. 6142 */ 6143 private final boolean checkHoldingPermissionsLocked( 6144 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6145 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6146 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6147 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6148 return false; 6149 } 6150 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6151 } 6152 6153 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6154 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6155 if (pi.applicationInfo.uid == uid) { 6156 return true; 6157 } else if (!pi.exported) { 6158 return false; 6159 } 6160 6161 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6162 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6163 try { 6164 // check if target holds top-level <provider> permissions 6165 if (!readMet && pi.readPermission != null && considerUidPermissions 6166 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6167 readMet = true; 6168 } 6169 if (!writeMet && pi.writePermission != null && considerUidPermissions 6170 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6171 writeMet = true; 6172 } 6173 6174 // track if unprotected read/write is allowed; any denied 6175 // <path-permission> below removes this ability 6176 boolean allowDefaultRead = pi.readPermission == null; 6177 boolean allowDefaultWrite = pi.writePermission == null; 6178 6179 // check if target holds any <path-permission> that match uri 6180 final PathPermission[] pps = pi.pathPermissions; 6181 if (pps != null) { 6182 final String path = grantUri.uri.getPath(); 6183 int i = pps.length; 6184 while (i > 0 && (!readMet || !writeMet)) { 6185 i--; 6186 PathPermission pp = pps[i]; 6187 if (pp.match(path)) { 6188 if (!readMet) { 6189 final String pprperm = pp.getReadPermission(); 6190 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6191 + pprperm + " for " + pp.getPath() 6192 + ": match=" + pp.match(path) 6193 + " check=" + pm.checkUidPermission(pprperm, uid)); 6194 if (pprperm != null) { 6195 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6196 == PERMISSION_GRANTED) { 6197 readMet = true; 6198 } else { 6199 allowDefaultRead = false; 6200 } 6201 } 6202 } 6203 if (!writeMet) { 6204 final String ppwperm = pp.getWritePermission(); 6205 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6206 + ppwperm + " for " + pp.getPath() 6207 + ": match=" + pp.match(path) 6208 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6209 if (ppwperm != null) { 6210 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6211 == PERMISSION_GRANTED) { 6212 writeMet = true; 6213 } else { 6214 allowDefaultWrite = false; 6215 } 6216 } 6217 } 6218 } 6219 } 6220 } 6221 6222 // grant unprotected <provider> read/write, if not blocked by 6223 // <path-permission> above 6224 if (allowDefaultRead) readMet = true; 6225 if (allowDefaultWrite) writeMet = true; 6226 6227 } catch (RemoteException e) { 6228 return false; 6229 } 6230 6231 return readMet && writeMet; 6232 } 6233 6234 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6235 ProviderInfo pi = null; 6236 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6237 if (cpr != null) { 6238 pi = cpr.info; 6239 } else { 6240 try { 6241 pi = AppGlobals.getPackageManager().resolveContentProvider( 6242 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6243 } catch (RemoteException ex) { 6244 } 6245 } 6246 return pi; 6247 } 6248 6249 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6250 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6251 if (targetUris != null) { 6252 return targetUris.get(grantUri); 6253 } 6254 return null; 6255 } 6256 6257 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6258 String targetPkg, int targetUid, GrantUri grantUri) { 6259 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6260 if (targetUris == null) { 6261 targetUris = Maps.newArrayMap(); 6262 mGrantedUriPermissions.put(targetUid, targetUris); 6263 } 6264 6265 UriPermission perm = targetUris.get(grantUri); 6266 if (perm == null) { 6267 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6268 targetUris.put(grantUri, perm); 6269 } 6270 6271 return perm; 6272 } 6273 6274 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6275 final int modeFlags) { 6276 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6277 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6278 : UriPermission.STRENGTH_OWNED; 6279 6280 // Root gets to do everything. 6281 if (uid == 0) { 6282 return true; 6283 } 6284 6285 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6286 if (perms == null) return false; 6287 6288 // First look for exact match 6289 final UriPermission exactPerm = perms.get(grantUri); 6290 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6291 return true; 6292 } 6293 6294 // No exact match, look for prefixes 6295 final int N = perms.size(); 6296 for (int i = 0; i < N; i++) { 6297 final UriPermission perm = perms.valueAt(i); 6298 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6299 && perm.getStrength(modeFlags) >= minStrength) { 6300 return true; 6301 } 6302 } 6303 6304 return false; 6305 } 6306 6307 @Override 6308 public int checkUriPermission(Uri uri, int pid, int uid, 6309 final int modeFlags, int userId) { 6310 enforceNotIsolatedCaller("checkUriPermission"); 6311 6312 // Another redirected-binder-call permissions check as in 6313 // {@link checkComponentPermission}. 6314 Identity tlsIdentity = sCallerIdentity.get(); 6315 if (tlsIdentity != null) { 6316 uid = tlsIdentity.uid; 6317 pid = tlsIdentity.pid; 6318 } 6319 6320 // Our own process gets to do everything. 6321 if (pid == MY_PID) { 6322 return PackageManager.PERMISSION_GRANTED; 6323 } 6324 synchronized (this) { 6325 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6326 ? PackageManager.PERMISSION_GRANTED 6327 : PackageManager.PERMISSION_DENIED; 6328 } 6329 } 6330 6331 /** 6332 * Check if the targetPkg can be granted permission to access uri by 6333 * the callingUid using the given modeFlags. Throws a security exception 6334 * if callingUid is not allowed to do this. Returns the uid of the target 6335 * if the URI permission grant should be performed; returns -1 if it is not 6336 * needed (for example targetPkg already has permission to access the URI). 6337 * If you already know the uid of the target, you can supply it in 6338 * lastTargetUid else set that to -1. 6339 */ 6340 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6341 final int modeFlags, int lastTargetUid) { 6342 if (!Intent.isAccessUriMode(modeFlags)) { 6343 return -1; 6344 } 6345 6346 if (targetPkg != null) { 6347 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6348 "Checking grant " + targetPkg + " permission to " + grantUri); 6349 } 6350 6351 final IPackageManager pm = AppGlobals.getPackageManager(); 6352 6353 // If this is not a content: uri, we can't do anything with it. 6354 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6355 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6356 "Can't grant URI permission for non-content URI: " + grantUri); 6357 return -1; 6358 } 6359 6360 final String authority = grantUri.uri.getAuthority(); 6361 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6362 if (pi == null) { 6363 Slog.w(TAG, "No content provider found for permission check: " + 6364 grantUri.uri.toSafeString()); 6365 return -1; 6366 } 6367 6368 int targetUid = lastTargetUid; 6369 if (targetUid < 0 && targetPkg != null) { 6370 try { 6371 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6372 if (targetUid < 0) { 6373 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6374 "Can't grant URI permission no uid for: " + targetPkg); 6375 return -1; 6376 } 6377 } catch (RemoteException ex) { 6378 return -1; 6379 } 6380 } 6381 6382 if (targetUid >= 0) { 6383 // First... does the target actually need this permission? 6384 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6385 // No need to grant the target this permission. 6386 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6387 "Target " + targetPkg + " already has full permission to " + grantUri); 6388 return -1; 6389 } 6390 } else { 6391 // First... there is no target package, so can anyone access it? 6392 boolean allowed = pi.exported; 6393 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6394 if (pi.readPermission != null) { 6395 allowed = false; 6396 } 6397 } 6398 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6399 if (pi.writePermission != null) { 6400 allowed = false; 6401 } 6402 } 6403 if (allowed) { 6404 return -1; 6405 } 6406 } 6407 6408 /* There is a special cross user grant if: 6409 * - The target is on another user. 6410 * - Apps on the current user can access the uri without any uid permissions. 6411 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6412 * grant uri permissions. 6413 */ 6414 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6415 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6416 modeFlags, false /*without considering the uid permissions*/); 6417 6418 // Second... is the provider allowing granting of URI permissions? 6419 if (!specialCrossUserGrant) { 6420 if (!pi.grantUriPermissions) { 6421 throw new SecurityException("Provider " + pi.packageName 6422 + "/" + pi.name 6423 + " does not allow granting of Uri permissions (uri " 6424 + grantUri + ")"); 6425 } 6426 if (pi.uriPermissionPatterns != null) { 6427 final int N = pi.uriPermissionPatterns.length; 6428 boolean allowed = false; 6429 for (int i=0; i<N; i++) { 6430 if (pi.uriPermissionPatterns[i] != null 6431 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6432 allowed = true; 6433 break; 6434 } 6435 } 6436 if (!allowed) { 6437 throw new SecurityException("Provider " + pi.packageName 6438 + "/" + pi.name 6439 + " does not allow granting of permission to path of Uri " 6440 + grantUri); 6441 } 6442 } 6443 } 6444 6445 // Third... does the caller itself have permission to access 6446 // this uri? 6447 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6448 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6449 // Require they hold a strong enough Uri permission 6450 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6451 throw new SecurityException("Uid " + callingUid 6452 + " does not have permission to uri " + grantUri); 6453 } 6454 } 6455 } 6456 return targetUid; 6457 } 6458 6459 @Override 6460 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6461 final int modeFlags, int userId) { 6462 enforceNotIsolatedCaller("checkGrantUriPermission"); 6463 synchronized(this) { 6464 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6465 new GrantUri(userId, uri, false), modeFlags, -1); 6466 } 6467 } 6468 6469 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6470 final int modeFlags, UriPermissionOwner owner) { 6471 if (!Intent.isAccessUriMode(modeFlags)) { 6472 return; 6473 } 6474 6475 // So here we are: the caller has the assumed permission 6476 // to the uri, and the target doesn't. Let's now give this to 6477 // the target. 6478 6479 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6480 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6481 6482 final String authority = grantUri.uri.getAuthority(); 6483 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6484 if (pi == null) { 6485 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6486 return; 6487 } 6488 6489 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6490 grantUri.prefix = true; 6491 } 6492 final UriPermission perm = findOrCreateUriPermissionLocked( 6493 pi.packageName, targetPkg, targetUid, grantUri); 6494 perm.grantModes(modeFlags, owner); 6495 } 6496 6497 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6498 final int modeFlags, UriPermissionOwner owner) { 6499 if (targetPkg == null) { 6500 throw new NullPointerException("targetPkg"); 6501 } 6502 6503 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6504 -1); 6505 if (targetUid < 0) { 6506 return; 6507 } 6508 6509 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6510 owner); 6511 } 6512 6513 static class NeededUriGrants extends ArrayList<GrantUri> { 6514 final String targetPkg; 6515 final int targetUid; 6516 final int flags; 6517 6518 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6519 this.targetPkg = targetPkg; 6520 this.targetUid = targetUid; 6521 this.flags = flags; 6522 } 6523 } 6524 6525 /** 6526 * Like checkGrantUriPermissionLocked, but takes an Intent. 6527 */ 6528 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6529 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6530 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6531 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6532 + " clip=" + (intent != null ? intent.getClipData() : null) 6533 + " from " + intent + "; flags=0x" 6534 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6535 6536 if (targetPkg == null) { 6537 throw new NullPointerException("targetPkg"); 6538 } 6539 6540 if (intent == null) { 6541 return null; 6542 } 6543 Uri data = intent.getData(); 6544 ClipData clip = intent.getClipData(); 6545 if (data == null && clip == null) { 6546 return null; 6547 } 6548 final IPackageManager pm = AppGlobals.getPackageManager(); 6549 int targetUid; 6550 if (needed != null) { 6551 targetUid = needed.targetUid; 6552 } else { 6553 try { 6554 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6555 } catch (RemoteException ex) { 6556 return null; 6557 } 6558 if (targetUid < 0) { 6559 if (DEBUG_URI_PERMISSION) { 6560 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6561 + " on user " + targetUserId); 6562 } 6563 return null; 6564 } 6565 } 6566 if (data != null) { 6567 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6568 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6569 targetUid); 6570 if (targetUid > 0) { 6571 if (needed == null) { 6572 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6573 } 6574 needed.add(grantUri); 6575 } 6576 } 6577 if (clip != null) { 6578 for (int i=0; i<clip.getItemCount(); i++) { 6579 Uri uri = clip.getItemAt(i).getUri(); 6580 if (uri != null) { 6581 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6582 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6583 targetUid); 6584 if (targetUid > 0) { 6585 if (needed == null) { 6586 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6587 } 6588 needed.add(grantUri); 6589 } 6590 } else { 6591 Intent clipIntent = clip.getItemAt(i).getIntent(); 6592 if (clipIntent != null) { 6593 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6594 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6595 if (newNeeded != null) { 6596 needed = newNeeded; 6597 } 6598 } 6599 } 6600 } 6601 } 6602 6603 return needed; 6604 } 6605 6606 /** 6607 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6608 */ 6609 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6610 UriPermissionOwner owner) { 6611 if (needed != null) { 6612 for (int i=0; i<needed.size(); i++) { 6613 GrantUri grantUri = needed.get(i); 6614 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6615 grantUri, needed.flags, owner); 6616 } 6617 } 6618 } 6619 6620 void grantUriPermissionFromIntentLocked(int callingUid, 6621 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6622 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6623 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6624 if (needed == null) { 6625 return; 6626 } 6627 6628 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6629 } 6630 6631 @Override 6632 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6633 final int modeFlags, int userId) { 6634 enforceNotIsolatedCaller("grantUriPermission"); 6635 GrantUri grantUri = new GrantUri(userId, uri, false); 6636 synchronized(this) { 6637 final ProcessRecord r = getRecordForAppLocked(caller); 6638 if (r == null) { 6639 throw new SecurityException("Unable to find app for caller " 6640 + caller 6641 + " when granting permission to uri " + grantUri); 6642 } 6643 if (targetPkg == null) { 6644 throw new IllegalArgumentException("null target"); 6645 } 6646 if (grantUri == null) { 6647 throw new IllegalArgumentException("null uri"); 6648 } 6649 6650 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6651 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6652 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6653 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6654 6655 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6656 } 6657 } 6658 6659 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6660 if (perm.modeFlags == 0) { 6661 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6662 perm.targetUid); 6663 if (perms != null) { 6664 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6665 "Removing " + perm.targetUid + " permission to " + perm.uri); 6666 6667 perms.remove(perm.uri); 6668 if (perms.isEmpty()) { 6669 mGrantedUriPermissions.remove(perm.targetUid); 6670 } 6671 } 6672 } 6673 } 6674 6675 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6676 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6677 6678 final IPackageManager pm = AppGlobals.getPackageManager(); 6679 final String authority = grantUri.uri.getAuthority(); 6680 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6681 if (pi == null) { 6682 Slog.w(TAG, "No content provider found for permission revoke: " 6683 + grantUri.toSafeString()); 6684 return; 6685 } 6686 6687 // Does the caller have this permission on the URI? 6688 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6689 // Right now, if you are not the original owner of the permission, 6690 // you are not allowed to revoke it. 6691 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6692 throw new SecurityException("Uid " + callingUid 6693 + " does not have permission to uri " + grantUri); 6694 //} 6695 } 6696 6697 boolean persistChanged = false; 6698 6699 // Go through all of the permissions and remove any that match. 6700 int N = mGrantedUriPermissions.size(); 6701 for (int i = 0; i < N; i++) { 6702 final int targetUid = mGrantedUriPermissions.keyAt(i); 6703 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6704 6705 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6706 final UriPermission perm = it.next(); 6707 if (perm.uri.sourceUserId == grantUri.sourceUserId 6708 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6709 if (DEBUG_URI_PERMISSION) 6710 Slog.v(TAG, 6711 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6712 persistChanged |= perm.revokeModes( 6713 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6714 if (perm.modeFlags == 0) { 6715 it.remove(); 6716 } 6717 } 6718 } 6719 6720 if (perms.isEmpty()) { 6721 mGrantedUriPermissions.remove(targetUid); 6722 N--; 6723 i--; 6724 } 6725 } 6726 6727 if (persistChanged) { 6728 schedulePersistUriGrants(); 6729 } 6730 } 6731 6732 @Override 6733 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6734 int userId) { 6735 enforceNotIsolatedCaller("revokeUriPermission"); 6736 synchronized(this) { 6737 final ProcessRecord r = getRecordForAppLocked(caller); 6738 if (r == null) { 6739 throw new SecurityException("Unable to find app for caller " 6740 + caller 6741 + " when revoking permission to uri " + uri); 6742 } 6743 if (uri == null) { 6744 Slog.w(TAG, "revokeUriPermission: null uri"); 6745 return; 6746 } 6747 6748 if (!Intent.isAccessUriMode(modeFlags)) { 6749 return; 6750 } 6751 6752 final IPackageManager pm = AppGlobals.getPackageManager(); 6753 final String authority = uri.getAuthority(); 6754 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6755 if (pi == null) { 6756 Slog.w(TAG, "No content provider found for permission revoke: " 6757 + uri.toSafeString()); 6758 return; 6759 } 6760 6761 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6762 } 6763 } 6764 6765 /** 6766 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6767 * given package. 6768 * 6769 * @param packageName Package name to match, or {@code null} to apply to all 6770 * packages. 6771 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6772 * to all users. 6773 * @param persistable If persistable grants should be removed. 6774 */ 6775 private void removeUriPermissionsForPackageLocked( 6776 String packageName, int userHandle, boolean persistable) { 6777 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6778 throw new IllegalArgumentException("Must narrow by either package or user"); 6779 } 6780 6781 boolean persistChanged = false; 6782 6783 int N = mGrantedUriPermissions.size(); 6784 for (int i = 0; i < N; i++) { 6785 final int targetUid = mGrantedUriPermissions.keyAt(i); 6786 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6787 6788 // Only inspect grants matching user 6789 if (userHandle == UserHandle.USER_ALL 6790 || userHandle == UserHandle.getUserId(targetUid)) { 6791 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6792 final UriPermission perm = it.next(); 6793 6794 // Only inspect grants matching package 6795 if (packageName == null || perm.sourcePkg.equals(packageName) 6796 || perm.targetPkg.equals(packageName)) { 6797 persistChanged |= perm.revokeModes( 6798 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6799 6800 // Only remove when no modes remain; any persisted grants 6801 // will keep this alive. 6802 if (perm.modeFlags == 0) { 6803 it.remove(); 6804 } 6805 } 6806 } 6807 6808 if (perms.isEmpty()) { 6809 mGrantedUriPermissions.remove(targetUid); 6810 N--; 6811 i--; 6812 } 6813 } 6814 } 6815 6816 if (persistChanged) { 6817 schedulePersistUriGrants(); 6818 } 6819 } 6820 6821 @Override 6822 public IBinder newUriPermissionOwner(String name) { 6823 enforceNotIsolatedCaller("newUriPermissionOwner"); 6824 synchronized(this) { 6825 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6826 return owner.getExternalTokenLocked(); 6827 } 6828 } 6829 6830 @Override 6831 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6832 final int modeFlags, int userId) { 6833 synchronized(this) { 6834 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6835 if (owner == null) { 6836 throw new IllegalArgumentException("Unknown owner: " + token); 6837 } 6838 if (fromUid != Binder.getCallingUid()) { 6839 if (Binder.getCallingUid() != Process.myUid()) { 6840 // Only system code can grant URI permissions on behalf 6841 // of other users. 6842 throw new SecurityException("nice try"); 6843 } 6844 } 6845 if (targetPkg == null) { 6846 throw new IllegalArgumentException("null target"); 6847 } 6848 if (uri == null) { 6849 throw new IllegalArgumentException("null uri"); 6850 } 6851 6852 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6853 modeFlags, owner); 6854 } 6855 } 6856 6857 @Override 6858 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6859 synchronized(this) { 6860 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6861 if (owner == null) { 6862 throw new IllegalArgumentException("Unknown owner: " + token); 6863 } 6864 6865 if (uri == null) { 6866 owner.removeUriPermissionsLocked(mode); 6867 } else { 6868 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6869 } 6870 } 6871 } 6872 6873 private void schedulePersistUriGrants() { 6874 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6875 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6876 10 * DateUtils.SECOND_IN_MILLIS); 6877 } 6878 } 6879 6880 private void writeGrantedUriPermissions() { 6881 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6882 6883 // Snapshot permissions so we can persist without lock 6884 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6885 synchronized (this) { 6886 final int size = mGrantedUriPermissions.size(); 6887 for (int i = 0; i < size; i++) { 6888 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6889 for (UriPermission perm : perms.values()) { 6890 if (perm.persistedModeFlags != 0) { 6891 persist.add(perm.snapshot()); 6892 } 6893 } 6894 } 6895 } 6896 6897 FileOutputStream fos = null; 6898 try { 6899 fos = mGrantFile.startWrite(); 6900 6901 XmlSerializer out = new FastXmlSerializer(); 6902 out.setOutput(fos, "utf-8"); 6903 out.startDocument(null, true); 6904 out.startTag(null, TAG_URI_GRANTS); 6905 for (UriPermission.Snapshot perm : persist) { 6906 out.startTag(null, TAG_URI_GRANT); 6907 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6908 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6909 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6910 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6911 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6912 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6913 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6914 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6915 out.endTag(null, TAG_URI_GRANT); 6916 } 6917 out.endTag(null, TAG_URI_GRANTS); 6918 out.endDocument(); 6919 6920 mGrantFile.finishWrite(fos); 6921 } catch (IOException e) { 6922 if (fos != null) { 6923 mGrantFile.failWrite(fos); 6924 } 6925 } 6926 } 6927 6928 private void readGrantedUriPermissionsLocked() { 6929 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6930 6931 final long now = System.currentTimeMillis(); 6932 6933 FileInputStream fis = null; 6934 try { 6935 fis = mGrantFile.openRead(); 6936 final XmlPullParser in = Xml.newPullParser(); 6937 in.setInput(fis, null); 6938 6939 int type; 6940 while ((type = in.next()) != END_DOCUMENT) { 6941 final String tag = in.getName(); 6942 if (type == START_TAG) { 6943 if (TAG_URI_GRANT.equals(tag)) { 6944 final int sourceUserId; 6945 final int targetUserId; 6946 final int userHandle = readIntAttribute(in, 6947 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6948 if (userHandle != UserHandle.USER_NULL) { 6949 // For backwards compatibility. 6950 sourceUserId = userHandle; 6951 targetUserId = userHandle; 6952 } else { 6953 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6954 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6955 } 6956 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6957 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6958 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6959 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6960 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6961 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6962 6963 // Sanity check that provider still belongs to source package 6964 final ProviderInfo pi = getProviderInfoLocked( 6965 uri.getAuthority(), sourceUserId); 6966 if (pi != null && sourcePkg.equals(pi.packageName)) { 6967 int targetUid = -1; 6968 try { 6969 targetUid = AppGlobals.getPackageManager() 6970 .getPackageUid(targetPkg, targetUserId); 6971 } catch (RemoteException e) { 6972 } 6973 if (targetUid != -1) { 6974 final UriPermission perm = findOrCreateUriPermissionLocked( 6975 sourcePkg, targetPkg, targetUid, 6976 new GrantUri(sourceUserId, uri, prefix)); 6977 perm.initPersistedModes(modeFlags, createdTime); 6978 } 6979 } else { 6980 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6981 + " but instead found " + pi); 6982 } 6983 } 6984 } 6985 } 6986 } catch (FileNotFoundException e) { 6987 // Missing grants is okay 6988 } catch (IOException e) { 6989 Log.wtf(TAG, "Failed reading Uri grants", e); 6990 } catch (XmlPullParserException e) { 6991 Log.wtf(TAG, "Failed reading Uri grants", e); 6992 } finally { 6993 IoUtils.closeQuietly(fis); 6994 } 6995 } 6996 6997 @Override 6998 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6999 enforceNotIsolatedCaller("takePersistableUriPermission"); 7000 7001 Preconditions.checkFlagsArgument(modeFlags, 7002 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7003 7004 synchronized (this) { 7005 final int callingUid = Binder.getCallingUid(); 7006 boolean persistChanged = false; 7007 GrantUri grantUri = new GrantUri(userId, uri, false); 7008 7009 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7010 new GrantUri(userId, uri, false)); 7011 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7012 new GrantUri(userId, uri, true)); 7013 7014 final boolean exactValid = (exactPerm != null) 7015 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7016 final boolean prefixValid = (prefixPerm != null) 7017 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7018 7019 if (!(exactValid || prefixValid)) { 7020 throw new SecurityException("No persistable permission grants found for UID " 7021 + callingUid + " and Uri " + grantUri.toSafeString()); 7022 } 7023 7024 if (exactValid) { 7025 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7026 } 7027 if (prefixValid) { 7028 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7029 } 7030 7031 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7032 7033 if (persistChanged) { 7034 schedulePersistUriGrants(); 7035 } 7036 } 7037 } 7038 7039 @Override 7040 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7041 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7042 7043 Preconditions.checkFlagsArgument(modeFlags, 7044 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7045 7046 synchronized (this) { 7047 final int callingUid = Binder.getCallingUid(); 7048 boolean persistChanged = false; 7049 7050 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7051 new GrantUri(userId, uri, false)); 7052 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7053 new GrantUri(userId, uri, true)); 7054 if (exactPerm == null && prefixPerm == null) { 7055 throw new SecurityException("No permission grants found for UID " + callingUid 7056 + " and Uri " + uri.toSafeString()); 7057 } 7058 7059 if (exactPerm != null) { 7060 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7061 removeUriPermissionIfNeededLocked(exactPerm); 7062 } 7063 if (prefixPerm != null) { 7064 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7065 removeUriPermissionIfNeededLocked(prefixPerm); 7066 } 7067 7068 if (persistChanged) { 7069 schedulePersistUriGrants(); 7070 } 7071 } 7072 } 7073 7074 /** 7075 * Prune any older {@link UriPermission} for the given UID until outstanding 7076 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7077 * 7078 * @return if any mutations occured that require persisting. 7079 */ 7080 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7081 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7082 if (perms == null) return false; 7083 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7084 7085 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7086 for (UriPermission perm : perms.values()) { 7087 if (perm.persistedModeFlags != 0) { 7088 persisted.add(perm); 7089 } 7090 } 7091 7092 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7093 if (trimCount <= 0) return false; 7094 7095 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7096 for (int i = 0; i < trimCount; i++) { 7097 final UriPermission perm = persisted.get(i); 7098 7099 if (DEBUG_URI_PERMISSION) { 7100 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7101 } 7102 7103 perm.releasePersistableModes(~0); 7104 removeUriPermissionIfNeededLocked(perm); 7105 } 7106 7107 return true; 7108 } 7109 7110 @Override 7111 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7112 String packageName, boolean incoming) { 7113 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7114 Preconditions.checkNotNull(packageName, "packageName"); 7115 7116 final int callingUid = Binder.getCallingUid(); 7117 final IPackageManager pm = AppGlobals.getPackageManager(); 7118 try { 7119 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7120 if (packageUid != callingUid) { 7121 throw new SecurityException( 7122 "Package " + packageName + " does not belong to calling UID " + callingUid); 7123 } 7124 } catch (RemoteException e) { 7125 throw new SecurityException("Failed to verify package name ownership"); 7126 } 7127 7128 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7129 synchronized (this) { 7130 if (incoming) { 7131 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7132 callingUid); 7133 if (perms == null) { 7134 Slog.w(TAG, "No permission grants found for " + packageName); 7135 } else { 7136 for (UriPermission perm : perms.values()) { 7137 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7138 result.add(perm.buildPersistedPublicApiObject()); 7139 } 7140 } 7141 } 7142 } else { 7143 final int size = mGrantedUriPermissions.size(); 7144 for (int i = 0; i < size; i++) { 7145 final ArrayMap<GrantUri, UriPermission> perms = 7146 mGrantedUriPermissions.valueAt(i); 7147 for (UriPermission perm : perms.values()) { 7148 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7149 result.add(perm.buildPersistedPublicApiObject()); 7150 } 7151 } 7152 } 7153 } 7154 } 7155 return new ParceledListSlice<android.content.UriPermission>(result); 7156 } 7157 7158 @Override 7159 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7160 synchronized (this) { 7161 ProcessRecord app = 7162 who != null ? getRecordForAppLocked(who) : null; 7163 if (app == null) return; 7164 7165 Message msg = Message.obtain(); 7166 msg.what = WAIT_FOR_DEBUGGER_MSG; 7167 msg.obj = app; 7168 msg.arg1 = waiting ? 1 : 0; 7169 mHandler.sendMessage(msg); 7170 } 7171 } 7172 7173 @Override 7174 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7175 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7176 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7177 outInfo.availMem = Process.getFreeMemory(); 7178 outInfo.totalMem = Process.getTotalMemory(); 7179 outInfo.threshold = homeAppMem; 7180 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7181 outInfo.hiddenAppThreshold = cachedAppMem; 7182 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7183 ProcessList.SERVICE_ADJ); 7184 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7185 ProcessList.VISIBLE_APP_ADJ); 7186 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7187 ProcessList.FOREGROUND_APP_ADJ); 7188 } 7189 7190 // ========================================================= 7191 // TASK MANAGEMENT 7192 // ========================================================= 7193 7194 @Override 7195 public List<IAppTask> getAppTasks() { 7196 final PackageManager pm = mContext.getPackageManager(); 7197 int callingUid = Binder.getCallingUid(); 7198 long ident = Binder.clearCallingIdentity(); 7199 7200 // Compose the list of packages for this id to test against 7201 HashSet<String> packages = new HashSet<String>(); 7202 String[] uidPackages = pm.getPackagesForUid(callingUid); 7203 for (int i = 0; i < uidPackages.length; i++) { 7204 packages.add(uidPackages[i]); 7205 } 7206 7207 synchronized(this) { 7208 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7209 try { 7210 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7211 7212 final int N = mRecentTasks.size(); 7213 for (int i = 0; i < N; i++) { 7214 TaskRecord tr = mRecentTasks.get(i); 7215 // Skip tasks that are not created by the caller 7216 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7217 ActivityManager.RecentTaskInfo taskInfo = 7218 createRecentTaskInfoFromTaskRecord(tr); 7219 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7220 list.add(taskImpl); 7221 } 7222 } 7223 } finally { 7224 Binder.restoreCallingIdentity(ident); 7225 } 7226 return list; 7227 } 7228 } 7229 7230 @Override 7231 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7232 final int callingUid = Binder.getCallingUid(); 7233 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7234 7235 synchronized(this) { 7236 if (localLOGV) Slog.v( 7237 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7238 7239 final boolean allowed = checkCallingPermission( 7240 android.Manifest.permission.GET_TASKS) 7241 == PackageManager.PERMISSION_GRANTED; 7242 if (!allowed) { 7243 Slog.w(TAG, "getTasks: caller " + callingUid 7244 + " does not hold GET_TASKS; limiting output"); 7245 } 7246 7247 // TODO: Improve with MRU list from all ActivityStacks. 7248 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7249 } 7250 7251 return list; 7252 } 7253 7254 TaskRecord getMostRecentTask() { 7255 return mRecentTasks.get(0); 7256 } 7257 7258 /** 7259 * Creates a new RecentTaskInfo from a TaskRecord. 7260 */ 7261 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7262 // Update the task description to reflect any changes in the task stack 7263 tr.updateTaskDescription(); 7264 7265 // Compose the recent task info 7266 ActivityManager.RecentTaskInfo rti 7267 = new ActivityManager.RecentTaskInfo(); 7268 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7269 rti.persistentId = tr.taskId; 7270 rti.baseIntent = new Intent(tr.getBaseIntent()); 7271 rti.origActivity = tr.origActivity; 7272 rti.description = tr.lastDescription; 7273 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7274 rti.userId = tr.userId; 7275 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7276 rti.firstActiveTime = tr.firstActiveTime; 7277 rti.lastActiveTime = tr.lastActiveTime; 7278 return rti; 7279 } 7280 7281 @Override 7282 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7283 int flags, int userId) { 7284 final int callingUid = Binder.getCallingUid(); 7285 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7286 false, true, "getRecentTasks", null); 7287 7288 synchronized (this) { 7289 final boolean allowed = checkCallingPermission( 7290 android.Manifest.permission.GET_TASKS) 7291 == PackageManager.PERMISSION_GRANTED; 7292 if (!allowed) { 7293 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7294 + " does not hold GET_TASKS; limiting output"); 7295 } 7296 final boolean detailed = checkCallingPermission( 7297 android.Manifest.permission.GET_DETAILED_TASKS) 7298 == PackageManager.PERMISSION_GRANTED; 7299 7300 IPackageManager pm = AppGlobals.getPackageManager(); 7301 7302 final int N = mRecentTasks.size(); 7303 ArrayList<ActivityManager.RecentTaskInfo> res 7304 = new ArrayList<ActivityManager.RecentTaskInfo>( 7305 maxNum < N ? maxNum : N); 7306 7307 final Set<Integer> includedUsers; 7308 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7309 includedUsers = getProfileIdsLocked(userId); 7310 } else { 7311 includedUsers = new HashSet<Integer>(); 7312 } 7313 includedUsers.add(Integer.valueOf(userId)); 7314 for (int i=0; i<N && maxNum > 0; i++) { 7315 TaskRecord tr = mRecentTasks.get(i); 7316 // Only add calling user or related users recent tasks 7317 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7318 7319 // Return the entry if desired by the caller. We always return 7320 // the first entry, because callers always expect this to be the 7321 // foreground app. We may filter others if the caller has 7322 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7323 // we should exclude the entry. 7324 7325 if (i == 0 7326 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7327 || (tr.intent == null) 7328 || ((tr.intent.getFlags() 7329 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7330 if (!allowed) { 7331 // If the caller doesn't have the GET_TASKS permission, then only 7332 // allow them to see a small subset of tasks -- their own and home. 7333 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7334 continue; 7335 } 7336 } 7337 if (tr.intent != null && 7338 (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) 7339 != 0 && tr.getTopActivity() == null) { 7340 // Don't include auto remove tasks that are finished or finishing. 7341 continue; 7342 } 7343 7344 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7345 if (!detailed) { 7346 rti.baseIntent.replaceExtras((Bundle)null); 7347 } 7348 7349 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7350 // Check whether this activity is currently available. 7351 try { 7352 if (rti.origActivity != null) { 7353 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7354 == null) { 7355 continue; 7356 } 7357 } else if (rti.baseIntent != null) { 7358 if (pm.queryIntentActivities(rti.baseIntent, 7359 null, 0, userId) == null) { 7360 continue; 7361 } 7362 } 7363 } catch (RemoteException e) { 7364 // Will never happen. 7365 } 7366 } 7367 7368 res.add(rti); 7369 maxNum--; 7370 } 7371 } 7372 return res; 7373 } 7374 } 7375 7376 private TaskRecord recentTaskForIdLocked(int id) { 7377 final int N = mRecentTasks.size(); 7378 for (int i=0; i<N; i++) { 7379 TaskRecord tr = mRecentTasks.get(i); 7380 if (tr.taskId == id) { 7381 return tr; 7382 } 7383 } 7384 return null; 7385 } 7386 7387 @Override 7388 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7389 synchronized (this) { 7390 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7391 "getTaskThumbnail()"); 7392 TaskRecord tr = recentTaskForIdLocked(id); 7393 if (tr != null) { 7394 return tr.getTaskThumbnailLocked(); 7395 } 7396 } 7397 return null; 7398 } 7399 7400 @Override 7401 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7402 synchronized (this) { 7403 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7404 if (r != null) { 7405 r.taskDescription = td; 7406 r.task.updateTaskDescription(); 7407 } 7408 } 7409 } 7410 7411 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7412 if (!pr.killedByAm) { 7413 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7414 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7415 pr.processName, pr.setAdj, reason); 7416 pr.killedByAm = true; 7417 Process.killProcessQuiet(pr.pid); 7418 } 7419 } 7420 7421 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7422 tr.disposeThumbnail(); 7423 mRecentTasks.remove(tr); 7424 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7425 Intent baseIntent = new Intent( 7426 tr.intent != null ? tr.intent : tr.affinityIntent); 7427 ComponentName component = baseIntent.getComponent(); 7428 if (component == null) { 7429 Slog.w(TAG, "Now component for base intent of task: " + tr); 7430 return; 7431 } 7432 7433 // Find any running services associated with this app. 7434 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7435 7436 if (killProcesses) { 7437 // Find any running processes associated with this app. 7438 final String pkg = component.getPackageName(); 7439 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7440 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7441 for (int i=0; i<pmap.size(); i++) { 7442 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7443 for (int j=0; j<uids.size(); j++) { 7444 ProcessRecord proc = uids.valueAt(j); 7445 if (proc.userId != tr.userId) { 7446 continue; 7447 } 7448 if (!proc.pkgList.containsKey(pkg)) { 7449 continue; 7450 } 7451 procs.add(proc); 7452 } 7453 } 7454 7455 // Kill the running processes. 7456 for (int i=0; i<procs.size(); i++) { 7457 ProcessRecord pr = procs.get(i); 7458 if (pr == mHomeProcess) { 7459 // Don't kill the home process along with tasks from the same package. 7460 continue; 7461 } 7462 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7463 killUnneededProcessLocked(pr, "remove task"); 7464 } else { 7465 pr.waitingToKill = "remove task"; 7466 } 7467 } 7468 } 7469 } 7470 7471 /** 7472 * Removes the task with the specified task id. 7473 * 7474 * @param taskId Identifier of the task to be removed. 7475 * @param flags Additional operational flags. May be 0 or 7476 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7477 * @return Returns true if the given task was found and removed. 7478 */ 7479 private boolean removeTaskByIdLocked(int taskId, int flags) { 7480 TaskRecord tr = recentTaskForIdLocked(taskId); 7481 if (tr != null) { 7482 tr.removeTaskActivitiesLocked(); 7483 cleanUpRemovedTaskLocked(tr, flags); 7484 if (tr.isPersistable) { 7485 notifyTaskPersisterLocked(tr, true); 7486 } 7487 return true; 7488 } 7489 return false; 7490 } 7491 7492 @Override 7493 public boolean removeTask(int taskId, int flags) { 7494 synchronized (this) { 7495 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7496 "removeTask()"); 7497 long ident = Binder.clearCallingIdentity(); 7498 try { 7499 return removeTaskByIdLocked(taskId, flags); 7500 } finally { 7501 Binder.restoreCallingIdentity(ident); 7502 } 7503 } 7504 } 7505 7506 /** 7507 * TODO: Add mController hook 7508 */ 7509 @Override 7510 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7511 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7512 "moveTaskToFront()"); 7513 7514 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7515 synchronized(this) { 7516 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7517 Binder.getCallingUid(), "Task to front")) { 7518 ActivityOptions.abort(options); 7519 return; 7520 } 7521 final long origId = Binder.clearCallingIdentity(); 7522 try { 7523 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7524 if (task == null) { 7525 return; 7526 } 7527 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7528 mStackSupervisor.showLockTaskToast(); 7529 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7530 return; 7531 } 7532 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7533 if (prev != null && prev.isRecentsActivity()) { 7534 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7535 } 7536 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7537 } finally { 7538 Binder.restoreCallingIdentity(origId); 7539 } 7540 ActivityOptions.abort(options); 7541 } 7542 } 7543 7544 @Override 7545 public void moveTaskToBack(int taskId) { 7546 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7547 "moveTaskToBack()"); 7548 7549 synchronized(this) { 7550 TaskRecord tr = recentTaskForIdLocked(taskId); 7551 if (tr != null) { 7552 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7553 ActivityStack stack = tr.stack; 7554 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7555 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7556 Binder.getCallingUid(), "Task to back")) { 7557 return; 7558 } 7559 } 7560 final long origId = Binder.clearCallingIdentity(); 7561 try { 7562 stack.moveTaskToBackLocked(taskId, null); 7563 } finally { 7564 Binder.restoreCallingIdentity(origId); 7565 } 7566 } 7567 } 7568 } 7569 7570 /** 7571 * Moves an activity, and all of the other activities within the same task, to the bottom 7572 * of the history stack. The activity's order within the task is unchanged. 7573 * 7574 * @param token A reference to the activity we wish to move 7575 * @param nonRoot If false then this only works if the activity is the root 7576 * of a task; if true it will work for any activity in a task. 7577 * @return Returns true if the move completed, false if not. 7578 */ 7579 @Override 7580 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7581 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7582 synchronized(this) { 7583 final long origId = Binder.clearCallingIdentity(); 7584 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7585 if (taskId >= 0) { 7586 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7587 } 7588 Binder.restoreCallingIdentity(origId); 7589 } 7590 return false; 7591 } 7592 7593 @Override 7594 public void moveTaskBackwards(int task) { 7595 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7596 "moveTaskBackwards()"); 7597 7598 synchronized(this) { 7599 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7600 Binder.getCallingUid(), "Task backwards")) { 7601 return; 7602 } 7603 final long origId = Binder.clearCallingIdentity(); 7604 moveTaskBackwardsLocked(task); 7605 Binder.restoreCallingIdentity(origId); 7606 } 7607 } 7608 7609 private final void moveTaskBackwardsLocked(int task) { 7610 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7611 } 7612 7613 @Override 7614 public IBinder getHomeActivityToken() throws RemoteException { 7615 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7616 "getHomeActivityToken()"); 7617 synchronized (this) { 7618 return mStackSupervisor.getHomeActivityToken(); 7619 } 7620 } 7621 7622 @Override 7623 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7624 IActivityContainerCallback callback) throws RemoteException { 7625 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7626 "createActivityContainer()"); 7627 synchronized (this) { 7628 if (parentActivityToken == null) { 7629 throw new IllegalArgumentException("parent token must not be null"); 7630 } 7631 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7632 if (r == null) { 7633 return null; 7634 } 7635 if (callback == null) { 7636 throw new IllegalArgumentException("callback must not be null"); 7637 } 7638 return mStackSupervisor.createActivityContainer(r, callback); 7639 } 7640 } 7641 7642 @Override 7643 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7644 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7645 "deleteActivityContainer()"); 7646 synchronized (this) { 7647 mStackSupervisor.deleteActivityContainer(container); 7648 } 7649 } 7650 7651 @Override 7652 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7653 throws RemoteException { 7654 synchronized (this) { 7655 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7656 if (stack != null) { 7657 return stack.mActivityContainer; 7658 } 7659 return null; 7660 } 7661 } 7662 7663 @Override 7664 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7665 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7666 "moveTaskToStack()"); 7667 if (stackId == HOME_STACK_ID) { 7668 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7669 new RuntimeException("here").fillInStackTrace()); 7670 } 7671 synchronized (this) { 7672 long ident = Binder.clearCallingIdentity(); 7673 try { 7674 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7675 + stackId + " toTop=" + toTop); 7676 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7677 } finally { 7678 Binder.restoreCallingIdentity(ident); 7679 } 7680 } 7681 } 7682 7683 @Override 7684 public void resizeStack(int stackBoxId, Rect bounds) { 7685 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7686 "resizeStackBox()"); 7687 long ident = Binder.clearCallingIdentity(); 7688 try { 7689 mWindowManager.resizeStack(stackBoxId, bounds); 7690 } finally { 7691 Binder.restoreCallingIdentity(ident); 7692 } 7693 } 7694 7695 @Override 7696 public List<StackInfo> getAllStackInfos() { 7697 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7698 "getAllStackInfos()"); 7699 long ident = Binder.clearCallingIdentity(); 7700 try { 7701 synchronized (this) { 7702 return mStackSupervisor.getAllStackInfosLocked(); 7703 } 7704 } finally { 7705 Binder.restoreCallingIdentity(ident); 7706 } 7707 } 7708 7709 @Override 7710 public StackInfo getStackInfo(int stackId) { 7711 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7712 "getStackInfo()"); 7713 long ident = Binder.clearCallingIdentity(); 7714 try { 7715 synchronized (this) { 7716 return mStackSupervisor.getStackInfoLocked(stackId); 7717 } 7718 } finally { 7719 Binder.restoreCallingIdentity(ident); 7720 } 7721 } 7722 7723 @Override 7724 public boolean isInHomeStack(int taskId) { 7725 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7726 "getStackInfo()"); 7727 long ident = Binder.clearCallingIdentity(); 7728 try { 7729 synchronized (this) { 7730 TaskRecord tr = recentTaskForIdLocked(taskId); 7731 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7732 } 7733 } finally { 7734 Binder.restoreCallingIdentity(ident); 7735 } 7736 } 7737 7738 @Override 7739 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7740 synchronized(this) { 7741 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7742 } 7743 } 7744 7745 private boolean isLockTaskAuthorized(String pkg) { 7746 final DevicePolicyManager dpm = (DevicePolicyManager) 7747 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7748 try { 7749 int uid = mContext.getPackageManager().getPackageUid(pkg, 7750 Binder.getCallingUserHandle().getIdentifier()); 7751 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7752 } catch (NameNotFoundException e) { 7753 return false; 7754 } 7755 } 7756 7757 void startLockTaskMode(TaskRecord task) { 7758 final String pkg; 7759 synchronized (this) { 7760 pkg = task.intent.getComponent().getPackageName(); 7761 } 7762 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7763 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7764 final TaskRecord taskRecord = task; 7765 mHandler.post(new Runnable() { 7766 @Override 7767 public void run() { 7768 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7769 } 7770 }); 7771 return; 7772 } 7773 long ident = Binder.clearCallingIdentity(); 7774 try { 7775 synchronized (this) { 7776 // Since we lost lock on task, make sure it is still there. 7777 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7778 if (task != null) { 7779 if (!isSystemInitiated 7780 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7781 throw new IllegalArgumentException("Invalid task, not in foreground"); 7782 } 7783 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 7784 } 7785 } 7786 } finally { 7787 Binder.restoreCallingIdentity(ident); 7788 } 7789 } 7790 7791 @Override 7792 public void startLockTaskMode(int taskId) { 7793 final TaskRecord task; 7794 long ident = Binder.clearCallingIdentity(); 7795 try { 7796 synchronized (this) { 7797 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7798 } 7799 } finally { 7800 Binder.restoreCallingIdentity(ident); 7801 } 7802 if (task != null) { 7803 startLockTaskMode(task); 7804 } 7805 } 7806 7807 @Override 7808 public void startLockTaskMode(IBinder token) { 7809 final TaskRecord task; 7810 long ident = Binder.clearCallingIdentity(); 7811 try { 7812 synchronized (this) { 7813 final ActivityRecord r = ActivityRecord.forToken(token); 7814 if (r == null) { 7815 return; 7816 } 7817 task = r.task; 7818 } 7819 } finally { 7820 Binder.restoreCallingIdentity(ident); 7821 } 7822 if (task != null) { 7823 startLockTaskMode(task); 7824 } 7825 } 7826 7827 @Override 7828 public void startLockTaskModeOnCurrent() throws RemoteException { 7829 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7830 ActivityRecord r = null; 7831 synchronized (this) { 7832 r = mStackSupervisor.topRunningActivityLocked(); 7833 } 7834 startLockTaskMode(r.task); 7835 } 7836 7837 @Override 7838 public void stopLockTaskMode() { 7839 // Verify that the user matches the package of the intent for the TaskRecord 7840 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7841 // and stopLockTaskMode. 7842 final int callingUid = Binder.getCallingUid(); 7843 if (callingUid != Process.SYSTEM_UID) { 7844 try { 7845 String pkg = 7846 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7847 int uid = mContext.getPackageManager().getPackageUid(pkg, 7848 Binder.getCallingUserHandle().getIdentifier()); 7849 if (uid != callingUid) { 7850 throw new SecurityException("Invalid uid, expected " + uid); 7851 } 7852 } catch (NameNotFoundException e) { 7853 Log.d(TAG, "stopLockTaskMode " + e); 7854 return; 7855 } 7856 } 7857 long ident = Binder.clearCallingIdentity(); 7858 try { 7859 Log.d(TAG, "stopLockTaskMode"); 7860 // Stop lock task 7861 synchronized (this) { 7862 mStackSupervisor.setLockTaskModeLocked(null, false); 7863 } 7864 } finally { 7865 Binder.restoreCallingIdentity(ident); 7866 } 7867 } 7868 7869 @Override 7870 public void stopLockTaskModeOnCurrent() throws RemoteException { 7871 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7872 long ident = Binder.clearCallingIdentity(); 7873 try { 7874 stopLockTaskMode(); 7875 } finally { 7876 Binder.restoreCallingIdentity(ident); 7877 } 7878 } 7879 7880 @Override 7881 public boolean isInLockTaskMode() { 7882 synchronized (this) { 7883 return mStackSupervisor.isInLockTaskMode(); 7884 } 7885 } 7886 7887 // ========================================================= 7888 // CONTENT PROVIDERS 7889 // ========================================================= 7890 7891 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7892 List<ProviderInfo> providers = null; 7893 try { 7894 providers = AppGlobals.getPackageManager(). 7895 queryContentProviders(app.processName, app.uid, 7896 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7897 } catch (RemoteException ex) { 7898 } 7899 if (DEBUG_MU) 7900 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7901 int userId = app.userId; 7902 if (providers != null) { 7903 int N = providers.size(); 7904 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7905 for (int i=0; i<N; i++) { 7906 ProviderInfo cpi = 7907 (ProviderInfo)providers.get(i); 7908 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7909 cpi.name, cpi.flags); 7910 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7911 // This is a singleton provider, but a user besides the 7912 // default user is asking to initialize a process it runs 7913 // in... well, no, it doesn't actually run in this process, 7914 // it runs in the process of the default user. Get rid of it. 7915 providers.remove(i); 7916 N--; 7917 i--; 7918 continue; 7919 } 7920 7921 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7922 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7923 if (cpr == null) { 7924 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7925 mProviderMap.putProviderByClass(comp, cpr); 7926 } 7927 if (DEBUG_MU) 7928 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7929 app.pubProviders.put(cpi.name, cpr); 7930 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7931 // Don't add this if it is a platform component that is marked 7932 // to run in multiple processes, because this is actually 7933 // part of the framework so doesn't make sense to track as a 7934 // separate apk in the process. 7935 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 7936 mProcessStats); 7937 } 7938 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7939 } 7940 } 7941 return providers; 7942 } 7943 7944 /** 7945 * Check if {@link ProcessRecord} has a possible chance at accessing the 7946 * given {@link ProviderInfo}. Final permission checking is always done 7947 * in {@link ContentProvider}. 7948 */ 7949 private final String checkContentProviderPermissionLocked( 7950 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 7951 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7952 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7953 boolean checkedGrants = false; 7954 if (checkUser) { 7955 // Looking for cross-user grants before enforcing the typical cross-users permissions 7956 if (UserHandle.getUserId(callingUid) != userId) { 7957 if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7958 return null; 7959 } 7960 checkedGrants = true; 7961 } 7962 userId = handleIncomingUser(callingPid, callingUid, userId, 7963 false, false, "checkContentProviderPermissionLocked " + cpi.authority, null); 7964 } 7965 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7966 cpi.applicationInfo.uid, cpi.exported) 7967 == PackageManager.PERMISSION_GRANTED) { 7968 return null; 7969 } 7970 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7971 cpi.applicationInfo.uid, cpi.exported) 7972 == PackageManager.PERMISSION_GRANTED) { 7973 return null; 7974 } 7975 7976 PathPermission[] pps = cpi.pathPermissions; 7977 if (pps != null) { 7978 int i = pps.length; 7979 while (i > 0) { 7980 i--; 7981 PathPermission pp = pps[i]; 7982 String pprperm = pp.getReadPermission(); 7983 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 7984 cpi.applicationInfo.uid, cpi.exported) 7985 == PackageManager.PERMISSION_GRANTED) { 7986 return null; 7987 } 7988 String ppwperm = pp.getWritePermission(); 7989 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 7990 cpi.applicationInfo.uid, cpi.exported) 7991 == PackageManager.PERMISSION_GRANTED) { 7992 return null; 7993 } 7994 } 7995 } 7996 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7997 return null; 7998 } 7999 8000 String msg; 8001 if (!cpi.exported) { 8002 msg = "Permission Denial: opening provider " + cpi.name 8003 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8004 + ", uid=" + callingUid + ") that is not exported from uid " 8005 + cpi.applicationInfo.uid; 8006 } else { 8007 msg = "Permission Denial: opening provider " + cpi.name 8008 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8009 + ", uid=" + callingUid + ") requires " 8010 + cpi.readPermission + " or " + cpi.writePermission; 8011 } 8012 Slog.w(TAG, msg); 8013 return msg; 8014 } 8015 8016 /** 8017 * Returns if the ContentProvider has granted a uri to callingUid 8018 */ 8019 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8020 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8021 if (perms != null) { 8022 for (GrantUri grantUri : perms.keySet()) { 8023 if (grantUri.sourceUserId == userId || !checkUser) { 8024 if (matchesProvider(grantUri.uri, cpi)) { 8025 return true; 8026 } 8027 } 8028 } 8029 } 8030 return false; 8031 } 8032 8033 /** 8034 * Returns true if the uri authority is one of the authorities specified in the provider. 8035 */ 8036 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8037 String uriAuth = uri.getAuthority(); 8038 String cpiAuth = cpi.authority; 8039 if (cpiAuth.indexOf(';') == -1) { 8040 return cpiAuth.equals(uriAuth); 8041 } 8042 String[] cpiAuths = cpiAuth.split(";"); 8043 int length = cpiAuths.length; 8044 for (int i = 0; i < length; i++) { 8045 if (cpiAuths[i].equals(uriAuth)) return true; 8046 } 8047 return false; 8048 } 8049 8050 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8051 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8052 if (r != null) { 8053 for (int i=0; i<r.conProviders.size(); i++) { 8054 ContentProviderConnection conn = r.conProviders.get(i); 8055 if (conn.provider == cpr) { 8056 if (DEBUG_PROVIDER) Slog.v(TAG, 8057 "Adding provider requested by " 8058 + r.processName + " from process " 8059 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8060 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8061 if (stable) { 8062 conn.stableCount++; 8063 conn.numStableIncs++; 8064 } else { 8065 conn.unstableCount++; 8066 conn.numUnstableIncs++; 8067 } 8068 return conn; 8069 } 8070 } 8071 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8072 if (stable) { 8073 conn.stableCount = 1; 8074 conn.numStableIncs = 1; 8075 } else { 8076 conn.unstableCount = 1; 8077 conn.numUnstableIncs = 1; 8078 } 8079 cpr.connections.add(conn); 8080 r.conProviders.add(conn); 8081 return conn; 8082 } 8083 cpr.addExternalProcessHandleLocked(externalProcessToken); 8084 return null; 8085 } 8086 8087 boolean decProviderCountLocked(ContentProviderConnection conn, 8088 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8089 if (conn != null) { 8090 cpr = conn.provider; 8091 if (DEBUG_PROVIDER) Slog.v(TAG, 8092 "Removing provider requested by " 8093 + conn.client.processName + " from process " 8094 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8095 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8096 if (stable) { 8097 conn.stableCount--; 8098 } else { 8099 conn.unstableCount--; 8100 } 8101 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8102 cpr.connections.remove(conn); 8103 conn.client.conProviders.remove(conn); 8104 return true; 8105 } 8106 return false; 8107 } 8108 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8109 return false; 8110 } 8111 8112 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8113 String name, IBinder token, boolean stable, int userId) { 8114 ContentProviderRecord cpr; 8115 ContentProviderConnection conn = null; 8116 ProviderInfo cpi = null; 8117 8118 synchronized(this) { 8119 ProcessRecord r = null; 8120 if (caller != null) { 8121 r = getRecordForAppLocked(caller); 8122 if (r == null) { 8123 throw new SecurityException( 8124 "Unable to find app for caller " + caller 8125 + " (pid=" + Binder.getCallingPid() 8126 + ") when getting content provider " + name); 8127 } 8128 } 8129 8130 boolean checkCrossUser = true; 8131 8132 // First check if this content provider has been published... 8133 cpr = mProviderMap.getProviderByName(name, userId); 8134 // If that didn't work, check if it exists for user 0 and then 8135 // verify that it's a singleton provider before using it. 8136 if (cpr == null && userId != UserHandle.USER_OWNER) { 8137 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8138 if (cpr != null) { 8139 cpi = cpr.info; 8140 if (isSingleton(cpi.processName, cpi.applicationInfo, 8141 cpi.name, cpi.flags) 8142 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8143 userId = UserHandle.USER_OWNER; 8144 checkCrossUser = false; 8145 } else { 8146 cpr = null; 8147 cpi = null; 8148 } 8149 } 8150 } 8151 8152 boolean providerRunning = cpr != null; 8153 if (providerRunning) { 8154 cpi = cpr.info; 8155 String msg; 8156 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8157 != null) { 8158 throw new SecurityException(msg); 8159 } 8160 8161 if (r != null && cpr.canRunHere(r)) { 8162 // This provider has been published or is in the process 8163 // of being published... but it is also allowed to run 8164 // in the caller's process, so don't make a connection 8165 // and just let the caller instantiate its own instance. 8166 ContentProviderHolder holder = cpr.newHolder(null); 8167 // don't give caller the provider object, it needs 8168 // to make its own. 8169 holder.provider = null; 8170 return holder; 8171 } 8172 8173 final long origId = Binder.clearCallingIdentity(); 8174 8175 // In this case the provider instance already exists, so we can 8176 // return it right away. 8177 conn = incProviderCountLocked(r, cpr, token, stable); 8178 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8179 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8180 // If this is a perceptible app accessing the provider, 8181 // make sure to count it as being accessed and thus 8182 // back up on the LRU list. This is good because 8183 // content providers are often expensive to start. 8184 updateLruProcessLocked(cpr.proc, false, null); 8185 } 8186 } 8187 8188 if (cpr.proc != null) { 8189 if (false) { 8190 if (cpr.name.flattenToShortString().equals( 8191 "com.android.providers.calendar/.CalendarProvider2")) { 8192 Slog.v(TAG, "****************** KILLING " 8193 + cpr.name.flattenToShortString()); 8194 Process.killProcess(cpr.proc.pid); 8195 } 8196 } 8197 boolean success = updateOomAdjLocked(cpr.proc); 8198 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8199 // NOTE: there is still a race here where a signal could be 8200 // pending on the process even though we managed to update its 8201 // adj level. Not sure what to do about this, but at least 8202 // the race is now smaller. 8203 if (!success) { 8204 // Uh oh... it looks like the provider's process 8205 // has been killed on us. We need to wait for a new 8206 // process to be started, and make sure its death 8207 // doesn't kill our process. 8208 Slog.i(TAG, 8209 "Existing provider " + cpr.name.flattenToShortString() 8210 + " is crashing; detaching " + r); 8211 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8212 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8213 if (!lastRef) { 8214 // This wasn't the last ref our process had on 8215 // the provider... we have now been killed, bail. 8216 return null; 8217 } 8218 providerRunning = false; 8219 conn = null; 8220 } 8221 } 8222 8223 Binder.restoreCallingIdentity(origId); 8224 } 8225 8226 boolean singleton; 8227 if (!providerRunning) { 8228 try { 8229 cpi = AppGlobals.getPackageManager(). 8230 resolveContentProvider(name, 8231 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8232 } catch (RemoteException ex) { 8233 } 8234 if (cpi == null) { 8235 return null; 8236 } 8237 // If the provider is a singleton AND 8238 // (it's a call within the same user || the provider is a 8239 // privileged app) 8240 // Then allow connecting to the singleton provider 8241 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8242 cpi.name, cpi.flags) 8243 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8244 if (singleton) { 8245 userId = UserHandle.USER_OWNER; 8246 } 8247 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8248 8249 String msg; 8250 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8251 != null) { 8252 throw new SecurityException(msg); 8253 } 8254 8255 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8256 && !cpi.processName.equals("system")) { 8257 // If this content provider does not run in the system 8258 // process, and the system is not yet ready to run other 8259 // processes, then fail fast instead of hanging. 8260 throw new IllegalArgumentException( 8261 "Attempt to launch content provider before system ready"); 8262 } 8263 8264 // Make sure that the user who owns this provider is started. If not, 8265 // we don't want to allow it to run. 8266 if (mStartedUsers.get(userId) == null) { 8267 Slog.w(TAG, "Unable to launch app " 8268 + cpi.applicationInfo.packageName + "/" 8269 + cpi.applicationInfo.uid + " for provider " 8270 + name + ": user " + userId + " is stopped"); 8271 return null; 8272 } 8273 8274 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8275 cpr = mProviderMap.getProviderByClass(comp, userId); 8276 final boolean firstClass = cpr == null; 8277 if (firstClass) { 8278 try { 8279 ApplicationInfo ai = 8280 AppGlobals.getPackageManager(). 8281 getApplicationInfo( 8282 cpi.applicationInfo.packageName, 8283 STOCK_PM_FLAGS, userId); 8284 if (ai == null) { 8285 Slog.w(TAG, "No package info for content provider " 8286 + cpi.name); 8287 return null; 8288 } 8289 ai = getAppInfoForUser(ai, userId); 8290 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8291 } catch (RemoteException ex) { 8292 // pm is in same process, this will never happen. 8293 } 8294 } 8295 8296 if (r != null && cpr.canRunHere(r)) { 8297 // If this is a multiprocess provider, then just return its 8298 // info and allow the caller to instantiate it. Only do 8299 // this if the provider is the same user as the caller's 8300 // process, or can run as root (so can be in any process). 8301 return cpr.newHolder(null); 8302 } 8303 8304 if (DEBUG_PROVIDER) { 8305 RuntimeException e = new RuntimeException("here"); 8306 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8307 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8308 } 8309 8310 // This is single process, and our app is now connecting to it. 8311 // See if we are already in the process of launching this 8312 // provider. 8313 final int N = mLaunchingProviders.size(); 8314 int i; 8315 for (i=0; i<N; i++) { 8316 if (mLaunchingProviders.get(i) == cpr) { 8317 break; 8318 } 8319 } 8320 8321 // If the provider is not already being launched, then get it 8322 // started. 8323 if (i >= N) { 8324 final long origId = Binder.clearCallingIdentity(); 8325 8326 try { 8327 // Content provider is now in use, its package can't be stopped. 8328 try { 8329 AppGlobals.getPackageManager().setPackageStoppedState( 8330 cpr.appInfo.packageName, false, userId); 8331 } catch (RemoteException e) { 8332 } catch (IllegalArgumentException e) { 8333 Slog.w(TAG, "Failed trying to unstop package " 8334 + cpr.appInfo.packageName + ": " + e); 8335 } 8336 8337 // Use existing process if already started 8338 ProcessRecord proc = getProcessRecordLocked( 8339 cpi.processName, cpr.appInfo.uid, false); 8340 if (proc != null && proc.thread != null) { 8341 if (DEBUG_PROVIDER) { 8342 Slog.d(TAG, "Installing in existing process " + proc); 8343 } 8344 proc.pubProviders.put(cpi.name, cpr); 8345 try { 8346 proc.thread.scheduleInstallProvider(cpi); 8347 } catch (RemoteException e) { 8348 } 8349 } else { 8350 proc = startProcessLocked(cpi.processName, 8351 cpr.appInfo, false, 0, "content provider", 8352 new ComponentName(cpi.applicationInfo.packageName, 8353 cpi.name), false, false, false); 8354 if (proc == null) { 8355 Slog.w(TAG, "Unable to launch app " 8356 + cpi.applicationInfo.packageName + "/" 8357 + cpi.applicationInfo.uid + " for provider " 8358 + name + ": process is bad"); 8359 return null; 8360 } 8361 } 8362 cpr.launchingApp = proc; 8363 mLaunchingProviders.add(cpr); 8364 } finally { 8365 Binder.restoreCallingIdentity(origId); 8366 } 8367 } 8368 8369 // Make sure the provider is published (the same provider class 8370 // may be published under multiple names). 8371 if (firstClass) { 8372 mProviderMap.putProviderByClass(comp, cpr); 8373 } 8374 8375 mProviderMap.putProviderByName(name, cpr); 8376 conn = incProviderCountLocked(r, cpr, token, stable); 8377 if (conn != null) { 8378 conn.waiting = true; 8379 } 8380 } 8381 } 8382 8383 // Wait for the provider to be published... 8384 synchronized (cpr) { 8385 while (cpr.provider == null) { 8386 if (cpr.launchingApp == null) { 8387 Slog.w(TAG, "Unable to launch app " 8388 + cpi.applicationInfo.packageName + "/" 8389 + cpi.applicationInfo.uid + " for provider " 8390 + name + ": launching app became null"); 8391 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8392 UserHandle.getUserId(cpi.applicationInfo.uid), 8393 cpi.applicationInfo.packageName, 8394 cpi.applicationInfo.uid, name); 8395 return null; 8396 } 8397 try { 8398 if (DEBUG_MU) { 8399 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8400 + cpr.launchingApp); 8401 } 8402 if (conn != null) { 8403 conn.waiting = true; 8404 } 8405 cpr.wait(); 8406 } catch (InterruptedException ex) { 8407 } finally { 8408 if (conn != null) { 8409 conn.waiting = false; 8410 } 8411 } 8412 } 8413 } 8414 return cpr != null ? cpr.newHolder(conn) : null; 8415 } 8416 8417 @Override 8418 public final ContentProviderHolder getContentProvider( 8419 IApplicationThread caller, String name, int userId, boolean stable) { 8420 enforceNotIsolatedCaller("getContentProvider"); 8421 if (caller == null) { 8422 String msg = "null IApplicationThread when getting content provider " 8423 + name; 8424 Slog.w(TAG, msg); 8425 throw new SecurityException(msg); 8426 } 8427 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8428 // with cross-user grant. 8429 return getContentProviderImpl(caller, name, null, stable, userId); 8430 } 8431 8432 public ContentProviderHolder getContentProviderExternal( 8433 String name, int userId, IBinder token) { 8434 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8435 "Do not have permission in call getContentProviderExternal()"); 8436 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8437 false, true, "getContentProvider", null); 8438 return getContentProviderExternalUnchecked(name, token, userId); 8439 } 8440 8441 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8442 IBinder token, int userId) { 8443 return getContentProviderImpl(null, name, token, true, userId); 8444 } 8445 8446 /** 8447 * Drop a content provider from a ProcessRecord's bookkeeping 8448 */ 8449 public void removeContentProvider(IBinder connection, boolean stable) { 8450 enforceNotIsolatedCaller("removeContentProvider"); 8451 long ident = Binder.clearCallingIdentity(); 8452 try { 8453 synchronized (this) { 8454 ContentProviderConnection conn; 8455 try { 8456 conn = (ContentProviderConnection)connection; 8457 } catch (ClassCastException e) { 8458 String msg ="removeContentProvider: " + connection 8459 + " not a ContentProviderConnection"; 8460 Slog.w(TAG, msg); 8461 throw new IllegalArgumentException(msg); 8462 } 8463 if (conn == null) { 8464 throw new NullPointerException("connection is null"); 8465 } 8466 if (decProviderCountLocked(conn, null, null, stable)) { 8467 updateOomAdjLocked(); 8468 } 8469 } 8470 } finally { 8471 Binder.restoreCallingIdentity(ident); 8472 } 8473 } 8474 8475 public void removeContentProviderExternal(String name, IBinder token) { 8476 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8477 "Do not have permission in call removeContentProviderExternal()"); 8478 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8479 } 8480 8481 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8482 synchronized (this) { 8483 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8484 if(cpr == null) { 8485 //remove from mProvidersByClass 8486 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8487 return; 8488 } 8489 8490 //update content provider record entry info 8491 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8492 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8493 if (localCpr.hasExternalProcessHandles()) { 8494 if (localCpr.removeExternalProcessHandleLocked(token)) { 8495 updateOomAdjLocked(); 8496 } else { 8497 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8498 + " with no external reference for token: " 8499 + token + "."); 8500 } 8501 } else { 8502 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8503 + " with no external references."); 8504 } 8505 } 8506 } 8507 8508 public final void publishContentProviders(IApplicationThread caller, 8509 List<ContentProviderHolder> providers) { 8510 if (providers == null) { 8511 return; 8512 } 8513 8514 enforceNotIsolatedCaller("publishContentProviders"); 8515 synchronized (this) { 8516 final ProcessRecord r = getRecordForAppLocked(caller); 8517 if (DEBUG_MU) 8518 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8519 if (r == null) { 8520 throw new SecurityException( 8521 "Unable to find app for caller " + caller 8522 + " (pid=" + Binder.getCallingPid() 8523 + ") when publishing content providers"); 8524 } 8525 8526 final long origId = Binder.clearCallingIdentity(); 8527 8528 final int N = providers.size(); 8529 for (int i=0; i<N; i++) { 8530 ContentProviderHolder src = providers.get(i); 8531 if (src == null || src.info == null || src.provider == null) { 8532 continue; 8533 } 8534 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8535 if (DEBUG_MU) 8536 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8537 if (dst != null) { 8538 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8539 mProviderMap.putProviderByClass(comp, dst); 8540 String names[] = dst.info.authority.split(";"); 8541 for (int j = 0; j < names.length; j++) { 8542 mProviderMap.putProviderByName(names[j], dst); 8543 } 8544 8545 int NL = mLaunchingProviders.size(); 8546 int j; 8547 for (j=0; j<NL; j++) { 8548 if (mLaunchingProviders.get(j) == dst) { 8549 mLaunchingProviders.remove(j); 8550 j--; 8551 NL--; 8552 } 8553 } 8554 synchronized (dst) { 8555 dst.provider = src.provider; 8556 dst.proc = r; 8557 dst.notifyAll(); 8558 } 8559 updateOomAdjLocked(r); 8560 } 8561 } 8562 8563 Binder.restoreCallingIdentity(origId); 8564 } 8565 } 8566 8567 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8568 ContentProviderConnection conn; 8569 try { 8570 conn = (ContentProviderConnection)connection; 8571 } catch (ClassCastException e) { 8572 String msg ="refContentProvider: " + connection 8573 + " not a ContentProviderConnection"; 8574 Slog.w(TAG, msg); 8575 throw new IllegalArgumentException(msg); 8576 } 8577 if (conn == null) { 8578 throw new NullPointerException("connection is null"); 8579 } 8580 8581 synchronized (this) { 8582 if (stable > 0) { 8583 conn.numStableIncs += stable; 8584 } 8585 stable = conn.stableCount + stable; 8586 if (stable < 0) { 8587 throw new IllegalStateException("stableCount < 0: " + stable); 8588 } 8589 8590 if (unstable > 0) { 8591 conn.numUnstableIncs += unstable; 8592 } 8593 unstable = conn.unstableCount + unstable; 8594 if (unstable < 0) { 8595 throw new IllegalStateException("unstableCount < 0: " + unstable); 8596 } 8597 8598 if ((stable+unstable) <= 0) { 8599 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8600 + stable + " unstable=" + unstable); 8601 } 8602 conn.stableCount = stable; 8603 conn.unstableCount = unstable; 8604 return !conn.dead; 8605 } 8606 } 8607 8608 public void unstableProviderDied(IBinder connection) { 8609 ContentProviderConnection conn; 8610 try { 8611 conn = (ContentProviderConnection)connection; 8612 } catch (ClassCastException e) { 8613 String msg ="refContentProvider: " + connection 8614 + " not a ContentProviderConnection"; 8615 Slog.w(TAG, msg); 8616 throw new IllegalArgumentException(msg); 8617 } 8618 if (conn == null) { 8619 throw new NullPointerException("connection is null"); 8620 } 8621 8622 // Safely retrieve the content provider associated with the connection. 8623 IContentProvider provider; 8624 synchronized (this) { 8625 provider = conn.provider.provider; 8626 } 8627 8628 if (provider == null) { 8629 // Um, yeah, we're way ahead of you. 8630 return; 8631 } 8632 8633 // Make sure the caller is being honest with us. 8634 if (provider.asBinder().pingBinder()) { 8635 // Er, no, still looks good to us. 8636 synchronized (this) { 8637 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8638 + " says " + conn + " died, but we don't agree"); 8639 return; 8640 } 8641 } 8642 8643 // Well look at that! It's dead! 8644 synchronized (this) { 8645 if (conn.provider.provider != provider) { 8646 // But something changed... good enough. 8647 return; 8648 } 8649 8650 ProcessRecord proc = conn.provider.proc; 8651 if (proc == null || proc.thread == null) { 8652 // Seems like the process is already cleaned up. 8653 return; 8654 } 8655 8656 // As far as we're concerned, this is just like receiving a 8657 // death notification... just a bit prematurely. 8658 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8659 + ") early provider death"); 8660 final long ident = Binder.clearCallingIdentity(); 8661 try { 8662 appDiedLocked(proc, proc.pid, proc.thread); 8663 } finally { 8664 Binder.restoreCallingIdentity(ident); 8665 } 8666 } 8667 } 8668 8669 @Override 8670 public void appNotRespondingViaProvider(IBinder connection) { 8671 enforceCallingPermission( 8672 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8673 8674 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8675 if (conn == null) { 8676 Slog.w(TAG, "ContentProviderConnection is null"); 8677 return; 8678 } 8679 8680 final ProcessRecord host = conn.provider.proc; 8681 if (host == null) { 8682 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8683 return; 8684 } 8685 8686 final long token = Binder.clearCallingIdentity(); 8687 try { 8688 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8689 } finally { 8690 Binder.restoreCallingIdentity(token); 8691 } 8692 } 8693 8694 public final void installSystemProviders() { 8695 List<ProviderInfo> providers; 8696 synchronized (this) { 8697 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8698 providers = generateApplicationProvidersLocked(app); 8699 if (providers != null) { 8700 for (int i=providers.size()-1; i>=0; i--) { 8701 ProviderInfo pi = (ProviderInfo)providers.get(i); 8702 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8703 Slog.w(TAG, "Not installing system proc provider " + pi.name 8704 + ": not system .apk"); 8705 providers.remove(i); 8706 } 8707 } 8708 } 8709 } 8710 if (providers != null) { 8711 mSystemThread.installSystemProviders(providers); 8712 } 8713 8714 mCoreSettingsObserver = new CoreSettingsObserver(this); 8715 8716 mUsageStatsService.monitorPackages(); 8717 } 8718 8719 /** 8720 * Allows app to retrieve the MIME type of a URI without having permission 8721 * to access its content provider. 8722 * 8723 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8724 * 8725 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8726 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8727 */ 8728 public String getProviderMimeType(Uri uri, int userId) { 8729 enforceNotIsolatedCaller("getProviderMimeType"); 8730 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8731 userId, false, true, "getProviderMimeType", null); 8732 final String name = uri.getAuthority(); 8733 final long ident = Binder.clearCallingIdentity(); 8734 ContentProviderHolder holder = null; 8735 8736 try { 8737 holder = getContentProviderExternalUnchecked(name, null, userId); 8738 if (holder != null) { 8739 return holder.provider.getType(uri); 8740 } 8741 } catch (RemoteException e) { 8742 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8743 return null; 8744 } finally { 8745 if (holder != null) { 8746 removeContentProviderExternalUnchecked(name, null, userId); 8747 } 8748 Binder.restoreCallingIdentity(ident); 8749 } 8750 8751 return null; 8752 } 8753 8754 // ========================================================= 8755 // GLOBAL MANAGEMENT 8756 // ========================================================= 8757 8758 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8759 boolean isolated) { 8760 String proc = customProcess != null ? customProcess : info.processName; 8761 BatteryStatsImpl.Uid.Proc ps = null; 8762 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8763 int uid = info.uid; 8764 if (isolated) { 8765 int userId = UserHandle.getUserId(uid); 8766 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8767 while (true) { 8768 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8769 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8770 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8771 } 8772 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8773 mNextIsolatedProcessUid++; 8774 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8775 // No process for this uid, use it. 8776 break; 8777 } 8778 stepsLeft--; 8779 if (stepsLeft <= 0) { 8780 return null; 8781 } 8782 } 8783 } 8784 return new ProcessRecord(stats, info, proc, uid); 8785 } 8786 8787 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8788 String abiOverride) { 8789 ProcessRecord app; 8790 if (!isolated) { 8791 app = getProcessRecordLocked(info.processName, info.uid, true); 8792 } else { 8793 app = null; 8794 } 8795 8796 if (app == null) { 8797 app = newProcessRecordLocked(info, null, isolated); 8798 mProcessNames.put(info.processName, app.uid, app); 8799 if (isolated) { 8800 mIsolatedProcesses.put(app.uid, app); 8801 } 8802 updateLruProcessLocked(app, false, null); 8803 updateOomAdjLocked(); 8804 } 8805 8806 // This package really, really can not be stopped. 8807 try { 8808 AppGlobals.getPackageManager().setPackageStoppedState( 8809 info.packageName, false, UserHandle.getUserId(app.uid)); 8810 } catch (RemoteException e) { 8811 } catch (IllegalArgumentException e) { 8812 Slog.w(TAG, "Failed trying to unstop package " 8813 + info.packageName + ": " + e); 8814 } 8815 8816 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8817 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8818 app.persistent = true; 8819 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8820 } 8821 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8822 mPersistentStartingProcesses.add(app); 8823 startProcessLocked(app, "added application", app.processName, 8824 abiOverride); 8825 } 8826 8827 return app; 8828 } 8829 8830 public void unhandledBack() { 8831 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8832 "unhandledBack()"); 8833 8834 synchronized(this) { 8835 final long origId = Binder.clearCallingIdentity(); 8836 try { 8837 getFocusedStack().unhandledBackLocked(); 8838 } finally { 8839 Binder.restoreCallingIdentity(origId); 8840 } 8841 } 8842 } 8843 8844 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8845 enforceNotIsolatedCaller("openContentUri"); 8846 final int userId = UserHandle.getCallingUserId(); 8847 String name = uri.getAuthority(); 8848 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8849 ParcelFileDescriptor pfd = null; 8850 if (cph != null) { 8851 // We record the binder invoker's uid in thread-local storage before 8852 // going to the content provider to open the file. Later, in the code 8853 // that handles all permissions checks, we look for this uid and use 8854 // that rather than the Activity Manager's own uid. The effect is that 8855 // we do the check against the caller's permissions even though it looks 8856 // to the content provider like the Activity Manager itself is making 8857 // the request. 8858 sCallerIdentity.set(new Identity( 8859 Binder.getCallingPid(), Binder.getCallingUid())); 8860 try { 8861 pfd = cph.provider.openFile(null, uri, "r", null); 8862 } catch (FileNotFoundException e) { 8863 // do nothing; pfd will be returned null 8864 } finally { 8865 // Ensure that whatever happens, we clean up the identity state 8866 sCallerIdentity.remove(); 8867 } 8868 8869 // We've got the fd now, so we're done with the provider. 8870 removeContentProviderExternalUnchecked(name, null, userId); 8871 } else { 8872 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8873 } 8874 return pfd; 8875 } 8876 8877 // Actually is sleeping or shutting down or whatever else in the future 8878 // is an inactive state. 8879 public boolean isSleepingOrShuttingDown() { 8880 return mSleeping || mShuttingDown; 8881 } 8882 8883 public boolean isSleeping() { 8884 return mSleeping; 8885 } 8886 8887 void goingToSleep() { 8888 synchronized(this) { 8889 mWentToSleep = true; 8890 updateEventDispatchingLocked(); 8891 goToSleepIfNeededLocked(); 8892 } 8893 } 8894 8895 void finishRunningVoiceLocked() { 8896 if (mRunningVoice) { 8897 mRunningVoice = false; 8898 goToSleepIfNeededLocked(); 8899 } 8900 } 8901 8902 void goToSleepIfNeededLocked() { 8903 if (mWentToSleep && !mRunningVoice) { 8904 if (!mSleeping) { 8905 mSleeping = true; 8906 mStackSupervisor.goingToSleepLocked(); 8907 8908 // Initialize the wake times of all processes. 8909 checkExcessivePowerUsageLocked(false); 8910 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8911 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8912 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8913 } 8914 } 8915 } 8916 8917 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8918 mTaskPersister.notify(task, flush); 8919 } 8920 8921 @Override 8922 public boolean shutdown(int timeout) { 8923 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8924 != PackageManager.PERMISSION_GRANTED) { 8925 throw new SecurityException("Requires permission " 8926 + android.Manifest.permission.SHUTDOWN); 8927 } 8928 8929 boolean timedout = false; 8930 8931 synchronized(this) { 8932 mShuttingDown = true; 8933 updateEventDispatchingLocked(); 8934 timedout = mStackSupervisor.shutdownLocked(timeout); 8935 } 8936 8937 mAppOpsService.shutdown(); 8938 mUsageStatsService.shutdown(); 8939 mBatteryStatsService.shutdown(); 8940 synchronized (this) { 8941 mProcessStats.shutdownLocked(); 8942 } 8943 notifyTaskPersisterLocked(null, true); 8944 8945 return timedout; 8946 } 8947 8948 public final void activitySlept(IBinder token) { 8949 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8950 8951 final long origId = Binder.clearCallingIdentity(); 8952 8953 synchronized (this) { 8954 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8955 if (r != null) { 8956 mStackSupervisor.activitySleptLocked(r); 8957 } 8958 } 8959 8960 Binder.restoreCallingIdentity(origId); 8961 } 8962 8963 void logLockScreen(String msg) { 8964 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8965 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8966 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8967 mStackSupervisor.mDismissKeyguardOnNextActivity); 8968 } 8969 8970 private void comeOutOfSleepIfNeededLocked() { 8971 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8972 if (mSleeping) { 8973 mSleeping = false; 8974 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8975 } 8976 } 8977 } 8978 8979 void wakingUp() { 8980 synchronized(this) { 8981 mWentToSleep = false; 8982 updateEventDispatchingLocked(); 8983 comeOutOfSleepIfNeededLocked(); 8984 } 8985 } 8986 8987 void startRunningVoiceLocked() { 8988 if (!mRunningVoice) { 8989 mRunningVoice = true; 8990 comeOutOfSleepIfNeededLocked(); 8991 } 8992 } 8993 8994 private void updateEventDispatchingLocked() { 8995 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8996 } 8997 8998 public void setLockScreenShown(boolean shown) { 8999 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9000 != PackageManager.PERMISSION_GRANTED) { 9001 throw new SecurityException("Requires permission " 9002 + android.Manifest.permission.DEVICE_POWER); 9003 } 9004 9005 synchronized(this) { 9006 long ident = Binder.clearCallingIdentity(); 9007 try { 9008 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9009 mLockScreenShown = shown; 9010 comeOutOfSleepIfNeededLocked(); 9011 } finally { 9012 Binder.restoreCallingIdentity(ident); 9013 } 9014 } 9015 } 9016 9017 public void stopAppSwitches() { 9018 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9019 != PackageManager.PERMISSION_GRANTED) { 9020 throw new SecurityException("Requires permission " 9021 + android.Manifest.permission.STOP_APP_SWITCHES); 9022 } 9023 9024 synchronized(this) { 9025 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9026 + APP_SWITCH_DELAY_TIME; 9027 mDidAppSwitch = false; 9028 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9029 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9030 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9031 } 9032 } 9033 9034 public void resumeAppSwitches() { 9035 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9036 != PackageManager.PERMISSION_GRANTED) { 9037 throw new SecurityException("Requires permission " 9038 + android.Manifest.permission.STOP_APP_SWITCHES); 9039 } 9040 9041 synchronized(this) { 9042 // Note that we don't execute any pending app switches... we will 9043 // let those wait until either the timeout, or the next start 9044 // activity request. 9045 mAppSwitchesAllowedTime = 0; 9046 } 9047 } 9048 9049 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9050 String name) { 9051 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9052 return true; 9053 } 9054 9055 final int perm = checkComponentPermission( 9056 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9057 callingUid, -1, true); 9058 if (perm == PackageManager.PERMISSION_GRANTED) { 9059 return true; 9060 } 9061 9062 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9063 return false; 9064 } 9065 9066 public void setDebugApp(String packageName, boolean waitForDebugger, 9067 boolean persistent) { 9068 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9069 "setDebugApp()"); 9070 9071 long ident = Binder.clearCallingIdentity(); 9072 try { 9073 // Note that this is not really thread safe if there are multiple 9074 // callers into it at the same time, but that's not a situation we 9075 // care about. 9076 if (persistent) { 9077 final ContentResolver resolver = mContext.getContentResolver(); 9078 Settings.Global.putString( 9079 resolver, Settings.Global.DEBUG_APP, 9080 packageName); 9081 Settings.Global.putInt( 9082 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9083 waitForDebugger ? 1 : 0); 9084 } 9085 9086 synchronized (this) { 9087 if (!persistent) { 9088 mOrigDebugApp = mDebugApp; 9089 mOrigWaitForDebugger = mWaitForDebugger; 9090 } 9091 mDebugApp = packageName; 9092 mWaitForDebugger = waitForDebugger; 9093 mDebugTransient = !persistent; 9094 if (packageName != null) { 9095 forceStopPackageLocked(packageName, -1, false, false, true, true, 9096 false, UserHandle.USER_ALL, "set debug app"); 9097 } 9098 } 9099 } finally { 9100 Binder.restoreCallingIdentity(ident); 9101 } 9102 } 9103 9104 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9105 synchronized (this) { 9106 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9107 if (!isDebuggable) { 9108 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9109 throw new SecurityException("Process not debuggable: " + app.packageName); 9110 } 9111 } 9112 9113 mOpenGlTraceApp = processName; 9114 } 9115 } 9116 9117 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9118 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9119 synchronized (this) { 9120 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9121 if (!isDebuggable) { 9122 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9123 throw new SecurityException("Process not debuggable: " + app.packageName); 9124 } 9125 } 9126 mProfileApp = processName; 9127 mProfileFile = profileFile; 9128 if (mProfileFd != null) { 9129 try { 9130 mProfileFd.close(); 9131 } catch (IOException e) { 9132 } 9133 mProfileFd = null; 9134 } 9135 mProfileFd = profileFd; 9136 mProfileType = 0; 9137 mAutoStopProfiler = autoStopProfiler; 9138 } 9139 } 9140 9141 @Override 9142 public void setAlwaysFinish(boolean enabled) { 9143 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9144 "setAlwaysFinish()"); 9145 9146 Settings.Global.putInt( 9147 mContext.getContentResolver(), 9148 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9149 9150 synchronized (this) { 9151 mAlwaysFinishActivities = enabled; 9152 } 9153 } 9154 9155 @Override 9156 public void setActivityController(IActivityController controller) { 9157 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9158 "setActivityController()"); 9159 synchronized (this) { 9160 mController = controller; 9161 Watchdog.getInstance().setActivityController(controller); 9162 } 9163 } 9164 9165 @Override 9166 public void setUserIsMonkey(boolean userIsMonkey) { 9167 synchronized (this) { 9168 synchronized (mPidsSelfLocked) { 9169 final int callingPid = Binder.getCallingPid(); 9170 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9171 if (precessRecord == null) { 9172 throw new SecurityException("Unknown process: " + callingPid); 9173 } 9174 if (precessRecord.instrumentationUiAutomationConnection == null) { 9175 throw new SecurityException("Only an instrumentation process " 9176 + "with a UiAutomation can call setUserIsMonkey"); 9177 } 9178 } 9179 mUserIsMonkey = userIsMonkey; 9180 } 9181 } 9182 9183 @Override 9184 public boolean isUserAMonkey() { 9185 synchronized (this) { 9186 // If there is a controller also implies the user is a monkey. 9187 return (mUserIsMonkey || mController != null); 9188 } 9189 } 9190 9191 public void requestBugReport() { 9192 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9193 SystemProperties.set("ctl.start", "bugreport"); 9194 } 9195 9196 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9197 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9198 } 9199 9200 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9201 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9202 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9203 } 9204 return KEY_DISPATCHING_TIMEOUT; 9205 } 9206 9207 @Override 9208 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9209 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9210 != PackageManager.PERMISSION_GRANTED) { 9211 throw new SecurityException("Requires permission " 9212 + android.Manifest.permission.FILTER_EVENTS); 9213 } 9214 ProcessRecord proc; 9215 long timeout; 9216 synchronized (this) { 9217 synchronized (mPidsSelfLocked) { 9218 proc = mPidsSelfLocked.get(pid); 9219 } 9220 timeout = getInputDispatchingTimeoutLocked(proc); 9221 } 9222 9223 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9224 return -1; 9225 } 9226 9227 return timeout; 9228 } 9229 9230 /** 9231 * Handle input dispatching timeouts. 9232 * Returns whether input dispatching should be aborted or not. 9233 */ 9234 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9235 final ActivityRecord activity, final ActivityRecord parent, 9236 final boolean aboveSystem, String reason) { 9237 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9238 != PackageManager.PERMISSION_GRANTED) { 9239 throw new SecurityException("Requires permission " 9240 + android.Manifest.permission.FILTER_EVENTS); 9241 } 9242 9243 final String annotation; 9244 if (reason == null) { 9245 annotation = "Input dispatching timed out"; 9246 } else { 9247 annotation = "Input dispatching timed out (" + reason + ")"; 9248 } 9249 9250 if (proc != null) { 9251 synchronized (this) { 9252 if (proc.debugging) { 9253 return false; 9254 } 9255 9256 if (mDidDexOpt) { 9257 // Give more time since we were dexopting. 9258 mDidDexOpt = false; 9259 return false; 9260 } 9261 9262 if (proc.instrumentationClass != null) { 9263 Bundle info = new Bundle(); 9264 info.putString("shortMsg", "keyDispatchingTimedOut"); 9265 info.putString("longMsg", annotation); 9266 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9267 return true; 9268 } 9269 } 9270 mHandler.post(new Runnable() { 9271 @Override 9272 public void run() { 9273 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9274 } 9275 }); 9276 } 9277 9278 return true; 9279 } 9280 9281 public Bundle getAssistContextExtras(int requestType) { 9282 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9283 "getAssistContextExtras()"); 9284 PendingAssistExtras pae; 9285 Bundle extras = new Bundle(); 9286 synchronized (this) { 9287 ActivityRecord activity = getFocusedStack().mResumedActivity; 9288 if (activity == null) { 9289 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9290 return null; 9291 } 9292 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9293 if (activity.app == null || activity.app.thread == null) { 9294 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9295 return extras; 9296 } 9297 if (activity.app.pid == Binder.getCallingPid()) { 9298 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9299 return extras; 9300 } 9301 pae = new PendingAssistExtras(activity); 9302 try { 9303 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9304 requestType); 9305 mPendingAssistExtras.add(pae); 9306 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9307 } catch (RemoteException e) { 9308 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9309 return extras; 9310 } 9311 } 9312 synchronized (pae) { 9313 while (!pae.haveResult) { 9314 try { 9315 pae.wait(); 9316 } catch (InterruptedException e) { 9317 } 9318 } 9319 if (pae.result != null) { 9320 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9321 } 9322 } 9323 synchronized (this) { 9324 mPendingAssistExtras.remove(pae); 9325 mHandler.removeCallbacks(pae); 9326 } 9327 return extras; 9328 } 9329 9330 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9331 PendingAssistExtras pae = (PendingAssistExtras)token; 9332 synchronized (pae) { 9333 pae.result = extras; 9334 pae.haveResult = true; 9335 pae.notifyAll(); 9336 } 9337 } 9338 9339 public void registerProcessObserver(IProcessObserver observer) { 9340 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9341 "registerProcessObserver()"); 9342 synchronized (this) { 9343 mProcessObservers.register(observer); 9344 } 9345 } 9346 9347 @Override 9348 public void unregisterProcessObserver(IProcessObserver observer) { 9349 synchronized (this) { 9350 mProcessObservers.unregister(observer); 9351 } 9352 } 9353 9354 @Override 9355 public boolean convertFromTranslucent(IBinder token) { 9356 final long origId = Binder.clearCallingIdentity(); 9357 try { 9358 synchronized (this) { 9359 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9360 if (r == null) { 9361 return false; 9362 } 9363 if (r.changeWindowTranslucency(true)) { 9364 mWindowManager.setAppFullscreen(token, true); 9365 r.task.stack.releaseMediaResources(); 9366 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9367 return true; 9368 } 9369 return false; 9370 } 9371 } finally { 9372 Binder.restoreCallingIdentity(origId); 9373 } 9374 } 9375 9376 @Override 9377 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9378 final long origId = Binder.clearCallingIdentity(); 9379 try { 9380 synchronized (this) { 9381 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9382 if (r == null) { 9383 return false; 9384 } 9385 if (r.changeWindowTranslucency(false)) { 9386 r.task.stack.convertToTranslucent(r, options); 9387 mWindowManager.setAppFullscreen(token, false); 9388 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9389 return true; 9390 } else { 9391 r.task.stack.mReturningActivityOptions = options; 9392 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9393 return false; 9394 } 9395 } 9396 } finally { 9397 Binder.restoreCallingIdentity(origId); 9398 } 9399 } 9400 9401 @Override 9402 public boolean setMediaPlaying(IBinder token, boolean playing) { 9403 final long origId = Binder.clearCallingIdentity(); 9404 try { 9405 synchronized (this) { 9406 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9407 if (r != null) { 9408 return mStackSupervisor.setMediaPlayingLocked(r, playing); 9409 } 9410 } 9411 return false; 9412 } finally { 9413 Binder.restoreCallingIdentity(origId); 9414 } 9415 } 9416 9417 @Override 9418 public boolean isBackgroundMediaPlaying(IBinder token) { 9419 final long origId = Binder.clearCallingIdentity(); 9420 try { 9421 synchronized (this) { 9422 final ActivityStack stack = ActivityRecord.getStackLocked(token); 9423 final boolean playing = stack == null ? false : stack.isMediaPlaying(); 9424 if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, 9425 "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing); 9426 return playing; 9427 } 9428 } finally { 9429 Binder.restoreCallingIdentity(origId); 9430 } 9431 } 9432 9433 @Override 9434 public ActivityOptions getActivityOptions(IBinder token) { 9435 final long origId = Binder.clearCallingIdentity(); 9436 try { 9437 synchronized (this) { 9438 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9439 if (r != null) { 9440 final ActivityOptions activityOptions = r.pendingOptions; 9441 r.pendingOptions = null; 9442 return activityOptions; 9443 } 9444 return null; 9445 } 9446 } finally { 9447 Binder.restoreCallingIdentity(origId); 9448 } 9449 } 9450 9451 @Override 9452 public void setImmersive(IBinder token, boolean immersive) { 9453 synchronized(this) { 9454 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9455 if (r == null) { 9456 throw new IllegalArgumentException(); 9457 } 9458 r.immersive = immersive; 9459 9460 // update associated state if we're frontmost 9461 if (r == mFocusedActivity) { 9462 if (DEBUG_IMMERSIVE) { 9463 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9464 } 9465 applyUpdateLockStateLocked(r); 9466 } 9467 } 9468 } 9469 9470 @Override 9471 public boolean isImmersive(IBinder token) { 9472 synchronized (this) { 9473 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9474 if (r == null) { 9475 throw new IllegalArgumentException(); 9476 } 9477 return r.immersive; 9478 } 9479 } 9480 9481 public boolean isTopActivityImmersive() { 9482 enforceNotIsolatedCaller("startActivity"); 9483 synchronized (this) { 9484 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9485 return (r != null) ? r.immersive : false; 9486 } 9487 } 9488 9489 @Override 9490 public boolean isTopOfTask(IBinder token) { 9491 synchronized (this) { 9492 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9493 if (r == null) { 9494 throw new IllegalArgumentException(); 9495 } 9496 return r.task.getTopActivity() == r; 9497 } 9498 } 9499 9500 public final void enterSafeMode() { 9501 synchronized(this) { 9502 // It only makes sense to do this before the system is ready 9503 // and started launching other packages. 9504 if (!mSystemReady) { 9505 try { 9506 AppGlobals.getPackageManager().enterSafeMode(); 9507 } catch (RemoteException e) { 9508 } 9509 } 9510 9511 mSafeMode = true; 9512 } 9513 } 9514 9515 public final void showSafeModeOverlay() { 9516 View v = LayoutInflater.from(mContext).inflate( 9517 com.android.internal.R.layout.safe_mode, null); 9518 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9519 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9520 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9521 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9522 lp.gravity = Gravity.BOTTOM | Gravity.START; 9523 lp.format = v.getBackground().getOpacity(); 9524 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9525 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9526 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9527 ((WindowManager)mContext.getSystemService( 9528 Context.WINDOW_SERVICE)).addView(v, lp); 9529 } 9530 9531 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9532 if (!(sender instanceof PendingIntentRecord)) { 9533 return; 9534 } 9535 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9536 synchronized (stats) { 9537 if (mBatteryStatsService.isOnBattery()) { 9538 mBatteryStatsService.enforceCallingPermission(); 9539 PendingIntentRecord rec = (PendingIntentRecord)sender; 9540 int MY_UID = Binder.getCallingUid(); 9541 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9542 BatteryStatsImpl.Uid.Pkg pkg = 9543 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9544 sourcePkg != null ? sourcePkg : rec.key.packageName); 9545 pkg.incWakeupsLocked(); 9546 } 9547 } 9548 } 9549 9550 public boolean killPids(int[] pids, String pReason, boolean secure) { 9551 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9552 throw new SecurityException("killPids only available to the system"); 9553 } 9554 String reason = (pReason == null) ? "Unknown" : pReason; 9555 // XXX Note: don't acquire main activity lock here, because the window 9556 // manager calls in with its locks held. 9557 9558 boolean killed = false; 9559 synchronized (mPidsSelfLocked) { 9560 int[] types = new int[pids.length]; 9561 int worstType = 0; 9562 for (int i=0; i<pids.length; i++) { 9563 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9564 if (proc != null) { 9565 int type = proc.setAdj; 9566 types[i] = type; 9567 if (type > worstType) { 9568 worstType = type; 9569 } 9570 } 9571 } 9572 9573 // If the worst oom_adj is somewhere in the cached proc LRU range, 9574 // then constrain it so we will kill all cached procs. 9575 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9576 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9577 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9578 } 9579 9580 // If this is not a secure call, don't let it kill processes that 9581 // are important. 9582 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9583 worstType = ProcessList.SERVICE_ADJ; 9584 } 9585 9586 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9587 for (int i=0; i<pids.length; i++) { 9588 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9589 if (proc == null) { 9590 continue; 9591 } 9592 int adj = proc.setAdj; 9593 if (adj >= worstType && !proc.killedByAm) { 9594 killUnneededProcessLocked(proc, reason); 9595 killed = true; 9596 } 9597 } 9598 } 9599 return killed; 9600 } 9601 9602 @Override 9603 public void killUid(int uid, String reason) { 9604 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9605 throw new SecurityException("killUid only available to the system"); 9606 } 9607 synchronized (this) { 9608 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9609 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9610 reason != null ? reason : "kill uid"); 9611 } 9612 } 9613 9614 @Override 9615 public boolean killProcessesBelowForeground(String reason) { 9616 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9617 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9618 } 9619 9620 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9621 } 9622 9623 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9624 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9625 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9626 } 9627 9628 boolean killed = false; 9629 synchronized (mPidsSelfLocked) { 9630 final int size = mPidsSelfLocked.size(); 9631 for (int i = 0; i < size; i++) { 9632 final int pid = mPidsSelfLocked.keyAt(i); 9633 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9634 if (proc == null) continue; 9635 9636 final int adj = proc.setAdj; 9637 if (adj > belowAdj && !proc.killedByAm) { 9638 killUnneededProcessLocked(proc, reason); 9639 killed = true; 9640 } 9641 } 9642 } 9643 return killed; 9644 } 9645 9646 @Override 9647 public void hang(final IBinder who, boolean allowRestart) { 9648 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9649 != PackageManager.PERMISSION_GRANTED) { 9650 throw new SecurityException("Requires permission " 9651 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9652 } 9653 9654 final IBinder.DeathRecipient death = new DeathRecipient() { 9655 @Override 9656 public void binderDied() { 9657 synchronized (this) { 9658 notifyAll(); 9659 } 9660 } 9661 }; 9662 9663 try { 9664 who.linkToDeath(death, 0); 9665 } catch (RemoteException e) { 9666 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9667 return; 9668 } 9669 9670 synchronized (this) { 9671 Watchdog.getInstance().setAllowRestart(allowRestart); 9672 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9673 synchronized (death) { 9674 while (who.isBinderAlive()) { 9675 try { 9676 death.wait(); 9677 } catch (InterruptedException e) { 9678 } 9679 } 9680 } 9681 Watchdog.getInstance().setAllowRestart(true); 9682 } 9683 } 9684 9685 @Override 9686 public void restart() { 9687 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9688 != PackageManager.PERMISSION_GRANTED) { 9689 throw new SecurityException("Requires permission " 9690 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9691 } 9692 9693 Log.i(TAG, "Sending shutdown broadcast..."); 9694 9695 BroadcastReceiver br = new BroadcastReceiver() { 9696 @Override public void onReceive(Context context, Intent intent) { 9697 // Now the broadcast is done, finish up the low-level shutdown. 9698 Log.i(TAG, "Shutting down activity manager..."); 9699 shutdown(10000); 9700 Log.i(TAG, "Shutdown complete, restarting!"); 9701 Process.killProcess(Process.myPid()); 9702 System.exit(10); 9703 } 9704 }; 9705 9706 // First send the high-level shut down broadcast. 9707 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9708 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9709 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9710 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9711 mContext.sendOrderedBroadcastAsUser(intent, 9712 UserHandle.ALL, null, br, mHandler, 0, null, null); 9713 */ 9714 br.onReceive(mContext, intent); 9715 } 9716 9717 private long getLowRamTimeSinceIdle(long now) { 9718 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9719 } 9720 9721 @Override 9722 public void performIdleMaintenance() { 9723 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9724 != PackageManager.PERMISSION_GRANTED) { 9725 throw new SecurityException("Requires permission " 9726 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9727 } 9728 9729 synchronized (this) { 9730 final long now = SystemClock.uptimeMillis(); 9731 final long timeSinceLastIdle = now - mLastIdleTime; 9732 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9733 mLastIdleTime = now; 9734 mLowRamTimeSinceLastIdle = 0; 9735 if (mLowRamStartTime != 0) { 9736 mLowRamStartTime = now; 9737 } 9738 9739 StringBuilder sb = new StringBuilder(128); 9740 sb.append("Idle maintenance over "); 9741 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9742 sb.append(" low RAM for "); 9743 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9744 Slog.i(TAG, sb.toString()); 9745 9746 // If at least 1/3 of our time since the last idle period has been spent 9747 // with RAM low, then we want to kill processes. 9748 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9749 9750 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9751 ProcessRecord proc = mLruProcesses.get(i); 9752 if (proc.notCachedSinceIdle) { 9753 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9754 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9755 if (doKilling && proc.initialIdlePss != 0 9756 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9757 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9758 + " from " + proc.initialIdlePss + ")"); 9759 } 9760 } 9761 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9762 proc.notCachedSinceIdle = true; 9763 proc.initialIdlePss = 0; 9764 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9765 isSleeping(), now); 9766 } 9767 } 9768 9769 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9770 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9771 } 9772 } 9773 9774 private void retrieveSettings() { 9775 final ContentResolver resolver = mContext.getContentResolver(); 9776 String debugApp = Settings.Global.getString( 9777 resolver, Settings.Global.DEBUG_APP); 9778 boolean waitForDebugger = Settings.Global.getInt( 9779 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9780 boolean alwaysFinishActivities = Settings.Global.getInt( 9781 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9782 boolean forceRtl = Settings.Global.getInt( 9783 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9784 // Transfer any global setting for forcing RTL layout, into a System Property 9785 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9786 9787 Configuration configuration = new Configuration(); 9788 Settings.System.getConfiguration(resolver, configuration); 9789 if (forceRtl) { 9790 // This will take care of setting the correct layout direction flags 9791 configuration.setLayoutDirection(configuration.locale); 9792 } 9793 9794 synchronized (this) { 9795 mDebugApp = mOrigDebugApp = debugApp; 9796 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9797 mAlwaysFinishActivities = alwaysFinishActivities; 9798 // This happens before any activities are started, so we can 9799 // change mConfiguration in-place. 9800 updateConfigurationLocked(configuration, null, false, true); 9801 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9802 } 9803 } 9804 9805 public boolean testIsSystemReady() { 9806 // no need to synchronize(this) just to read & return the value 9807 return mSystemReady; 9808 } 9809 9810 private static File getCalledPreBootReceiversFile() { 9811 File dataDir = Environment.getDataDirectory(); 9812 File systemDir = new File(dataDir, "system"); 9813 File fname = new File(systemDir, "called_pre_boots.dat"); 9814 return fname; 9815 } 9816 9817 static final int LAST_DONE_VERSION = 10000; 9818 9819 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9820 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9821 File file = getCalledPreBootReceiversFile(); 9822 FileInputStream fis = null; 9823 try { 9824 fis = new FileInputStream(file); 9825 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9826 int fvers = dis.readInt(); 9827 if (fvers == LAST_DONE_VERSION) { 9828 String vers = dis.readUTF(); 9829 String codename = dis.readUTF(); 9830 String build = dis.readUTF(); 9831 if (android.os.Build.VERSION.RELEASE.equals(vers) 9832 && android.os.Build.VERSION.CODENAME.equals(codename) 9833 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9834 int num = dis.readInt(); 9835 while (num > 0) { 9836 num--; 9837 String pkg = dis.readUTF(); 9838 String cls = dis.readUTF(); 9839 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9840 } 9841 } 9842 } 9843 } catch (FileNotFoundException e) { 9844 } catch (IOException e) { 9845 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9846 } finally { 9847 if (fis != null) { 9848 try { 9849 fis.close(); 9850 } catch (IOException e) { 9851 } 9852 } 9853 } 9854 return lastDoneReceivers; 9855 } 9856 9857 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9858 File file = getCalledPreBootReceiversFile(); 9859 FileOutputStream fos = null; 9860 DataOutputStream dos = null; 9861 try { 9862 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9863 fos = new FileOutputStream(file); 9864 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9865 dos.writeInt(LAST_DONE_VERSION); 9866 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9867 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9868 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9869 dos.writeInt(list.size()); 9870 for (int i=0; i<list.size(); i++) { 9871 dos.writeUTF(list.get(i).getPackageName()); 9872 dos.writeUTF(list.get(i).getClassName()); 9873 } 9874 } catch (IOException e) { 9875 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9876 file.delete(); 9877 } finally { 9878 FileUtils.sync(fos); 9879 if (dos != null) { 9880 try { 9881 dos.close(); 9882 } catch (IOException e) { 9883 // TODO Auto-generated catch block 9884 e.printStackTrace(); 9885 } 9886 } 9887 } 9888 } 9889 9890 public void systemReady(final Runnable goingCallback) { 9891 synchronized(this) { 9892 if (mSystemReady) { 9893 if (goingCallback != null) goingCallback.run(); 9894 return; 9895 } 9896 9897 if (mRecentTasks == null) { 9898 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9899 if (!mRecentTasks.isEmpty()) { 9900 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9901 } 9902 mTaskPersister.startPersisting(); 9903 } 9904 9905 // Check to see if there are any update receivers to run. 9906 if (!mDidUpdate) { 9907 if (mWaitingUpdate) { 9908 return; 9909 } 9910 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9911 List<ResolveInfo> ris = null; 9912 try { 9913 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9914 intent, null, 0, 0); 9915 } catch (RemoteException e) { 9916 } 9917 if (ris != null) { 9918 for (int i=ris.size()-1; i>=0; i--) { 9919 if ((ris.get(i).activityInfo.applicationInfo.flags 9920 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9921 ris.remove(i); 9922 } 9923 } 9924 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9925 9926 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9927 9928 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9929 for (int i=0; i<ris.size(); i++) { 9930 ActivityInfo ai = ris.get(i).activityInfo; 9931 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9932 if (lastDoneReceivers.contains(comp)) { 9933 // We already did the pre boot receiver for this app with the current 9934 // platform version, so don't do it again... 9935 ris.remove(i); 9936 i--; 9937 // ...however, do keep it as one that has been done, so we don't 9938 // forget about it when rewriting the file of last done receivers. 9939 doneReceivers.add(comp); 9940 } 9941 } 9942 9943 final int[] users = getUsersLocked(); 9944 for (int i=0; i<ris.size(); i++) { 9945 ActivityInfo ai = ris.get(i).activityInfo; 9946 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9947 doneReceivers.add(comp); 9948 intent.setComponent(comp); 9949 for (int j=0; j<users.length; j++) { 9950 IIntentReceiver finisher = null; 9951 if (i == ris.size()-1 && j == users.length-1) { 9952 finisher = new IIntentReceiver.Stub() { 9953 public void performReceive(Intent intent, int resultCode, 9954 String data, Bundle extras, boolean ordered, 9955 boolean sticky, int sendingUser) { 9956 // The raw IIntentReceiver interface is called 9957 // with the AM lock held, so redispatch to 9958 // execute our code without the lock. 9959 mHandler.post(new Runnable() { 9960 public void run() { 9961 synchronized (ActivityManagerService.this) { 9962 mDidUpdate = true; 9963 } 9964 writeLastDonePreBootReceivers(doneReceivers); 9965 showBootMessage(mContext.getText( 9966 R.string.android_upgrading_complete), 9967 false); 9968 systemReady(goingCallback); 9969 } 9970 }); 9971 } 9972 }; 9973 } 9974 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9975 + " for user " + users[j]); 9976 broadcastIntentLocked(null, null, intent, null, finisher, 9977 0, null, null, null, AppOpsManager.OP_NONE, 9978 true, false, MY_PID, Process.SYSTEM_UID, 9979 users[j]); 9980 if (finisher != null) { 9981 mWaitingUpdate = true; 9982 } 9983 } 9984 } 9985 } 9986 if (mWaitingUpdate) { 9987 return; 9988 } 9989 mDidUpdate = true; 9990 } 9991 9992 mAppOpsService.systemReady(); 9993 mUsageStatsService.systemReady(); 9994 mSystemReady = true; 9995 } 9996 9997 ArrayList<ProcessRecord> procsToKill = null; 9998 synchronized(mPidsSelfLocked) { 9999 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10000 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10001 if (!isAllowedWhileBooting(proc.info)){ 10002 if (procsToKill == null) { 10003 procsToKill = new ArrayList<ProcessRecord>(); 10004 } 10005 procsToKill.add(proc); 10006 } 10007 } 10008 } 10009 10010 synchronized(this) { 10011 if (procsToKill != null) { 10012 for (int i=procsToKill.size()-1; i>=0; i--) { 10013 ProcessRecord proc = procsToKill.get(i); 10014 Slog.i(TAG, "Removing system update proc: " + proc); 10015 removeProcessLocked(proc, true, false, "system update done"); 10016 } 10017 } 10018 10019 // Now that we have cleaned up any update processes, we 10020 // are ready to start launching real processes and know that 10021 // we won't trample on them any more. 10022 mProcessesReady = true; 10023 } 10024 10025 Slog.i(TAG, "System now ready"); 10026 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10027 SystemClock.uptimeMillis()); 10028 10029 synchronized(this) { 10030 // Make sure we have no pre-ready processes sitting around. 10031 10032 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10033 ResolveInfo ri = mContext.getPackageManager() 10034 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10035 STOCK_PM_FLAGS); 10036 CharSequence errorMsg = null; 10037 if (ri != null) { 10038 ActivityInfo ai = ri.activityInfo; 10039 ApplicationInfo app = ai.applicationInfo; 10040 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10041 mTopAction = Intent.ACTION_FACTORY_TEST; 10042 mTopData = null; 10043 mTopComponent = new ComponentName(app.packageName, 10044 ai.name); 10045 } else { 10046 errorMsg = mContext.getResources().getText( 10047 com.android.internal.R.string.factorytest_not_system); 10048 } 10049 } else { 10050 errorMsg = mContext.getResources().getText( 10051 com.android.internal.R.string.factorytest_no_action); 10052 } 10053 if (errorMsg != null) { 10054 mTopAction = null; 10055 mTopData = null; 10056 mTopComponent = null; 10057 Message msg = Message.obtain(); 10058 msg.what = SHOW_FACTORY_ERROR_MSG; 10059 msg.getData().putCharSequence("msg", errorMsg); 10060 mHandler.sendMessage(msg); 10061 } 10062 } 10063 } 10064 10065 retrieveSettings(); 10066 10067 synchronized (this) { 10068 readGrantedUriPermissionsLocked(); 10069 } 10070 10071 if (goingCallback != null) goingCallback.run(); 10072 10073 mSystemServiceManager.startUser(mCurrentUserId); 10074 10075 synchronized (this) { 10076 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10077 try { 10078 List apps = AppGlobals.getPackageManager(). 10079 getPersistentApplications(STOCK_PM_FLAGS); 10080 if (apps != null) { 10081 int N = apps.size(); 10082 int i; 10083 for (i=0; i<N; i++) { 10084 ApplicationInfo info 10085 = (ApplicationInfo)apps.get(i); 10086 if (info != null && 10087 !info.packageName.equals("android")) { 10088 addAppLocked(info, false, null /* ABI override */); 10089 } 10090 } 10091 } 10092 } catch (RemoteException ex) { 10093 // pm is in same process, this will never happen. 10094 } 10095 } 10096 10097 // Start up initial activity. 10098 mBooting = true; 10099 10100 try { 10101 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10102 Message msg = Message.obtain(); 10103 msg.what = SHOW_UID_ERROR_MSG; 10104 mHandler.sendMessage(msg); 10105 } 10106 } catch (RemoteException e) { 10107 } 10108 10109 long ident = Binder.clearCallingIdentity(); 10110 try { 10111 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10112 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10113 | Intent.FLAG_RECEIVER_FOREGROUND); 10114 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10115 broadcastIntentLocked(null, null, intent, 10116 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10117 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10118 intent = new Intent(Intent.ACTION_USER_STARTING); 10119 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10120 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10121 broadcastIntentLocked(null, null, intent, 10122 null, new IIntentReceiver.Stub() { 10123 @Override 10124 public void performReceive(Intent intent, int resultCode, String data, 10125 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10126 throws RemoteException { 10127 } 10128 }, 0, null, null, 10129 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10130 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10131 } catch (Throwable t) { 10132 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10133 } finally { 10134 Binder.restoreCallingIdentity(ident); 10135 } 10136 mStackSupervisor.resumeTopActivitiesLocked(); 10137 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10138 } 10139 } 10140 10141 private boolean makeAppCrashingLocked(ProcessRecord app, 10142 String shortMsg, String longMsg, String stackTrace) { 10143 app.crashing = true; 10144 app.crashingReport = generateProcessError(app, 10145 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10146 startAppProblemLocked(app); 10147 app.stopFreezingAllLocked(); 10148 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10149 } 10150 10151 private void makeAppNotRespondingLocked(ProcessRecord app, 10152 String activity, String shortMsg, String longMsg) { 10153 app.notResponding = true; 10154 app.notRespondingReport = generateProcessError(app, 10155 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10156 activity, shortMsg, longMsg, null); 10157 startAppProblemLocked(app); 10158 app.stopFreezingAllLocked(); 10159 } 10160 10161 /** 10162 * Generate a process error record, suitable for attachment to a ProcessRecord. 10163 * 10164 * @param app The ProcessRecord in which the error occurred. 10165 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10166 * ActivityManager.AppErrorStateInfo 10167 * @param activity The activity associated with the crash, if known. 10168 * @param shortMsg Short message describing the crash. 10169 * @param longMsg Long message describing the crash. 10170 * @param stackTrace Full crash stack trace, may be null. 10171 * 10172 * @return Returns a fully-formed AppErrorStateInfo record. 10173 */ 10174 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10175 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10176 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10177 10178 report.condition = condition; 10179 report.processName = app.processName; 10180 report.pid = app.pid; 10181 report.uid = app.info.uid; 10182 report.tag = activity; 10183 report.shortMsg = shortMsg; 10184 report.longMsg = longMsg; 10185 report.stackTrace = stackTrace; 10186 10187 return report; 10188 } 10189 10190 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10191 synchronized (this) { 10192 app.crashing = false; 10193 app.crashingReport = null; 10194 app.notResponding = false; 10195 app.notRespondingReport = null; 10196 if (app.anrDialog == fromDialog) { 10197 app.anrDialog = null; 10198 } 10199 if (app.waitDialog == fromDialog) { 10200 app.waitDialog = null; 10201 } 10202 if (app.pid > 0 && app.pid != MY_PID) { 10203 handleAppCrashLocked(app, null, null, null); 10204 killUnneededProcessLocked(app, "user request after error"); 10205 } 10206 } 10207 } 10208 10209 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10210 String stackTrace) { 10211 long now = SystemClock.uptimeMillis(); 10212 10213 Long crashTime; 10214 if (!app.isolated) { 10215 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10216 } else { 10217 crashTime = null; 10218 } 10219 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10220 // This process loses! 10221 Slog.w(TAG, "Process " + app.info.processName 10222 + " has crashed too many times: killing!"); 10223 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10224 app.userId, app.info.processName, app.uid); 10225 mStackSupervisor.handleAppCrashLocked(app); 10226 if (!app.persistent) { 10227 // We don't want to start this process again until the user 10228 // explicitly does so... but for persistent process, we really 10229 // need to keep it running. If a persistent process is actually 10230 // repeatedly crashing, then badness for everyone. 10231 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10232 app.info.processName); 10233 if (!app.isolated) { 10234 // XXX We don't have a way to mark isolated processes 10235 // as bad, since they don't have a peristent identity. 10236 mBadProcesses.put(app.info.processName, app.uid, 10237 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10238 mProcessCrashTimes.remove(app.info.processName, app.uid); 10239 } 10240 app.bad = true; 10241 app.removed = true; 10242 // Don't let services in this process be restarted and potentially 10243 // annoy the user repeatedly. Unless it is persistent, since those 10244 // processes run critical code. 10245 removeProcessLocked(app, false, false, "crash"); 10246 mStackSupervisor.resumeTopActivitiesLocked(); 10247 return false; 10248 } 10249 mStackSupervisor.resumeTopActivitiesLocked(); 10250 } else { 10251 mStackSupervisor.finishTopRunningActivityLocked(app); 10252 } 10253 10254 // Bump up the crash count of any services currently running in the proc. 10255 for (int i=app.services.size()-1; i>=0; i--) { 10256 // Any services running in the application need to be placed 10257 // back in the pending list. 10258 ServiceRecord sr = app.services.valueAt(i); 10259 sr.crashCount++; 10260 } 10261 10262 // If the crashing process is what we consider to be the "home process" and it has been 10263 // replaced by a third-party app, clear the package preferred activities from packages 10264 // with a home activity running in the process to prevent a repeatedly crashing app 10265 // from blocking the user to manually clear the list. 10266 final ArrayList<ActivityRecord> activities = app.activities; 10267 if (app == mHomeProcess && activities.size() > 0 10268 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10269 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10270 final ActivityRecord r = activities.get(activityNdx); 10271 if (r.isHomeActivity()) { 10272 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10273 try { 10274 ActivityThread.getPackageManager() 10275 .clearPackagePreferredActivities(r.packageName); 10276 } catch (RemoteException c) { 10277 // pm is in same process, this will never happen. 10278 } 10279 } 10280 } 10281 } 10282 10283 if (!app.isolated) { 10284 // XXX Can't keep track of crash times for isolated processes, 10285 // because they don't have a perisistent identity. 10286 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10287 } 10288 10289 return true; 10290 } 10291 10292 void startAppProblemLocked(ProcessRecord app) { 10293 if (app.userId == mCurrentUserId) { 10294 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10295 mContext, app.info.packageName, app.info.flags); 10296 } else { 10297 // If this app is not running under the current user, then we 10298 // can't give it a report button because that would require 10299 // launching the report UI under a different user. 10300 app.errorReportReceiver = null; 10301 } 10302 skipCurrentReceiverLocked(app); 10303 } 10304 10305 void skipCurrentReceiverLocked(ProcessRecord app) { 10306 for (BroadcastQueue queue : mBroadcastQueues) { 10307 queue.skipCurrentReceiverLocked(app); 10308 } 10309 } 10310 10311 /** 10312 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10313 * The application process will exit immediately after this call returns. 10314 * @param app object of the crashing app, null for the system server 10315 * @param crashInfo describing the exception 10316 */ 10317 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10318 ProcessRecord r = findAppProcess(app, "Crash"); 10319 final String processName = app == null ? "system_server" 10320 : (r == null ? "unknown" : r.processName); 10321 10322 handleApplicationCrashInner("crash", r, processName, crashInfo); 10323 } 10324 10325 /* Native crash reporting uses this inner version because it needs to be somewhat 10326 * decoupled from the AM-managed cleanup lifecycle 10327 */ 10328 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10329 ApplicationErrorReport.CrashInfo crashInfo) { 10330 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10331 UserHandle.getUserId(Binder.getCallingUid()), processName, 10332 r == null ? -1 : r.info.flags, 10333 crashInfo.exceptionClassName, 10334 crashInfo.exceptionMessage, 10335 crashInfo.throwFileName, 10336 crashInfo.throwLineNumber); 10337 10338 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10339 10340 crashApplication(r, crashInfo); 10341 } 10342 10343 public void handleApplicationStrictModeViolation( 10344 IBinder app, 10345 int violationMask, 10346 StrictMode.ViolationInfo info) { 10347 ProcessRecord r = findAppProcess(app, "StrictMode"); 10348 if (r == null) { 10349 return; 10350 } 10351 10352 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10353 Integer stackFingerprint = info.hashCode(); 10354 boolean logIt = true; 10355 synchronized (mAlreadyLoggedViolatedStacks) { 10356 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10357 logIt = false; 10358 // TODO: sub-sample into EventLog for these, with 10359 // the info.durationMillis? Then we'd get 10360 // the relative pain numbers, without logging all 10361 // the stack traces repeatedly. We'd want to do 10362 // likewise in the client code, which also does 10363 // dup suppression, before the Binder call. 10364 } else { 10365 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10366 mAlreadyLoggedViolatedStacks.clear(); 10367 } 10368 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10369 } 10370 } 10371 if (logIt) { 10372 logStrictModeViolationToDropBox(r, info); 10373 } 10374 } 10375 10376 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10377 AppErrorResult result = new AppErrorResult(); 10378 synchronized (this) { 10379 final long origId = Binder.clearCallingIdentity(); 10380 10381 Message msg = Message.obtain(); 10382 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10383 HashMap<String, Object> data = new HashMap<String, Object>(); 10384 data.put("result", result); 10385 data.put("app", r); 10386 data.put("violationMask", violationMask); 10387 data.put("info", info); 10388 msg.obj = data; 10389 mHandler.sendMessage(msg); 10390 10391 Binder.restoreCallingIdentity(origId); 10392 } 10393 int res = result.get(); 10394 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10395 } 10396 } 10397 10398 // Depending on the policy in effect, there could be a bunch of 10399 // these in quick succession so we try to batch these together to 10400 // minimize disk writes, number of dropbox entries, and maximize 10401 // compression, by having more fewer, larger records. 10402 private void logStrictModeViolationToDropBox( 10403 ProcessRecord process, 10404 StrictMode.ViolationInfo info) { 10405 if (info == null) { 10406 return; 10407 } 10408 final boolean isSystemApp = process == null || 10409 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10410 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10411 final String processName = process == null ? "unknown" : process.processName; 10412 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10413 final DropBoxManager dbox = (DropBoxManager) 10414 mContext.getSystemService(Context.DROPBOX_SERVICE); 10415 10416 // Exit early if the dropbox isn't configured to accept this report type. 10417 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10418 10419 boolean bufferWasEmpty; 10420 boolean needsFlush; 10421 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10422 synchronized (sb) { 10423 bufferWasEmpty = sb.length() == 0; 10424 appendDropBoxProcessHeaders(process, processName, sb); 10425 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10426 sb.append("System-App: ").append(isSystemApp).append("\n"); 10427 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10428 if (info.violationNumThisLoop != 0) { 10429 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10430 } 10431 if (info.numAnimationsRunning != 0) { 10432 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10433 } 10434 if (info.broadcastIntentAction != null) { 10435 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10436 } 10437 if (info.durationMillis != -1) { 10438 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10439 } 10440 if (info.numInstances != -1) { 10441 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10442 } 10443 if (info.tags != null) { 10444 for (String tag : info.tags) { 10445 sb.append("Span-Tag: ").append(tag).append("\n"); 10446 } 10447 } 10448 sb.append("\n"); 10449 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10450 sb.append(info.crashInfo.stackTrace); 10451 } 10452 sb.append("\n"); 10453 10454 // Only buffer up to ~64k. Various logging bits truncate 10455 // things at 128k. 10456 needsFlush = (sb.length() > 64 * 1024); 10457 } 10458 10459 // Flush immediately if the buffer's grown too large, or this 10460 // is a non-system app. Non-system apps are isolated with a 10461 // different tag & policy and not batched. 10462 // 10463 // Batching is useful during internal testing with 10464 // StrictMode settings turned up high. Without batching, 10465 // thousands of separate files could be created on boot. 10466 if (!isSystemApp || needsFlush) { 10467 new Thread("Error dump: " + dropboxTag) { 10468 @Override 10469 public void run() { 10470 String report; 10471 synchronized (sb) { 10472 report = sb.toString(); 10473 sb.delete(0, sb.length()); 10474 sb.trimToSize(); 10475 } 10476 if (report.length() != 0) { 10477 dbox.addText(dropboxTag, report); 10478 } 10479 } 10480 }.start(); 10481 return; 10482 } 10483 10484 // System app batching: 10485 if (!bufferWasEmpty) { 10486 // An existing dropbox-writing thread is outstanding, so 10487 // we don't need to start it up. The existing thread will 10488 // catch the buffer appends we just did. 10489 return; 10490 } 10491 10492 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10493 // (After this point, we shouldn't access AMS internal data structures.) 10494 new Thread("Error dump: " + dropboxTag) { 10495 @Override 10496 public void run() { 10497 // 5 second sleep to let stacks arrive and be batched together 10498 try { 10499 Thread.sleep(5000); // 5 seconds 10500 } catch (InterruptedException e) {} 10501 10502 String errorReport; 10503 synchronized (mStrictModeBuffer) { 10504 errorReport = mStrictModeBuffer.toString(); 10505 if (errorReport.length() == 0) { 10506 return; 10507 } 10508 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10509 mStrictModeBuffer.trimToSize(); 10510 } 10511 dbox.addText(dropboxTag, errorReport); 10512 } 10513 }.start(); 10514 } 10515 10516 /** 10517 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10518 * @param app object of the crashing app, null for the system server 10519 * @param tag reported by the caller 10520 * @param crashInfo describing the context of the error 10521 * @return true if the process should exit immediately (WTF is fatal) 10522 */ 10523 public boolean handleApplicationWtf(IBinder app, String tag, 10524 ApplicationErrorReport.CrashInfo crashInfo) { 10525 ProcessRecord r = findAppProcess(app, "WTF"); 10526 final String processName = app == null ? "system_server" 10527 : (r == null ? "unknown" : r.processName); 10528 10529 EventLog.writeEvent(EventLogTags.AM_WTF, 10530 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10531 processName, 10532 r == null ? -1 : r.info.flags, 10533 tag, crashInfo.exceptionMessage); 10534 10535 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10536 10537 if (r != null && r.pid != Process.myPid() && 10538 Settings.Global.getInt(mContext.getContentResolver(), 10539 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10540 crashApplication(r, crashInfo); 10541 return true; 10542 } else { 10543 return false; 10544 } 10545 } 10546 10547 /** 10548 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10549 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10550 */ 10551 private ProcessRecord findAppProcess(IBinder app, String reason) { 10552 if (app == null) { 10553 return null; 10554 } 10555 10556 synchronized (this) { 10557 final int NP = mProcessNames.getMap().size(); 10558 for (int ip=0; ip<NP; ip++) { 10559 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10560 final int NA = apps.size(); 10561 for (int ia=0; ia<NA; ia++) { 10562 ProcessRecord p = apps.valueAt(ia); 10563 if (p.thread != null && p.thread.asBinder() == app) { 10564 return p; 10565 } 10566 } 10567 } 10568 10569 Slog.w(TAG, "Can't find mystery application for " + reason 10570 + " from pid=" + Binder.getCallingPid() 10571 + " uid=" + Binder.getCallingUid() + ": " + app); 10572 return null; 10573 } 10574 } 10575 10576 /** 10577 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10578 * to append various headers to the dropbox log text. 10579 */ 10580 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10581 StringBuilder sb) { 10582 // Watchdog thread ends up invoking this function (with 10583 // a null ProcessRecord) to add the stack file to dropbox. 10584 // Do not acquire a lock on this (am) in such cases, as it 10585 // could cause a potential deadlock, if and when watchdog 10586 // is invoked due to unavailability of lock on am and it 10587 // would prevent watchdog from killing system_server. 10588 if (process == null) { 10589 sb.append("Process: ").append(processName).append("\n"); 10590 return; 10591 } 10592 // Note: ProcessRecord 'process' is guarded by the service 10593 // instance. (notably process.pkgList, which could otherwise change 10594 // concurrently during execution of this method) 10595 synchronized (this) { 10596 sb.append("Process: ").append(processName).append("\n"); 10597 int flags = process.info.flags; 10598 IPackageManager pm = AppGlobals.getPackageManager(); 10599 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10600 for (int ip=0; ip<process.pkgList.size(); ip++) { 10601 String pkg = process.pkgList.keyAt(ip); 10602 sb.append("Package: ").append(pkg); 10603 try { 10604 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10605 if (pi != null) { 10606 sb.append(" v").append(pi.versionCode); 10607 if (pi.versionName != null) { 10608 sb.append(" (").append(pi.versionName).append(")"); 10609 } 10610 } 10611 } catch (RemoteException e) { 10612 Slog.e(TAG, "Error getting package info: " + pkg, e); 10613 } 10614 sb.append("\n"); 10615 } 10616 } 10617 } 10618 10619 private static String processClass(ProcessRecord process) { 10620 if (process == null || process.pid == MY_PID) { 10621 return "system_server"; 10622 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10623 return "system_app"; 10624 } else { 10625 return "data_app"; 10626 } 10627 } 10628 10629 /** 10630 * Write a description of an error (crash, WTF, ANR) to the drop box. 10631 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10632 * @param process which caused the error, null means the system server 10633 * @param activity which triggered the error, null if unknown 10634 * @param parent activity related to the error, null if unknown 10635 * @param subject line related to the error, null if absent 10636 * @param report in long form describing the error, null if absent 10637 * @param logFile to include in the report, null if none 10638 * @param crashInfo giving an application stack trace, null if absent 10639 */ 10640 public void addErrorToDropBox(String eventType, 10641 ProcessRecord process, String processName, ActivityRecord activity, 10642 ActivityRecord parent, String subject, 10643 final String report, final File logFile, 10644 final ApplicationErrorReport.CrashInfo crashInfo) { 10645 // NOTE -- this must never acquire the ActivityManagerService lock, 10646 // otherwise the watchdog may be prevented from resetting the system. 10647 10648 final String dropboxTag = processClass(process) + "_" + eventType; 10649 final DropBoxManager dbox = (DropBoxManager) 10650 mContext.getSystemService(Context.DROPBOX_SERVICE); 10651 10652 // Exit early if the dropbox isn't configured to accept this report type. 10653 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10654 10655 final StringBuilder sb = new StringBuilder(1024); 10656 appendDropBoxProcessHeaders(process, processName, sb); 10657 if (activity != null) { 10658 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10659 } 10660 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10661 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10662 } 10663 if (parent != null && parent != activity) { 10664 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10665 } 10666 if (subject != null) { 10667 sb.append("Subject: ").append(subject).append("\n"); 10668 } 10669 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10670 if (Debug.isDebuggerConnected()) { 10671 sb.append("Debugger: Connected\n"); 10672 } 10673 sb.append("\n"); 10674 10675 // Do the rest in a worker thread to avoid blocking the caller on I/O 10676 // (After this point, we shouldn't access AMS internal data structures.) 10677 Thread worker = new Thread("Error dump: " + dropboxTag) { 10678 @Override 10679 public void run() { 10680 if (report != null) { 10681 sb.append(report); 10682 } 10683 if (logFile != null) { 10684 try { 10685 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10686 "\n\n[[TRUNCATED]]")); 10687 } catch (IOException e) { 10688 Slog.e(TAG, "Error reading " + logFile, e); 10689 } 10690 } 10691 if (crashInfo != null && crashInfo.stackTrace != null) { 10692 sb.append(crashInfo.stackTrace); 10693 } 10694 10695 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10696 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10697 if (lines > 0) { 10698 sb.append("\n"); 10699 10700 // Merge several logcat streams, and take the last N lines 10701 InputStreamReader input = null; 10702 try { 10703 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10704 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10705 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10706 10707 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10708 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10709 input = new InputStreamReader(logcat.getInputStream()); 10710 10711 int num; 10712 char[] buf = new char[8192]; 10713 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10714 } catch (IOException e) { 10715 Slog.e(TAG, "Error running logcat", e); 10716 } finally { 10717 if (input != null) try { input.close(); } catch (IOException e) {} 10718 } 10719 } 10720 10721 dbox.addText(dropboxTag, sb.toString()); 10722 } 10723 }; 10724 10725 if (process == null) { 10726 // If process is null, we are being called from some internal code 10727 // and may be about to die -- run this synchronously. 10728 worker.run(); 10729 } else { 10730 worker.start(); 10731 } 10732 } 10733 10734 /** 10735 * Bring up the "unexpected error" dialog box for a crashing app. 10736 * Deal with edge cases (intercepts from instrumented applications, 10737 * ActivityController, error intent receivers, that sort of thing). 10738 * @param r the application crashing 10739 * @param crashInfo describing the failure 10740 */ 10741 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10742 long timeMillis = System.currentTimeMillis(); 10743 String shortMsg = crashInfo.exceptionClassName; 10744 String longMsg = crashInfo.exceptionMessage; 10745 String stackTrace = crashInfo.stackTrace; 10746 if (shortMsg != null && longMsg != null) { 10747 longMsg = shortMsg + ": " + longMsg; 10748 } else if (shortMsg != null) { 10749 longMsg = shortMsg; 10750 } 10751 10752 AppErrorResult result = new AppErrorResult(); 10753 synchronized (this) { 10754 if (mController != null) { 10755 try { 10756 String name = r != null ? r.processName : null; 10757 int pid = r != null ? r.pid : Binder.getCallingPid(); 10758 if (!mController.appCrashed(name, pid, 10759 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10760 Slog.w(TAG, "Force-killing crashed app " + name 10761 + " at watcher's request"); 10762 Process.killProcess(pid); 10763 return; 10764 } 10765 } catch (RemoteException e) { 10766 mController = null; 10767 Watchdog.getInstance().setActivityController(null); 10768 } 10769 } 10770 10771 final long origId = Binder.clearCallingIdentity(); 10772 10773 // If this process is running instrumentation, finish it. 10774 if (r != null && r.instrumentationClass != null) { 10775 Slog.w(TAG, "Error in app " + r.processName 10776 + " running instrumentation " + r.instrumentationClass + ":"); 10777 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10778 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10779 Bundle info = new Bundle(); 10780 info.putString("shortMsg", shortMsg); 10781 info.putString("longMsg", longMsg); 10782 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10783 Binder.restoreCallingIdentity(origId); 10784 return; 10785 } 10786 10787 // If we can't identify the process or it's already exceeded its crash quota, 10788 // quit right away without showing a crash dialog. 10789 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10790 Binder.restoreCallingIdentity(origId); 10791 return; 10792 } 10793 10794 Message msg = Message.obtain(); 10795 msg.what = SHOW_ERROR_MSG; 10796 HashMap data = new HashMap(); 10797 data.put("result", result); 10798 data.put("app", r); 10799 msg.obj = data; 10800 mHandler.sendMessage(msg); 10801 10802 Binder.restoreCallingIdentity(origId); 10803 } 10804 10805 int res = result.get(); 10806 10807 Intent appErrorIntent = null; 10808 synchronized (this) { 10809 if (r != null && !r.isolated) { 10810 // XXX Can't keep track of crash time for isolated processes, 10811 // since they don't have a persistent identity. 10812 mProcessCrashTimes.put(r.info.processName, r.uid, 10813 SystemClock.uptimeMillis()); 10814 } 10815 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10816 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10817 } 10818 } 10819 10820 if (appErrorIntent != null) { 10821 try { 10822 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10823 } catch (ActivityNotFoundException e) { 10824 Slog.w(TAG, "bug report receiver dissappeared", e); 10825 } 10826 } 10827 } 10828 10829 Intent createAppErrorIntentLocked(ProcessRecord r, 10830 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10831 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10832 if (report == null) { 10833 return null; 10834 } 10835 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10836 result.setComponent(r.errorReportReceiver); 10837 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10838 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10839 return result; 10840 } 10841 10842 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10843 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10844 if (r.errorReportReceiver == null) { 10845 return null; 10846 } 10847 10848 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10849 return null; 10850 } 10851 10852 ApplicationErrorReport report = new ApplicationErrorReport(); 10853 report.packageName = r.info.packageName; 10854 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10855 report.processName = r.processName; 10856 report.time = timeMillis; 10857 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10858 10859 if (r.crashing || r.forceCrashReport) { 10860 report.type = ApplicationErrorReport.TYPE_CRASH; 10861 report.crashInfo = crashInfo; 10862 } else if (r.notResponding) { 10863 report.type = ApplicationErrorReport.TYPE_ANR; 10864 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10865 10866 report.anrInfo.activity = r.notRespondingReport.tag; 10867 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10868 report.anrInfo.info = r.notRespondingReport.longMsg; 10869 } 10870 10871 return report; 10872 } 10873 10874 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10875 enforceNotIsolatedCaller("getProcessesInErrorState"); 10876 // assume our apps are happy - lazy create the list 10877 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10878 10879 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10880 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10881 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10882 10883 synchronized (this) { 10884 10885 // iterate across all processes 10886 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10887 ProcessRecord app = mLruProcesses.get(i); 10888 if (!allUsers && app.userId != userId) { 10889 continue; 10890 } 10891 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10892 // This one's in trouble, so we'll generate a report for it 10893 // crashes are higher priority (in case there's a crash *and* an anr) 10894 ActivityManager.ProcessErrorStateInfo report = null; 10895 if (app.crashing) { 10896 report = app.crashingReport; 10897 } else if (app.notResponding) { 10898 report = app.notRespondingReport; 10899 } 10900 10901 if (report != null) { 10902 if (errList == null) { 10903 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10904 } 10905 errList.add(report); 10906 } else { 10907 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10908 " crashing = " + app.crashing + 10909 " notResponding = " + app.notResponding); 10910 } 10911 } 10912 } 10913 } 10914 10915 return errList; 10916 } 10917 10918 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10919 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10920 if (currApp != null) { 10921 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10922 } 10923 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10924 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10925 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10926 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10927 if (currApp != null) { 10928 currApp.lru = 0; 10929 } 10930 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10931 } else if (adj >= ProcessList.SERVICE_ADJ) { 10932 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10933 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10934 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10935 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10936 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10937 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10938 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10939 } else { 10940 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10941 } 10942 } 10943 10944 private void fillInProcMemInfo(ProcessRecord app, 10945 ActivityManager.RunningAppProcessInfo outInfo) { 10946 outInfo.pid = app.pid; 10947 outInfo.uid = app.info.uid; 10948 if (mHeavyWeightProcess == app) { 10949 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10950 } 10951 if (app.persistent) { 10952 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10953 } 10954 if (app.activities.size() > 0) { 10955 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10956 } 10957 outInfo.lastTrimLevel = app.trimMemoryLevel; 10958 int adj = app.curAdj; 10959 outInfo.importance = oomAdjToImportance(adj, outInfo); 10960 outInfo.importanceReasonCode = app.adjTypeCode; 10961 outInfo.processState = app.curProcState; 10962 } 10963 10964 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10965 enforceNotIsolatedCaller("getRunningAppProcesses"); 10966 // Lazy instantiation of list 10967 List<ActivityManager.RunningAppProcessInfo> runList = null; 10968 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10969 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10970 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10971 synchronized (this) { 10972 // Iterate across all processes 10973 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10974 ProcessRecord app = mLruProcesses.get(i); 10975 if (!allUsers && app.userId != userId) { 10976 continue; 10977 } 10978 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10979 // Generate process state info for running application 10980 ActivityManager.RunningAppProcessInfo currApp = 10981 new ActivityManager.RunningAppProcessInfo(app.processName, 10982 app.pid, app.getPackageList()); 10983 fillInProcMemInfo(app, currApp); 10984 if (app.adjSource instanceof ProcessRecord) { 10985 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10986 currApp.importanceReasonImportance = oomAdjToImportance( 10987 app.adjSourceOom, null); 10988 } else if (app.adjSource instanceof ActivityRecord) { 10989 ActivityRecord r = (ActivityRecord)app.adjSource; 10990 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10991 } 10992 if (app.adjTarget instanceof ComponentName) { 10993 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10994 } 10995 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10996 // + " lru=" + currApp.lru); 10997 if (runList == null) { 10998 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10999 } 11000 runList.add(currApp); 11001 } 11002 } 11003 } 11004 return runList; 11005 } 11006 11007 public List<ApplicationInfo> getRunningExternalApplications() { 11008 enforceNotIsolatedCaller("getRunningExternalApplications"); 11009 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11010 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11011 if (runningApps != null && runningApps.size() > 0) { 11012 Set<String> extList = new HashSet<String>(); 11013 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11014 if (app.pkgList != null) { 11015 for (String pkg : app.pkgList) { 11016 extList.add(pkg); 11017 } 11018 } 11019 } 11020 IPackageManager pm = AppGlobals.getPackageManager(); 11021 for (String pkg : extList) { 11022 try { 11023 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11024 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11025 retList.add(info); 11026 } 11027 } catch (RemoteException e) { 11028 } 11029 } 11030 } 11031 return retList; 11032 } 11033 11034 @Override 11035 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11036 enforceNotIsolatedCaller("getMyMemoryState"); 11037 synchronized (this) { 11038 ProcessRecord proc; 11039 synchronized (mPidsSelfLocked) { 11040 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11041 } 11042 fillInProcMemInfo(proc, outInfo); 11043 } 11044 } 11045 11046 @Override 11047 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11048 if (checkCallingPermission(android.Manifest.permission.DUMP) 11049 != PackageManager.PERMISSION_GRANTED) { 11050 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11051 + Binder.getCallingPid() 11052 + ", uid=" + Binder.getCallingUid() 11053 + " without permission " 11054 + android.Manifest.permission.DUMP); 11055 return; 11056 } 11057 11058 boolean dumpAll = false; 11059 boolean dumpClient = false; 11060 String dumpPackage = null; 11061 11062 int opti = 0; 11063 while (opti < args.length) { 11064 String opt = args[opti]; 11065 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11066 break; 11067 } 11068 opti++; 11069 if ("-a".equals(opt)) { 11070 dumpAll = true; 11071 } else if ("-c".equals(opt)) { 11072 dumpClient = true; 11073 } else if ("-h".equals(opt)) { 11074 pw.println("Activity manager dump options:"); 11075 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11076 pw.println(" cmd may be one of:"); 11077 pw.println(" a[ctivities]: activity stack state"); 11078 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11079 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11080 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11081 pw.println(" o[om]: out of memory management"); 11082 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11083 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11084 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11085 pw.println(" service [COMP_SPEC]: service client-side state"); 11086 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11087 pw.println(" all: dump all activities"); 11088 pw.println(" top: dump the top activity"); 11089 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11090 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11091 pw.println(" a partial substring in a component name, a"); 11092 pw.println(" hex object identifier."); 11093 pw.println(" -a: include all available server state."); 11094 pw.println(" -c: include client state."); 11095 return; 11096 } else { 11097 pw.println("Unknown argument: " + opt + "; use -h for help"); 11098 } 11099 } 11100 11101 long origId = Binder.clearCallingIdentity(); 11102 boolean more = false; 11103 // Is the caller requesting to dump a particular piece of data? 11104 if (opti < args.length) { 11105 String cmd = args[opti]; 11106 opti++; 11107 if ("activities".equals(cmd) || "a".equals(cmd)) { 11108 synchronized (this) { 11109 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11110 } 11111 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11112 String[] newArgs; 11113 String name; 11114 if (opti >= args.length) { 11115 name = null; 11116 newArgs = EMPTY_STRING_ARRAY; 11117 } else { 11118 name = args[opti]; 11119 opti++; 11120 newArgs = new String[args.length - opti]; 11121 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11122 args.length - opti); 11123 } 11124 synchronized (this) { 11125 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11126 } 11127 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11128 String[] newArgs; 11129 String name; 11130 if (opti >= args.length) { 11131 name = null; 11132 newArgs = EMPTY_STRING_ARRAY; 11133 } else { 11134 name = args[opti]; 11135 opti++; 11136 newArgs = new String[args.length - opti]; 11137 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11138 args.length - opti); 11139 } 11140 synchronized (this) { 11141 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11142 } 11143 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11144 String[] newArgs; 11145 String name; 11146 if (opti >= args.length) { 11147 name = null; 11148 newArgs = EMPTY_STRING_ARRAY; 11149 } else { 11150 name = args[opti]; 11151 opti++; 11152 newArgs = new String[args.length - opti]; 11153 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11154 args.length - opti); 11155 } 11156 synchronized (this) { 11157 dumpProcessesLocked(fd, pw, args, opti, true, name); 11158 } 11159 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11160 synchronized (this) { 11161 dumpOomLocked(fd, pw, args, opti, true); 11162 } 11163 } else if ("provider".equals(cmd)) { 11164 String[] newArgs; 11165 String name; 11166 if (opti >= args.length) { 11167 name = null; 11168 newArgs = EMPTY_STRING_ARRAY; 11169 } else { 11170 name = args[opti]; 11171 opti++; 11172 newArgs = new String[args.length - opti]; 11173 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11174 } 11175 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11176 pw.println("No providers match: " + name); 11177 pw.println("Use -h for help."); 11178 } 11179 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11180 synchronized (this) { 11181 dumpProvidersLocked(fd, pw, args, opti, true, null); 11182 } 11183 } else if ("service".equals(cmd)) { 11184 String[] newArgs; 11185 String name; 11186 if (opti >= args.length) { 11187 name = null; 11188 newArgs = EMPTY_STRING_ARRAY; 11189 } else { 11190 name = args[opti]; 11191 opti++; 11192 newArgs = new String[args.length - opti]; 11193 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11194 args.length - opti); 11195 } 11196 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11197 pw.println("No services match: " + name); 11198 pw.println("Use -h for help."); 11199 } 11200 } else if ("package".equals(cmd)) { 11201 String[] newArgs; 11202 if (opti >= args.length) { 11203 pw.println("package: no package name specified"); 11204 pw.println("Use -h for help."); 11205 } else { 11206 dumpPackage = args[opti]; 11207 opti++; 11208 newArgs = new String[args.length - opti]; 11209 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11210 args.length - opti); 11211 args = newArgs; 11212 opti = 0; 11213 more = true; 11214 } 11215 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11216 synchronized (this) { 11217 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11218 } 11219 } else { 11220 // Dumping a single activity? 11221 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11222 pw.println("Bad activity command, or no activities match: " + cmd); 11223 pw.println("Use -h for help."); 11224 } 11225 } 11226 if (!more) { 11227 Binder.restoreCallingIdentity(origId); 11228 return; 11229 } 11230 } 11231 11232 // No piece of data specified, dump everything. 11233 synchronized (this) { 11234 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11235 pw.println(); 11236 if (dumpAll) { 11237 pw.println("-------------------------------------------------------------------------------"); 11238 } 11239 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11240 pw.println(); 11241 if (dumpAll) { 11242 pw.println("-------------------------------------------------------------------------------"); 11243 } 11244 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11245 pw.println(); 11246 if (dumpAll) { 11247 pw.println("-------------------------------------------------------------------------------"); 11248 } 11249 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11250 pw.println(); 11251 if (dumpAll) { 11252 pw.println("-------------------------------------------------------------------------------"); 11253 } 11254 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11255 pw.println(); 11256 if (dumpAll) { 11257 pw.println("-------------------------------------------------------------------------------"); 11258 } 11259 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11260 } 11261 Binder.restoreCallingIdentity(origId); 11262 } 11263 11264 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11265 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11266 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11267 11268 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11269 dumpPackage); 11270 boolean needSep = printedAnything; 11271 11272 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11273 dumpPackage, needSep, " mFocusedActivity: "); 11274 if (printed) { 11275 printedAnything = true; 11276 needSep = false; 11277 } 11278 11279 if (dumpPackage == null) { 11280 if (needSep) { 11281 pw.println(); 11282 } 11283 needSep = true; 11284 printedAnything = true; 11285 mStackSupervisor.dump(pw, " "); 11286 } 11287 11288 if (mRecentTasks.size() > 0) { 11289 boolean printedHeader = false; 11290 11291 final int N = mRecentTasks.size(); 11292 for (int i=0; i<N; i++) { 11293 TaskRecord tr = mRecentTasks.get(i); 11294 if (dumpPackage != null) { 11295 if (tr.realActivity == null || 11296 !dumpPackage.equals(tr.realActivity)) { 11297 continue; 11298 } 11299 } 11300 if (!printedHeader) { 11301 if (needSep) { 11302 pw.println(); 11303 } 11304 pw.println(" Recent tasks:"); 11305 printedHeader = true; 11306 printedAnything = true; 11307 } 11308 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11309 pw.println(tr); 11310 if (dumpAll) { 11311 mRecentTasks.get(i).dump(pw, " "); 11312 } 11313 } 11314 } 11315 11316 if (!printedAnything) { 11317 pw.println(" (nothing)"); 11318 } 11319 } 11320 11321 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11322 int opti, boolean dumpAll, String dumpPackage) { 11323 boolean needSep = false; 11324 boolean printedAnything = false; 11325 int numPers = 0; 11326 11327 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11328 11329 if (dumpAll) { 11330 final int NP = mProcessNames.getMap().size(); 11331 for (int ip=0; ip<NP; ip++) { 11332 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11333 final int NA = procs.size(); 11334 for (int ia=0; ia<NA; ia++) { 11335 ProcessRecord r = procs.valueAt(ia); 11336 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11337 continue; 11338 } 11339 if (!needSep) { 11340 pw.println(" All known processes:"); 11341 needSep = true; 11342 printedAnything = true; 11343 } 11344 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11345 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11346 pw.print(" "); pw.println(r); 11347 r.dump(pw, " "); 11348 if (r.persistent) { 11349 numPers++; 11350 } 11351 } 11352 } 11353 } 11354 11355 if (mIsolatedProcesses.size() > 0) { 11356 boolean printed = false; 11357 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11358 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11359 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11360 continue; 11361 } 11362 if (!printed) { 11363 if (needSep) { 11364 pw.println(); 11365 } 11366 pw.println(" Isolated process list (sorted by uid):"); 11367 printedAnything = true; 11368 printed = true; 11369 needSep = true; 11370 } 11371 pw.println(String.format("%sIsolated #%2d: %s", 11372 " ", i, r.toString())); 11373 } 11374 } 11375 11376 if (mLruProcesses.size() > 0) { 11377 if (needSep) { 11378 pw.println(); 11379 } 11380 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11381 pw.print(" total, non-act at "); 11382 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11383 pw.print(", non-svc at "); 11384 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11385 pw.println("):"); 11386 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11387 needSep = true; 11388 printedAnything = true; 11389 } 11390 11391 if (dumpAll || dumpPackage != null) { 11392 synchronized (mPidsSelfLocked) { 11393 boolean printed = false; 11394 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11395 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11396 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11397 continue; 11398 } 11399 if (!printed) { 11400 if (needSep) pw.println(); 11401 needSep = true; 11402 pw.println(" PID mappings:"); 11403 printed = true; 11404 printedAnything = true; 11405 } 11406 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11407 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11408 } 11409 } 11410 } 11411 11412 if (mForegroundProcesses.size() > 0) { 11413 synchronized (mPidsSelfLocked) { 11414 boolean printed = false; 11415 for (int i=0; i<mForegroundProcesses.size(); i++) { 11416 ProcessRecord r = mPidsSelfLocked.get( 11417 mForegroundProcesses.valueAt(i).pid); 11418 if (dumpPackage != null && (r == null 11419 || !r.pkgList.containsKey(dumpPackage))) { 11420 continue; 11421 } 11422 if (!printed) { 11423 if (needSep) pw.println(); 11424 needSep = true; 11425 pw.println(" Foreground Processes:"); 11426 printed = true; 11427 printedAnything = true; 11428 } 11429 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11430 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11431 } 11432 } 11433 } 11434 11435 if (mPersistentStartingProcesses.size() > 0) { 11436 if (needSep) pw.println(); 11437 needSep = true; 11438 printedAnything = true; 11439 pw.println(" Persisent processes that are starting:"); 11440 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11441 "Starting Norm", "Restarting PERS", dumpPackage); 11442 } 11443 11444 if (mRemovedProcesses.size() > 0) { 11445 if (needSep) pw.println(); 11446 needSep = true; 11447 printedAnything = true; 11448 pw.println(" Processes that are being removed:"); 11449 dumpProcessList(pw, this, mRemovedProcesses, " ", 11450 "Removed Norm", "Removed PERS", dumpPackage); 11451 } 11452 11453 if (mProcessesOnHold.size() > 0) { 11454 if (needSep) pw.println(); 11455 needSep = true; 11456 printedAnything = true; 11457 pw.println(" Processes that are on old until the system is ready:"); 11458 dumpProcessList(pw, this, mProcessesOnHold, " ", 11459 "OnHold Norm", "OnHold PERS", dumpPackage); 11460 } 11461 11462 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11463 11464 if (mProcessCrashTimes.getMap().size() > 0) { 11465 boolean printed = false; 11466 long now = SystemClock.uptimeMillis(); 11467 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11468 final int NP = pmap.size(); 11469 for (int ip=0; ip<NP; ip++) { 11470 String pname = pmap.keyAt(ip); 11471 SparseArray<Long> uids = pmap.valueAt(ip); 11472 final int N = uids.size(); 11473 for (int i=0; i<N; i++) { 11474 int puid = uids.keyAt(i); 11475 ProcessRecord r = mProcessNames.get(pname, puid); 11476 if (dumpPackage != null && (r == null 11477 || !r.pkgList.containsKey(dumpPackage))) { 11478 continue; 11479 } 11480 if (!printed) { 11481 if (needSep) pw.println(); 11482 needSep = true; 11483 pw.println(" Time since processes crashed:"); 11484 printed = true; 11485 printedAnything = true; 11486 } 11487 pw.print(" Process "); pw.print(pname); 11488 pw.print(" uid "); pw.print(puid); 11489 pw.print(": last crashed "); 11490 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11491 pw.println(" ago"); 11492 } 11493 } 11494 } 11495 11496 if (mBadProcesses.getMap().size() > 0) { 11497 boolean printed = false; 11498 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11499 final int NP = pmap.size(); 11500 for (int ip=0; ip<NP; ip++) { 11501 String pname = pmap.keyAt(ip); 11502 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11503 final int N = uids.size(); 11504 for (int i=0; i<N; i++) { 11505 int puid = uids.keyAt(i); 11506 ProcessRecord r = mProcessNames.get(pname, puid); 11507 if (dumpPackage != null && (r == null 11508 || !r.pkgList.containsKey(dumpPackage))) { 11509 continue; 11510 } 11511 if (!printed) { 11512 if (needSep) pw.println(); 11513 needSep = true; 11514 pw.println(" Bad processes:"); 11515 printedAnything = true; 11516 } 11517 BadProcessInfo info = uids.valueAt(i); 11518 pw.print(" Bad process "); pw.print(pname); 11519 pw.print(" uid "); pw.print(puid); 11520 pw.print(": crashed at time "); pw.println(info.time); 11521 if (info.shortMsg != null) { 11522 pw.print(" Short msg: "); pw.println(info.shortMsg); 11523 } 11524 if (info.longMsg != null) { 11525 pw.print(" Long msg: "); pw.println(info.longMsg); 11526 } 11527 if (info.stack != null) { 11528 pw.println(" Stack:"); 11529 int lastPos = 0; 11530 for (int pos=0; pos<info.stack.length(); pos++) { 11531 if (info.stack.charAt(pos) == '\n') { 11532 pw.print(" "); 11533 pw.write(info.stack, lastPos, pos-lastPos); 11534 pw.println(); 11535 lastPos = pos+1; 11536 } 11537 } 11538 if (lastPos < info.stack.length()) { 11539 pw.print(" "); 11540 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11541 pw.println(); 11542 } 11543 } 11544 } 11545 } 11546 } 11547 11548 if (dumpPackage == null) { 11549 pw.println(); 11550 needSep = false; 11551 pw.println(" mStartedUsers:"); 11552 for (int i=0; i<mStartedUsers.size(); i++) { 11553 UserStartedState uss = mStartedUsers.valueAt(i); 11554 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11555 pw.print(": "); uss.dump("", pw); 11556 } 11557 pw.print(" mStartedUserArray: ["); 11558 for (int i=0; i<mStartedUserArray.length; i++) { 11559 if (i > 0) pw.print(", "); 11560 pw.print(mStartedUserArray[i]); 11561 } 11562 pw.println("]"); 11563 pw.print(" mUserLru: ["); 11564 for (int i=0; i<mUserLru.size(); i++) { 11565 if (i > 0) pw.print(", "); 11566 pw.print(mUserLru.get(i)); 11567 } 11568 pw.println("]"); 11569 if (dumpAll) { 11570 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11571 } 11572 } 11573 if (mHomeProcess != null && (dumpPackage == null 11574 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11575 if (needSep) { 11576 pw.println(); 11577 needSep = false; 11578 } 11579 pw.println(" mHomeProcess: " + mHomeProcess); 11580 } 11581 if (mPreviousProcess != null && (dumpPackage == null 11582 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11583 if (needSep) { 11584 pw.println(); 11585 needSep = false; 11586 } 11587 pw.println(" mPreviousProcess: " + mPreviousProcess); 11588 } 11589 if (dumpAll) { 11590 StringBuilder sb = new StringBuilder(128); 11591 sb.append(" mPreviousProcessVisibleTime: "); 11592 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11593 pw.println(sb); 11594 } 11595 if (mHeavyWeightProcess != null && (dumpPackage == null 11596 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11597 if (needSep) { 11598 pw.println(); 11599 needSep = false; 11600 } 11601 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11602 } 11603 if (dumpPackage == null) { 11604 pw.println(" mConfiguration: " + mConfiguration); 11605 } 11606 if (dumpAll) { 11607 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11608 if (mCompatModePackages.getPackages().size() > 0) { 11609 boolean printed = false; 11610 for (Map.Entry<String, Integer> entry 11611 : mCompatModePackages.getPackages().entrySet()) { 11612 String pkg = entry.getKey(); 11613 int mode = entry.getValue(); 11614 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11615 continue; 11616 } 11617 if (!printed) { 11618 pw.println(" mScreenCompatPackages:"); 11619 printed = true; 11620 } 11621 pw.print(" "); pw.print(pkg); pw.print(": "); 11622 pw.print(mode); pw.println(); 11623 } 11624 } 11625 } 11626 if (dumpPackage == null) { 11627 if (mSleeping || mWentToSleep || mLockScreenShown) { 11628 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11629 + " mLockScreenShown " + mLockScreenShown); 11630 } 11631 if (mShuttingDown || mRunningVoice) { 11632 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11633 } 11634 } 11635 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11636 || mOrigWaitForDebugger) { 11637 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11638 || dumpPackage.equals(mOrigDebugApp)) { 11639 if (needSep) { 11640 pw.println(); 11641 needSep = false; 11642 } 11643 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11644 + " mDebugTransient=" + mDebugTransient 11645 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11646 } 11647 } 11648 if (mOpenGlTraceApp != null) { 11649 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11650 if (needSep) { 11651 pw.println(); 11652 needSep = false; 11653 } 11654 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11655 } 11656 } 11657 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11658 || mProfileFd != null) { 11659 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11660 if (needSep) { 11661 pw.println(); 11662 needSep = false; 11663 } 11664 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11665 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11666 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11667 + mAutoStopProfiler); 11668 } 11669 } 11670 if (dumpPackage == null) { 11671 if (mAlwaysFinishActivities || mController != null) { 11672 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11673 + " mController=" + mController); 11674 } 11675 if (dumpAll) { 11676 pw.println(" Total persistent processes: " + numPers); 11677 pw.println(" mProcessesReady=" + mProcessesReady 11678 + " mSystemReady=" + mSystemReady); 11679 pw.println(" mBooting=" + mBooting 11680 + " mBooted=" + mBooted 11681 + " mFactoryTest=" + mFactoryTest); 11682 pw.print(" mLastPowerCheckRealtime="); 11683 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11684 pw.println(""); 11685 pw.print(" mLastPowerCheckUptime="); 11686 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11687 pw.println(""); 11688 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11689 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11690 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11691 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11692 + " (" + mLruProcesses.size() + " total)" 11693 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11694 + " mNumServiceProcs=" + mNumServiceProcs 11695 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11696 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11697 + " mLastMemoryLevel" + mLastMemoryLevel 11698 + " mLastNumProcesses" + mLastNumProcesses); 11699 long now = SystemClock.uptimeMillis(); 11700 pw.print(" mLastIdleTime="); 11701 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11702 pw.print(" mLowRamSinceLastIdle="); 11703 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11704 pw.println(); 11705 } 11706 } 11707 11708 if (!printedAnything) { 11709 pw.println(" (nothing)"); 11710 } 11711 } 11712 11713 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11714 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11715 if (mProcessesToGc.size() > 0) { 11716 boolean printed = false; 11717 long now = SystemClock.uptimeMillis(); 11718 for (int i=0; i<mProcessesToGc.size(); i++) { 11719 ProcessRecord proc = mProcessesToGc.get(i); 11720 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11721 continue; 11722 } 11723 if (!printed) { 11724 if (needSep) pw.println(); 11725 needSep = true; 11726 pw.println(" Processes that are waiting to GC:"); 11727 printed = true; 11728 } 11729 pw.print(" Process "); pw.println(proc); 11730 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11731 pw.print(", last gced="); 11732 pw.print(now-proc.lastRequestedGc); 11733 pw.print(" ms ago, last lowMem="); 11734 pw.print(now-proc.lastLowMemory); 11735 pw.println(" ms ago"); 11736 11737 } 11738 } 11739 return needSep; 11740 } 11741 11742 void printOomLevel(PrintWriter pw, String name, int adj) { 11743 pw.print(" "); 11744 if (adj >= 0) { 11745 pw.print(' '); 11746 if (adj < 10) pw.print(' '); 11747 } else { 11748 if (adj > -10) pw.print(' '); 11749 } 11750 pw.print(adj); 11751 pw.print(": "); 11752 pw.print(name); 11753 pw.print(" ("); 11754 pw.print(mProcessList.getMemLevel(adj)/1024); 11755 pw.println(" kB)"); 11756 } 11757 11758 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11759 int opti, boolean dumpAll) { 11760 boolean needSep = false; 11761 11762 if (mLruProcesses.size() > 0) { 11763 if (needSep) pw.println(); 11764 needSep = true; 11765 pw.println(" OOM levels:"); 11766 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11767 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11768 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11769 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11770 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11771 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11772 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11773 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11774 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11775 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11776 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11777 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11778 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11779 11780 if (needSep) pw.println(); 11781 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11782 pw.print(" total, non-act at "); 11783 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11784 pw.print(", non-svc at "); 11785 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11786 pw.println("):"); 11787 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11788 needSep = true; 11789 } 11790 11791 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11792 11793 pw.println(); 11794 pw.println(" mHomeProcess: " + mHomeProcess); 11795 pw.println(" mPreviousProcess: " + mPreviousProcess); 11796 if (mHeavyWeightProcess != null) { 11797 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11798 } 11799 11800 return true; 11801 } 11802 11803 /** 11804 * There are three ways to call this: 11805 * - no provider specified: dump all the providers 11806 * - a flattened component name that matched an existing provider was specified as the 11807 * first arg: dump that one provider 11808 * - the first arg isn't the flattened component name of an existing provider: 11809 * dump all providers whose component contains the first arg as a substring 11810 */ 11811 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11812 int opti, boolean dumpAll) { 11813 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11814 } 11815 11816 static class ItemMatcher { 11817 ArrayList<ComponentName> components; 11818 ArrayList<String> strings; 11819 ArrayList<Integer> objects; 11820 boolean all; 11821 11822 ItemMatcher() { 11823 all = true; 11824 } 11825 11826 void build(String name) { 11827 ComponentName componentName = ComponentName.unflattenFromString(name); 11828 if (componentName != null) { 11829 if (components == null) { 11830 components = new ArrayList<ComponentName>(); 11831 } 11832 components.add(componentName); 11833 all = false; 11834 } else { 11835 int objectId = 0; 11836 // Not a '/' separated full component name; maybe an object ID? 11837 try { 11838 objectId = Integer.parseInt(name, 16); 11839 if (objects == null) { 11840 objects = new ArrayList<Integer>(); 11841 } 11842 objects.add(objectId); 11843 all = false; 11844 } catch (RuntimeException e) { 11845 // Not an integer; just do string match. 11846 if (strings == null) { 11847 strings = new ArrayList<String>(); 11848 } 11849 strings.add(name); 11850 all = false; 11851 } 11852 } 11853 } 11854 11855 int build(String[] args, int opti) { 11856 for (; opti<args.length; opti++) { 11857 String name = args[opti]; 11858 if ("--".equals(name)) { 11859 return opti+1; 11860 } 11861 build(name); 11862 } 11863 return opti; 11864 } 11865 11866 boolean match(Object object, ComponentName comp) { 11867 if (all) { 11868 return true; 11869 } 11870 if (components != null) { 11871 for (int i=0; i<components.size(); i++) { 11872 if (components.get(i).equals(comp)) { 11873 return true; 11874 } 11875 } 11876 } 11877 if (objects != null) { 11878 for (int i=0; i<objects.size(); i++) { 11879 if (System.identityHashCode(object) == objects.get(i)) { 11880 return true; 11881 } 11882 } 11883 } 11884 if (strings != null) { 11885 String flat = comp.flattenToString(); 11886 for (int i=0; i<strings.size(); i++) { 11887 if (flat.contains(strings.get(i))) { 11888 return true; 11889 } 11890 } 11891 } 11892 return false; 11893 } 11894 } 11895 11896 /** 11897 * There are three things that cmd can be: 11898 * - a flattened component name that matches an existing activity 11899 * - the cmd arg isn't the flattened component name of an existing activity: 11900 * dump all activity whose component contains the cmd as a substring 11901 * - A hex number of the ActivityRecord object instance. 11902 */ 11903 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11904 int opti, boolean dumpAll) { 11905 ArrayList<ActivityRecord> activities; 11906 11907 synchronized (this) { 11908 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11909 } 11910 11911 if (activities.size() <= 0) { 11912 return false; 11913 } 11914 11915 String[] newArgs = new String[args.length - opti]; 11916 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11917 11918 TaskRecord lastTask = null; 11919 boolean needSep = false; 11920 for (int i=activities.size()-1; i>=0; i--) { 11921 ActivityRecord r = activities.get(i); 11922 if (needSep) { 11923 pw.println(); 11924 } 11925 needSep = true; 11926 synchronized (this) { 11927 if (lastTask != r.task) { 11928 lastTask = r.task; 11929 pw.print("TASK "); pw.print(lastTask.affinity); 11930 pw.print(" id="); pw.println(lastTask.taskId); 11931 if (dumpAll) { 11932 lastTask.dump(pw, " "); 11933 } 11934 } 11935 } 11936 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11937 } 11938 return true; 11939 } 11940 11941 /** 11942 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11943 * there is a thread associated with the activity. 11944 */ 11945 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11946 final ActivityRecord r, String[] args, boolean dumpAll) { 11947 String innerPrefix = prefix + " "; 11948 synchronized (this) { 11949 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11950 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11951 pw.print(" pid="); 11952 if (r.app != null) pw.println(r.app.pid); 11953 else pw.println("(not running)"); 11954 if (dumpAll) { 11955 r.dump(pw, innerPrefix); 11956 } 11957 } 11958 if (r.app != null && r.app.thread != null) { 11959 // flush anything that is already in the PrintWriter since the thread is going 11960 // to write to the file descriptor directly 11961 pw.flush(); 11962 try { 11963 TransferPipe tp = new TransferPipe(); 11964 try { 11965 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11966 r.appToken, innerPrefix, args); 11967 tp.go(fd); 11968 } finally { 11969 tp.kill(); 11970 } 11971 } catch (IOException e) { 11972 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11973 } catch (RemoteException e) { 11974 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11975 } 11976 } 11977 } 11978 11979 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11980 int opti, boolean dumpAll, String dumpPackage) { 11981 boolean needSep = false; 11982 boolean onlyHistory = false; 11983 boolean printedAnything = false; 11984 11985 if ("history".equals(dumpPackage)) { 11986 if (opti < args.length && "-s".equals(args[opti])) { 11987 dumpAll = false; 11988 } 11989 onlyHistory = true; 11990 dumpPackage = null; 11991 } 11992 11993 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11994 if (!onlyHistory && dumpAll) { 11995 if (mRegisteredReceivers.size() > 0) { 11996 boolean printed = false; 11997 Iterator it = mRegisteredReceivers.values().iterator(); 11998 while (it.hasNext()) { 11999 ReceiverList r = (ReceiverList)it.next(); 12000 if (dumpPackage != null && (r.app == null || 12001 !dumpPackage.equals(r.app.info.packageName))) { 12002 continue; 12003 } 12004 if (!printed) { 12005 pw.println(" Registered Receivers:"); 12006 needSep = true; 12007 printed = true; 12008 printedAnything = true; 12009 } 12010 pw.print(" * "); pw.println(r); 12011 r.dump(pw, " "); 12012 } 12013 } 12014 12015 if (mReceiverResolver.dump(pw, needSep ? 12016 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12017 " ", dumpPackage, false)) { 12018 needSep = true; 12019 printedAnything = true; 12020 } 12021 } 12022 12023 for (BroadcastQueue q : mBroadcastQueues) { 12024 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12025 printedAnything |= needSep; 12026 } 12027 12028 needSep = true; 12029 12030 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12031 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12032 if (needSep) { 12033 pw.println(); 12034 } 12035 needSep = true; 12036 printedAnything = true; 12037 pw.print(" Sticky broadcasts for user "); 12038 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12039 StringBuilder sb = new StringBuilder(128); 12040 for (Map.Entry<String, ArrayList<Intent>> ent 12041 : mStickyBroadcasts.valueAt(user).entrySet()) { 12042 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12043 if (dumpAll) { 12044 pw.println(":"); 12045 ArrayList<Intent> intents = ent.getValue(); 12046 final int N = intents.size(); 12047 for (int i=0; i<N; i++) { 12048 sb.setLength(0); 12049 sb.append(" Intent: "); 12050 intents.get(i).toShortString(sb, false, true, false, false); 12051 pw.println(sb.toString()); 12052 Bundle bundle = intents.get(i).getExtras(); 12053 if (bundle != null) { 12054 pw.print(" "); 12055 pw.println(bundle.toString()); 12056 } 12057 } 12058 } else { 12059 pw.println(""); 12060 } 12061 } 12062 } 12063 } 12064 12065 if (!onlyHistory && dumpAll) { 12066 pw.println(); 12067 for (BroadcastQueue queue : mBroadcastQueues) { 12068 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12069 + queue.mBroadcastsScheduled); 12070 } 12071 pw.println(" mHandler:"); 12072 mHandler.dump(new PrintWriterPrinter(pw), " "); 12073 needSep = true; 12074 printedAnything = true; 12075 } 12076 12077 if (!printedAnything) { 12078 pw.println(" (nothing)"); 12079 } 12080 } 12081 12082 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12083 int opti, boolean dumpAll, String dumpPackage) { 12084 boolean needSep; 12085 boolean printedAnything = false; 12086 12087 ItemMatcher matcher = new ItemMatcher(); 12088 matcher.build(args, opti); 12089 12090 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12091 12092 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12093 printedAnything |= needSep; 12094 12095 if (mLaunchingProviders.size() > 0) { 12096 boolean printed = false; 12097 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12098 ContentProviderRecord r = mLaunchingProviders.get(i); 12099 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12100 continue; 12101 } 12102 if (!printed) { 12103 if (needSep) pw.println(); 12104 needSep = true; 12105 pw.println(" Launching content providers:"); 12106 printed = true; 12107 printedAnything = true; 12108 } 12109 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12110 pw.println(r); 12111 } 12112 } 12113 12114 if (mGrantedUriPermissions.size() > 0) { 12115 boolean printed = false; 12116 int dumpUid = -2; 12117 if (dumpPackage != null) { 12118 try { 12119 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12120 } catch (NameNotFoundException e) { 12121 dumpUid = -1; 12122 } 12123 } 12124 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12125 int uid = mGrantedUriPermissions.keyAt(i); 12126 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12127 continue; 12128 } 12129 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12130 if (!printed) { 12131 if (needSep) pw.println(); 12132 needSep = true; 12133 pw.println(" Granted Uri Permissions:"); 12134 printed = true; 12135 printedAnything = true; 12136 } 12137 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12138 for (UriPermission perm : perms.values()) { 12139 pw.print(" "); pw.println(perm); 12140 if (dumpAll) { 12141 perm.dump(pw, " "); 12142 } 12143 } 12144 } 12145 } 12146 12147 if (!printedAnything) { 12148 pw.println(" (nothing)"); 12149 } 12150 } 12151 12152 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12153 int opti, boolean dumpAll, String dumpPackage) { 12154 boolean printed = false; 12155 12156 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12157 12158 if (mIntentSenderRecords.size() > 0) { 12159 Iterator<WeakReference<PendingIntentRecord>> it 12160 = mIntentSenderRecords.values().iterator(); 12161 while (it.hasNext()) { 12162 WeakReference<PendingIntentRecord> ref = it.next(); 12163 PendingIntentRecord rec = ref != null ? ref.get(): null; 12164 if (dumpPackage != null && (rec == null 12165 || !dumpPackage.equals(rec.key.packageName))) { 12166 continue; 12167 } 12168 printed = true; 12169 if (rec != null) { 12170 pw.print(" * "); pw.println(rec); 12171 if (dumpAll) { 12172 rec.dump(pw, " "); 12173 } 12174 } else { 12175 pw.print(" * "); pw.println(ref); 12176 } 12177 } 12178 } 12179 12180 if (!printed) { 12181 pw.println(" (nothing)"); 12182 } 12183 } 12184 12185 private static final int dumpProcessList(PrintWriter pw, 12186 ActivityManagerService service, List list, 12187 String prefix, String normalLabel, String persistentLabel, 12188 String dumpPackage) { 12189 int numPers = 0; 12190 final int N = list.size()-1; 12191 for (int i=N; i>=0; i--) { 12192 ProcessRecord r = (ProcessRecord)list.get(i); 12193 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12194 continue; 12195 } 12196 pw.println(String.format("%s%s #%2d: %s", 12197 prefix, (r.persistent ? persistentLabel : normalLabel), 12198 i, r.toString())); 12199 if (r.persistent) { 12200 numPers++; 12201 } 12202 } 12203 return numPers; 12204 } 12205 12206 private static final boolean dumpProcessOomList(PrintWriter pw, 12207 ActivityManagerService service, List<ProcessRecord> origList, 12208 String prefix, String normalLabel, String persistentLabel, 12209 boolean inclDetails, String dumpPackage) { 12210 12211 ArrayList<Pair<ProcessRecord, Integer>> list 12212 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12213 for (int i=0; i<origList.size(); i++) { 12214 ProcessRecord r = origList.get(i); 12215 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12216 continue; 12217 } 12218 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12219 } 12220 12221 if (list.size() <= 0) { 12222 return false; 12223 } 12224 12225 Comparator<Pair<ProcessRecord, Integer>> comparator 12226 = new Comparator<Pair<ProcessRecord, Integer>>() { 12227 @Override 12228 public int compare(Pair<ProcessRecord, Integer> object1, 12229 Pair<ProcessRecord, Integer> object2) { 12230 if (object1.first.setAdj != object2.first.setAdj) { 12231 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12232 } 12233 if (object1.second.intValue() != object2.second.intValue()) { 12234 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12235 } 12236 return 0; 12237 } 12238 }; 12239 12240 Collections.sort(list, comparator); 12241 12242 final long curRealtime = SystemClock.elapsedRealtime(); 12243 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12244 final long curUptime = SystemClock.uptimeMillis(); 12245 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12246 12247 for (int i=list.size()-1; i>=0; i--) { 12248 ProcessRecord r = list.get(i).first; 12249 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12250 char schedGroup; 12251 switch (r.setSchedGroup) { 12252 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12253 schedGroup = 'B'; 12254 break; 12255 case Process.THREAD_GROUP_DEFAULT: 12256 schedGroup = 'F'; 12257 break; 12258 default: 12259 schedGroup = '?'; 12260 break; 12261 } 12262 char foreground; 12263 if (r.foregroundActivities) { 12264 foreground = 'A'; 12265 } else if (r.foregroundServices) { 12266 foreground = 'S'; 12267 } else { 12268 foreground = ' '; 12269 } 12270 String procState = ProcessList.makeProcStateString(r.curProcState); 12271 pw.print(prefix); 12272 pw.print(r.persistent ? persistentLabel : normalLabel); 12273 pw.print(" #"); 12274 int num = (origList.size()-1)-list.get(i).second; 12275 if (num < 10) pw.print(' '); 12276 pw.print(num); 12277 pw.print(": "); 12278 pw.print(oomAdj); 12279 pw.print(' '); 12280 pw.print(schedGroup); 12281 pw.print('/'); 12282 pw.print(foreground); 12283 pw.print('/'); 12284 pw.print(procState); 12285 pw.print(" trm:"); 12286 if (r.trimMemoryLevel < 10) pw.print(' '); 12287 pw.print(r.trimMemoryLevel); 12288 pw.print(' '); 12289 pw.print(r.toShortString()); 12290 pw.print(" ("); 12291 pw.print(r.adjType); 12292 pw.println(')'); 12293 if (r.adjSource != null || r.adjTarget != null) { 12294 pw.print(prefix); 12295 pw.print(" "); 12296 if (r.adjTarget instanceof ComponentName) { 12297 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12298 } else if (r.adjTarget != null) { 12299 pw.print(r.adjTarget.toString()); 12300 } else { 12301 pw.print("{null}"); 12302 } 12303 pw.print("<="); 12304 if (r.adjSource instanceof ProcessRecord) { 12305 pw.print("Proc{"); 12306 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12307 pw.println("}"); 12308 } else if (r.adjSource != null) { 12309 pw.println(r.adjSource.toString()); 12310 } else { 12311 pw.println("{null}"); 12312 } 12313 } 12314 if (inclDetails) { 12315 pw.print(prefix); 12316 pw.print(" "); 12317 pw.print("oom: max="); pw.print(r.maxAdj); 12318 pw.print(" curRaw="); pw.print(r.curRawAdj); 12319 pw.print(" setRaw="); pw.print(r.setRawAdj); 12320 pw.print(" cur="); pw.print(r.curAdj); 12321 pw.print(" set="); pw.println(r.setAdj); 12322 pw.print(prefix); 12323 pw.print(" "); 12324 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12325 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12326 pw.print(" lastPss="); pw.print(r.lastPss); 12327 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12328 pw.print(prefix); 12329 pw.print(" "); 12330 pw.print("keeping="); pw.print(r.keeping); 12331 pw.print(" cached="); pw.print(r.cached); 12332 pw.print(" empty="); pw.print(r.empty); 12333 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12334 12335 if (!r.keeping) { 12336 if (r.lastWakeTime != 0) { 12337 long wtime; 12338 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12339 synchronized (stats) { 12340 wtime = stats.getProcessWakeTime(r.info.uid, 12341 r.pid, curRealtime); 12342 } 12343 long timeUsed = wtime - r.lastWakeTime; 12344 pw.print(prefix); 12345 pw.print(" "); 12346 pw.print("keep awake over "); 12347 TimeUtils.formatDuration(realtimeSince, pw); 12348 pw.print(" used "); 12349 TimeUtils.formatDuration(timeUsed, pw); 12350 pw.print(" ("); 12351 pw.print((timeUsed*100)/realtimeSince); 12352 pw.println("%)"); 12353 } 12354 if (r.lastCpuTime != 0) { 12355 long timeUsed = r.curCpuTime - r.lastCpuTime; 12356 pw.print(prefix); 12357 pw.print(" "); 12358 pw.print("run cpu over "); 12359 TimeUtils.formatDuration(uptimeSince, pw); 12360 pw.print(" used "); 12361 TimeUtils.formatDuration(timeUsed, pw); 12362 pw.print(" ("); 12363 pw.print((timeUsed*100)/uptimeSince); 12364 pw.println("%)"); 12365 } 12366 } 12367 } 12368 } 12369 return true; 12370 } 12371 12372 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12373 ArrayList<ProcessRecord> procs; 12374 synchronized (this) { 12375 if (args != null && args.length > start 12376 && args[start].charAt(0) != '-') { 12377 procs = new ArrayList<ProcessRecord>(); 12378 int pid = -1; 12379 try { 12380 pid = Integer.parseInt(args[start]); 12381 } catch (NumberFormatException e) { 12382 } 12383 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12384 ProcessRecord proc = mLruProcesses.get(i); 12385 if (proc.pid == pid) { 12386 procs.add(proc); 12387 } else if (proc.processName.equals(args[start])) { 12388 procs.add(proc); 12389 } 12390 } 12391 if (procs.size() <= 0) { 12392 return null; 12393 } 12394 } else { 12395 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12396 } 12397 } 12398 return procs; 12399 } 12400 12401 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12402 PrintWriter pw, String[] args) { 12403 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12404 if (procs == null) { 12405 pw.println("No process found for: " + args[0]); 12406 return; 12407 } 12408 12409 long uptime = SystemClock.uptimeMillis(); 12410 long realtime = SystemClock.elapsedRealtime(); 12411 pw.println("Applications Graphics Acceleration Info:"); 12412 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12413 12414 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12415 ProcessRecord r = procs.get(i); 12416 if (r.thread != null) { 12417 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12418 pw.flush(); 12419 try { 12420 TransferPipe tp = new TransferPipe(); 12421 try { 12422 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12423 tp.go(fd); 12424 } finally { 12425 tp.kill(); 12426 } 12427 } catch (IOException e) { 12428 pw.println("Failure while dumping the app: " + r); 12429 pw.flush(); 12430 } catch (RemoteException e) { 12431 pw.println("Got a RemoteException while dumping the app " + r); 12432 pw.flush(); 12433 } 12434 } 12435 } 12436 } 12437 12438 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12439 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12440 if (procs == null) { 12441 pw.println("No process found for: " + args[0]); 12442 return; 12443 } 12444 12445 pw.println("Applications Database Info:"); 12446 12447 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12448 ProcessRecord r = procs.get(i); 12449 if (r.thread != null) { 12450 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12451 pw.flush(); 12452 try { 12453 TransferPipe tp = new TransferPipe(); 12454 try { 12455 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12456 tp.go(fd); 12457 } finally { 12458 tp.kill(); 12459 } 12460 } catch (IOException e) { 12461 pw.println("Failure while dumping the app: " + r); 12462 pw.flush(); 12463 } catch (RemoteException e) { 12464 pw.println("Got a RemoteException while dumping the app " + r); 12465 pw.flush(); 12466 } 12467 } 12468 } 12469 } 12470 12471 final static class MemItem { 12472 final boolean isProc; 12473 final String label; 12474 final String shortLabel; 12475 final long pss; 12476 final int id; 12477 final boolean hasActivities; 12478 ArrayList<MemItem> subitems; 12479 12480 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12481 boolean _hasActivities) { 12482 isProc = true; 12483 label = _label; 12484 shortLabel = _shortLabel; 12485 pss = _pss; 12486 id = _id; 12487 hasActivities = _hasActivities; 12488 } 12489 12490 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12491 isProc = false; 12492 label = _label; 12493 shortLabel = _shortLabel; 12494 pss = _pss; 12495 id = _id; 12496 hasActivities = false; 12497 } 12498 } 12499 12500 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12501 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12502 if (sort && !isCompact) { 12503 Collections.sort(items, new Comparator<MemItem>() { 12504 @Override 12505 public int compare(MemItem lhs, MemItem rhs) { 12506 if (lhs.pss < rhs.pss) { 12507 return 1; 12508 } else if (lhs.pss > rhs.pss) { 12509 return -1; 12510 } 12511 return 0; 12512 } 12513 }); 12514 } 12515 12516 for (int i=0; i<items.size(); i++) { 12517 MemItem mi = items.get(i); 12518 if (!isCompact) { 12519 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12520 } else if (mi.isProc) { 12521 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12522 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12523 pw.println(mi.hasActivities ? ",a" : ",e"); 12524 } else { 12525 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12526 pw.println(mi.pss); 12527 } 12528 if (mi.subitems != null) { 12529 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12530 true, isCompact); 12531 } 12532 } 12533 } 12534 12535 // These are in KB. 12536 static final long[] DUMP_MEM_BUCKETS = new long[] { 12537 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12538 120*1024, 160*1024, 200*1024, 12539 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12540 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12541 }; 12542 12543 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12544 boolean stackLike) { 12545 int start = label.lastIndexOf('.'); 12546 if (start >= 0) start++; 12547 else start = 0; 12548 int end = label.length(); 12549 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12550 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12551 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12552 out.append(bucket); 12553 out.append(stackLike ? "MB." : "MB "); 12554 out.append(label, start, end); 12555 return; 12556 } 12557 } 12558 out.append(memKB/1024); 12559 out.append(stackLike ? "MB." : "MB "); 12560 out.append(label, start, end); 12561 } 12562 12563 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12564 ProcessList.NATIVE_ADJ, 12565 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12566 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12567 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12568 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12569 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12570 }; 12571 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12572 "Native", 12573 "System", "Persistent", "Foreground", 12574 "Visible", "Perceptible", 12575 "Heavy Weight", "Backup", 12576 "A Services", "Home", 12577 "Previous", "B Services", "Cached" 12578 }; 12579 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12580 "native", 12581 "sys", "pers", "fore", 12582 "vis", "percept", 12583 "heavy", "backup", 12584 "servicea", "home", 12585 "prev", "serviceb", "cached" 12586 }; 12587 12588 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12589 long realtime, boolean isCheckinRequest, boolean isCompact) { 12590 if (isCheckinRequest || isCompact) { 12591 // short checkin version 12592 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12593 } else { 12594 pw.println("Applications Memory Usage (kB):"); 12595 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12596 } 12597 } 12598 12599 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12600 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12601 boolean dumpDetails = false; 12602 boolean dumpFullDetails = false; 12603 boolean dumpDalvik = false; 12604 boolean oomOnly = false; 12605 boolean isCompact = false; 12606 boolean localOnly = false; 12607 12608 int opti = 0; 12609 while (opti < args.length) { 12610 String opt = args[opti]; 12611 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12612 break; 12613 } 12614 opti++; 12615 if ("-a".equals(opt)) { 12616 dumpDetails = true; 12617 dumpFullDetails = true; 12618 dumpDalvik = true; 12619 } else if ("-d".equals(opt)) { 12620 dumpDalvik = true; 12621 } else if ("-c".equals(opt)) { 12622 isCompact = true; 12623 } else if ("--oom".equals(opt)) { 12624 oomOnly = true; 12625 } else if ("--local".equals(opt)) { 12626 localOnly = true; 12627 } else if ("-h".equals(opt)) { 12628 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12629 pw.println(" -a: include all available information for each process."); 12630 pw.println(" -d: include dalvik details when dumping process details."); 12631 pw.println(" -c: dump in a compact machine-parseable representation."); 12632 pw.println(" --oom: only show processes organized by oom adj."); 12633 pw.println(" --local: only collect details locally, don't call process."); 12634 pw.println("If [process] is specified it can be the name or "); 12635 pw.println("pid of a specific process to dump."); 12636 return; 12637 } else { 12638 pw.println("Unknown argument: " + opt + "; use -h for help"); 12639 } 12640 } 12641 12642 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12643 long uptime = SystemClock.uptimeMillis(); 12644 long realtime = SystemClock.elapsedRealtime(); 12645 final long[] tmpLong = new long[1]; 12646 12647 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12648 if (procs == null) { 12649 // No Java processes. Maybe they want to print a native process. 12650 if (args != null && args.length > opti 12651 && args[opti].charAt(0) != '-') { 12652 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12653 = new ArrayList<ProcessCpuTracker.Stats>(); 12654 updateCpuStatsNow(); 12655 int findPid = -1; 12656 try { 12657 findPid = Integer.parseInt(args[opti]); 12658 } catch (NumberFormatException e) { 12659 } 12660 synchronized (mProcessCpuThread) { 12661 final int N = mProcessCpuTracker.countStats(); 12662 for (int i=0; i<N; i++) { 12663 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12664 if (st.pid == findPid || (st.baseName != null 12665 && st.baseName.equals(args[opti]))) { 12666 nativeProcs.add(st); 12667 } 12668 } 12669 } 12670 if (nativeProcs.size() > 0) { 12671 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12672 isCompact); 12673 Debug.MemoryInfo mi = null; 12674 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12675 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12676 final int pid = r.pid; 12677 if (!isCheckinRequest && dumpDetails) { 12678 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12679 } 12680 if (mi == null) { 12681 mi = new Debug.MemoryInfo(); 12682 } 12683 if (dumpDetails || (!brief && !oomOnly)) { 12684 Debug.getMemoryInfo(pid, mi); 12685 } else { 12686 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12687 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12688 } 12689 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12690 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12691 if (isCheckinRequest) { 12692 pw.println(); 12693 } 12694 } 12695 return; 12696 } 12697 } 12698 pw.println("No process found for: " + args[opti]); 12699 return; 12700 } 12701 12702 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12703 dumpDetails = true; 12704 } 12705 12706 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12707 12708 String[] innerArgs = new String[args.length-opti]; 12709 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12710 12711 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12712 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12713 long nativePss=0, dalvikPss=0, otherPss=0; 12714 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12715 12716 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12717 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12718 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12719 12720 long totalPss = 0; 12721 long cachedPss = 0; 12722 12723 Debug.MemoryInfo mi = null; 12724 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12725 final ProcessRecord r = procs.get(i); 12726 final IApplicationThread thread; 12727 final int pid; 12728 final int oomAdj; 12729 final boolean hasActivities; 12730 synchronized (this) { 12731 thread = r.thread; 12732 pid = r.pid; 12733 oomAdj = r.getSetAdjWithServices(); 12734 hasActivities = r.activities.size() > 0; 12735 } 12736 if (thread != null) { 12737 if (!isCheckinRequest && dumpDetails) { 12738 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12739 } 12740 if (mi == null) { 12741 mi = new Debug.MemoryInfo(); 12742 } 12743 if (dumpDetails || (!brief && !oomOnly)) { 12744 Debug.getMemoryInfo(pid, mi); 12745 } else { 12746 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12747 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12748 } 12749 if (dumpDetails) { 12750 if (localOnly) { 12751 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12752 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12753 if (isCheckinRequest) { 12754 pw.println(); 12755 } 12756 } else { 12757 try { 12758 pw.flush(); 12759 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12760 dumpDalvik, innerArgs); 12761 } catch (RemoteException e) { 12762 if (!isCheckinRequest) { 12763 pw.println("Got RemoteException!"); 12764 pw.flush(); 12765 } 12766 } 12767 } 12768 } 12769 12770 final long myTotalPss = mi.getTotalPss(); 12771 final long myTotalUss = mi.getTotalUss(); 12772 12773 synchronized (this) { 12774 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12775 // Record this for posterity if the process has been stable. 12776 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12777 } 12778 } 12779 12780 if (!isCheckinRequest && mi != null) { 12781 totalPss += myTotalPss; 12782 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12783 (hasActivities ? " / activities)" : ")"), 12784 r.processName, myTotalPss, pid, hasActivities); 12785 procMems.add(pssItem); 12786 procMemsMap.put(pid, pssItem); 12787 12788 nativePss += mi.nativePss; 12789 dalvikPss += mi.dalvikPss; 12790 otherPss += mi.otherPss; 12791 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12792 long mem = mi.getOtherPss(j); 12793 miscPss[j] += mem; 12794 otherPss -= mem; 12795 } 12796 12797 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12798 cachedPss += myTotalPss; 12799 } 12800 12801 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12802 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12803 || oomIndex == (oomPss.length-1)) { 12804 oomPss[oomIndex] += myTotalPss; 12805 if (oomProcs[oomIndex] == null) { 12806 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12807 } 12808 oomProcs[oomIndex].add(pssItem); 12809 break; 12810 } 12811 } 12812 } 12813 } 12814 } 12815 12816 long nativeProcTotalPss = 0; 12817 12818 if (!isCheckinRequest && procs.size() > 1) { 12819 // If we are showing aggregations, also look for native processes to 12820 // include so that our aggregations are more accurate. 12821 updateCpuStatsNow(); 12822 synchronized (mProcessCpuThread) { 12823 final int N = mProcessCpuTracker.countStats(); 12824 for (int i=0; i<N; i++) { 12825 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12826 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12827 if (mi == null) { 12828 mi = new Debug.MemoryInfo(); 12829 } 12830 if (!brief && !oomOnly) { 12831 Debug.getMemoryInfo(st.pid, mi); 12832 } else { 12833 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12834 mi.nativePrivateDirty = (int)tmpLong[0]; 12835 } 12836 12837 final long myTotalPss = mi.getTotalPss(); 12838 totalPss += myTotalPss; 12839 nativeProcTotalPss += myTotalPss; 12840 12841 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12842 st.name, myTotalPss, st.pid, false); 12843 procMems.add(pssItem); 12844 12845 nativePss += mi.nativePss; 12846 dalvikPss += mi.dalvikPss; 12847 otherPss += mi.otherPss; 12848 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12849 long mem = mi.getOtherPss(j); 12850 miscPss[j] += mem; 12851 otherPss -= mem; 12852 } 12853 oomPss[0] += myTotalPss; 12854 if (oomProcs[0] == null) { 12855 oomProcs[0] = new ArrayList<MemItem>(); 12856 } 12857 oomProcs[0].add(pssItem); 12858 } 12859 } 12860 } 12861 12862 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12863 12864 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12865 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12866 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12867 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12868 String label = Debug.MemoryInfo.getOtherLabel(j); 12869 catMems.add(new MemItem(label, label, miscPss[j], j)); 12870 } 12871 12872 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12873 for (int j=0; j<oomPss.length; j++) { 12874 if (oomPss[j] != 0) { 12875 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12876 : DUMP_MEM_OOM_LABEL[j]; 12877 MemItem item = new MemItem(label, label, oomPss[j], 12878 DUMP_MEM_OOM_ADJ[j]); 12879 item.subitems = oomProcs[j]; 12880 oomMems.add(item); 12881 } 12882 } 12883 12884 if (!brief && !oomOnly && !isCompact) { 12885 pw.println(); 12886 pw.println("Total PSS by process:"); 12887 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12888 pw.println(); 12889 } 12890 if (!isCompact) { 12891 pw.println("Total PSS by OOM adjustment:"); 12892 } 12893 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12894 if (!brief && !oomOnly) { 12895 PrintWriter out = categoryPw != null ? categoryPw : pw; 12896 if (!isCompact) { 12897 out.println(); 12898 out.println("Total PSS by category:"); 12899 } 12900 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12901 } 12902 if (!isCompact) { 12903 pw.println(); 12904 } 12905 MemInfoReader memInfo = new MemInfoReader(); 12906 memInfo.readMemInfo(); 12907 if (nativeProcTotalPss > 0) { 12908 synchronized (this) { 12909 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 12910 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 12911 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 12912 nativeProcTotalPss); 12913 } 12914 } 12915 if (!brief) { 12916 if (!isCompact) { 12917 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12918 pw.print(" kB (status "); 12919 switch (mLastMemoryLevel) { 12920 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12921 pw.println("normal)"); 12922 break; 12923 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12924 pw.println("moderate)"); 12925 break; 12926 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12927 pw.println("low)"); 12928 break; 12929 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12930 pw.println("critical)"); 12931 break; 12932 default: 12933 pw.print(mLastMemoryLevel); 12934 pw.println(")"); 12935 break; 12936 } 12937 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12938 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12939 pw.print(cachedPss); pw.print(" cached pss + "); 12940 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12941 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12942 } else { 12943 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12944 pw.print(cachedPss + memInfo.getCachedSizeKb() 12945 + memInfo.getFreeSizeKb()); pw.print(","); 12946 pw.println(totalPss - cachedPss); 12947 } 12948 } 12949 if (!isCompact) { 12950 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12951 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12952 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12953 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12954 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12955 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12956 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12957 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12958 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12959 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12960 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12961 } 12962 if (!brief) { 12963 if (memInfo.getZramTotalSizeKb() != 0) { 12964 if (!isCompact) { 12965 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12966 pw.print(" kB physical used for "); 12967 pw.print(memInfo.getSwapTotalSizeKb() 12968 - memInfo.getSwapFreeSizeKb()); 12969 pw.print(" kB in swap ("); 12970 pw.print(memInfo.getSwapTotalSizeKb()); 12971 pw.println(" kB total swap)"); 12972 } else { 12973 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12974 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12975 pw.println(memInfo.getSwapFreeSizeKb()); 12976 } 12977 } 12978 final int[] SINGLE_LONG_FORMAT = new int[] { 12979 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12980 }; 12981 long[] longOut = new long[1]; 12982 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12983 SINGLE_LONG_FORMAT, null, longOut, null); 12984 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12985 longOut[0] = 0; 12986 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12987 SINGLE_LONG_FORMAT, null, longOut, null); 12988 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12989 longOut[0] = 0; 12990 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12991 SINGLE_LONG_FORMAT, null, longOut, null); 12992 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12993 longOut[0] = 0; 12994 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12995 SINGLE_LONG_FORMAT, null, longOut, null); 12996 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12997 if (!isCompact) { 12998 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12999 pw.print(" KSM: "); pw.print(sharing); 13000 pw.print(" kB saved from shared "); 13001 pw.print(shared); pw.println(" kB"); 13002 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13003 pw.print(voltile); pw.println(" kB volatile"); 13004 } 13005 pw.print(" Tuning: "); 13006 pw.print(ActivityManager.staticGetMemoryClass()); 13007 pw.print(" (large "); 13008 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13009 pw.print("), oom "); 13010 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13011 pw.print(" kB"); 13012 pw.print(", restore limit "); 13013 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13014 pw.print(" kB"); 13015 if (ActivityManager.isLowRamDeviceStatic()) { 13016 pw.print(" (low-ram)"); 13017 } 13018 if (ActivityManager.isHighEndGfx()) { 13019 pw.print(" (high-end-gfx)"); 13020 } 13021 pw.println(); 13022 } else { 13023 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13024 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13025 pw.println(voltile); 13026 pw.print("tuning,"); 13027 pw.print(ActivityManager.staticGetMemoryClass()); 13028 pw.print(','); 13029 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13030 pw.print(','); 13031 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13032 if (ActivityManager.isLowRamDeviceStatic()) { 13033 pw.print(",low-ram"); 13034 } 13035 if (ActivityManager.isHighEndGfx()) { 13036 pw.print(",high-end-gfx"); 13037 } 13038 pw.println(); 13039 } 13040 } 13041 } 13042 } 13043 13044 /** 13045 * Searches array of arguments for the specified string 13046 * @param args array of argument strings 13047 * @param value value to search for 13048 * @return true if the value is contained in the array 13049 */ 13050 private static boolean scanArgs(String[] args, String value) { 13051 if (args != null) { 13052 for (String arg : args) { 13053 if (value.equals(arg)) { 13054 return true; 13055 } 13056 } 13057 } 13058 return false; 13059 } 13060 13061 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13062 ContentProviderRecord cpr, boolean always) { 13063 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13064 13065 if (!inLaunching || always) { 13066 synchronized (cpr) { 13067 cpr.launchingApp = null; 13068 cpr.notifyAll(); 13069 } 13070 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13071 String names[] = cpr.info.authority.split(";"); 13072 for (int j = 0; j < names.length; j++) { 13073 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13074 } 13075 } 13076 13077 for (int i=0; i<cpr.connections.size(); i++) { 13078 ContentProviderConnection conn = cpr.connections.get(i); 13079 if (conn.waiting) { 13080 // If this connection is waiting for the provider, then we don't 13081 // need to mess with its process unless we are always removing 13082 // or for some reason the provider is not currently launching. 13083 if (inLaunching && !always) { 13084 continue; 13085 } 13086 } 13087 ProcessRecord capp = conn.client; 13088 conn.dead = true; 13089 if (conn.stableCount > 0) { 13090 if (!capp.persistent && capp.thread != null 13091 && capp.pid != 0 13092 && capp.pid != MY_PID) { 13093 killUnneededProcessLocked(capp, "depends on provider " 13094 + cpr.name.flattenToShortString() 13095 + " in dying proc " + (proc != null ? proc.processName : "??")); 13096 } 13097 } else if (capp.thread != null && conn.provider.provider != null) { 13098 try { 13099 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13100 } catch (RemoteException e) { 13101 } 13102 // In the protocol here, we don't expect the client to correctly 13103 // clean up this connection, we'll just remove it. 13104 cpr.connections.remove(i); 13105 conn.client.conProviders.remove(conn); 13106 } 13107 } 13108 13109 if (inLaunching && always) { 13110 mLaunchingProviders.remove(cpr); 13111 } 13112 return inLaunching; 13113 } 13114 13115 /** 13116 * Main code for cleaning up a process when it has gone away. This is 13117 * called both as a result of the process dying, or directly when stopping 13118 * a process when running in single process mode. 13119 */ 13120 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13121 boolean restarting, boolean allowRestart, int index) { 13122 if (index >= 0) { 13123 removeLruProcessLocked(app); 13124 ProcessList.remove(app.pid); 13125 } 13126 13127 mProcessesToGc.remove(app); 13128 mPendingPssProcesses.remove(app); 13129 13130 // Dismiss any open dialogs. 13131 if (app.crashDialog != null && !app.forceCrashReport) { 13132 app.crashDialog.dismiss(); 13133 app.crashDialog = null; 13134 } 13135 if (app.anrDialog != null) { 13136 app.anrDialog.dismiss(); 13137 app.anrDialog = null; 13138 } 13139 if (app.waitDialog != null) { 13140 app.waitDialog.dismiss(); 13141 app.waitDialog = null; 13142 } 13143 13144 app.crashing = false; 13145 app.notResponding = false; 13146 13147 app.resetPackageList(mProcessStats); 13148 app.unlinkDeathRecipient(); 13149 app.makeInactive(mProcessStats); 13150 app.waitingToKill = null; 13151 app.forcingToForeground = null; 13152 updateProcessForegroundLocked(app, false, false); 13153 app.foregroundActivities = false; 13154 app.hasShownUi = false; 13155 app.treatLikeActivity = false; 13156 app.hasAboveClient = false; 13157 app.hasClientActivities = false; 13158 13159 mServices.killServicesLocked(app, allowRestart); 13160 13161 boolean restart = false; 13162 13163 // Remove published content providers. 13164 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13165 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13166 final boolean always = app.bad || !allowRestart; 13167 if (removeDyingProviderLocked(app, cpr, always) || always) { 13168 // We left the provider in the launching list, need to 13169 // restart it. 13170 restart = true; 13171 } 13172 13173 cpr.provider = null; 13174 cpr.proc = null; 13175 } 13176 app.pubProviders.clear(); 13177 13178 // Take care of any launching providers waiting for this process. 13179 if (checkAppInLaunchingProvidersLocked(app, false)) { 13180 restart = true; 13181 } 13182 13183 // Unregister from connected content providers. 13184 if (!app.conProviders.isEmpty()) { 13185 for (int i=0; i<app.conProviders.size(); i++) { 13186 ContentProviderConnection conn = app.conProviders.get(i); 13187 conn.provider.connections.remove(conn); 13188 } 13189 app.conProviders.clear(); 13190 } 13191 13192 // At this point there may be remaining entries in mLaunchingProviders 13193 // where we were the only one waiting, so they are no longer of use. 13194 // Look for these and clean up if found. 13195 // XXX Commented out for now. Trying to figure out a way to reproduce 13196 // the actual situation to identify what is actually going on. 13197 if (false) { 13198 for (int i=0; i<mLaunchingProviders.size(); i++) { 13199 ContentProviderRecord cpr = (ContentProviderRecord) 13200 mLaunchingProviders.get(i); 13201 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13202 synchronized (cpr) { 13203 cpr.launchingApp = null; 13204 cpr.notifyAll(); 13205 } 13206 } 13207 } 13208 } 13209 13210 skipCurrentReceiverLocked(app); 13211 13212 // Unregister any receivers. 13213 for (int i=app.receivers.size()-1; i>=0; i--) { 13214 removeReceiverLocked(app.receivers.valueAt(i)); 13215 } 13216 app.receivers.clear(); 13217 13218 // If the app is undergoing backup, tell the backup manager about it 13219 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13220 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13221 + mBackupTarget.appInfo + " died during backup"); 13222 try { 13223 IBackupManager bm = IBackupManager.Stub.asInterface( 13224 ServiceManager.getService(Context.BACKUP_SERVICE)); 13225 bm.agentDisconnected(app.info.packageName); 13226 } catch (RemoteException e) { 13227 // can't happen; backup manager is local 13228 } 13229 } 13230 13231 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13232 ProcessChangeItem item = mPendingProcessChanges.get(i); 13233 if (item.pid == app.pid) { 13234 mPendingProcessChanges.remove(i); 13235 mAvailProcessChanges.add(item); 13236 } 13237 } 13238 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13239 13240 // If the caller is restarting this app, then leave it in its 13241 // current lists and let the caller take care of it. 13242 if (restarting) { 13243 return; 13244 } 13245 13246 if (!app.persistent || app.isolated) { 13247 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13248 "Removing non-persistent process during cleanup: " + app); 13249 mProcessNames.remove(app.processName, app.uid); 13250 mIsolatedProcesses.remove(app.uid); 13251 if (mHeavyWeightProcess == app) { 13252 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13253 mHeavyWeightProcess.userId, 0)); 13254 mHeavyWeightProcess = null; 13255 } 13256 } else if (!app.removed) { 13257 // This app is persistent, so we need to keep its record around. 13258 // If it is not already on the pending app list, add it there 13259 // and start a new process for it. 13260 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13261 mPersistentStartingProcesses.add(app); 13262 restart = true; 13263 } 13264 } 13265 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13266 "Clean-up removing on hold: " + app); 13267 mProcessesOnHold.remove(app); 13268 13269 if (app == mHomeProcess) { 13270 mHomeProcess = null; 13271 } 13272 if (app == mPreviousProcess) { 13273 mPreviousProcess = null; 13274 } 13275 13276 if (restart && !app.isolated) { 13277 // We have components that still need to be running in the 13278 // process, so re-launch it. 13279 mProcessNames.put(app.processName, app.uid, app); 13280 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13281 } else if (app.pid > 0 && app.pid != MY_PID) { 13282 // Goodbye! 13283 boolean removed; 13284 synchronized (mPidsSelfLocked) { 13285 mPidsSelfLocked.remove(app.pid); 13286 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13287 } 13288 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 13289 app.processName, app.info.uid); 13290 if (app.isolated) { 13291 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13292 } 13293 app.setPid(0); 13294 } 13295 } 13296 13297 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13298 // Look through the content providers we are waiting to have launched, 13299 // and if any run in this process then either schedule a restart of 13300 // the process or kill the client waiting for it if this process has 13301 // gone bad. 13302 int NL = mLaunchingProviders.size(); 13303 boolean restart = false; 13304 for (int i=0; i<NL; i++) { 13305 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13306 if (cpr.launchingApp == app) { 13307 if (!alwaysBad && !app.bad) { 13308 restart = true; 13309 } else { 13310 removeDyingProviderLocked(app, cpr, true); 13311 // cpr should have been removed from mLaunchingProviders 13312 NL = mLaunchingProviders.size(); 13313 i--; 13314 } 13315 } 13316 } 13317 return restart; 13318 } 13319 13320 // ========================================================= 13321 // SERVICES 13322 // ========================================================= 13323 13324 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13325 int flags) { 13326 enforceNotIsolatedCaller("getServices"); 13327 synchronized (this) { 13328 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13329 } 13330 } 13331 13332 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13333 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13334 synchronized (this) { 13335 return mServices.getRunningServiceControlPanelLocked(name); 13336 } 13337 } 13338 13339 public ComponentName startService(IApplicationThread caller, Intent service, 13340 String resolvedType, int userId) { 13341 enforceNotIsolatedCaller("startService"); 13342 // Refuse possible leaked file descriptors 13343 if (service != null && service.hasFileDescriptors() == true) { 13344 throw new IllegalArgumentException("File descriptors passed in Intent"); 13345 } 13346 13347 if (DEBUG_SERVICE) 13348 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13349 synchronized(this) { 13350 final int callingPid = Binder.getCallingPid(); 13351 final int callingUid = Binder.getCallingUid(); 13352 final long origId = Binder.clearCallingIdentity(); 13353 ComponentName res = mServices.startServiceLocked(caller, service, 13354 resolvedType, callingPid, callingUid, userId); 13355 Binder.restoreCallingIdentity(origId); 13356 return res; 13357 } 13358 } 13359 13360 ComponentName startServiceInPackage(int uid, 13361 Intent service, String resolvedType, int userId) { 13362 synchronized(this) { 13363 if (DEBUG_SERVICE) 13364 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13365 final long origId = Binder.clearCallingIdentity(); 13366 ComponentName res = mServices.startServiceLocked(null, service, 13367 resolvedType, -1, uid, userId); 13368 Binder.restoreCallingIdentity(origId); 13369 return res; 13370 } 13371 } 13372 13373 public int stopService(IApplicationThread caller, Intent service, 13374 String resolvedType, int userId) { 13375 enforceNotIsolatedCaller("stopService"); 13376 // Refuse possible leaked file descriptors 13377 if (service != null && service.hasFileDescriptors() == true) { 13378 throw new IllegalArgumentException("File descriptors passed in Intent"); 13379 } 13380 13381 synchronized(this) { 13382 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13383 } 13384 } 13385 13386 public IBinder peekService(Intent service, String resolvedType) { 13387 enforceNotIsolatedCaller("peekService"); 13388 // Refuse possible leaked file descriptors 13389 if (service != null && service.hasFileDescriptors() == true) { 13390 throw new IllegalArgumentException("File descriptors passed in Intent"); 13391 } 13392 synchronized(this) { 13393 return mServices.peekServiceLocked(service, resolvedType); 13394 } 13395 } 13396 13397 public boolean stopServiceToken(ComponentName className, IBinder token, 13398 int startId) { 13399 synchronized(this) { 13400 return mServices.stopServiceTokenLocked(className, token, startId); 13401 } 13402 } 13403 13404 public void setServiceForeground(ComponentName className, IBinder token, 13405 int id, Notification notification, boolean removeNotification) { 13406 synchronized(this) { 13407 mServices.setServiceForegroundLocked(className, token, id, notification, 13408 removeNotification); 13409 } 13410 } 13411 13412 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13413 boolean requireFull, String name, String callerPackage) { 13414 final int callingUserId = UserHandle.getUserId(callingUid); 13415 if (callingUserId != userId) { 13416 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13417 if ((requireFull || checkComponentPermission( 13418 android.Manifest.permission.INTERACT_ACROSS_USERS, 13419 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13420 && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, 13421 callingPid, callingUid, -1, true) 13422 != PackageManager.PERMISSION_GRANTED) { 13423 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13424 // In this case, they would like to just execute as their 13425 // owner user instead of failing. 13426 userId = callingUserId; 13427 } else { 13428 StringBuilder builder = new StringBuilder(128); 13429 builder.append("Permission Denial: "); 13430 builder.append(name); 13431 if (callerPackage != null) { 13432 builder.append(" from "); 13433 builder.append(callerPackage); 13434 } 13435 builder.append(" asks to run as user "); 13436 builder.append(userId); 13437 builder.append(" but is calling from user "); 13438 builder.append(UserHandle.getUserId(callingUid)); 13439 builder.append("; this requires "); 13440 builder.append(INTERACT_ACROSS_USERS_FULL); 13441 if (!requireFull) { 13442 builder.append(" or "); 13443 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13444 } 13445 String msg = builder.toString(); 13446 Slog.w(TAG, msg); 13447 throw new SecurityException(msg); 13448 } 13449 } 13450 } 13451 if (userId == UserHandle.USER_CURRENT 13452 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13453 // Note that we may be accessing this outside of a lock... 13454 // shouldn't be a big deal, if this is being called outside 13455 // of a locked context there is intrinsically a race with 13456 // the value the caller will receive and someone else changing it. 13457 userId = mCurrentUserId; 13458 } 13459 if (!allowAll && userId < 0) { 13460 throw new IllegalArgumentException( 13461 "Call does not support special user #" + userId); 13462 } 13463 } 13464 return userId; 13465 } 13466 13467 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13468 String className, int flags) { 13469 boolean result = false; 13470 // For apps that don't have pre-defined UIDs, check for permission 13471 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13472 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13473 if (ActivityManager.checkUidPermission( 13474 android.Manifest.permission.INTERACT_ACROSS_USERS, 13475 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13476 ComponentName comp = new ComponentName(aInfo.packageName, className); 13477 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13478 + " requests FLAG_SINGLE_USER, but app does not hold " 13479 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13480 Slog.w(TAG, msg); 13481 throw new SecurityException(msg); 13482 } 13483 // Permission passed 13484 result = true; 13485 } 13486 } else if ("system".equals(componentProcessName)) { 13487 result = true; 13488 } else { 13489 // App with pre-defined UID, check if it's a persistent app 13490 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13491 } 13492 if (DEBUG_MU) { 13493 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13494 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13495 } 13496 return result; 13497 } 13498 13499 /** 13500 * Checks to see if the caller is in the same app as the singleton 13501 * component, or the component is in a special app. It allows special apps 13502 * to export singleton components but prevents exporting singleton 13503 * components for regular apps. 13504 */ 13505 boolean isValidSingletonCall(int callingUid, int componentUid) { 13506 int componentAppId = UserHandle.getAppId(componentUid); 13507 return UserHandle.isSameApp(callingUid, componentUid) 13508 || componentAppId == Process.SYSTEM_UID 13509 || componentAppId == Process.PHONE_UID 13510 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13511 == PackageManager.PERMISSION_GRANTED; 13512 } 13513 13514 public int bindService(IApplicationThread caller, IBinder token, 13515 Intent service, String resolvedType, 13516 IServiceConnection connection, int flags, int userId) { 13517 enforceNotIsolatedCaller("bindService"); 13518 // Refuse possible leaked file descriptors 13519 if (service != null && service.hasFileDescriptors() == true) { 13520 throw new IllegalArgumentException("File descriptors passed in Intent"); 13521 } 13522 13523 synchronized(this) { 13524 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13525 connection, flags, userId); 13526 } 13527 } 13528 13529 public boolean unbindService(IServiceConnection connection) { 13530 synchronized (this) { 13531 return mServices.unbindServiceLocked(connection); 13532 } 13533 } 13534 13535 public void publishService(IBinder token, Intent intent, IBinder service) { 13536 // Refuse possible leaked file descriptors 13537 if (intent != null && intent.hasFileDescriptors() == true) { 13538 throw new IllegalArgumentException("File descriptors passed in Intent"); 13539 } 13540 13541 synchronized(this) { 13542 if (!(token instanceof ServiceRecord)) { 13543 throw new IllegalArgumentException("Invalid service token"); 13544 } 13545 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13546 } 13547 } 13548 13549 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13550 // Refuse possible leaked file descriptors 13551 if (intent != null && intent.hasFileDescriptors() == true) { 13552 throw new IllegalArgumentException("File descriptors passed in Intent"); 13553 } 13554 13555 synchronized(this) { 13556 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13557 } 13558 } 13559 13560 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13561 synchronized(this) { 13562 if (!(token instanceof ServiceRecord)) { 13563 throw new IllegalArgumentException("Invalid service token"); 13564 } 13565 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13566 } 13567 } 13568 13569 // ========================================================= 13570 // BACKUP AND RESTORE 13571 // ========================================================= 13572 13573 // Cause the target app to be launched if necessary and its backup agent 13574 // instantiated. The backup agent will invoke backupAgentCreated() on the 13575 // activity manager to announce its creation. 13576 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13577 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13578 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13579 13580 synchronized(this) { 13581 // !!! TODO: currently no check here that we're already bound 13582 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13583 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13584 synchronized (stats) { 13585 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13586 } 13587 13588 // Backup agent is now in use, its package can't be stopped. 13589 try { 13590 AppGlobals.getPackageManager().setPackageStoppedState( 13591 app.packageName, false, UserHandle.getUserId(app.uid)); 13592 } catch (RemoteException e) { 13593 } catch (IllegalArgumentException e) { 13594 Slog.w(TAG, "Failed trying to unstop package " 13595 + app.packageName + ": " + e); 13596 } 13597 13598 BackupRecord r = new BackupRecord(ss, app, backupMode); 13599 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13600 ? new ComponentName(app.packageName, app.backupAgentName) 13601 : new ComponentName("android", "FullBackupAgent"); 13602 // startProcessLocked() returns existing proc's record if it's already running 13603 ProcessRecord proc = startProcessLocked(app.processName, app, 13604 false, 0, "backup", hostingName, false, false, false); 13605 if (proc == null) { 13606 Slog.e(TAG, "Unable to start backup agent process " + r); 13607 return false; 13608 } 13609 13610 r.app = proc; 13611 mBackupTarget = r; 13612 mBackupAppName = app.packageName; 13613 13614 // Try not to kill the process during backup 13615 updateOomAdjLocked(proc); 13616 13617 // If the process is already attached, schedule the creation of the backup agent now. 13618 // If it is not yet live, this will be done when it attaches to the framework. 13619 if (proc.thread != null) { 13620 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13621 try { 13622 proc.thread.scheduleCreateBackupAgent(app, 13623 compatibilityInfoForPackageLocked(app), backupMode); 13624 } catch (RemoteException e) { 13625 // Will time out on the backup manager side 13626 } 13627 } else { 13628 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13629 } 13630 // Invariants: at this point, the target app process exists and the application 13631 // is either already running or in the process of coming up. mBackupTarget and 13632 // mBackupAppName describe the app, so that when it binds back to the AM we 13633 // know that it's scheduled for a backup-agent operation. 13634 } 13635 13636 return true; 13637 } 13638 13639 @Override 13640 public void clearPendingBackup() { 13641 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13642 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13643 13644 synchronized (this) { 13645 mBackupTarget = null; 13646 mBackupAppName = null; 13647 } 13648 } 13649 13650 // A backup agent has just come up 13651 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13652 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13653 + " = " + agent); 13654 13655 synchronized(this) { 13656 if (!agentPackageName.equals(mBackupAppName)) { 13657 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13658 return; 13659 } 13660 } 13661 13662 long oldIdent = Binder.clearCallingIdentity(); 13663 try { 13664 IBackupManager bm = IBackupManager.Stub.asInterface( 13665 ServiceManager.getService(Context.BACKUP_SERVICE)); 13666 bm.agentConnected(agentPackageName, agent); 13667 } catch (RemoteException e) { 13668 // can't happen; the backup manager service is local 13669 } catch (Exception e) { 13670 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13671 e.printStackTrace(); 13672 } finally { 13673 Binder.restoreCallingIdentity(oldIdent); 13674 } 13675 } 13676 13677 // done with this agent 13678 public void unbindBackupAgent(ApplicationInfo appInfo) { 13679 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13680 if (appInfo == null) { 13681 Slog.w(TAG, "unbind backup agent for null app"); 13682 return; 13683 } 13684 13685 synchronized(this) { 13686 try { 13687 if (mBackupAppName == null) { 13688 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13689 return; 13690 } 13691 13692 if (!mBackupAppName.equals(appInfo.packageName)) { 13693 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13694 return; 13695 } 13696 13697 // Not backing this app up any more; reset its OOM adjustment 13698 final ProcessRecord proc = mBackupTarget.app; 13699 updateOomAdjLocked(proc); 13700 13701 // If the app crashed during backup, 'thread' will be null here 13702 if (proc.thread != null) { 13703 try { 13704 proc.thread.scheduleDestroyBackupAgent(appInfo, 13705 compatibilityInfoForPackageLocked(appInfo)); 13706 } catch (Exception e) { 13707 Slog.e(TAG, "Exception when unbinding backup agent:"); 13708 e.printStackTrace(); 13709 } 13710 } 13711 } finally { 13712 mBackupTarget = null; 13713 mBackupAppName = null; 13714 } 13715 } 13716 } 13717 // ========================================================= 13718 // BROADCASTS 13719 // ========================================================= 13720 13721 private final List getStickiesLocked(String action, IntentFilter filter, 13722 List cur, int userId) { 13723 final ContentResolver resolver = mContext.getContentResolver(); 13724 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13725 if (stickies == null) { 13726 return cur; 13727 } 13728 final ArrayList<Intent> list = stickies.get(action); 13729 if (list == null) { 13730 return cur; 13731 } 13732 int N = list.size(); 13733 for (int i=0; i<N; i++) { 13734 Intent intent = list.get(i); 13735 if (filter.match(resolver, intent, true, TAG) >= 0) { 13736 if (cur == null) { 13737 cur = new ArrayList<Intent>(); 13738 } 13739 cur.add(intent); 13740 } 13741 } 13742 return cur; 13743 } 13744 13745 boolean isPendingBroadcastProcessLocked(int pid) { 13746 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13747 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13748 } 13749 13750 void skipPendingBroadcastLocked(int pid) { 13751 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13752 for (BroadcastQueue queue : mBroadcastQueues) { 13753 queue.skipPendingBroadcastLocked(pid); 13754 } 13755 } 13756 13757 // The app just attached; send any pending broadcasts that it should receive 13758 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13759 boolean didSomething = false; 13760 for (BroadcastQueue queue : mBroadcastQueues) { 13761 didSomething |= queue.sendPendingBroadcastsLocked(app); 13762 } 13763 return didSomething; 13764 } 13765 13766 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13767 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13768 enforceNotIsolatedCaller("registerReceiver"); 13769 int callingUid; 13770 int callingPid; 13771 synchronized(this) { 13772 ProcessRecord callerApp = null; 13773 if (caller != null) { 13774 callerApp = getRecordForAppLocked(caller); 13775 if (callerApp == null) { 13776 throw new SecurityException( 13777 "Unable to find app for caller " + caller 13778 + " (pid=" + Binder.getCallingPid() 13779 + ") when registering receiver " + receiver); 13780 } 13781 if (callerApp.info.uid != Process.SYSTEM_UID && 13782 !callerApp.pkgList.containsKey(callerPackage) && 13783 !"android".equals(callerPackage)) { 13784 throw new SecurityException("Given caller package " + callerPackage 13785 + " is not running in process " + callerApp); 13786 } 13787 callingUid = callerApp.info.uid; 13788 callingPid = callerApp.pid; 13789 } else { 13790 callerPackage = null; 13791 callingUid = Binder.getCallingUid(); 13792 callingPid = Binder.getCallingPid(); 13793 } 13794 13795 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13796 true, true, "registerReceiver", callerPackage); 13797 13798 List allSticky = null; 13799 13800 // Look for any matching sticky broadcasts... 13801 Iterator actions = filter.actionsIterator(); 13802 if (actions != null) { 13803 while (actions.hasNext()) { 13804 String action = (String)actions.next(); 13805 allSticky = getStickiesLocked(action, filter, allSticky, 13806 UserHandle.USER_ALL); 13807 allSticky = getStickiesLocked(action, filter, allSticky, 13808 UserHandle.getUserId(callingUid)); 13809 } 13810 } else { 13811 allSticky = getStickiesLocked(null, filter, allSticky, 13812 UserHandle.USER_ALL); 13813 allSticky = getStickiesLocked(null, filter, allSticky, 13814 UserHandle.getUserId(callingUid)); 13815 } 13816 13817 // The first sticky in the list is returned directly back to 13818 // the client. 13819 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13820 13821 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13822 + ": " + sticky); 13823 13824 if (receiver == null) { 13825 return sticky; 13826 } 13827 13828 ReceiverList rl 13829 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13830 if (rl == null) { 13831 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13832 userId, receiver); 13833 if (rl.app != null) { 13834 rl.app.receivers.add(rl); 13835 } else { 13836 try { 13837 receiver.asBinder().linkToDeath(rl, 0); 13838 } catch (RemoteException e) { 13839 return sticky; 13840 } 13841 rl.linkedToDeath = true; 13842 } 13843 mRegisteredReceivers.put(receiver.asBinder(), rl); 13844 } else if (rl.uid != callingUid) { 13845 throw new IllegalArgumentException( 13846 "Receiver requested to register for uid " + callingUid 13847 + " was previously registered for uid " + rl.uid); 13848 } else if (rl.pid != callingPid) { 13849 throw new IllegalArgumentException( 13850 "Receiver requested to register for pid " + callingPid 13851 + " was previously registered for pid " + rl.pid); 13852 } else if (rl.userId != userId) { 13853 throw new IllegalArgumentException( 13854 "Receiver requested to register for user " + userId 13855 + " was previously registered for user " + rl.userId); 13856 } 13857 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13858 permission, callingUid, userId); 13859 rl.add(bf); 13860 if (!bf.debugCheck()) { 13861 Slog.w(TAG, "==> For Dynamic broadast"); 13862 } 13863 mReceiverResolver.addFilter(bf); 13864 13865 // Enqueue broadcasts for all existing stickies that match 13866 // this filter. 13867 if (allSticky != null) { 13868 ArrayList receivers = new ArrayList(); 13869 receivers.add(bf); 13870 13871 int N = allSticky.size(); 13872 for (int i=0; i<N; i++) { 13873 Intent intent = (Intent)allSticky.get(i); 13874 BroadcastQueue queue = broadcastQueueForIntent(intent); 13875 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13876 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13877 null, null, false, true, true, -1); 13878 queue.enqueueParallelBroadcastLocked(r); 13879 queue.scheduleBroadcastsLocked(); 13880 } 13881 } 13882 13883 return sticky; 13884 } 13885 } 13886 13887 public void unregisterReceiver(IIntentReceiver receiver) { 13888 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13889 13890 final long origId = Binder.clearCallingIdentity(); 13891 try { 13892 boolean doTrim = false; 13893 13894 synchronized(this) { 13895 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13896 if (rl != null) { 13897 if (rl.curBroadcast != null) { 13898 BroadcastRecord r = rl.curBroadcast; 13899 final boolean doNext = finishReceiverLocked( 13900 receiver.asBinder(), r.resultCode, r.resultData, 13901 r.resultExtras, r.resultAbort); 13902 if (doNext) { 13903 doTrim = true; 13904 r.queue.processNextBroadcast(false); 13905 } 13906 } 13907 13908 if (rl.app != null) { 13909 rl.app.receivers.remove(rl); 13910 } 13911 removeReceiverLocked(rl); 13912 if (rl.linkedToDeath) { 13913 rl.linkedToDeath = false; 13914 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13915 } 13916 } 13917 } 13918 13919 // If we actually concluded any broadcasts, we might now be able 13920 // to trim the recipients' apps from our working set 13921 if (doTrim) { 13922 trimApplications(); 13923 return; 13924 } 13925 13926 } finally { 13927 Binder.restoreCallingIdentity(origId); 13928 } 13929 } 13930 13931 void removeReceiverLocked(ReceiverList rl) { 13932 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13933 int N = rl.size(); 13934 for (int i=0; i<N; i++) { 13935 mReceiverResolver.removeFilter(rl.get(i)); 13936 } 13937 } 13938 13939 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13940 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13941 ProcessRecord r = mLruProcesses.get(i); 13942 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13943 try { 13944 r.thread.dispatchPackageBroadcast(cmd, packages); 13945 } catch (RemoteException ex) { 13946 } 13947 } 13948 } 13949 } 13950 13951 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13952 int[] users) { 13953 List<ResolveInfo> receivers = null; 13954 try { 13955 HashSet<ComponentName> singleUserReceivers = null; 13956 boolean scannedFirstReceivers = false; 13957 for (int user : users) { 13958 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13959 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13960 if (user != 0 && newReceivers != null) { 13961 // If this is not the primary user, we need to check for 13962 // any receivers that should be filtered out. 13963 for (int i=0; i<newReceivers.size(); i++) { 13964 ResolveInfo ri = newReceivers.get(i); 13965 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13966 newReceivers.remove(i); 13967 i--; 13968 } 13969 } 13970 } 13971 if (newReceivers != null && newReceivers.size() == 0) { 13972 newReceivers = null; 13973 } 13974 if (receivers == null) { 13975 receivers = newReceivers; 13976 } else if (newReceivers != null) { 13977 // We need to concatenate the additional receivers 13978 // found with what we have do far. This would be easy, 13979 // but we also need to de-dup any receivers that are 13980 // singleUser. 13981 if (!scannedFirstReceivers) { 13982 // Collect any single user receivers we had already retrieved. 13983 scannedFirstReceivers = true; 13984 for (int i=0; i<receivers.size(); i++) { 13985 ResolveInfo ri = receivers.get(i); 13986 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13987 ComponentName cn = new ComponentName( 13988 ri.activityInfo.packageName, ri.activityInfo.name); 13989 if (singleUserReceivers == null) { 13990 singleUserReceivers = new HashSet<ComponentName>(); 13991 } 13992 singleUserReceivers.add(cn); 13993 } 13994 } 13995 } 13996 // Add the new results to the existing results, tracking 13997 // and de-dupping single user receivers. 13998 for (int i=0; i<newReceivers.size(); i++) { 13999 ResolveInfo ri = newReceivers.get(i); 14000 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14001 ComponentName cn = new ComponentName( 14002 ri.activityInfo.packageName, ri.activityInfo.name); 14003 if (singleUserReceivers == null) { 14004 singleUserReceivers = new HashSet<ComponentName>(); 14005 } 14006 if (!singleUserReceivers.contains(cn)) { 14007 singleUserReceivers.add(cn); 14008 receivers.add(ri); 14009 } 14010 } else { 14011 receivers.add(ri); 14012 } 14013 } 14014 } 14015 } 14016 } catch (RemoteException ex) { 14017 // pm is in same process, this will never happen. 14018 } 14019 return receivers; 14020 } 14021 14022 private final int broadcastIntentLocked(ProcessRecord callerApp, 14023 String callerPackage, Intent intent, String resolvedType, 14024 IIntentReceiver resultTo, int resultCode, String resultData, 14025 Bundle map, String requiredPermission, int appOp, 14026 boolean ordered, boolean sticky, int callingPid, int callingUid, 14027 int userId) { 14028 intent = new Intent(intent); 14029 14030 // By default broadcasts do not go to stopped apps. 14031 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 14032 14033 if (DEBUG_BROADCAST_LIGHT) Slog.v( 14034 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 14035 + " ordered=" + ordered + " userid=" + userId); 14036 if ((resultTo != null) && !ordered) { 14037 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 14038 } 14039 14040 userId = handleIncomingUser(callingPid, callingUid, userId, 14041 true, false, "broadcast", callerPackage); 14042 14043 // Make sure that the user who is receiving this broadcast is started. 14044 // If not, we will just skip it. 14045 14046 14047 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 14048 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 14049 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 14050 Slog.w(TAG, "Skipping broadcast of " + intent 14051 + ": user " + userId + " is stopped"); 14052 return ActivityManager.BROADCAST_SUCCESS; 14053 } 14054 } 14055 14056 /* 14057 * Prevent non-system code (defined here to be non-persistent 14058 * processes) from sending protected broadcasts. 14059 */ 14060 int callingAppId = UserHandle.getAppId(callingUid); 14061 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14062 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14063 || callingAppId == Process.NFC_UID || callingUid == 0) { 14064 // Always okay. 14065 } else if (callerApp == null || !callerApp.persistent) { 14066 try { 14067 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14068 intent.getAction())) { 14069 String msg = "Permission Denial: not allowed to send broadcast " 14070 + intent.getAction() + " from pid=" 14071 + callingPid + ", uid=" + callingUid; 14072 Slog.w(TAG, msg); 14073 throw new SecurityException(msg); 14074 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14075 // Special case for compatibility: we don't want apps to send this, 14076 // but historically it has not been protected and apps may be using it 14077 // to poke their own app widget. So, instead of making it protected, 14078 // just limit it to the caller. 14079 if (callerApp == null) { 14080 String msg = "Permission Denial: not allowed to send broadcast " 14081 + intent.getAction() + " from unknown caller."; 14082 Slog.w(TAG, msg); 14083 throw new SecurityException(msg); 14084 } else if (intent.getComponent() != null) { 14085 // They are good enough to send to an explicit component... verify 14086 // it is being sent to the calling app. 14087 if (!intent.getComponent().getPackageName().equals( 14088 callerApp.info.packageName)) { 14089 String msg = "Permission Denial: not allowed to send broadcast " 14090 + intent.getAction() + " to " 14091 + intent.getComponent().getPackageName() + " from " 14092 + callerApp.info.packageName; 14093 Slog.w(TAG, msg); 14094 throw new SecurityException(msg); 14095 } 14096 } else { 14097 // Limit broadcast to their own package. 14098 intent.setPackage(callerApp.info.packageName); 14099 } 14100 } 14101 } catch (RemoteException e) { 14102 Slog.w(TAG, "Remote exception", e); 14103 return ActivityManager.BROADCAST_SUCCESS; 14104 } 14105 } 14106 14107 // Handle special intents: if this broadcast is from the package 14108 // manager about a package being removed, we need to remove all of 14109 // its activities from the history stack. 14110 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14111 intent.getAction()); 14112 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14113 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14114 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14115 || uidRemoved) { 14116 if (checkComponentPermission( 14117 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14118 callingPid, callingUid, -1, true) 14119 == PackageManager.PERMISSION_GRANTED) { 14120 if (uidRemoved) { 14121 final Bundle intentExtras = intent.getExtras(); 14122 final int uid = intentExtras != null 14123 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14124 if (uid >= 0) { 14125 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14126 synchronized (bs) { 14127 bs.removeUidStatsLocked(uid); 14128 } 14129 mAppOpsService.uidRemoved(uid); 14130 } 14131 } else { 14132 // If resources are unavailable just force stop all 14133 // those packages and flush the attribute cache as well. 14134 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14135 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14136 if (list != null && (list.length > 0)) { 14137 for (String pkg : list) { 14138 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14139 "storage unmount"); 14140 } 14141 sendPackageBroadcastLocked( 14142 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14143 } 14144 } else { 14145 Uri data = intent.getData(); 14146 String ssp; 14147 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14148 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14149 intent.getAction()); 14150 boolean fullUninstall = removed && 14151 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14152 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14153 forceStopPackageLocked(ssp, UserHandle.getAppId( 14154 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14155 false, fullUninstall, userId, 14156 removed ? "pkg removed" : "pkg changed"); 14157 } 14158 if (removed) { 14159 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14160 new String[] {ssp}, userId); 14161 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14162 mAppOpsService.packageRemoved( 14163 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14164 14165 // Remove all permissions granted from/to this package 14166 removeUriPermissionsForPackageLocked(ssp, userId, true); 14167 } 14168 } 14169 } 14170 } 14171 } 14172 } else { 14173 String msg = "Permission Denial: " + intent.getAction() 14174 + " broadcast from " + callerPackage + " (pid=" + callingPid 14175 + ", uid=" + callingUid + ")" 14176 + " requires " 14177 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14178 Slog.w(TAG, msg); 14179 throw new SecurityException(msg); 14180 } 14181 14182 // Special case for adding a package: by default turn on compatibility 14183 // mode. 14184 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14185 Uri data = intent.getData(); 14186 String ssp; 14187 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14188 mCompatModePackages.handlePackageAddedLocked(ssp, 14189 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14190 } 14191 } 14192 14193 /* 14194 * If this is the time zone changed action, queue up a message that will reset the timezone 14195 * of all currently running processes. This message will get queued up before the broadcast 14196 * happens. 14197 */ 14198 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14199 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14200 } 14201 14202 /* 14203 * If the user set the time, let all running processes know. 14204 */ 14205 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14206 final int is24Hour = intent.getBooleanExtra( 14207 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14208 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14209 } 14210 14211 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14212 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14213 } 14214 14215 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14216 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14217 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14218 } 14219 14220 // Add to the sticky list if requested. 14221 if (sticky) { 14222 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14223 callingPid, callingUid) 14224 != PackageManager.PERMISSION_GRANTED) { 14225 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14226 + callingPid + ", uid=" + callingUid 14227 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14228 Slog.w(TAG, msg); 14229 throw new SecurityException(msg); 14230 } 14231 if (requiredPermission != null) { 14232 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14233 + " and enforce permission " + requiredPermission); 14234 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14235 } 14236 if (intent.getComponent() != null) { 14237 throw new SecurityException( 14238 "Sticky broadcasts can't target a specific component"); 14239 } 14240 // We use userId directly here, since the "all" target is maintained 14241 // as a separate set of sticky broadcasts. 14242 if (userId != UserHandle.USER_ALL) { 14243 // But first, if this is not a broadcast to all users, then 14244 // make sure it doesn't conflict with an existing broadcast to 14245 // all users. 14246 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14247 UserHandle.USER_ALL); 14248 if (stickies != null) { 14249 ArrayList<Intent> list = stickies.get(intent.getAction()); 14250 if (list != null) { 14251 int N = list.size(); 14252 int i; 14253 for (i=0; i<N; i++) { 14254 if (intent.filterEquals(list.get(i))) { 14255 throw new IllegalArgumentException( 14256 "Sticky broadcast " + intent + " for user " 14257 + userId + " conflicts with existing global broadcast"); 14258 } 14259 } 14260 } 14261 } 14262 } 14263 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14264 if (stickies == null) { 14265 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14266 mStickyBroadcasts.put(userId, stickies); 14267 } 14268 ArrayList<Intent> list = stickies.get(intent.getAction()); 14269 if (list == null) { 14270 list = new ArrayList<Intent>(); 14271 stickies.put(intent.getAction(), list); 14272 } 14273 int N = list.size(); 14274 int i; 14275 for (i=0; i<N; i++) { 14276 if (intent.filterEquals(list.get(i))) { 14277 // This sticky already exists, replace it. 14278 list.set(i, new Intent(intent)); 14279 break; 14280 } 14281 } 14282 if (i >= N) { 14283 list.add(new Intent(intent)); 14284 } 14285 } 14286 14287 int[] users; 14288 if (userId == UserHandle.USER_ALL) { 14289 // Caller wants broadcast to go to all started users. 14290 users = mStartedUserArray; 14291 } else { 14292 // Caller wants broadcast to go to one specific user. 14293 users = new int[] {userId}; 14294 } 14295 14296 // Figure out who all will receive this broadcast. 14297 List receivers = null; 14298 List<BroadcastFilter> registeredReceivers = null; 14299 // Need to resolve the intent to interested receivers... 14300 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14301 == 0) { 14302 receivers = collectReceiverComponents(intent, resolvedType, users); 14303 } 14304 if (intent.getComponent() == null) { 14305 registeredReceivers = mReceiverResolver.queryIntent(intent, 14306 resolvedType, false, userId); 14307 } 14308 14309 final boolean replacePending = 14310 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14311 14312 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14313 + " replacePending=" + replacePending); 14314 14315 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14316 if (!ordered && NR > 0) { 14317 // If we are not serializing this broadcast, then send the 14318 // registered receivers separately so they don't wait for the 14319 // components to be launched. 14320 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14321 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14322 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14323 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14324 ordered, sticky, false, userId); 14325 if (DEBUG_BROADCAST) Slog.v( 14326 TAG, "Enqueueing parallel broadcast " + r); 14327 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14328 if (!replaced) { 14329 queue.enqueueParallelBroadcastLocked(r); 14330 queue.scheduleBroadcastsLocked(); 14331 } 14332 registeredReceivers = null; 14333 NR = 0; 14334 } 14335 14336 // Merge into one list. 14337 int ir = 0; 14338 if (receivers != null) { 14339 // A special case for PACKAGE_ADDED: do not allow the package 14340 // being added to see this broadcast. This prevents them from 14341 // using this as a back door to get run as soon as they are 14342 // installed. Maybe in the future we want to have a special install 14343 // broadcast or such for apps, but we'd like to deliberately make 14344 // this decision. 14345 String skipPackages[] = null; 14346 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14347 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14348 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14349 Uri data = intent.getData(); 14350 if (data != null) { 14351 String pkgName = data.getSchemeSpecificPart(); 14352 if (pkgName != null) { 14353 skipPackages = new String[] { pkgName }; 14354 } 14355 } 14356 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14357 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14358 } 14359 if (skipPackages != null && (skipPackages.length > 0)) { 14360 for (String skipPackage : skipPackages) { 14361 if (skipPackage != null) { 14362 int NT = receivers.size(); 14363 for (int it=0; it<NT; it++) { 14364 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14365 if (curt.activityInfo.packageName.equals(skipPackage)) { 14366 receivers.remove(it); 14367 it--; 14368 NT--; 14369 } 14370 } 14371 } 14372 } 14373 } 14374 14375 int NT = receivers != null ? receivers.size() : 0; 14376 int it = 0; 14377 ResolveInfo curt = null; 14378 BroadcastFilter curr = null; 14379 while (it < NT && ir < NR) { 14380 if (curt == null) { 14381 curt = (ResolveInfo)receivers.get(it); 14382 } 14383 if (curr == null) { 14384 curr = registeredReceivers.get(ir); 14385 } 14386 if (curr.getPriority() >= curt.priority) { 14387 // Insert this broadcast record into the final list. 14388 receivers.add(it, curr); 14389 ir++; 14390 curr = null; 14391 it++; 14392 NT++; 14393 } else { 14394 // Skip to the next ResolveInfo in the final list. 14395 it++; 14396 curt = null; 14397 } 14398 } 14399 } 14400 while (ir < NR) { 14401 if (receivers == null) { 14402 receivers = new ArrayList(); 14403 } 14404 receivers.add(registeredReceivers.get(ir)); 14405 ir++; 14406 } 14407 14408 if ((receivers != null && receivers.size() > 0) 14409 || resultTo != null) { 14410 BroadcastQueue queue = broadcastQueueForIntent(intent); 14411 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14412 callerPackage, callingPid, callingUid, resolvedType, 14413 requiredPermission, appOp, receivers, resultTo, resultCode, 14414 resultData, map, ordered, sticky, false, userId); 14415 if (DEBUG_BROADCAST) Slog.v( 14416 TAG, "Enqueueing ordered broadcast " + r 14417 + ": prev had " + queue.mOrderedBroadcasts.size()); 14418 if (DEBUG_BROADCAST) { 14419 int seq = r.intent.getIntExtra("seq", -1); 14420 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14421 } 14422 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14423 if (!replaced) { 14424 queue.enqueueOrderedBroadcastLocked(r); 14425 queue.scheduleBroadcastsLocked(); 14426 } 14427 } 14428 14429 return ActivityManager.BROADCAST_SUCCESS; 14430 } 14431 14432 final Intent verifyBroadcastLocked(Intent intent) { 14433 // Refuse possible leaked file descriptors 14434 if (intent != null && intent.hasFileDescriptors() == true) { 14435 throw new IllegalArgumentException("File descriptors passed in Intent"); 14436 } 14437 14438 int flags = intent.getFlags(); 14439 14440 if (!mProcessesReady) { 14441 // if the caller really truly claims to know what they're doing, go 14442 // ahead and allow the broadcast without launching any receivers 14443 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14444 intent = new Intent(intent); 14445 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14446 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14447 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14448 + " before boot completion"); 14449 throw new IllegalStateException("Cannot broadcast before boot completed"); 14450 } 14451 } 14452 14453 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14454 throw new IllegalArgumentException( 14455 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14456 } 14457 14458 return intent; 14459 } 14460 14461 public final int broadcastIntent(IApplicationThread caller, 14462 Intent intent, String resolvedType, IIntentReceiver resultTo, 14463 int resultCode, String resultData, Bundle map, 14464 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14465 enforceNotIsolatedCaller("broadcastIntent"); 14466 synchronized(this) { 14467 intent = verifyBroadcastLocked(intent); 14468 14469 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14470 final int callingPid = Binder.getCallingPid(); 14471 final int callingUid = Binder.getCallingUid(); 14472 final long origId = Binder.clearCallingIdentity(); 14473 int res = broadcastIntentLocked(callerApp, 14474 callerApp != null ? callerApp.info.packageName : null, 14475 intent, resolvedType, resultTo, 14476 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14477 callingPid, callingUid, userId); 14478 Binder.restoreCallingIdentity(origId); 14479 return res; 14480 } 14481 } 14482 14483 int broadcastIntentInPackage(String packageName, int uid, 14484 Intent intent, String resolvedType, IIntentReceiver resultTo, 14485 int resultCode, String resultData, Bundle map, 14486 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14487 synchronized(this) { 14488 intent = verifyBroadcastLocked(intent); 14489 14490 final long origId = Binder.clearCallingIdentity(); 14491 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14492 resultTo, resultCode, resultData, map, requiredPermission, 14493 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14494 Binder.restoreCallingIdentity(origId); 14495 return res; 14496 } 14497 } 14498 14499 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14500 // Refuse possible leaked file descriptors 14501 if (intent != null && intent.hasFileDescriptors() == true) { 14502 throw new IllegalArgumentException("File descriptors passed in Intent"); 14503 } 14504 14505 userId = handleIncomingUser(Binder.getCallingPid(), 14506 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14507 14508 synchronized(this) { 14509 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14510 != PackageManager.PERMISSION_GRANTED) { 14511 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14512 + Binder.getCallingPid() 14513 + ", uid=" + Binder.getCallingUid() 14514 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14515 Slog.w(TAG, msg); 14516 throw new SecurityException(msg); 14517 } 14518 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14519 if (stickies != null) { 14520 ArrayList<Intent> list = stickies.get(intent.getAction()); 14521 if (list != null) { 14522 int N = list.size(); 14523 int i; 14524 for (i=0; i<N; i++) { 14525 if (intent.filterEquals(list.get(i))) { 14526 list.remove(i); 14527 break; 14528 } 14529 } 14530 if (list.size() <= 0) { 14531 stickies.remove(intent.getAction()); 14532 } 14533 } 14534 if (stickies.size() <= 0) { 14535 mStickyBroadcasts.remove(userId); 14536 } 14537 } 14538 } 14539 } 14540 14541 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14542 String resultData, Bundle resultExtras, boolean resultAbort) { 14543 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14544 if (r == null) { 14545 Slog.w(TAG, "finishReceiver called but not found on queue"); 14546 return false; 14547 } 14548 14549 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14550 } 14551 14552 void backgroundServicesFinishedLocked(int userId) { 14553 for (BroadcastQueue queue : mBroadcastQueues) { 14554 queue.backgroundServicesFinishedLocked(userId); 14555 } 14556 } 14557 14558 public void finishReceiver(IBinder who, int resultCode, String resultData, 14559 Bundle resultExtras, boolean resultAbort) { 14560 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14561 14562 // Refuse possible leaked file descriptors 14563 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14564 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14565 } 14566 14567 final long origId = Binder.clearCallingIdentity(); 14568 try { 14569 boolean doNext = false; 14570 BroadcastRecord r; 14571 14572 synchronized(this) { 14573 r = broadcastRecordForReceiverLocked(who); 14574 if (r != null) { 14575 doNext = r.queue.finishReceiverLocked(r, resultCode, 14576 resultData, resultExtras, resultAbort, true); 14577 } 14578 } 14579 14580 if (doNext) { 14581 r.queue.processNextBroadcast(false); 14582 } 14583 trimApplications(); 14584 } finally { 14585 Binder.restoreCallingIdentity(origId); 14586 } 14587 } 14588 14589 // ========================================================= 14590 // INSTRUMENTATION 14591 // ========================================================= 14592 14593 public boolean startInstrumentation(ComponentName className, 14594 String profileFile, int flags, Bundle arguments, 14595 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14596 int userId, String abiOverride) { 14597 enforceNotIsolatedCaller("startInstrumentation"); 14598 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14599 userId, false, true, "startInstrumentation", null); 14600 // Refuse possible leaked file descriptors 14601 if (arguments != null && arguments.hasFileDescriptors()) { 14602 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14603 } 14604 14605 synchronized(this) { 14606 InstrumentationInfo ii = null; 14607 ApplicationInfo ai = null; 14608 try { 14609 ii = mContext.getPackageManager().getInstrumentationInfo( 14610 className, STOCK_PM_FLAGS); 14611 ai = AppGlobals.getPackageManager().getApplicationInfo( 14612 ii.targetPackage, STOCK_PM_FLAGS, userId); 14613 } catch (PackageManager.NameNotFoundException e) { 14614 } catch (RemoteException e) { 14615 } 14616 if (ii == null) { 14617 reportStartInstrumentationFailure(watcher, className, 14618 "Unable to find instrumentation info for: " + className); 14619 return false; 14620 } 14621 if (ai == null) { 14622 reportStartInstrumentationFailure(watcher, className, 14623 "Unable to find instrumentation target package: " + ii.targetPackage); 14624 return false; 14625 } 14626 14627 int match = mContext.getPackageManager().checkSignatures( 14628 ii.targetPackage, ii.packageName); 14629 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14630 String msg = "Permission Denial: starting instrumentation " 14631 + className + " from pid=" 14632 + Binder.getCallingPid() 14633 + ", uid=" + Binder.getCallingPid() 14634 + " not allowed because package " + ii.packageName 14635 + " does not have a signature matching the target " 14636 + ii.targetPackage; 14637 reportStartInstrumentationFailure(watcher, className, msg); 14638 throw new SecurityException(msg); 14639 } 14640 14641 final long origId = Binder.clearCallingIdentity(); 14642 // Instrumentation can kill and relaunch even persistent processes 14643 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14644 "start instr"); 14645 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14646 app.instrumentationClass = className; 14647 app.instrumentationInfo = ai; 14648 app.instrumentationProfileFile = profileFile; 14649 app.instrumentationArguments = arguments; 14650 app.instrumentationWatcher = watcher; 14651 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14652 app.instrumentationResultClass = className; 14653 Binder.restoreCallingIdentity(origId); 14654 } 14655 14656 return true; 14657 } 14658 14659 /** 14660 * Report errors that occur while attempting to start Instrumentation. Always writes the 14661 * error to the logs, but if somebody is watching, send the report there too. This enables 14662 * the "am" command to report errors with more information. 14663 * 14664 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14665 * @param cn The component name of the instrumentation. 14666 * @param report The error report. 14667 */ 14668 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14669 ComponentName cn, String report) { 14670 Slog.w(TAG, report); 14671 try { 14672 if (watcher != null) { 14673 Bundle results = new Bundle(); 14674 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14675 results.putString("Error", report); 14676 watcher.instrumentationStatus(cn, -1, results); 14677 } 14678 } catch (RemoteException e) { 14679 Slog.w(TAG, e); 14680 } 14681 } 14682 14683 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14684 if (app.instrumentationWatcher != null) { 14685 try { 14686 // NOTE: IInstrumentationWatcher *must* be oneway here 14687 app.instrumentationWatcher.instrumentationFinished( 14688 app.instrumentationClass, 14689 resultCode, 14690 results); 14691 } catch (RemoteException e) { 14692 } 14693 } 14694 if (app.instrumentationUiAutomationConnection != null) { 14695 try { 14696 app.instrumentationUiAutomationConnection.shutdown(); 14697 } catch (RemoteException re) { 14698 /* ignore */ 14699 } 14700 // Only a UiAutomation can set this flag and now that 14701 // it is finished we make sure it is reset to its default. 14702 mUserIsMonkey = false; 14703 } 14704 app.instrumentationWatcher = null; 14705 app.instrumentationUiAutomationConnection = null; 14706 app.instrumentationClass = null; 14707 app.instrumentationInfo = null; 14708 app.instrumentationProfileFile = null; 14709 app.instrumentationArguments = null; 14710 14711 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14712 "finished inst"); 14713 } 14714 14715 public void finishInstrumentation(IApplicationThread target, 14716 int resultCode, Bundle results) { 14717 int userId = UserHandle.getCallingUserId(); 14718 // Refuse possible leaked file descriptors 14719 if (results != null && results.hasFileDescriptors()) { 14720 throw new IllegalArgumentException("File descriptors passed in Intent"); 14721 } 14722 14723 synchronized(this) { 14724 ProcessRecord app = getRecordForAppLocked(target); 14725 if (app == null) { 14726 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14727 return; 14728 } 14729 final long origId = Binder.clearCallingIdentity(); 14730 finishInstrumentationLocked(app, resultCode, results); 14731 Binder.restoreCallingIdentity(origId); 14732 } 14733 } 14734 14735 // ========================================================= 14736 // CONFIGURATION 14737 // ========================================================= 14738 14739 public ConfigurationInfo getDeviceConfigurationInfo() { 14740 ConfigurationInfo config = new ConfigurationInfo(); 14741 synchronized (this) { 14742 config.reqTouchScreen = mConfiguration.touchscreen; 14743 config.reqKeyboardType = mConfiguration.keyboard; 14744 config.reqNavigation = mConfiguration.navigation; 14745 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14746 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14747 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14748 } 14749 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14750 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14751 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14752 } 14753 config.reqGlEsVersion = GL_ES_VERSION; 14754 } 14755 return config; 14756 } 14757 14758 ActivityStack getFocusedStack() { 14759 return mStackSupervisor.getFocusedStack(); 14760 } 14761 14762 public Configuration getConfiguration() { 14763 Configuration ci; 14764 synchronized(this) { 14765 ci = new Configuration(mConfiguration); 14766 } 14767 return ci; 14768 } 14769 14770 public void updatePersistentConfiguration(Configuration values) { 14771 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14772 "updateConfiguration()"); 14773 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14774 "updateConfiguration()"); 14775 if (values == null) { 14776 throw new NullPointerException("Configuration must not be null"); 14777 } 14778 14779 synchronized(this) { 14780 final long origId = Binder.clearCallingIdentity(); 14781 updateConfigurationLocked(values, null, true, false); 14782 Binder.restoreCallingIdentity(origId); 14783 } 14784 } 14785 14786 public void updateConfiguration(Configuration values) { 14787 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14788 "updateConfiguration()"); 14789 14790 synchronized(this) { 14791 if (values == null && mWindowManager != null) { 14792 // sentinel: fetch the current configuration from the window manager 14793 values = mWindowManager.computeNewConfiguration(); 14794 } 14795 14796 if (mWindowManager != null) { 14797 mProcessList.applyDisplaySize(mWindowManager); 14798 } 14799 14800 final long origId = Binder.clearCallingIdentity(); 14801 if (values != null) { 14802 Settings.System.clearConfiguration(values); 14803 } 14804 updateConfigurationLocked(values, null, false, false); 14805 Binder.restoreCallingIdentity(origId); 14806 } 14807 } 14808 14809 /** 14810 * Do either or both things: (1) change the current configuration, and (2) 14811 * make sure the given activity is running with the (now) current 14812 * configuration. Returns true if the activity has been left running, or 14813 * false if <var>starting</var> is being destroyed to match the new 14814 * configuration. 14815 * @param persistent TODO 14816 */ 14817 boolean updateConfigurationLocked(Configuration values, 14818 ActivityRecord starting, boolean persistent, boolean initLocale) { 14819 int changes = 0; 14820 14821 if (values != null) { 14822 Configuration newConfig = new Configuration(mConfiguration); 14823 changes = newConfig.updateFrom(values); 14824 if (changes != 0) { 14825 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14826 Slog.i(TAG, "Updating configuration to: " + values); 14827 } 14828 14829 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14830 14831 if (values.locale != null && !initLocale) { 14832 saveLocaleLocked(values.locale, 14833 !values.locale.equals(mConfiguration.locale), 14834 values.userSetLocale); 14835 } 14836 14837 mConfigurationSeq++; 14838 if (mConfigurationSeq <= 0) { 14839 mConfigurationSeq = 1; 14840 } 14841 newConfig.seq = mConfigurationSeq; 14842 mConfiguration = newConfig; 14843 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14844 mUsageStatsService.noteStartConfig(newConfig); 14845 14846 final Configuration configCopy = new Configuration(mConfiguration); 14847 14848 // TODO: If our config changes, should we auto dismiss any currently 14849 // showing dialogs? 14850 mShowDialogs = shouldShowDialogs(newConfig); 14851 14852 AttributeCache ac = AttributeCache.instance(); 14853 if (ac != null) { 14854 ac.updateConfiguration(configCopy); 14855 } 14856 14857 // Make sure all resources in our process are updated 14858 // right now, so that anyone who is going to retrieve 14859 // resource values after we return will be sure to get 14860 // the new ones. This is especially important during 14861 // boot, where the first config change needs to guarantee 14862 // all resources have that config before following boot 14863 // code is executed. 14864 mSystemThread.applyConfigurationToResources(configCopy); 14865 14866 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14867 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14868 msg.obj = new Configuration(configCopy); 14869 mHandler.sendMessage(msg); 14870 } 14871 14872 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14873 ProcessRecord app = mLruProcesses.get(i); 14874 try { 14875 if (app.thread != null) { 14876 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14877 + app.processName + " new config " + mConfiguration); 14878 app.thread.scheduleConfigurationChanged(configCopy); 14879 } 14880 } catch (Exception e) { 14881 } 14882 } 14883 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14884 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14885 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14886 | Intent.FLAG_RECEIVER_FOREGROUND); 14887 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14888 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14889 Process.SYSTEM_UID, UserHandle.USER_ALL); 14890 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14891 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14892 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14893 broadcastIntentLocked(null, null, intent, 14894 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14895 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14896 } 14897 } 14898 } 14899 14900 boolean kept = true; 14901 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14902 // mainStack is null during startup. 14903 if (mainStack != null) { 14904 if (changes != 0 && starting == null) { 14905 // If the configuration changed, and the caller is not already 14906 // in the process of starting an activity, then find the top 14907 // activity to check if its configuration needs to change. 14908 starting = mainStack.topRunningActivityLocked(null); 14909 } 14910 14911 if (starting != null) { 14912 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14913 // And we need to make sure at this point that all other activities 14914 // are made visible with the correct configuration. 14915 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14916 } 14917 } 14918 14919 if (values != null && mWindowManager != null) { 14920 mWindowManager.setNewConfiguration(mConfiguration); 14921 } 14922 14923 return kept; 14924 } 14925 14926 /** 14927 * Decide based on the configuration whether we should shouw the ANR, 14928 * crash, etc dialogs. The idea is that if there is no affordnace to 14929 * press the on-screen buttons, we shouldn't show the dialog. 14930 * 14931 * A thought: SystemUI might also want to get told about this, the Power 14932 * dialog / global actions also might want different behaviors. 14933 */ 14934 private static final boolean shouldShowDialogs(Configuration config) { 14935 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14936 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14937 } 14938 14939 /** 14940 * Save the locale. You must be inside a synchronized (this) block. 14941 */ 14942 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14943 if(isDiff) { 14944 SystemProperties.set("user.language", l.getLanguage()); 14945 SystemProperties.set("user.region", l.getCountry()); 14946 } 14947 14948 if(isPersist) { 14949 SystemProperties.set("persist.sys.language", l.getLanguage()); 14950 SystemProperties.set("persist.sys.country", l.getCountry()); 14951 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14952 } 14953 } 14954 14955 @Override 14956 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14957 ActivityRecord srec = ActivityRecord.forToken(token); 14958 return srec != null && srec.task.affinity != null && 14959 srec.task.affinity.equals(destAffinity); 14960 } 14961 14962 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14963 Intent resultData) { 14964 14965 synchronized (this) { 14966 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14967 if (stack != null) { 14968 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14969 } 14970 return false; 14971 } 14972 } 14973 14974 public int getLaunchedFromUid(IBinder activityToken) { 14975 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14976 if (srec == null) { 14977 return -1; 14978 } 14979 return srec.launchedFromUid; 14980 } 14981 14982 public String getLaunchedFromPackage(IBinder activityToken) { 14983 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14984 if (srec == null) { 14985 return null; 14986 } 14987 return srec.launchedFromPackage; 14988 } 14989 14990 // ========================================================= 14991 // LIFETIME MANAGEMENT 14992 // ========================================================= 14993 14994 // Returns which broadcast queue the app is the current [or imminent] receiver 14995 // on, or 'null' if the app is not an active broadcast recipient. 14996 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14997 BroadcastRecord r = app.curReceiver; 14998 if (r != null) { 14999 return r.queue; 15000 } 15001 15002 // It's not the current receiver, but it might be starting up to become one 15003 synchronized (this) { 15004 for (BroadcastQueue queue : mBroadcastQueues) { 15005 r = queue.mPendingBroadcast; 15006 if (r != null && r.curApp == app) { 15007 // found it; report which queue it's in 15008 return queue; 15009 } 15010 } 15011 } 15012 15013 return null; 15014 } 15015 15016 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 15017 boolean doingAll, long now) { 15018 if (mAdjSeq == app.adjSeq) { 15019 // This adjustment has already been computed. 15020 return app.curRawAdj; 15021 } 15022 15023 if (app.thread == null) { 15024 app.adjSeq = mAdjSeq; 15025 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15026 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15027 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 15028 } 15029 15030 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 15031 app.adjSource = null; 15032 app.adjTarget = null; 15033 app.empty = false; 15034 app.cached = false; 15035 15036 final int activitiesSize = app.activities.size(); 15037 15038 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 15039 // The max adjustment doesn't allow this app to be anything 15040 // below foreground, so it is not worth doing work for it. 15041 app.adjType = "fixed"; 15042 app.adjSeq = mAdjSeq; 15043 app.curRawAdj = app.maxAdj; 15044 app.foregroundActivities = false; 15045 app.keeping = true; 15046 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 15047 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 15048 // System processes can do UI, and when they do we want to have 15049 // them trim their memory after the user leaves the UI. To 15050 // facilitate this, here we need to determine whether or not it 15051 // is currently showing UI. 15052 app.systemNoUi = true; 15053 if (app == TOP_APP) { 15054 app.systemNoUi = false; 15055 } else if (activitiesSize > 0) { 15056 for (int j = 0; j < activitiesSize; j++) { 15057 final ActivityRecord r = app.activities.get(j); 15058 if (r.visible) { 15059 app.systemNoUi = false; 15060 } 15061 } 15062 } 15063 if (!app.systemNoUi) { 15064 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15065 } 15066 return (app.curAdj=app.maxAdj); 15067 } 15068 15069 app.keeping = false; 15070 app.systemNoUi = false; 15071 15072 // Determine the importance of the process, starting with most 15073 // important to least, and assign an appropriate OOM adjustment. 15074 int adj; 15075 int schedGroup; 15076 int procState; 15077 boolean foregroundActivities = false; 15078 BroadcastQueue queue; 15079 if (app == TOP_APP) { 15080 // The last app on the list is the foreground app. 15081 adj = ProcessList.FOREGROUND_APP_ADJ; 15082 schedGroup = Process.THREAD_GROUP_DEFAULT; 15083 app.adjType = "top-activity"; 15084 foregroundActivities = true; 15085 procState = ActivityManager.PROCESS_STATE_TOP; 15086 } else if (app.instrumentationClass != null) { 15087 // Don't want to kill running instrumentation. 15088 adj = ProcessList.FOREGROUND_APP_ADJ; 15089 schedGroup = Process.THREAD_GROUP_DEFAULT; 15090 app.adjType = "instrumentation"; 15091 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15092 } else if ((queue = isReceivingBroadcast(app)) != null) { 15093 // An app that is currently receiving a broadcast also 15094 // counts as being in the foreground for OOM killer purposes. 15095 // It's placed in a sched group based on the nature of the 15096 // broadcast as reflected by which queue it's active in. 15097 adj = ProcessList.FOREGROUND_APP_ADJ; 15098 schedGroup = (queue == mFgBroadcastQueue) 15099 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15100 app.adjType = "broadcast"; 15101 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15102 } else if (app.executingServices.size() > 0) { 15103 // An app that is currently executing a service callback also 15104 // counts as being in the foreground. 15105 adj = ProcessList.FOREGROUND_APP_ADJ; 15106 schedGroup = app.execServicesFg ? 15107 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15108 app.adjType = "exec-service"; 15109 procState = ActivityManager.PROCESS_STATE_SERVICE; 15110 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15111 } else { 15112 // As far as we know the process is empty. We may change our mind later. 15113 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15114 // At this point we don't actually know the adjustment. Use the cached adj 15115 // value that the caller wants us to. 15116 adj = cachedAdj; 15117 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15118 app.cached = true; 15119 app.empty = true; 15120 app.adjType = "cch-empty"; 15121 } 15122 15123 // Examine all activities if not already foreground. 15124 if (!foregroundActivities && activitiesSize > 0) { 15125 for (int j = 0; j < activitiesSize; j++) { 15126 final ActivityRecord r = app.activities.get(j); 15127 if (r.app != app) { 15128 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15129 + app + "?!?"); 15130 continue; 15131 } 15132 if (r.visible) { 15133 // App has a visible activity; only upgrade adjustment. 15134 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15135 adj = ProcessList.VISIBLE_APP_ADJ; 15136 app.adjType = "visible"; 15137 } 15138 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15139 procState = ActivityManager.PROCESS_STATE_TOP; 15140 } 15141 schedGroup = Process.THREAD_GROUP_DEFAULT; 15142 app.cached = false; 15143 app.empty = false; 15144 foregroundActivities = true; 15145 break; 15146 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15147 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15148 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15149 app.adjType = "pausing"; 15150 } 15151 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15152 procState = ActivityManager.PROCESS_STATE_TOP; 15153 } 15154 schedGroup = Process.THREAD_GROUP_DEFAULT; 15155 app.cached = false; 15156 app.empty = false; 15157 foregroundActivities = true; 15158 } else if (r.state == ActivityState.STOPPING) { 15159 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15160 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15161 app.adjType = "stopping"; 15162 } 15163 // For the process state, we will at this point consider the 15164 // process to be cached. It will be cached either as an activity 15165 // or empty depending on whether the activity is finishing. We do 15166 // this so that we can treat the process as cached for purposes of 15167 // memory trimming (determing current memory level, trim command to 15168 // send to process) since there can be an arbitrary number of stopping 15169 // processes and they should soon all go into the cached state. 15170 if (!r.finishing) { 15171 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15172 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15173 } 15174 } 15175 app.cached = false; 15176 app.empty = false; 15177 foregroundActivities = true; 15178 } else { 15179 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15180 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15181 app.adjType = "cch-act"; 15182 } 15183 } 15184 } 15185 } 15186 15187 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15188 if (app.foregroundServices) { 15189 // The user is aware of this app, so make it visible. 15190 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15191 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15192 app.cached = false; 15193 app.adjType = "fg-service"; 15194 schedGroup = Process.THREAD_GROUP_DEFAULT; 15195 } else if (app.forcingToForeground != null) { 15196 // The user is aware of this app, so make it visible. 15197 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15198 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15199 app.cached = false; 15200 app.adjType = "force-fg"; 15201 app.adjSource = app.forcingToForeground; 15202 schedGroup = Process.THREAD_GROUP_DEFAULT; 15203 } 15204 } 15205 15206 if (app == mHeavyWeightProcess) { 15207 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15208 // We don't want to kill the current heavy-weight process. 15209 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15210 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15211 app.cached = false; 15212 app.adjType = "heavy"; 15213 } 15214 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15215 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15216 } 15217 } 15218 15219 if (app == mHomeProcess) { 15220 if (adj > ProcessList.HOME_APP_ADJ) { 15221 // This process is hosting what we currently consider to be the 15222 // home app, so we don't want to let it go into the background. 15223 adj = ProcessList.HOME_APP_ADJ; 15224 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15225 app.cached = false; 15226 app.adjType = "home"; 15227 } 15228 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15229 procState = ActivityManager.PROCESS_STATE_HOME; 15230 } 15231 } 15232 15233 if (app == mPreviousProcess && app.activities.size() > 0) { 15234 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15235 // This was the previous process that showed UI to the user. 15236 // We want to try to keep it around more aggressively, to give 15237 // a good experience around switching between two apps. 15238 adj = ProcessList.PREVIOUS_APP_ADJ; 15239 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15240 app.cached = false; 15241 app.adjType = "previous"; 15242 } 15243 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15244 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15245 } 15246 } 15247 15248 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15249 + " reason=" + app.adjType); 15250 15251 // By default, we use the computed adjustment. It may be changed if 15252 // there are applications dependent on our services or providers, but 15253 // this gives us a baseline and makes sure we don't get into an 15254 // infinite recursion. 15255 app.adjSeq = mAdjSeq; 15256 app.curRawAdj = adj; 15257 app.hasStartedServices = false; 15258 15259 if (mBackupTarget != null && app == mBackupTarget.app) { 15260 // If possible we want to avoid killing apps while they're being backed up 15261 if (adj > ProcessList.BACKUP_APP_ADJ) { 15262 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15263 adj = ProcessList.BACKUP_APP_ADJ; 15264 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15265 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15266 } 15267 app.adjType = "backup"; 15268 app.cached = false; 15269 } 15270 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15271 procState = ActivityManager.PROCESS_STATE_BACKUP; 15272 } 15273 } 15274 15275 boolean mayBeTop = false; 15276 15277 for (int is = app.services.size()-1; 15278 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15279 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15280 || procState > ActivityManager.PROCESS_STATE_TOP); 15281 is--) { 15282 ServiceRecord s = app.services.valueAt(is); 15283 if (s.startRequested) { 15284 app.hasStartedServices = true; 15285 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15286 procState = ActivityManager.PROCESS_STATE_SERVICE; 15287 } 15288 if (app.hasShownUi && app != mHomeProcess) { 15289 // If this process has shown some UI, let it immediately 15290 // go to the LRU list because it may be pretty heavy with 15291 // UI stuff. We'll tag it with a label just to help 15292 // debug and understand what is going on. 15293 if (adj > ProcessList.SERVICE_ADJ) { 15294 app.adjType = "cch-started-ui-services"; 15295 } 15296 } else { 15297 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15298 // This service has seen some activity within 15299 // recent memory, so we will keep its process ahead 15300 // of the background processes. 15301 if (adj > ProcessList.SERVICE_ADJ) { 15302 adj = ProcessList.SERVICE_ADJ; 15303 app.adjType = "started-services"; 15304 app.cached = false; 15305 } 15306 } 15307 // If we have let the service slide into the background 15308 // state, still have some text describing what it is doing 15309 // even though the service no longer has an impact. 15310 if (adj > ProcessList.SERVICE_ADJ) { 15311 app.adjType = "cch-started-services"; 15312 } 15313 } 15314 // Don't kill this process because it is doing work; it 15315 // has said it is doing work. 15316 app.keeping = true; 15317 } 15318 for (int conni = s.connections.size()-1; 15319 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15320 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15321 || procState > ActivityManager.PROCESS_STATE_TOP); 15322 conni--) { 15323 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15324 for (int i = 0; 15325 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15326 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15327 || procState > ActivityManager.PROCESS_STATE_TOP); 15328 i++) { 15329 // XXX should compute this based on the max of 15330 // all connected clients. 15331 ConnectionRecord cr = clist.get(i); 15332 if (cr.binding.client == app) { 15333 // Binding to ourself is not interesting. 15334 continue; 15335 } 15336 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15337 ProcessRecord client = cr.binding.client; 15338 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15339 TOP_APP, doingAll, now); 15340 int clientProcState = client.curProcState; 15341 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15342 // If the other app is cached for any reason, for purposes here 15343 // we are going to consider it empty. The specific cached state 15344 // doesn't propagate except under certain conditions. 15345 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15346 } 15347 String adjType = null; 15348 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15349 // Not doing bind OOM management, so treat 15350 // this guy more like a started service. 15351 if (app.hasShownUi && app != mHomeProcess) { 15352 // If this process has shown some UI, let it immediately 15353 // go to the LRU list because it may be pretty heavy with 15354 // UI stuff. We'll tag it with a label just to help 15355 // debug and understand what is going on. 15356 if (adj > clientAdj) { 15357 adjType = "cch-bound-ui-services"; 15358 } 15359 app.cached = false; 15360 clientAdj = adj; 15361 clientProcState = procState; 15362 } else { 15363 if (now >= (s.lastActivity 15364 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15365 // This service has not seen activity within 15366 // recent memory, so allow it to drop to the 15367 // LRU list if there is no other reason to keep 15368 // it around. We'll also tag it with a label just 15369 // to help debug and undertand what is going on. 15370 if (adj > clientAdj) { 15371 adjType = "cch-bound-services"; 15372 } 15373 clientAdj = adj; 15374 } 15375 } 15376 } 15377 if (adj > clientAdj) { 15378 // If this process has recently shown UI, and 15379 // the process that is binding to it is less 15380 // important than being visible, then we don't 15381 // care about the binding as much as we care 15382 // about letting this process get into the LRU 15383 // list to be killed and restarted if needed for 15384 // memory. 15385 if (app.hasShownUi && app != mHomeProcess 15386 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15387 adjType = "cch-bound-ui-services"; 15388 } else { 15389 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15390 |Context.BIND_IMPORTANT)) != 0) { 15391 adj = clientAdj; 15392 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15393 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15394 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15395 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15396 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15397 adj = clientAdj; 15398 } else { 15399 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15400 adj = ProcessList.VISIBLE_APP_ADJ; 15401 } 15402 } 15403 if (!client.cached) { 15404 app.cached = false; 15405 } 15406 if (client.keeping) { 15407 app.keeping = true; 15408 } 15409 adjType = "service"; 15410 } 15411 } 15412 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15413 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15414 schedGroup = Process.THREAD_GROUP_DEFAULT; 15415 } 15416 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15417 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15418 // Special handling of clients who are in the top state. 15419 // We *may* want to consider this process to be in the 15420 // top state as well, but only if there is not another 15421 // reason for it to be running. Being on the top is a 15422 // special state, meaning you are specifically running 15423 // for the current top app. If the process is already 15424 // running in the background for some other reason, it 15425 // is more important to continue considering it to be 15426 // in the background state. 15427 mayBeTop = true; 15428 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15429 } else { 15430 // Special handling for above-top states (persistent 15431 // processes). These should not bring the current process 15432 // into the top state, since they are not on top. Instead 15433 // give them the best state after that. 15434 clientProcState = 15435 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15436 } 15437 } 15438 } else { 15439 if (clientProcState < 15440 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15441 clientProcState = 15442 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15443 } 15444 } 15445 if (procState > clientProcState) { 15446 procState = clientProcState; 15447 } 15448 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15449 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15450 app.pendingUiClean = true; 15451 } 15452 if (adjType != null) { 15453 app.adjType = adjType; 15454 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15455 .REASON_SERVICE_IN_USE; 15456 app.adjSource = cr.binding.client; 15457 app.adjSourceOom = clientAdj; 15458 app.adjTarget = s.name; 15459 } 15460 } 15461 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15462 app.treatLikeActivity = true; 15463 } 15464 final ActivityRecord a = cr.activity; 15465 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15466 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15467 (a.visible || a.state == ActivityState.RESUMED 15468 || a.state == ActivityState.PAUSING)) { 15469 adj = ProcessList.FOREGROUND_APP_ADJ; 15470 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15471 schedGroup = Process.THREAD_GROUP_DEFAULT; 15472 } 15473 app.cached = false; 15474 app.adjType = "service"; 15475 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15476 .REASON_SERVICE_IN_USE; 15477 app.adjSource = a; 15478 app.adjSourceOom = adj; 15479 app.adjTarget = s.name; 15480 } 15481 } 15482 } 15483 } 15484 } 15485 15486 for (int provi = app.pubProviders.size()-1; 15487 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15488 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15489 || procState > ActivityManager.PROCESS_STATE_TOP); 15490 provi--) { 15491 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15492 for (int i = cpr.connections.size()-1; 15493 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15494 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15495 || procState > ActivityManager.PROCESS_STATE_TOP); 15496 i--) { 15497 ContentProviderConnection conn = cpr.connections.get(i); 15498 ProcessRecord client = conn.client; 15499 if (client == app) { 15500 // Being our own client is not interesting. 15501 continue; 15502 } 15503 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15504 int clientProcState = client.curProcState; 15505 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15506 // If the other app is cached for any reason, for purposes here 15507 // we are going to consider it empty. 15508 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15509 } 15510 if (adj > clientAdj) { 15511 if (app.hasShownUi && app != mHomeProcess 15512 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15513 app.adjType = "cch-ui-provider"; 15514 } else { 15515 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15516 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15517 app.adjType = "provider"; 15518 } 15519 app.cached &= client.cached; 15520 app.keeping |= client.keeping; 15521 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15522 .REASON_PROVIDER_IN_USE; 15523 app.adjSource = client; 15524 app.adjSourceOom = clientAdj; 15525 app.adjTarget = cpr.name; 15526 } 15527 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15528 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15529 // Special handling of clients who are in the top state. 15530 // We *may* want to consider this process to be in the 15531 // top state as well, but only if there is not another 15532 // reason for it to be running. Being on the top is a 15533 // special state, meaning you are specifically running 15534 // for the current top app. If the process is already 15535 // running in the background for some other reason, it 15536 // is more important to continue considering it to be 15537 // in the background state. 15538 mayBeTop = true; 15539 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15540 } else { 15541 // Special handling for above-top states (persistent 15542 // processes). These should not bring the current process 15543 // into the top state, since they are not on top. Instead 15544 // give them the best state after that. 15545 clientProcState = 15546 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15547 } 15548 } 15549 if (procState > clientProcState) { 15550 procState = clientProcState; 15551 } 15552 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15553 schedGroup = Process.THREAD_GROUP_DEFAULT; 15554 } 15555 } 15556 // If the provider has external (non-framework) process 15557 // dependencies, ensure that its adjustment is at least 15558 // FOREGROUND_APP_ADJ. 15559 if (cpr.hasExternalProcessHandles()) { 15560 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15561 adj = ProcessList.FOREGROUND_APP_ADJ; 15562 schedGroup = Process.THREAD_GROUP_DEFAULT; 15563 app.cached = false; 15564 app.keeping = true; 15565 app.adjType = "provider"; 15566 app.adjTarget = cpr.name; 15567 } 15568 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15569 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15570 } 15571 } 15572 } 15573 15574 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15575 // A client of one of our services or providers is in the top state. We 15576 // *may* want to be in the top state, but not if we are already running in 15577 // the background for some other reason. For the decision here, we are going 15578 // to pick out a few specific states that we want to remain in when a client 15579 // is top (states that tend to be longer-term) and otherwise allow it to go 15580 // to the top state. 15581 switch (procState) { 15582 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15583 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15584 case ActivityManager.PROCESS_STATE_SERVICE: 15585 // These all are longer-term states, so pull them up to the top 15586 // of the background states, but not all the way to the top state. 15587 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15588 break; 15589 default: 15590 // Otherwise, top is a better choice, so take it. 15591 procState = ActivityManager.PROCESS_STATE_TOP; 15592 break; 15593 } 15594 } 15595 15596 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15597 if (app.hasClientActivities) { 15598 // This is a cached process, but with client activities. Mark it so. 15599 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15600 app.adjType = "cch-client-act"; 15601 } else if (app.treatLikeActivity) { 15602 // This is a cached process, but somebody wants us to treat it like it has 15603 // an activity, okay! 15604 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15605 app.adjType = "cch-as-act"; 15606 } 15607 } 15608 15609 if (adj == ProcessList.SERVICE_ADJ) { 15610 if (doingAll) { 15611 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15612 mNewNumServiceProcs++; 15613 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15614 if (!app.serviceb) { 15615 // This service isn't far enough down on the LRU list to 15616 // normally be a B service, but if we are low on RAM and it 15617 // is large we want to force it down since we would prefer to 15618 // keep launcher over it. 15619 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15620 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15621 app.serviceHighRam = true; 15622 app.serviceb = true; 15623 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15624 } else { 15625 mNewNumAServiceProcs++; 15626 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15627 } 15628 } else { 15629 app.serviceHighRam = false; 15630 } 15631 } 15632 if (app.serviceb) { 15633 adj = ProcessList.SERVICE_B_ADJ; 15634 } 15635 } 15636 15637 app.curRawAdj = adj; 15638 15639 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15640 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15641 if (adj > app.maxAdj) { 15642 adj = app.maxAdj; 15643 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15644 schedGroup = Process.THREAD_GROUP_DEFAULT; 15645 } 15646 } 15647 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15648 app.keeping = true; 15649 } 15650 15651 // Do final modification to adj. Everything we do between here and applying 15652 // the final setAdj must be done in this function, because we will also use 15653 // it when computing the final cached adj later. Note that we don't need to 15654 // worry about this for max adj above, since max adj will always be used to 15655 // keep it out of the cached vaues. 15656 app.curAdj = app.modifyRawOomAdj(adj); 15657 app.curSchedGroup = schedGroup; 15658 app.curProcState = procState; 15659 app.foregroundActivities = foregroundActivities; 15660 15661 return app.curRawAdj; 15662 } 15663 15664 /** 15665 * Schedule PSS collection of a process. 15666 */ 15667 void requestPssLocked(ProcessRecord proc, int procState) { 15668 if (mPendingPssProcesses.contains(proc)) { 15669 return; 15670 } 15671 if (mPendingPssProcesses.size() == 0) { 15672 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15673 } 15674 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15675 proc.pssProcState = procState; 15676 mPendingPssProcesses.add(proc); 15677 } 15678 15679 /** 15680 * Schedule PSS collection of all processes. 15681 */ 15682 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15683 if (!always) { 15684 if (now < (mLastFullPssTime + 15685 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15686 return; 15687 } 15688 } 15689 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15690 mLastFullPssTime = now; 15691 mFullPssPending = true; 15692 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15693 mPendingPssProcesses.clear(); 15694 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15695 ProcessRecord app = mLruProcesses.get(i); 15696 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15697 app.pssProcState = app.setProcState; 15698 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15699 isSleeping(), now); 15700 mPendingPssProcesses.add(app); 15701 } 15702 } 15703 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15704 } 15705 15706 /** 15707 * Ask a given process to GC right now. 15708 */ 15709 final void performAppGcLocked(ProcessRecord app) { 15710 try { 15711 app.lastRequestedGc = SystemClock.uptimeMillis(); 15712 if (app.thread != null) { 15713 if (app.reportLowMemory) { 15714 app.reportLowMemory = false; 15715 app.thread.scheduleLowMemory(); 15716 } else { 15717 app.thread.processInBackground(); 15718 } 15719 } 15720 } catch (Exception e) { 15721 // whatever. 15722 } 15723 } 15724 15725 /** 15726 * Returns true if things are idle enough to perform GCs. 15727 */ 15728 private final boolean canGcNowLocked() { 15729 boolean processingBroadcasts = false; 15730 for (BroadcastQueue q : mBroadcastQueues) { 15731 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15732 processingBroadcasts = true; 15733 } 15734 } 15735 return !processingBroadcasts 15736 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15737 } 15738 15739 /** 15740 * Perform GCs on all processes that are waiting for it, but only 15741 * if things are idle. 15742 */ 15743 final void performAppGcsLocked() { 15744 final int N = mProcessesToGc.size(); 15745 if (N <= 0) { 15746 return; 15747 } 15748 if (canGcNowLocked()) { 15749 while (mProcessesToGc.size() > 0) { 15750 ProcessRecord proc = mProcessesToGc.remove(0); 15751 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15752 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15753 <= SystemClock.uptimeMillis()) { 15754 // To avoid spamming the system, we will GC processes one 15755 // at a time, waiting a few seconds between each. 15756 performAppGcLocked(proc); 15757 scheduleAppGcsLocked(); 15758 return; 15759 } else { 15760 // It hasn't been long enough since we last GCed this 15761 // process... put it in the list to wait for its time. 15762 addProcessToGcListLocked(proc); 15763 break; 15764 } 15765 } 15766 } 15767 15768 scheduleAppGcsLocked(); 15769 } 15770 } 15771 15772 /** 15773 * If all looks good, perform GCs on all processes waiting for them. 15774 */ 15775 final void performAppGcsIfAppropriateLocked() { 15776 if (canGcNowLocked()) { 15777 performAppGcsLocked(); 15778 return; 15779 } 15780 // Still not idle, wait some more. 15781 scheduleAppGcsLocked(); 15782 } 15783 15784 /** 15785 * Schedule the execution of all pending app GCs. 15786 */ 15787 final void scheduleAppGcsLocked() { 15788 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15789 15790 if (mProcessesToGc.size() > 0) { 15791 // Schedule a GC for the time to the next process. 15792 ProcessRecord proc = mProcessesToGc.get(0); 15793 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15794 15795 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15796 long now = SystemClock.uptimeMillis(); 15797 if (when < (now+GC_TIMEOUT)) { 15798 when = now + GC_TIMEOUT; 15799 } 15800 mHandler.sendMessageAtTime(msg, when); 15801 } 15802 } 15803 15804 /** 15805 * Add a process to the array of processes waiting to be GCed. Keeps the 15806 * list in sorted order by the last GC time. The process can't already be 15807 * on the list. 15808 */ 15809 final void addProcessToGcListLocked(ProcessRecord proc) { 15810 boolean added = false; 15811 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15812 if (mProcessesToGc.get(i).lastRequestedGc < 15813 proc.lastRequestedGc) { 15814 added = true; 15815 mProcessesToGc.add(i+1, proc); 15816 break; 15817 } 15818 } 15819 if (!added) { 15820 mProcessesToGc.add(0, proc); 15821 } 15822 } 15823 15824 /** 15825 * Set up to ask a process to GC itself. This will either do it 15826 * immediately, or put it on the list of processes to gc the next 15827 * time things are idle. 15828 */ 15829 final void scheduleAppGcLocked(ProcessRecord app) { 15830 long now = SystemClock.uptimeMillis(); 15831 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15832 return; 15833 } 15834 if (!mProcessesToGc.contains(app)) { 15835 addProcessToGcListLocked(app); 15836 scheduleAppGcsLocked(); 15837 } 15838 } 15839 15840 final void checkExcessivePowerUsageLocked(boolean doKills) { 15841 updateCpuStatsNow(); 15842 15843 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15844 boolean doWakeKills = doKills; 15845 boolean doCpuKills = doKills; 15846 if (mLastPowerCheckRealtime == 0) { 15847 doWakeKills = false; 15848 } 15849 if (mLastPowerCheckUptime == 0) { 15850 doCpuKills = false; 15851 } 15852 if (stats.isScreenOn()) { 15853 doWakeKills = false; 15854 } 15855 final long curRealtime = SystemClock.elapsedRealtime(); 15856 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15857 final long curUptime = SystemClock.uptimeMillis(); 15858 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15859 mLastPowerCheckRealtime = curRealtime; 15860 mLastPowerCheckUptime = curUptime; 15861 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15862 doWakeKills = false; 15863 } 15864 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15865 doCpuKills = false; 15866 } 15867 int i = mLruProcesses.size(); 15868 while (i > 0) { 15869 i--; 15870 ProcessRecord app = mLruProcesses.get(i); 15871 if (!app.keeping) { 15872 long wtime; 15873 synchronized (stats) { 15874 wtime = stats.getProcessWakeTime(app.info.uid, 15875 app.pid, curRealtime); 15876 } 15877 long wtimeUsed = wtime - app.lastWakeTime; 15878 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15879 if (DEBUG_POWER) { 15880 StringBuilder sb = new StringBuilder(128); 15881 sb.append("Wake for "); 15882 app.toShortString(sb); 15883 sb.append(": over "); 15884 TimeUtils.formatDuration(realtimeSince, sb); 15885 sb.append(" used "); 15886 TimeUtils.formatDuration(wtimeUsed, sb); 15887 sb.append(" ("); 15888 sb.append((wtimeUsed*100)/realtimeSince); 15889 sb.append("%)"); 15890 Slog.i(TAG, sb.toString()); 15891 sb.setLength(0); 15892 sb.append("CPU for "); 15893 app.toShortString(sb); 15894 sb.append(": over "); 15895 TimeUtils.formatDuration(uptimeSince, sb); 15896 sb.append(" used "); 15897 TimeUtils.formatDuration(cputimeUsed, sb); 15898 sb.append(" ("); 15899 sb.append((cputimeUsed*100)/uptimeSince); 15900 sb.append("%)"); 15901 Slog.i(TAG, sb.toString()); 15902 } 15903 // If a process has held a wake lock for more 15904 // than 50% of the time during this period, 15905 // that sounds bad. Kill! 15906 if (doWakeKills && realtimeSince > 0 15907 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15908 synchronized (stats) { 15909 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15910 realtimeSince, wtimeUsed); 15911 } 15912 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15913 + " during " + realtimeSince); 15914 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15915 } else if (doCpuKills && uptimeSince > 0 15916 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15917 synchronized (stats) { 15918 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15919 uptimeSince, cputimeUsed); 15920 } 15921 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15922 + " during " + uptimeSince); 15923 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15924 } else { 15925 app.lastWakeTime = wtime; 15926 app.lastCpuTime = app.curCpuTime; 15927 } 15928 } 15929 } 15930 } 15931 15932 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15933 ProcessRecord TOP_APP, boolean doingAll, long now) { 15934 boolean success = true; 15935 15936 if (app.curRawAdj != app.setRawAdj) { 15937 if (wasKeeping && !app.keeping) { 15938 // This app is no longer something we want to keep. Note 15939 // its current wake lock time to later know to kill it if 15940 // it is not behaving well. 15941 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15942 synchronized (stats) { 15943 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15944 app.pid, SystemClock.elapsedRealtime()); 15945 } 15946 app.lastCpuTime = app.curCpuTime; 15947 } 15948 15949 app.setRawAdj = app.curRawAdj; 15950 } 15951 15952 int changes = 0; 15953 15954 if (app.curAdj != app.setAdj) { 15955 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 15956 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15957 TAG, "Set " + app.pid + " " + app.processName + 15958 " adj " + app.curAdj + ": " + app.adjType); 15959 app.setAdj = app.curAdj; 15960 } 15961 15962 if (app.setSchedGroup != app.curSchedGroup) { 15963 app.setSchedGroup = app.curSchedGroup; 15964 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15965 "Setting process group of " + app.processName 15966 + " to " + app.curSchedGroup); 15967 if (app.waitingToKill != null && 15968 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15969 killUnneededProcessLocked(app, app.waitingToKill); 15970 success = false; 15971 } else { 15972 if (true) { 15973 long oldId = Binder.clearCallingIdentity(); 15974 try { 15975 Process.setProcessGroup(app.pid, app.curSchedGroup); 15976 } catch (Exception e) { 15977 Slog.w(TAG, "Failed setting process group of " + app.pid 15978 + " to " + app.curSchedGroup); 15979 e.printStackTrace(); 15980 } finally { 15981 Binder.restoreCallingIdentity(oldId); 15982 } 15983 } else { 15984 if (app.thread != null) { 15985 try { 15986 app.thread.setSchedulingGroup(app.curSchedGroup); 15987 } catch (RemoteException e) { 15988 } 15989 } 15990 } 15991 Process.setSwappiness(app.pid, 15992 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15993 } 15994 } 15995 if (app.repForegroundActivities != app.foregroundActivities) { 15996 app.repForegroundActivities = app.foregroundActivities; 15997 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15998 } 15999 if (app.repProcState != app.curProcState) { 16000 app.repProcState = app.curProcState; 16001 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16002 if (app.thread != null) { 16003 try { 16004 if (false) { 16005 //RuntimeException h = new RuntimeException("here"); 16006 Slog.i(TAG, "Sending new process state " + app.repProcState 16007 + " to " + app /*, h*/); 16008 } 16009 app.thread.setProcessState(app.repProcState); 16010 } catch (RemoteException e) { 16011 } 16012 } 16013 } 16014 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16015 app.setProcState)) { 16016 app.lastStateTime = now; 16017 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16018 isSleeping(), now); 16019 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16020 + ProcessList.makeProcStateString(app.setProcState) + " to " 16021 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 16022 + (app.nextPssTime-now) + ": " + app); 16023 } else { 16024 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 16025 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 16026 requestPssLocked(app, app.setProcState); 16027 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 16028 isSleeping(), now); 16029 } else if (false && DEBUG_PSS) { 16030 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 16031 } 16032 } 16033 if (app.setProcState != app.curProcState) { 16034 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16035 "Proc state change of " + app.processName 16036 + " to " + app.curProcState); 16037 app.setProcState = app.curProcState; 16038 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16039 app.notCachedSinceIdle = false; 16040 } 16041 if (!doingAll) { 16042 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 16043 } else { 16044 app.procStateChanged = true; 16045 } 16046 } 16047 16048 if (changes != 0) { 16049 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16050 int i = mPendingProcessChanges.size()-1; 16051 ProcessChangeItem item = null; 16052 while (i >= 0) { 16053 item = mPendingProcessChanges.get(i); 16054 if (item.pid == app.pid) { 16055 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16056 break; 16057 } 16058 i--; 16059 } 16060 if (i < 0) { 16061 // No existing item in pending changes; need a new one. 16062 final int NA = mAvailProcessChanges.size(); 16063 if (NA > 0) { 16064 item = mAvailProcessChanges.remove(NA-1); 16065 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16066 } else { 16067 item = new ProcessChangeItem(); 16068 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16069 } 16070 item.changes = 0; 16071 item.pid = app.pid; 16072 item.uid = app.info.uid; 16073 if (mPendingProcessChanges.size() == 0) { 16074 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16075 "*** Enqueueing dispatch processes changed!"); 16076 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16077 } 16078 mPendingProcessChanges.add(item); 16079 } 16080 item.changes |= changes; 16081 item.processState = app.repProcState; 16082 item.foregroundActivities = app.repForegroundActivities; 16083 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16084 + Integer.toHexString(System.identityHashCode(item)) 16085 + " " + app.toShortString() + ": changes=" + item.changes 16086 + " procState=" + item.processState 16087 + " foreground=" + item.foregroundActivities 16088 + " type=" + app.adjType + " source=" + app.adjSource 16089 + " target=" + app.adjTarget); 16090 } 16091 16092 return success; 16093 } 16094 16095 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 16096 if (proc.thread != null && proc.baseProcessTracker != null) { 16097 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16098 } 16099 } 16100 16101 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16102 ProcessRecord TOP_APP, boolean doingAll, long now) { 16103 if (app.thread == null) { 16104 return false; 16105 } 16106 16107 final boolean wasKeeping = app.keeping; 16108 16109 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16110 16111 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 16112 } 16113 16114 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16115 boolean oomAdj) { 16116 if (isForeground != proc.foregroundServices) { 16117 proc.foregroundServices = isForeground; 16118 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16119 proc.info.uid); 16120 if (isForeground) { 16121 if (curProcs == null) { 16122 curProcs = new ArrayList<ProcessRecord>(); 16123 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16124 } 16125 if (!curProcs.contains(proc)) { 16126 curProcs.add(proc); 16127 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16128 proc.info.packageName, proc.info.uid); 16129 } 16130 } else { 16131 if (curProcs != null) { 16132 if (curProcs.remove(proc)) { 16133 mBatteryStatsService.noteEvent( 16134 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16135 proc.info.packageName, proc.info.uid); 16136 if (curProcs.size() <= 0) { 16137 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16138 } 16139 } 16140 } 16141 } 16142 if (oomAdj) { 16143 updateOomAdjLocked(); 16144 } 16145 } 16146 } 16147 16148 private final ActivityRecord resumedAppLocked() { 16149 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16150 String pkg; 16151 int uid; 16152 if (act != null && !act.sleeping) { 16153 pkg = act.packageName; 16154 uid = act.info.applicationInfo.uid; 16155 } else { 16156 pkg = null; 16157 uid = -1; 16158 } 16159 // Has the UID or resumed package name changed? 16160 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16161 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16162 if (mCurResumedPackage != null) { 16163 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16164 mCurResumedPackage, mCurResumedUid); 16165 } 16166 mCurResumedPackage = pkg; 16167 mCurResumedUid = uid; 16168 if (mCurResumedPackage != null) { 16169 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16170 mCurResumedPackage, mCurResumedUid); 16171 } 16172 } 16173 return act; 16174 } 16175 16176 final boolean updateOomAdjLocked(ProcessRecord app) { 16177 final ActivityRecord TOP_ACT = resumedAppLocked(); 16178 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16179 final boolean wasCached = app.cached; 16180 16181 mAdjSeq++; 16182 16183 // This is the desired cached adjusment we want to tell it to use. 16184 // If our app is currently cached, we know it, and that is it. Otherwise, 16185 // we don't know it yet, and it needs to now be cached we will then 16186 // need to do a complete oom adj. 16187 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16188 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16189 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16190 SystemClock.uptimeMillis()); 16191 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16192 // Changed to/from cached state, so apps after it in the LRU 16193 // list may also be changed. 16194 updateOomAdjLocked(); 16195 } 16196 return success; 16197 } 16198 16199 final void updateOomAdjLocked() { 16200 final ActivityRecord TOP_ACT = resumedAppLocked(); 16201 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16202 final long now = SystemClock.uptimeMillis(); 16203 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16204 final int N = mLruProcesses.size(); 16205 16206 if (false) { 16207 RuntimeException e = new RuntimeException(); 16208 e.fillInStackTrace(); 16209 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16210 } 16211 16212 mAdjSeq++; 16213 mNewNumServiceProcs = 0; 16214 mNewNumAServiceProcs = 0; 16215 16216 final int emptyProcessLimit; 16217 final int cachedProcessLimit; 16218 if (mProcessLimit <= 0) { 16219 emptyProcessLimit = cachedProcessLimit = 0; 16220 } else if (mProcessLimit == 1) { 16221 emptyProcessLimit = 1; 16222 cachedProcessLimit = 0; 16223 } else { 16224 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16225 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16226 } 16227 16228 // Let's determine how many processes we have running vs. 16229 // how many slots we have for background processes; we may want 16230 // to put multiple processes in a slot of there are enough of 16231 // them. 16232 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16233 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16234 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16235 if (numEmptyProcs > cachedProcessLimit) { 16236 // If there are more empty processes than our limit on cached 16237 // processes, then use the cached process limit for the factor. 16238 // This ensures that the really old empty processes get pushed 16239 // down to the bottom, so if we are running low on memory we will 16240 // have a better chance at keeping around more cached processes 16241 // instead of a gazillion empty processes. 16242 numEmptyProcs = cachedProcessLimit; 16243 } 16244 int emptyFactor = numEmptyProcs/numSlots; 16245 if (emptyFactor < 1) emptyFactor = 1; 16246 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16247 if (cachedFactor < 1) cachedFactor = 1; 16248 int stepCached = 0; 16249 int stepEmpty = 0; 16250 int numCached = 0; 16251 int numEmpty = 0; 16252 int numTrimming = 0; 16253 16254 mNumNonCachedProcs = 0; 16255 mNumCachedHiddenProcs = 0; 16256 16257 // First update the OOM adjustment for each of the 16258 // application processes based on their current state. 16259 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16260 int nextCachedAdj = curCachedAdj+1; 16261 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16262 int nextEmptyAdj = curEmptyAdj+2; 16263 for (int i=N-1; i>=0; i--) { 16264 ProcessRecord app = mLruProcesses.get(i); 16265 if (!app.killedByAm && app.thread != null) { 16266 app.procStateChanged = false; 16267 final boolean wasKeeping = app.keeping; 16268 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16269 16270 // If we haven't yet assigned the final cached adj 16271 // to the process, do that now. 16272 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16273 switch (app.curProcState) { 16274 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16275 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16276 // This process is a cached process holding activities... 16277 // assign it the next cached value for that type, and then 16278 // step that cached level. 16279 app.curRawAdj = curCachedAdj; 16280 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16281 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16282 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16283 + ")"); 16284 if (curCachedAdj != nextCachedAdj) { 16285 stepCached++; 16286 if (stepCached >= cachedFactor) { 16287 stepCached = 0; 16288 curCachedAdj = nextCachedAdj; 16289 nextCachedAdj += 2; 16290 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16291 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16292 } 16293 } 16294 } 16295 break; 16296 default: 16297 // For everything else, assign next empty cached process 16298 // level and bump that up. Note that this means that 16299 // long-running services that have dropped down to the 16300 // cached level will be treated as empty (since their process 16301 // state is still as a service), which is what we want. 16302 app.curRawAdj = curEmptyAdj; 16303 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16304 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16305 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16306 + ")"); 16307 if (curEmptyAdj != nextEmptyAdj) { 16308 stepEmpty++; 16309 if (stepEmpty >= emptyFactor) { 16310 stepEmpty = 0; 16311 curEmptyAdj = nextEmptyAdj; 16312 nextEmptyAdj += 2; 16313 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16314 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16315 } 16316 } 16317 } 16318 break; 16319 } 16320 } 16321 16322 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16323 16324 // Count the number of process types. 16325 switch (app.curProcState) { 16326 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16327 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16328 mNumCachedHiddenProcs++; 16329 numCached++; 16330 if (numCached > cachedProcessLimit) { 16331 killUnneededProcessLocked(app, "cached #" + numCached); 16332 } 16333 break; 16334 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16335 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16336 && app.lastActivityTime < oldTime) { 16337 killUnneededProcessLocked(app, "empty for " 16338 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16339 / 1000) + "s"); 16340 } else { 16341 numEmpty++; 16342 if (numEmpty > emptyProcessLimit) { 16343 killUnneededProcessLocked(app, "empty #" + numEmpty); 16344 } 16345 } 16346 break; 16347 default: 16348 mNumNonCachedProcs++; 16349 break; 16350 } 16351 16352 if (app.isolated && app.services.size() <= 0) { 16353 // If this is an isolated process, and there are no 16354 // services running in it, then the process is no longer 16355 // needed. We agressively kill these because we can by 16356 // definition not re-use the same process again, and it is 16357 // good to avoid having whatever code was running in them 16358 // left sitting around after no longer needed. 16359 killUnneededProcessLocked(app, "isolated not needed"); 16360 } 16361 16362 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16363 && !app.killedByAm) { 16364 numTrimming++; 16365 } 16366 } 16367 } 16368 16369 mNumServiceProcs = mNewNumServiceProcs; 16370 16371 // Now determine the memory trimming level of background processes. 16372 // Unfortunately we need to start at the back of the list to do this 16373 // properly. We only do this if the number of background apps we 16374 // are managing to keep around is less than half the maximum we desire; 16375 // if we are keeping a good number around, we'll let them use whatever 16376 // memory they want. 16377 final int numCachedAndEmpty = numCached + numEmpty; 16378 int memFactor; 16379 if (numCached <= ProcessList.TRIM_CACHED_APPS 16380 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16381 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16382 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16383 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16384 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16385 } else { 16386 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16387 } 16388 } else { 16389 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16390 } 16391 // We always allow the memory level to go up (better). We only allow it to go 16392 // down if we are in a state where that is allowed, *and* the total number of processes 16393 // has gone down since last time. 16394 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16395 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16396 + " last=" + mLastNumProcesses); 16397 if (memFactor > mLastMemoryLevel) { 16398 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16399 memFactor = mLastMemoryLevel; 16400 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16401 } 16402 } 16403 mLastMemoryLevel = memFactor; 16404 mLastNumProcesses = mLruProcesses.size(); 16405 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16406 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16407 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16408 if (mLowRamStartTime == 0) { 16409 mLowRamStartTime = now; 16410 } 16411 int step = 0; 16412 int fgTrimLevel; 16413 switch (memFactor) { 16414 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16415 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16416 break; 16417 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16418 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16419 break; 16420 default: 16421 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16422 break; 16423 } 16424 int factor = numTrimming/3; 16425 int minFactor = 2; 16426 if (mHomeProcess != null) minFactor++; 16427 if (mPreviousProcess != null) minFactor++; 16428 if (factor < minFactor) factor = minFactor; 16429 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16430 for (int i=N-1; i>=0; i--) { 16431 ProcessRecord app = mLruProcesses.get(i); 16432 if (allChanged || app.procStateChanged) { 16433 setProcessTrackerState(app, trackerMemFactor, now); 16434 app.procStateChanged = false; 16435 } 16436 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16437 && !app.killedByAm) { 16438 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16439 try { 16440 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16441 "Trimming memory of " + app.processName 16442 + " to " + curLevel); 16443 app.thread.scheduleTrimMemory(curLevel); 16444 } catch (RemoteException e) { 16445 } 16446 if (false) { 16447 // For now we won't do this; our memory trimming seems 16448 // to be good enough at this point that destroying 16449 // activities causes more harm than good. 16450 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16451 && app != mHomeProcess && app != mPreviousProcess) { 16452 // Need to do this on its own message because the stack may not 16453 // be in a consistent state at this point. 16454 // For these apps we will also finish their activities 16455 // to help them free memory. 16456 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16457 } 16458 } 16459 } 16460 app.trimMemoryLevel = curLevel; 16461 step++; 16462 if (step >= factor) { 16463 step = 0; 16464 switch (curLevel) { 16465 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16466 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16467 break; 16468 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16469 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16470 break; 16471 } 16472 } 16473 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16474 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16475 && app.thread != null) { 16476 try { 16477 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16478 "Trimming memory of heavy-weight " + app.processName 16479 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16480 app.thread.scheduleTrimMemory( 16481 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16482 } catch (RemoteException e) { 16483 } 16484 } 16485 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16486 } else { 16487 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16488 || app.systemNoUi) && app.pendingUiClean) { 16489 // If this application is now in the background and it 16490 // had done UI, then give it the special trim level to 16491 // have it free UI resources. 16492 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16493 if (app.trimMemoryLevel < level && app.thread != null) { 16494 try { 16495 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16496 "Trimming memory of bg-ui " + app.processName 16497 + " to " + level); 16498 app.thread.scheduleTrimMemory(level); 16499 } catch (RemoteException e) { 16500 } 16501 } 16502 app.pendingUiClean = false; 16503 } 16504 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16505 try { 16506 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16507 "Trimming memory of fg " + app.processName 16508 + " to " + fgTrimLevel); 16509 app.thread.scheduleTrimMemory(fgTrimLevel); 16510 } catch (RemoteException e) { 16511 } 16512 } 16513 app.trimMemoryLevel = fgTrimLevel; 16514 } 16515 } 16516 } else { 16517 if (mLowRamStartTime != 0) { 16518 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16519 mLowRamStartTime = 0; 16520 } 16521 for (int i=N-1; i>=0; i--) { 16522 ProcessRecord app = mLruProcesses.get(i); 16523 if (allChanged || app.procStateChanged) { 16524 setProcessTrackerState(app, trackerMemFactor, now); 16525 app.procStateChanged = false; 16526 } 16527 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16528 || app.systemNoUi) && app.pendingUiClean) { 16529 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16530 && app.thread != null) { 16531 try { 16532 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16533 "Trimming memory of ui hidden " + app.processName 16534 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16535 app.thread.scheduleTrimMemory( 16536 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16537 } catch (RemoteException e) { 16538 } 16539 } 16540 app.pendingUiClean = false; 16541 } 16542 app.trimMemoryLevel = 0; 16543 } 16544 } 16545 16546 if (mAlwaysFinishActivities) { 16547 // Need to do this on its own message because the stack may not 16548 // be in a consistent state at this point. 16549 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16550 } 16551 16552 if (allChanged) { 16553 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16554 } 16555 16556 if (mProcessStats.shouldWriteNowLocked(now)) { 16557 mHandler.post(new Runnable() { 16558 @Override public void run() { 16559 synchronized (ActivityManagerService.this) { 16560 mProcessStats.writeStateAsyncLocked(); 16561 } 16562 } 16563 }); 16564 } 16565 16566 if (DEBUG_OOM_ADJ) { 16567 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16568 } 16569 } 16570 16571 final void trimApplications() { 16572 synchronized (this) { 16573 int i; 16574 16575 // First remove any unused application processes whose package 16576 // has been removed. 16577 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16578 final ProcessRecord app = mRemovedProcesses.get(i); 16579 if (app.activities.size() == 0 16580 && app.curReceiver == null && app.services.size() == 0) { 16581 Slog.i( 16582 TAG, "Exiting empty application process " 16583 + app.processName + " (" 16584 + (app.thread != null ? app.thread.asBinder() : null) 16585 + ")\n"); 16586 if (app.pid > 0 && app.pid != MY_PID) { 16587 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16588 app.processName, app.setAdj, "empty"); 16589 app.killedByAm = true; 16590 Process.killProcessQuiet(app.pid); 16591 } else { 16592 try { 16593 app.thread.scheduleExit(); 16594 } catch (Exception e) { 16595 // Ignore exceptions. 16596 } 16597 } 16598 cleanUpApplicationRecordLocked(app, false, true, -1); 16599 mRemovedProcesses.remove(i); 16600 16601 if (app.persistent) { 16602 addAppLocked(app.info, false, null /* ABI override */); 16603 } 16604 } 16605 } 16606 16607 // Now update the oom adj for all processes. 16608 updateOomAdjLocked(); 16609 } 16610 } 16611 16612 /** This method sends the specified signal to each of the persistent apps */ 16613 public void signalPersistentProcesses(int sig) throws RemoteException { 16614 if (sig != Process.SIGNAL_USR1) { 16615 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16616 } 16617 16618 synchronized (this) { 16619 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16620 != PackageManager.PERMISSION_GRANTED) { 16621 throw new SecurityException("Requires permission " 16622 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16623 } 16624 16625 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16626 ProcessRecord r = mLruProcesses.get(i); 16627 if (r.thread != null && r.persistent) { 16628 Process.sendSignal(r.pid, sig); 16629 } 16630 } 16631 } 16632 } 16633 16634 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16635 if (proc == null || proc == mProfileProc) { 16636 proc = mProfileProc; 16637 path = mProfileFile; 16638 profileType = mProfileType; 16639 clearProfilerLocked(); 16640 } 16641 if (proc == null) { 16642 return; 16643 } 16644 try { 16645 proc.thread.profilerControl(false, path, null, profileType); 16646 } catch (RemoteException e) { 16647 throw new IllegalStateException("Process disappeared"); 16648 } 16649 } 16650 16651 private void clearProfilerLocked() { 16652 if (mProfileFd != null) { 16653 try { 16654 mProfileFd.close(); 16655 } catch (IOException e) { 16656 } 16657 } 16658 mProfileApp = null; 16659 mProfileProc = null; 16660 mProfileFile = null; 16661 mProfileType = 0; 16662 mAutoStopProfiler = false; 16663 } 16664 16665 public boolean profileControl(String process, int userId, boolean start, 16666 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16667 16668 try { 16669 synchronized (this) { 16670 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16671 // its own permission. 16672 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16673 != PackageManager.PERMISSION_GRANTED) { 16674 throw new SecurityException("Requires permission " 16675 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16676 } 16677 16678 if (start && fd == null) { 16679 throw new IllegalArgumentException("null fd"); 16680 } 16681 16682 ProcessRecord proc = null; 16683 if (process != null) { 16684 proc = findProcessLocked(process, userId, "profileControl"); 16685 } 16686 16687 if (start && (proc == null || proc.thread == null)) { 16688 throw new IllegalArgumentException("Unknown process: " + process); 16689 } 16690 16691 if (start) { 16692 stopProfilerLocked(null, null, 0); 16693 setProfileApp(proc.info, proc.processName, path, fd, false); 16694 mProfileProc = proc; 16695 mProfileType = profileType; 16696 try { 16697 fd = fd.dup(); 16698 } catch (IOException e) { 16699 fd = null; 16700 } 16701 proc.thread.profilerControl(start, path, fd, profileType); 16702 fd = null; 16703 mProfileFd = null; 16704 } else { 16705 stopProfilerLocked(proc, path, profileType); 16706 if (fd != null) { 16707 try { 16708 fd.close(); 16709 } catch (IOException e) { 16710 } 16711 } 16712 } 16713 16714 return true; 16715 } 16716 } catch (RemoteException e) { 16717 throw new IllegalStateException("Process disappeared"); 16718 } finally { 16719 if (fd != null) { 16720 try { 16721 fd.close(); 16722 } catch (IOException e) { 16723 } 16724 } 16725 } 16726 } 16727 16728 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16729 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16730 userId, true, true, callName, null); 16731 ProcessRecord proc = null; 16732 try { 16733 int pid = Integer.parseInt(process); 16734 synchronized (mPidsSelfLocked) { 16735 proc = mPidsSelfLocked.get(pid); 16736 } 16737 } catch (NumberFormatException e) { 16738 } 16739 16740 if (proc == null) { 16741 ArrayMap<String, SparseArray<ProcessRecord>> all 16742 = mProcessNames.getMap(); 16743 SparseArray<ProcessRecord> procs = all.get(process); 16744 if (procs != null && procs.size() > 0) { 16745 proc = procs.valueAt(0); 16746 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16747 for (int i=1; i<procs.size(); i++) { 16748 ProcessRecord thisProc = procs.valueAt(i); 16749 if (thisProc.userId == userId) { 16750 proc = thisProc; 16751 break; 16752 } 16753 } 16754 } 16755 } 16756 } 16757 16758 return proc; 16759 } 16760 16761 public boolean dumpHeap(String process, int userId, boolean managed, 16762 String path, ParcelFileDescriptor fd) throws RemoteException { 16763 16764 try { 16765 synchronized (this) { 16766 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16767 // its own permission (same as profileControl). 16768 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16769 != PackageManager.PERMISSION_GRANTED) { 16770 throw new SecurityException("Requires permission " 16771 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16772 } 16773 16774 if (fd == null) { 16775 throw new IllegalArgumentException("null fd"); 16776 } 16777 16778 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16779 if (proc == null || proc.thread == null) { 16780 throw new IllegalArgumentException("Unknown process: " + process); 16781 } 16782 16783 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16784 if (!isDebuggable) { 16785 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16786 throw new SecurityException("Process not debuggable: " + proc); 16787 } 16788 } 16789 16790 proc.thread.dumpHeap(managed, path, fd); 16791 fd = null; 16792 return true; 16793 } 16794 } catch (RemoteException e) { 16795 throw new IllegalStateException("Process disappeared"); 16796 } finally { 16797 if (fd != null) { 16798 try { 16799 fd.close(); 16800 } catch (IOException e) { 16801 } 16802 } 16803 } 16804 } 16805 16806 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16807 public void monitor() { 16808 synchronized (this) { } 16809 } 16810 16811 void onCoreSettingsChange(Bundle settings) { 16812 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16813 ProcessRecord processRecord = mLruProcesses.get(i); 16814 try { 16815 if (processRecord.thread != null) { 16816 processRecord.thread.setCoreSettings(settings); 16817 } 16818 } catch (RemoteException re) { 16819 /* ignore */ 16820 } 16821 } 16822 } 16823 16824 // Multi-user methods 16825 16826 /** 16827 * Start user, if its not already running, but don't bring it to foreground. 16828 */ 16829 @Override 16830 public boolean startUserInBackground(final int userId) { 16831 return startUser(userId, /* foreground */ false); 16832 } 16833 16834 /** 16835 * Refreshes the list of users related to the current user when either a 16836 * user switch happens or when a new related user is started in the 16837 * background. 16838 */ 16839 private void updateCurrentProfileIdsLocked() { 16840 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16841 mCurrentUserId, false /* enabledOnly */); 16842 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16843 for (int i = 0; i < currentProfileIds.length; i++) { 16844 currentProfileIds[i] = profiles.get(i).id; 16845 } 16846 mCurrentProfileIds = currentProfileIds; 16847 } 16848 16849 private Set getProfileIdsLocked(int userId) { 16850 Set userIds = new HashSet<Integer>(); 16851 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16852 userId, false /* enabledOnly */); 16853 for (UserInfo user : profiles) { 16854 userIds.add(Integer.valueOf(user.id)); 16855 } 16856 return userIds; 16857 } 16858 16859 @Override 16860 public boolean switchUser(final int userId) { 16861 return startUser(userId, /* foregound */ true); 16862 } 16863 16864 private boolean startUser(final int userId, boolean foreground) { 16865 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16866 != PackageManager.PERMISSION_GRANTED) { 16867 String msg = "Permission Denial: switchUser() from pid=" 16868 + Binder.getCallingPid() 16869 + ", uid=" + Binder.getCallingUid() 16870 + " requires " + INTERACT_ACROSS_USERS_FULL; 16871 Slog.w(TAG, msg); 16872 throw new SecurityException(msg); 16873 } 16874 16875 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16876 16877 final long ident = Binder.clearCallingIdentity(); 16878 try { 16879 synchronized (this) { 16880 final int oldUserId = mCurrentUserId; 16881 if (oldUserId == userId) { 16882 return true; 16883 } 16884 16885 mStackSupervisor.setLockTaskModeLocked(null, false); 16886 16887 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16888 if (userInfo == null) { 16889 Slog.w(TAG, "No user info for user #" + userId); 16890 return false; 16891 } 16892 16893 if (foreground) { 16894 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16895 R.anim.screen_user_enter); 16896 } 16897 16898 boolean needStart = false; 16899 16900 // If the user we are switching to is not currently started, then 16901 // we need to start it now. 16902 if (mStartedUsers.get(userId) == null) { 16903 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16904 updateStartedUserArrayLocked(); 16905 needStart = true; 16906 } 16907 16908 final Integer userIdInt = Integer.valueOf(userId); 16909 mUserLru.remove(userIdInt); 16910 mUserLru.add(userIdInt); 16911 16912 if (foreground) { 16913 mCurrentUserId = userId; 16914 updateCurrentProfileIdsLocked(); 16915 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16916 // Once the internal notion of the active user has switched, we lock the device 16917 // with the option to show the user switcher on the keyguard. 16918 mWindowManager.lockNow(null); 16919 } else { 16920 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16921 updateCurrentProfileIdsLocked(); 16922 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16923 mUserLru.remove(currentUserIdInt); 16924 mUserLru.add(currentUserIdInt); 16925 } 16926 16927 final UserStartedState uss = mStartedUsers.get(userId); 16928 16929 // Make sure user is in the started state. If it is currently 16930 // stopping, we need to knock that off. 16931 if (uss.mState == UserStartedState.STATE_STOPPING) { 16932 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16933 // so we can just fairly silently bring the user back from 16934 // the almost-dead. 16935 uss.mState = UserStartedState.STATE_RUNNING; 16936 updateStartedUserArrayLocked(); 16937 needStart = true; 16938 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16939 // This means ACTION_SHUTDOWN has been sent, so we will 16940 // need to treat this as a new boot of the user. 16941 uss.mState = UserStartedState.STATE_BOOTING; 16942 updateStartedUserArrayLocked(); 16943 needStart = true; 16944 } 16945 16946 if (uss.mState == UserStartedState.STATE_BOOTING) { 16947 // Booting up a new user, need to tell system services about it. 16948 // Note that this is on the same handler as scheduling of broadcasts, 16949 // which is important because it needs to go first. 16950 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16951 } 16952 16953 if (foreground) { 16954 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16955 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16956 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16957 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16958 oldUserId, userId, uss)); 16959 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16960 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16961 } 16962 16963 if (needStart) { 16964 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16965 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16966 | Intent.FLAG_RECEIVER_FOREGROUND); 16967 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16968 broadcastIntentLocked(null, null, intent, 16969 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16970 false, false, MY_PID, Process.SYSTEM_UID, userId); 16971 } 16972 16973 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16974 if (userId != UserHandle.USER_OWNER) { 16975 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16976 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16977 broadcastIntentLocked(null, null, intent, null, 16978 new IIntentReceiver.Stub() { 16979 public void performReceive(Intent intent, int resultCode, 16980 String data, Bundle extras, boolean ordered, 16981 boolean sticky, int sendingUser) { 16982 userInitialized(uss, userId); 16983 } 16984 }, 0, null, null, null, AppOpsManager.OP_NONE, 16985 true, false, MY_PID, Process.SYSTEM_UID, 16986 userId); 16987 uss.initializing = true; 16988 } else { 16989 getUserManagerLocked().makeInitialized(userInfo.id); 16990 } 16991 } 16992 16993 if (foreground) { 16994 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16995 if (homeInFront) { 16996 startHomeActivityLocked(userId); 16997 } else { 16998 mStackSupervisor.resumeTopActivitiesLocked(); 16999 } 17000 EventLogTags.writeAmSwitchUser(userId); 17001 getUserManagerLocked().userForeground(userId); 17002 sendUserSwitchBroadcastsLocked(oldUserId, userId); 17003 } else { 17004 mStackSupervisor.startBackgroundUserLocked(userId, uss); 17005 } 17006 17007 if (needStart) { 17008 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 17009 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17010 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17011 broadcastIntentLocked(null, null, intent, 17012 null, new IIntentReceiver.Stub() { 17013 @Override 17014 public void performReceive(Intent intent, int resultCode, String data, 17015 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 17016 throws RemoteException { 17017 } 17018 }, 0, null, null, 17019 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17020 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17021 } 17022 } 17023 } finally { 17024 Binder.restoreCallingIdentity(ident); 17025 } 17026 17027 return true; 17028 } 17029 17030 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 17031 long ident = Binder.clearCallingIdentity(); 17032 try { 17033 Intent intent; 17034 if (oldUserId >= 0) { 17035 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 17036 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17037 | Intent.FLAG_RECEIVER_FOREGROUND); 17038 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 17039 broadcastIntentLocked(null, null, intent, 17040 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17041 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 17042 } 17043 if (newUserId >= 0) { 17044 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 17045 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17046 | Intent.FLAG_RECEIVER_FOREGROUND); 17047 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17048 broadcastIntentLocked(null, null, intent, 17049 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17050 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 17051 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17052 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17053 | Intent.FLAG_RECEIVER_FOREGROUND); 17054 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17055 broadcastIntentLocked(null, null, intent, 17056 null, null, 0, null, null, 17057 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17058 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17059 } 17060 } finally { 17061 Binder.restoreCallingIdentity(ident); 17062 } 17063 } 17064 17065 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17066 final int newUserId) { 17067 final int N = mUserSwitchObservers.beginBroadcast(); 17068 if (N > 0) { 17069 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17070 int mCount = 0; 17071 @Override 17072 public void sendResult(Bundle data) throws RemoteException { 17073 synchronized (ActivityManagerService.this) { 17074 if (mCurUserSwitchCallback == this) { 17075 mCount++; 17076 if (mCount == N) { 17077 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17078 } 17079 } 17080 } 17081 } 17082 }; 17083 synchronized (this) { 17084 uss.switching = true; 17085 mCurUserSwitchCallback = callback; 17086 } 17087 for (int i=0; i<N; i++) { 17088 try { 17089 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17090 newUserId, callback); 17091 } catch (RemoteException e) { 17092 } 17093 } 17094 } else { 17095 synchronized (this) { 17096 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17097 } 17098 } 17099 mUserSwitchObservers.finishBroadcast(); 17100 } 17101 17102 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17103 synchronized (this) { 17104 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17105 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17106 } 17107 } 17108 17109 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17110 mCurUserSwitchCallback = null; 17111 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17112 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17113 oldUserId, newUserId, uss)); 17114 } 17115 17116 void userInitialized(UserStartedState uss, int newUserId) { 17117 completeSwitchAndInitalize(uss, newUserId, true, false); 17118 } 17119 17120 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17121 completeSwitchAndInitalize(uss, newUserId, false, true); 17122 } 17123 17124 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17125 boolean clearInitializing, boolean clearSwitching) { 17126 boolean unfrozen = false; 17127 synchronized (this) { 17128 if (clearInitializing) { 17129 uss.initializing = false; 17130 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17131 } 17132 if (clearSwitching) { 17133 uss.switching = false; 17134 } 17135 if (!uss.switching && !uss.initializing) { 17136 mWindowManager.stopFreezingScreen(); 17137 unfrozen = true; 17138 } 17139 } 17140 if (unfrozen) { 17141 final int N = mUserSwitchObservers.beginBroadcast(); 17142 for (int i=0; i<N; i++) { 17143 try { 17144 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17145 } catch (RemoteException e) { 17146 } 17147 } 17148 mUserSwitchObservers.finishBroadcast(); 17149 } 17150 } 17151 17152 void scheduleStartProfilesLocked() { 17153 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17154 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17155 DateUtils.SECOND_IN_MILLIS); 17156 } 17157 } 17158 17159 void startProfilesLocked() { 17160 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17161 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17162 mCurrentUserId, false /* enabledOnly */); 17163 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17164 for (UserInfo user : profiles) { 17165 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17166 && user.id != mCurrentUserId) { 17167 toStart.add(user); 17168 } 17169 } 17170 final int n = toStart.size(); 17171 int i = 0; 17172 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17173 startUserInBackground(toStart.get(i).id); 17174 } 17175 if (i < n) { 17176 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17177 } 17178 } 17179 17180 void finishUserBoot(UserStartedState uss) { 17181 synchronized (this) { 17182 if (uss.mState == UserStartedState.STATE_BOOTING 17183 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17184 uss.mState = UserStartedState.STATE_RUNNING; 17185 final int userId = uss.mHandle.getIdentifier(); 17186 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17187 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17188 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17189 broadcastIntentLocked(null, null, intent, 17190 null, null, 0, null, null, 17191 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17192 true, false, MY_PID, Process.SYSTEM_UID, userId); 17193 } 17194 } 17195 } 17196 17197 void finishUserSwitch(UserStartedState uss) { 17198 synchronized (this) { 17199 finishUserBoot(uss); 17200 17201 startProfilesLocked(); 17202 17203 int num = mUserLru.size(); 17204 int i = 0; 17205 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17206 Integer oldUserId = mUserLru.get(i); 17207 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17208 if (oldUss == null) { 17209 // Shouldn't happen, but be sane if it does. 17210 mUserLru.remove(i); 17211 num--; 17212 continue; 17213 } 17214 if (oldUss.mState == UserStartedState.STATE_STOPPING 17215 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17216 // This user is already stopping, doesn't count. 17217 num--; 17218 i++; 17219 continue; 17220 } 17221 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17222 // Owner and current can't be stopped, but count as running. 17223 i++; 17224 continue; 17225 } 17226 // This is a user to be stopped. 17227 stopUserLocked(oldUserId, null); 17228 num--; 17229 i++; 17230 } 17231 } 17232 } 17233 17234 @Override 17235 public int stopUser(final int userId, final IStopUserCallback callback) { 17236 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17237 != PackageManager.PERMISSION_GRANTED) { 17238 String msg = "Permission Denial: switchUser() from pid=" 17239 + Binder.getCallingPid() 17240 + ", uid=" + Binder.getCallingUid() 17241 + " requires " + INTERACT_ACROSS_USERS_FULL; 17242 Slog.w(TAG, msg); 17243 throw new SecurityException(msg); 17244 } 17245 if (userId <= 0) { 17246 throw new IllegalArgumentException("Can't stop primary user " + userId); 17247 } 17248 synchronized (this) { 17249 return stopUserLocked(userId, callback); 17250 } 17251 } 17252 17253 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17254 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17255 if (mCurrentUserId == userId) { 17256 return ActivityManager.USER_OP_IS_CURRENT; 17257 } 17258 17259 final UserStartedState uss = mStartedUsers.get(userId); 17260 if (uss == null) { 17261 // User is not started, nothing to do... but we do need to 17262 // callback if requested. 17263 if (callback != null) { 17264 mHandler.post(new Runnable() { 17265 @Override 17266 public void run() { 17267 try { 17268 callback.userStopped(userId); 17269 } catch (RemoteException e) { 17270 } 17271 } 17272 }); 17273 } 17274 return ActivityManager.USER_OP_SUCCESS; 17275 } 17276 17277 if (callback != null) { 17278 uss.mStopCallbacks.add(callback); 17279 } 17280 17281 if (uss.mState != UserStartedState.STATE_STOPPING 17282 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17283 uss.mState = UserStartedState.STATE_STOPPING; 17284 updateStartedUserArrayLocked(); 17285 17286 long ident = Binder.clearCallingIdentity(); 17287 try { 17288 // We are going to broadcast ACTION_USER_STOPPING and then 17289 // once that is done send a final ACTION_SHUTDOWN and then 17290 // stop the user. 17291 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17292 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17293 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17294 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17295 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17296 // This is the result receiver for the final shutdown broadcast. 17297 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17298 @Override 17299 public void performReceive(Intent intent, int resultCode, String data, 17300 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17301 finishUserStop(uss); 17302 } 17303 }; 17304 // This is the result receiver for the initial stopping broadcast. 17305 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17306 @Override 17307 public void performReceive(Intent intent, int resultCode, String data, 17308 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17309 // On to the next. 17310 synchronized (ActivityManagerService.this) { 17311 if (uss.mState != UserStartedState.STATE_STOPPING) { 17312 // Whoops, we are being started back up. Abort, abort! 17313 return; 17314 } 17315 uss.mState = UserStartedState.STATE_SHUTDOWN; 17316 } 17317 mSystemServiceManager.stopUser(userId); 17318 broadcastIntentLocked(null, null, shutdownIntent, 17319 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17320 true, false, MY_PID, Process.SYSTEM_UID, userId); 17321 } 17322 }; 17323 // Kick things off. 17324 broadcastIntentLocked(null, null, stoppingIntent, 17325 null, stoppingReceiver, 0, null, null, 17326 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17327 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17328 } finally { 17329 Binder.restoreCallingIdentity(ident); 17330 } 17331 } 17332 17333 return ActivityManager.USER_OP_SUCCESS; 17334 } 17335 17336 void finishUserStop(UserStartedState uss) { 17337 final int userId = uss.mHandle.getIdentifier(); 17338 boolean stopped; 17339 ArrayList<IStopUserCallback> callbacks; 17340 synchronized (this) { 17341 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17342 if (mStartedUsers.get(userId) != uss) { 17343 stopped = false; 17344 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17345 stopped = false; 17346 } else { 17347 stopped = true; 17348 // User can no longer run. 17349 mStartedUsers.remove(userId); 17350 mUserLru.remove(Integer.valueOf(userId)); 17351 updateStartedUserArrayLocked(); 17352 17353 // Clean up all state and processes associated with the user. 17354 // Kill all the processes for the user. 17355 forceStopUserLocked(userId, "finish user"); 17356 } 17357 } 17358 17359 for (int i=0; i<callbacks.size(); i++) { 17360 try { 17361 if (stopped) callbacks.get(i).userStopped(userId); 17362 else callbacks.get(i).userStopAborted(userId); 17363 } catch (RemoteException e) { 17364 } 17365 } 17366 17367 if (stopped) { 17368 mSystemServiceManager.cleanupUser(userId); 17369 synchronized (this) { 17370 mStackSupervisor.removeUserLocked(userId); 17371 } 17372 } 17373 } 17374 17375 @Override 17376 public UserInfo getCurrentUser() { 17377 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17378 != PackageManager.PERMISSION_GRANTED) && ( 17379 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17380 != PackageManager.PERMISSION_GRANTED)) { 17381 String msg = "Permission Denial: getCurrentUser() from pid=" 17382 + Binder.getCallingPid() 17383 + ", uid=" + Binder.getCallingUid() 17384 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17385 Slog.w(TAG, msg); 17386 throw new SecurityException(msg); 17387 } 17388 synchronized (this) { 17389 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17390 } 17391 } 17392 17393 int getCurrentUserIdLocked() { 17394 return mCurrentUserId; 17395 } 17396 17397 @Override 17398 public boolean isUserRunning(int userId, boolean orStopped) { 17399 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17400 != PackageManager.PERMISSION_GRANTED) { 17401 String msg = "Permission Denial: isUserRunning() from pid=" 17402 + Binder.getCallingPid() 17403 + ", uid=" + Binder.getCallingUid() 17404 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17405 Slog.w(TAG, msg); 17406 throw new SecurityException(msg); 17407 } 17408 synchronized (this) { 17409 return isUserRunningLocked(userId, orStopped); 17410 } 17411 } 17412 17413 boolean isUserRunningLocked(int userId, boolean orStopped) { 17414 UserStartedState state = mStartedUsers.get(userId); 17415 if (state == null) { 17416 return false; 17417 } 17418 if (orStopped) { 17419 return true; 17420 } 17421 return state.mState != UserStartedState.STATE_STOPPING 17422 && state.mState != UserStartedState.STATE_SHUTDOWN; 17423 } 17424 17425 @Override 17426 public int[] getRunningUserIds() { 17427 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17428 != PackageManager.PERMISSION_GRANTED) { 17429 String msg = "Permission Denial: isUserRunning() from pid=" 17430 + Binder.getCallingPid() 17431 + ", uid=" + Binder.getCallingUid() 17432 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17433 Slog.w(TAG, msg); 17434 throw new SecurityException(msg); 17435 } 17436 synchronized (this) { 17437 return mStartedUserArray; 17438 } 17439 } 17440 17441 private void updateStartedUserArrayLocked() { 17442 int num = 0; 17443 for (int i=0; i<mStartedUsers.size(); i++) { 17444 UserStartedState uss = mStartedUsers.valueAt(i); 17445 // This list does not include stopping users. 17446 if (uss.mState != UserStartedState.STATE_STOPPING 17447 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17448 num++; 17449 } 17450 } 17451 mStartedUserArray = new int[num]; 17452 num = 0; 17453 for (int i=0; i<mStartedUsers.size(); i++) { 17454 UserStartedState uss = mStartedUsers.valueAt(i); 17455 if (uss.mState != UserStartedState.STATE_STOPPING 17456 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17457 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17458 num++; 17459 } 17460 } 17461 } 17462 17463 @Override 17464 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17465 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17466 != PackageManager.PERMISSION_GRANTED) { 17467 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17468 + Binder.getCallingPid() 17469 + ", uid=" + Binder.getCallingUid() 17470 + " requires " + INTERACT_ACROSS_USERS_FULL; 17471 Slog.w(TAG, msg); 17472 throw new SecurityException(msg); 17473 } 17474 17475 mUserSwitchObservers.register(observer); 17476 } 17477 17478 @Override 17479 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17480 mUserSwitchObservers.unregister(observer); 17481 } 17482 17483 private boolean userExists(int userId) { 17484 if (userId == 0) { 17485 return true; 17486 } 17487 UserManagerService ums = getUserManagerLocked(); 17488 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17489 } 17490 17491 int[] getUsersLocked() { 17492 UserManagerService ums = getUserManagerLocked(); 17493 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17494 } 17495 17496 UserManagerService getUserManagerLocked() { 17497 if (mUserManager == null) { 17498 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17499 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17500 } 17501 return mUserManager; 17502 } 17503 17504 private int applyUserId(int uid, int userId) { 17505 return UserHandle.getUid(userId, uid); 17506 } 17507 17508 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17509 if (info == null) return null; 17510 ApplicationInfo newInfo = new ApplicationInfo(info); 17511 newInfo.uid = applyUserId(info.uid, userId); 17512 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17513 + info.packageName; 17514 return newInfo; 17515 } 17516 17517 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17518 if (aInfo == null 17519 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17520 return aInfo; 17521 } 17522 17523 ActivityInfo info = new ActivityInfo(aInfo); 17524 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17525 return info; 17526 } 17527 17528 private final class LocalService extends ActivityManagerInternal { 17529 @Override 17530 public void goingToSleep() { 17531 ActivityManagerService.this.goingToSleep(); 17532 } 17533 17534 @Override 17535 public void wakingUp() { 17536 ActivityManagerService.this.wakingUp(); 17537 } 17538 } 17539 17540 /** 17541 * An implementation of IAppTask, that allows an app to manage its own tasks via 17542 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17543 * only the process that calls getAppTasks() can call the AppTask methods. 17544 */ 17545 class AppTaskImpl extends IAppTask.Stub { 17546 private int mTaskId; 17547 private int mCallingUid; 17548 17549 public AppTaskImpl(int taskId, int callingUid) { 17550 mTaskId = taskId; 17551 mCallingUid = callingUid; 17552 } 17553 17554 @Override 17555 public void finishAndRemoveTask() { 17556 // Ensure that we are called from the same process that created this AppTask 17557 if (mCallingUid != Binder.getCallingUid()) { 17558 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17559 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17560 return; 17561 } 17562 17563 synchronized (ActivityManagerService.this) { 17564 long origId = Binder.clearCallingIdentity(); 17565 try { 17566 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17567 if (tr != null) { 17568 // Only kill the process if we are not a new document 17569 int flags = tr.getBaseIntent().getFlags(); 17570 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17571 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17572 removeTaskByIdLocked(mTaskId, 17573 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17574 } 17575 } finally { 17576 Binder.restoreCallingIdentity(origId); 17577 } 17578 } 17579 } 17580 17581 @Override 17582 public ActivityManager.RecentTaskInfo getTaskInfo() { 17583 // Ensure that we are called from the same process that created this AppTask 17584 if (mCallingUid != Binder.getCallingUid()) { 17585 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17586 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17587 return null; 17588 } 17589 17590 synchronized (ActivityManagerService.this) { 17591 long origId = Binder.clearCallingIdentity(); 17592 try { 17593 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17594 if (tr != null) { 17595 return createRecentTaskInfoFromTaskRecord(tr); 17596 } 17597 } finally { 17598 Binder.restoreCallingIdentity(origId); 17599 } 17600 return null; 17601 } 17602 } 17603 } 17604} 17605