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 17 package com.android.server.am; 18 19 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 import static com.android.internal.util.XmlUtils.readIntAttribute; 21 import static com.android.internal.util.XmlUtils.readLongAttribute; 22 import static com.android.internal.util.XmlUtils.writeIntAttribute; 23 import static com.android.internal.util.XmlUtils.writeLongAttribute; 24 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 25 import static org.xmlpull.v1.XmlPullParser.START_TAG; 26 27 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 28 29 import android.app.AppOpsManager; 30 import android.appwidget.AppWidgetManager; 31 import android.util.ArrayMap; 32 import com.android.internal.R; 33 import com.android.internal.annotations.GuardedBy; 34 import com.android.internal.app.IAppOpsService; 35 import com.android.internal.app.ProcessStats; 36 import com.android.internal.app.ResolverActivity; 37 import com.android.internal.os.BackgroundThread; 38 import com.android.internal.os.BatteryStatsImpl; 39 import com.android.internal.os.ProcessCpuTracker; 40 import com.android.internal.os.TransferPipe; 41 import com.android.internal.util.FastPrintWriter; 42 import com.android.internal.util.FastXmlSerializer; 43 import com.android.internal.util.MemInfoReader; 44 import com.android.internal.util.Preconditions; 45 import com.android.server.AppOpsService; 46 import com.android.server.AttributeCache; 47 import com.android.server.IntentResolver; 48 import com.android.internal.app.ProcessMap; 49 import com.android.server.SystemServer; 50 import com.android.server.Watchdog; 51 import com.android.server.am.ActivityStack.ActivityState; 52 import com.android.server.firewall.IntentFirewall; 53 import com.android.server.pm.UserManagerService; 54 import com.android.server.wm.AppTransition; 55 import com.android.server.wm.StackBox; 56 import com.android.server.wm.WindowManagerService; 57 import com.google.android.collect.Lists; 58 import com.google.android.collect.Maps; 59 60 import dalvik.system.Zygote; 61 62 import libcore.io.IoUtils; 63 64 import org.xmlpull.v1.XmlPullParser; 65 import org.xmlpull.v1.XmlPullParserException; 66 import org.xmlpull.v1.XmlSerializer; 67 68 import android.app.Activity; 69 import android.app.ActivityManager; 70 import android.app.ActivityManager.RunningTaskInfo; 71 import android.app.ActivityManager.StackBoxInfo; 72 import android.app.ActivityManager.StackInfo; 73 import android.app.ActivityManagerNative; 74 import android.app.ActivityOptions; 75 import android.app.ActivityThread; 76 import android.app.AlertDialog; 77 import android.app.AppGlobals; 78 import android.app.ApplicationErrorReport; 79 import android.app.Dialog; 80 import android.app.IActivityController; 81 import android.app.IApplicationThread; 82 import android.app.IInstrumentationWatcher; 83 import android.app.INotificationManager; 84 import android.app.IProcessObserver; 85 import android.app.IServiceConnection; 86 import android.app.IStopUserCallback; 87 import android.app.IThumbnailReceiver; 88 import android.app.IUiAutomationConnection; 89 import android.app.IUserSwitchObserver; 90 import android.app.Instrumentation; 91 import android.app.Notification; 92 import android.app.NotificationManager; 93 import android.app.PendingIntent; 94 import android.app.backup.IBackupManager; 95 import android.content.ActivityNotFoundException; 96 import android.content.BroadcastReceiver; 97 import android.content.ClipData; 98 import android.content.ComponentCallbacks2; 99 import android.content.ComponentName; 100 import android.content.ContentProvider; 101 import android.content.ContentResolver; 102 import android.content.Context; 103 import android.content.DialogInterface; 104 import android.content.IContentProvider; 105 import android.content.IIntentReceiver; 106 import android.content.IIntentSender; 107 import android.content.Intent; 108 import android.content.IntentFilter; 109 import android.content.IntentSender; 110 import android.content.pm.ActivityInfo; 111 import android.content.pm.ApplicationInfo; 112 import android.content.pm.ConfigurationInfo; 113 import android.content.pm.IPackageDataObserver; 114 import android.content.pm.IPackageManager; 115 import android.content.pm.InstrumentationInfo; 116 import android.content.pm.PackageInfo; 117 import android.content.pm.PackageManager; 118 import android.content.pm.ParceledListSlice; 119 import android.content.pm.UserInfo; 120 import android.content.pm.PackageManager.NameNotFoundException; 121 import android.content.pm.PathPermission; 122 import android.content.pm.ProviderInfo; 123 import android.content.pm.ResolveInfo; 124 import android.content.pm.ServiceInfo; 125 import android.content.res.CompatibilityInfo; 126 import android.content.res.Configuration; 127 import android.graphics.Bitmap; 128 import android.net.Proxy; 129 import android.net.ProxyProperties; 130 import android.net.Uri; 131 import android.os.Binder; 132 import android.os.Build; 133 import android.os.Bundle; 134 import android.os.Debug; 135 import android.os.DropBoxManager; 136 import android.os.Environment; 137 import android.os.FileObserver; 138 import android.os.FileUtils; 139 import android.os.Handler; 140 import android.os.IBinder; 141 import android.os.IPermissionController; 142 import android.os.IRemoteCallback; 143 import android.os.IUserManager; 144 import android.os.Looper; 145 import android.os.Message; 146 import android.os.Parcel; 147 import android.os.ParcelFileDescriptor; 148 import android.os.Process; 149 import android.os.RemoteCallbackList; 150 import android.os.RemoteException; 151 import android.os.SELinux; 152 import android.os.ServiceManager; 153 import android.os.StrictMode; 154 import android.os.SystemClock; 155 import android.os.SystemProperties; 156 import android.os.UpdateLock; 157 import android.os.UserHandle; 158 import android.provider.Settings; 159 import android.text.format.DateUtils; 160 import android.text.format.Time; 161 import android.util.AtomicFile; 162 import android.util.EventLog; 163 import android.util.Log; 164 import android.util.Pair; 165 import android.util.PrintWriterPrinter; 166 import android.util.Slog; 167 import android.util.SparseArray; 168 import android.util.TimeUtils; 169 import android.util.Xml; 170 import android.view.Gravity; 171 import android.view.LayoutInflater; 172 import android.view.View; 173 import android.view.WindowManager; 174 175 import java.io.BufferedInputStream; 176 import java.io.BufferedOutputStream; 177 import java.io.DataInputStream; 178 import java.io.DataOutputStream; 179 import java.io.File; 180 import java.io.FileDescriptor; 181 import java.io.FileInputStream; 182 import java.io.FileNotFoundException; 183 import java.io.FileOutputStream; 184 import java.io.IOException; 185 import java.io.InputStreamReader; 186 import java.io.PrintWriter; 187 import java.io.StringWriter; 188 import java.lang.ref.WeakReference; 189 import java.util.ArrayList; 190 import java.util.Arrays; 191 import java.util.Collections; 192 import java.util.Comparator; 193 import java.util.HashMap; 194 import java.util.HashSet; 195 import java.util.Iterator; 196 import java.util.List; 197 import java.util.Locale; 198 import java.util.Map; 199 import java.util.Set; 200 import java.util.concurrent.atomic.AtomicBoolean; 201 import java.util.concurrent.atomic.AtomicLong; 202 203 public final class ActivityManagerService extends ActivityManagerNative 204 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 205 private static final String USER_DATA_DIR = "/data/user/"; 206 static final String TAG = "ActivityManager"; 207 static final String TAG_MU = "ActivityManagerServiceMU"; 208 static final boolean DEBUG = false; 209 static final boolean localLOGV = DEBUG; 210 static final boolean DEBUG_BACKUP = localLOGV || false; 211 static final boolean DEBUG_BROADCAST = localLOGV || false; 212 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 213 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 214 static final boolean DEBUG_CLEANUP = localLOGV || false; 215 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 216 static final boolean DEBUG_FOCUS = false; 217 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 218 static final boolean DEBUG_MU = localLOGV || false; 219 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 220 static final boolean DEBUG_PAUSE = localLOGV || false; 221 static final boolean DEBUG_POWER = localLOGV || false; 222 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 223 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 224 static final boolean DEBUG_PROCESSES = localLOGV || false; 225 static final boolean DEBUG_PROVIDER = localLOGV || false; 226 static final boolean DEBUG_RESULTS = localLOGV || false; 227 static final boolean DEBUG_SERVICE = localLOGV || false; 228 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 229 static final boolean DEBUG_STACK = localLOGV || false; 230 static final boolean DEBUG_SWITCH = localLOGV || false; 231 static final boolean DEBUG_TASKS = localLOGV || false; 232 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 233 static final boolean DEBUG_TRANSITION = localLOGV || false; 234 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 235 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 236 static final boolean DEBUG_VISBILITY = localLOGV || false; 237 static final boolean DEBUG_PSS = localLOGV || false; 238 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 239 static final boolean VALIDATE_TOKENS = false; 240 static final boolean SHOW_ACTIVITY_START_TIME = true; 241 242 // Control over CPU and battery monitoring. 243 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 244 static final boolean MONITOR_CPU_USAGE = true; 245 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 246 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 247 static final boolean MONITOR_THREAD_CPU_USAGE = false; 248 249 // The flags that are set for all calls we make to the package manager. 250 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 251 252 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 253 254 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 255 256 // Maximum number of recent tasks that we can remember. 257 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 258 259 // Amount of time after a call to stopAppSwitches() during which we will 260 // prevent further untrusted switches from happening. 261 static final long APP_SWITCH_DELAY_TIME = 5*1000; 262 263 // How long we wait for a launched process to attach to the activity manager 264 // before we decide it's never going to come up for real. 265 static final int PROC_START_TIMEOUT = 10*1000; 266 267 // How long we wait for a launched process to attach to the activity manager 268 // before we decide it's never going to come up for real, when the process was 269 // started with a wrapper for instrumentation (such as Valgrind) because it 270 // could take much longer than usual. 271 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 272 273 // How long to wait after going idle before forcing apps to GC. 274 static final int GC_TIMEOUT = 5*1000; 275 276 // The minimum amount of time between successive GC requests for a process. 277 static final int GC_MIN_INTERVAL = 60*1000; 278 279 // The minimum amount of time between successive PSS requests for a process. 280 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 281 282 // The minimum amount of time between successive PSS requests for a process 283 // when the request is due to the memory state being lowered. 284 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 285 286 // The rate at which we check for apps using excessive power -- 15 mins. 287 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 288 289 // The minimum sample duration we will allow before deciding we have 290 // enough data on wake locks to start killing things. 291 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 292 293 // The minimum sample duration we will allow before deciding we have 294 // enough data on CPU usage to start killing things. 295 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 296 297 // How long we allow a receiver to run before giving up on it. 298 static final int BROADCAST_FG_TIMEOUT = 10*1000; 299 static final int BROADCAST_BG_TIMEOUT = 60*1000; 300 301 // How long we wait until we timeout on key dispatching. 302 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 303 304 // How long we wait until we timeout on key dispatching during instrumentation. 305 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 306 307 // Amount of time we wait for observers to handle a user switch before 308 // giving up on them and unfreezing the screen. 309 static final int USER_SWITCH_TIMEOUT = 2*1000; 310 311 // Maximum number of users we allow to be running at a time. 312 static final int MAX_RUNNING_USERS = 3; 313 314 // How long to wait in getAssistContextExtras for the activity and foreground services 315 // to respond with the result. 316 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 317 318 // Maximum number of persisted Uri grants a package is allowed 319 static final int MAX_PERSISTED_URI_GRANTS = 128; 320 321 static final int MY_PID = Process.myPid(); 322 323 static final String[] EMPTY_STRING_ARRAY = new String[0]; 324 325 /** Run all ActivityStacks through this */ 326 ActivityStackSupervisor mStackSupervisor; 327 328 public IntentFirewall mIntentFirewall; 329 330 private final boolean mHeadless; 331 332 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 333 // default actuion automatically. Important for devices without direct input 334 // devices. 335 private boolean mShowDialogs = true; 336 337 /** 338 * Description of a request to start a new activity, which has been held 339 * due to app switches being disabled. 340 */ 341 static class PendingActivityLaunch { 342 final ActivityRecord r; 343 final ActivityRecord sourceRecord; 344 final int startFlags; 345 final ActivityStack stack; 346 347 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 348 int _startFlags, ActivityStack _stack) { 349 r = _r; 350 sourceRecord = _sourceRecord; 351 startFlags = _startFlags; 352 stack = _stack; 353 } 354 } 355 356 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 357 = new ArrayList<PendingActivityLaunch>(); 358 359 BroadcastQueue mFgBroadcastQueue; 360 BroadcastQueue mBgBroadcastQueue; 361 // Convenient for easy iteration over the queues. Foreground is first 362 // so that dispatch of foreground broadcasts gets precedence. 363 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 364 365 BroadcastQueue broadcastQueueForIntent(Intent intent) { 366 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 367 if (DEBUG_BACKGROUND_BROADCAST) { 368 Slog.i(TAG, "Broadcast intent " + intent + " on " 369 + (isFg ? "foreground" : "background") 370 + " queue"); 371 } 372 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 373 } 374 375 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 376 for (BroadcastQueue queue : mBroadcastQueues) { 377 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 378 if (r != null) { 379 return r; 380 } 381 } 382 return null; 383 } 384 385 /** 386 * Activity we have told the window manager to have key focus. 387 */ 388 ActivityRecord mFocusedActivity = null; 389 390 /** 391 * List of intents that were used to start the most recent tasks. 392 */ 393 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 394 395 public class PendingAssistExtras extends Binder implements Runnable { 396 public final ActivityRecord activity; 397 public boolean haveResult = false; 398 public Bundle result = null; 399 public PendingAssistExtras(ActivityRecord _activity) { 400 activity = _activity; 401 } 402 @Override 403 public void run() { 404 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 405 synchronized (this) { 406 haveResult = true; 407 notifyAll(); 408 } 409 } 410 } 411 412 final ArrayList<PendingAssistExtras> mPendingAssistExtras 413 = new ArrayList<PendingAssistExtras>(); 414 415 /** 416 * Process management. 417 */ 418 final ProcessList mProcessList = new ProcessList(); 419 420 /** 421 * All of the applications we currently have running organized by name. 422 * The keys are strings of the application package name (as 423 * returned by the package manager), and the keys are ApplicationRecord 424 * objects. 425 */ 426 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 427 428 /** 429 * Tracking long-term execution of processes to look for abuse and other 430 * bad app behavior. 431 */ 432 final ProcessStatsService mProcessStats; 433 434 /** 435 * The currently running isolated processes. 436 */ 437 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 438 439 /** 440 * Counter for assigning isolated process uids, to avoid frequently reusing the 441 * same ones. 442 */ 443 int mNextIsolatedProcessUid = 0; 444 445 /** 446 * The currently running heavy-weight process, if any. 447 */ 448 ProcessRecord mHeavyWeightProcess = null; 449 450 /** 451 * The last time that various processes have crashed. 452 */ 453 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 454 455 /** 456 * Set of applications that we consider to be bad, and will reject 457 * incoming broadcasts from (which the user has no control over). 458 * Processes are added to this set when they have crashed twice within 459 * a minimum amount of time; they are removed from it when they are 460 * later restarted (hopefully due to some user action). The value is the 461 * time it was added to the list. 462 */ 463 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 464 465 /** 466 * All of the processes we currently have running organized by pid. 467 * The keys are the pid running the application. 468 * 469 * <p>NOTE: This object is protected by its own lock, NOT the global 470 * activity manager lock! 471 */ 472 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 473 474 /** 475 * All of the processes that have been forced to be foreground. The key 476 * is the pid of the caller who requested it (we hold a death 477 * link on it). 478 */ 479 abstract class ForegroundToken implements IBinder.DeathRecipient { 480 int pid; 481 IBinder token; 482 } 483 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 484 485 /** 486 * List of records for processes that someone had tried to start before the 487 * system was ready. We don't start them at that point, but ensure they 488 * are started by the time booting is complete. 489 */ 490 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 491 492 /** 493 * List of persistent applications that are in the process 494 * of being started. 495 */ 496 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 497 498 /** 499 * Processes that are being forcibly torn down. 500 */ 501 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 502 503 /** 504 * List of running applications, sorted by recent usage. 505 * The first entry in the list is the least recently used. 506 */ 507 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 508 509 /** 510 * Where in mLruProcesses that the processes hosting activities start. 511 */ 512 int mLruProcessActivityStart = 0; 513 514 /** 515 * Where in mLruProcesses that the processes hosting services start. 516 * This is after (lower index) than mLruProcessesActivityStart. 517 */ 518 int mLruProcessServiceStart = 0; 519 520 /** 521 * List of processes that should gc as soon as things are idle. 522 */ 523 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 524 525 /** 526 * Processes we want to collect PSS data from. 527 */ 528 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 529 530 /** 531 * Last time we requested PSS data of all processes. 532 */ 533 long mLastFullPssTime = SystemClock.uptimeMillis(); 534 535 /** 536 * This is the process holding what we currently consider to be 537 * the "home" activity. 538 */ 539 ProcessRecord mHomeProcess; 540 541 /** 542 * This is the process holding the activity the user last visited that 543 * is in a different process from the one they are currently in. 544 */ 545 ProcessRecord mPreviousProcess; 546 547 /** 548 * The time at which the previous process was last visible. 549 */ 550 long mPreviousProcessVisibleTime; 551 552 /** 553 * Which uses have been started, so are allowed to run code. 554 */ 555 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 556 557 /** 558 * LRU list of history of current users. Most recently current is at the end. 559 */ 560 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 561 562 /** 563 * Constant array of the users that are currently started. 564 */ 565 int[] mStartedUserArray = new int[] { 0 }; 566 567 /** 568 * Registered observers of the user switching mechanics. 569 */ 570 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 571 = new RemoteCallbackList<IUserSwitchObserver>(); 572 573 /** 574 * Currently active user switch. 575 */ 576 Object mCurUserSwitchCallback; 577 578 /** 579 * Packages that the user has asked to have run in screen size 580 * compatibility mode instead of filling the screen. 581 */ 582 final CompatModePackages mCompatModePackages; 583 584 /** 585 * Set of IntentSenderRecord objects that are currently active. 586 */ 587 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 588 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 589 590 /** 591 * Fingerprints (hashCode()) of stack traces that we've 592 * already logged DropBox entries for. Guarded by itself. If 593 * something (rogue user app) forces this over 594 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 595 */ 596 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 597 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 598 599 /** 600 * Strict Mode background batched logging state. 601 * 602 * The string buffer is guarded by itself, and its lock is also 603 * used to determine if another batched write is already 604 * in-flight. 605 */ 606 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 607 608 /** 609 * Keeps track of all IIntentReceivers that have been registered for 610 * broadcasts. Hash keys are the receiver IBinder, hash value is 611 * a ReceiverList. 612 */ 613 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 614 new HashMap<IBinder, ReceiverList>(); 615 616 /** 617 * Resolver for broadcast intents to registered receivers. 618 * Holds BroadcastFilter (subclass of IntentFilter). 619 */ 620 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 621 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 622 @Override 623 protected boolean allowFilterResult( 624 BroadcastFilter filter, List<BroadcastFilter> dest) { 625 IBinder target = filter.receiverList.receiver.asBinder(); 626 for (int i=dest.size()-1; i>=0; i--) { 627 if (dest.get(i).receiverList.receiver.asBinder() == target) { 628 return false; 629 } 630 } 631 return true; 632 } 633 634 @Override 635 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 636 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 637 || userId == filter.owningUserId) { 638 return super.newResult(filter, match, userId); 639 } 640 return null; 641 } 642 643 @Override 644 protected BroadcastFilter[] newArray(int size) { 645 return new BroadcastFilter[size]; 646 } 647 648 @Override 649 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 650 return packageName.equals(filter.packageName); 651 } 652 }; 653 654 /** 655 * State of all active sticky broadcasts per user. Keys are the action of the 656 * sticky Intent, values are an ArrayList of all broadcasted intents with 657 * that action (which should usually be one). The SparseArray is keyed 658 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 659 * for stickies that are sent to all users. 660 */ 661 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 662 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 663 664 final ActiveServices mServices; 665 666 /** 667 * Backup/restore process management 668 */ 669 String mBackupAppName = null; 670 BackupRecord mBackupTarget = null; 671 672 /** 673 * List of PendingThumbnailsRecord objects of clients who are still 674 * waiting to receive all of the thumbnails for a task. 675 */ 676 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 677 new ArrayList<PendingThumbnailsRecord>(); 678 679 final ProviderMap mProviderMap; 680 681 /** 682 * List of content providers who have clients waiting for them. The 683 * application is currently being launched and the provider will be 684 * removed from this list once it is published. 685 */ 686 final ArrayList<ContentProviderRecord> mLaunchingProviders 687 = new ArrayList<ContentProviderRecord>(); 688 689 /** 690 * File storing persisted {@link #mGrantedUriPermissions}. 691 */ 692 private final AtomicFile mGrantFile; 693 694 /** XML constants used in {@link #mGrantFile} */ 695 private static final String TAG_URI_GRANTS = "uri-grants"; 696 private static final String TAG_URI_GRANT = "uri-grant"; 697 private static final String ATTR_USER_HANDLE = "userHandle"; 698 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 699 private static final String ATTR_TARGET_PKG = "targetPkg"; 700 private static final String ATTR_URI = "uri"; 701 private static final String ATTR_MODE_FLAGS = "modeFlags"; 702 private static final String ATTR_CREATED_TIME = "createdTime"; 703 704 /** 705 * Global set of specific {@link Uri} permissions that have been granted. 706 * This optimized lookup structure maps from {@link UriPermission#targetUid} 707 * to {@link UriPermission#uri} to {@link UriPermission}. 708 */ 709 @GuardedBy("this") 710 private final SparseArray<ArrayMap<Uri, UriPermission>> 711 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 712 713 CoreSettingsObserver mCoreSettingsObserver; 714 715 /** 716 * Thread-local storage used to carry caller permissions over through 717 * indirect content-provider access. 718 */ 719 private class Identity { 720 public int pid; 721 public int uid; 722 723 Identity(int _pid, int _uid) { 724 pid = _pid; 725 uid = _uid; 726 } 727 } 728 729 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 730 731 /** 732 * All information we have collected about the runtime performance of 733 * any user id that can impact battery performance. 734 */ 735 final BatteryStatsService mBatteryStatsService; 736 737 /** 738 * Information about component usage 739 */ 740 final UsageStatsService mUsageStatsService; 741 742 /** 743 * Information about and control over application operations 744 */ 745 final AppOpsService mAppOpsService; 746 747 /** 748 * Current configuration information. HistoryRecord objects are given 749 * a reference to this object to indicate which configuration they are 750 * currently running in, so this object must be kept immutable. 751 */ 752 Configuration mConfiguration = new Configuration(); 753 754 /** 755 * Current sequencing integer of the configuration, for skipping old 756 * configurations. 757 */ 758 int mConfigurationSeq = 0; 759 760 /** 761 * Hardware-reported OpenGLES version. 762 */ 763 final int GL_ES_VERSION; 764 765 /** 766 * List of initialization arguments to pass to all processes when binding applications to them. 767 * For example, references to the commonly used services. 768 */ 769 HashMap<String, IBinder> mAppBindArgs; 770 771 /** 772 * Temporary to avoid allocations. Protected by main lock. 773 */ 774 final StringBuilder mStringBuilder = new StringBuilder(256); 775 776 /** 777 * Used to control how we initialize the service. 778 */ 779 boolean mStartRunning = false; 780 ComponentName mTopComponent; 781 String mTopAction; 782 String mTopData; 783 boolean mProcessesReady = false; 784 boolean mSystemReady = false; 785 boolean mBooting = false; 786 boolean mWaitingUpdate = false; 787 boolean mDidUpdate = false; 788 boolean mOnBattery = false; 789 boolean mLaunchWarningShown = false; 790 791 Context mContext; 792 793 int mFactoryTest; 794 795 boolean mCheckedForSetup; 796 797 /** 798 * The time at which we will allow normal application switches again, 799 * after a call to {@link #stopAppSwitches()}. 800 */ 801 long mAppSwitchesAllowedTime; 802 803 /** 804 * This is set to true after the first switch after mAppSwitchesAllowedTime 805 * is set; any switches after that will clear the time. 806 */ 807 boolean mDidAppSwitch; 808 809 /** 810 * Last time (in realtime) at which we checked for power usage. 811 */ 812 long mLastPowerCheckRealtime; 813 814 /** 815 * Last time (in uptime) at which we checked for power usage. 816 */ 817 long mLastPowerCheckUptime; 818 819 /** 820 * Set while we are wanting to sleep, to prevent any 821 * activities from being started/resumed. 822 */ 823 boolean mSleeping = false; 824 825 /** 826 * State of external calls telling us if the device is asleep. 827 */ 828 boolean mWentToSleep = false; 829 830 /** 831 * State of external call telling us if the lock screen is shown. 832 */ 833 boolean mLockScreenShown = false; 834 835 /** 836 * Set if we are shutting down the system, similar to sleeping. 837 */ 838 boolean mShuttingDown = false; 839 840 /** 841 * Current sequence id for oom_adj computation traversal. 842 */ 843 int mAdjSeq = 0; 844 845 /** 846 * Current sequence id for process LRU updating. 847 */ 848 int mLruSeq = 0; 849 850 /** 851 * Keep track of the non-cached/empty process we last found, to help 852 * determine how to distribute cached/empty processes next time. 853 */ 854 int mNumNonCachedProcs = 0; 855 856 /** 857 * Keep track of the number of cached hidden procs, to balance oom adj 858 * distribution between those and empty procs. 859 */ 860 int mNumCachedHiddenProcs = 0; 861 862 /** 863 * Keep track of the number of service processes we last found, to 864 * determine on the next iteration which should be B services. 865 */ 866 int mNumServiceProcs = 0; 867 int mNewNumAServiceProcs = 0; 868 int mNewNumServiceProcs = 0; 869 870 /** 871 * Allow the current computed overall memory level of the system to go down? 872 * This is set to false when we are killing processes for reasons other than 873 * memory management, so that the now smaller process list will not be taken as 874 * an indication that memory is tighter. 875 */ 876 boolean mAllowLowerMemLevel = false; 877 878 /** 879 * The last computed memory level, for holding when we are in a state that 880 * processes are going away for other reasons. 881 */ 882 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 883 884 /** 885 * The last total number of process we have, to determine if changes actually look 886 * like a shrinking number of process due to lower RAM. 887 */ 888 int mLastNumProcesses; 889 890 /** 891 * The uptime of the last time we performed idle maintenance. 892 */ 893 long mLastIdleTime = SystemClock.uptimeMillis(); 894 895 /** 896 * Total time spent with RAM that has been added in the past since the last idle time. 897 */ 898 long mLowRamTimeSinceLastIdle = 0; 899 900 /** 901 * If RAM is currently low, when that horrible situatin started. 902 */ 903 long mLowRamStartTime = 0; 904 905 /** 906 * This is set if we had to do a delayed dexopt of an app before launching 907 * it, to increasing the ANR timeouts in that case. 908 */ 909 boolean mDidDexOpt; 910 911 String mDebugApp = null; 912 boolean mWaitForDebugger = false; 913 boolean mDebugTransient = false; 914 String mOrigDebugApp = null; 915 boolean mOrigWaitForDebugger = false; 916 boolean mAlwaysFinishActivities = false; 917 IActivityController mController = null; 918 String mProfileApp = null; 919 ProcessRecord mProfileProc = null; 920 String mProfileFile; 921 ParcelFileDescriptor mProfileFd; 922 int mProfileType = 0; 923 boolean mAutoStopProfiler = false; 924 String mOpenGlTraceApp = null; 925 926 static class ProcessChangeItem { 927 static final int CHANGE_ACTIVITIES = 1<<0; 928 static final int CHANGE_IMPORTANCE= 1<<1; 929 int changes; 930 int uid; 931 int pid; 932 int importance; 933 boolean foregroundActivities; 934 } 935 936 final RemoteCallbackList<IProcessObserver> mProcessObservers 937 = new RemoteCallbackList<IProcessObserver>(); 938 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 939 940 final ArrayList<ProcessChangeItem> mPendingProcessChanges 941 = new ArrayList<ProcessChangeItem>(); 942 final ArrayList<ProcessChangeItem> mAvailProcessChanges 943 = new ArrayList<ProcessChangeItem>(); 944 945 /** 946 * Runtime CPU use collection thread. This object's lock is used to 947 * protect all related state. 948 */ 949 final Thread mProcessCpuThread; 950 951 /** 952 * Used to collect process stats when showing not responding dialog. 953 * Protected by mProcessCpuThread. 954 */ 955 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 956 MONITOR_THREAD_CPU_USAGE); 957 final AtomicLong mLastCpuTime = new AtomicLong(0); 958 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 959 960 long mLastWriteTime = 0; 961 962 /** 963 * Used to retain an update lock when the foreground activity is in 964 * immersive mode. 965 */ 966 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 967 968 /** 969 * Set to true after the system has finished booting. 970 */ 971 boolean mBooted = false; 972 973 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 974 int mProcessLimitOverride = -1; 975 976 WindowManagerService mWindowManager; 977 978 static ActivityManagerService mSelf; 979 static ActivityThread mSystemThread; 980 981 int mCurrentUserId = 0; 982 private UserManagerService mUserManager; 983 984 private final class AppDeathRecipient implements IBinder.DeathRecipient { 985 final ProcessRecord mApp; 986 final int mPid; 987 final IApplicationThread mAppThread; 988 989 AppDeathRecipient(ProcessRecord app, int pid, 990 IApplicationThread thread) { 991 if (localLOGV) Slog.v( 992 TAG, "New death recipient " + this 993 + " for thread " + thread.asBinder()); 994 mApp = app; 995 mPid = pid; 996 mAppThread = thread; 997 } 998 999 @Override 1000 public void binderDied() { 1001 if (localLOGV) Slog.v( 1002 TAG, "Death received in " + this 1003 + " for thread " + mAppThread.asBinder()); 1004 synchronized(ActivityManagerService.this) { 1005 appDiedLocked(mApp, mPid, mAppThread); 1006 } 1007 } 1008 } 1009 1010 static final int SHOW_ERROR_MSG = 1; 1011 static final int SHOW_NOT_RESPONDING_MSG = 2; 1012 static final int SHOW_FACTORY_ERROR_MSG = 3; 1013 static final int UPDATE_CONFIGURATION_MSG = 4; 1014 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1015 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1016 static final int SERVICE_TIMEOUT_MSG = 12; 1017 static final int UPDATE_TIME_ZONE = 13; 1018 static final int SHOW_UID_ERROR_MSG = 14; 1019 static final int IM_FEELING_LUCKY_MSG = 15; 1020 static final int PROC_START_TIMEOUT_MSG = 20; 1021 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1022 static final int KILL_APPLICATION_MSG = 22; 1023 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1024 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1025 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1026 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1027 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1028 static final int CLEAR_DNS_CACHE_MSG = 28; 1029 static final int UPDATE_HTTP_PROXY_MSG = 29; 1030 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1031 static final int DISPATCH_PROCESSES_CHANGED = 31; 1032 static final int DISPATCH_PROCESS_DIED = 32; 1033 static final int REPORT_MEM_USAGE_MSG = 33; 1034 static final int REPORT_USER_SWITCH_MSG = 34; 1035 static final int CONTINUE_USER_SWITCH_MSG = 35; 1036 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1037 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1038 static final int PERSIST_URI_GRANTS_MSG = 38; 1039 static final int REQUEST_ALL_PSS_MSG = 39; 1040 1041 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1042 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1043 static final int FIRST_COMPAT_MODE_MSG = 300; 1044 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1045 1046 AlertDialog mUidAlert; 1047 CompatModeDialog mCompatModeDialog; 1048 long mLastMemUsageReportTime = 0; 1049 1050 /** 1051 * Flag whether the current user is a "monkey", i.e. whether 1052 * the UI is driven by a UI automation tool. 1053 */ 1054 private boolean mUserIsMonkey; 1055 1056 final Handler mHandler = new Handler() { 1057 //public Handler() { 1058 // if (localLOGV) Slog.v(TAG, "Handler started!"); 1059 //} 1060 1061 @Override 1062 public void handleMessage(Message msg) { 1063 switch (msg.what) { 1064 case SHOW_ERROR_MSG: { 1065 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1066 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1067 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1068 synchronized (ActivityManagerService.this) { 1069 ProcessRecord proc = (ProcessRecord)data.get("app"); 1070 AppErrorResult res = (AppErrorResult) data.get("result"); 1071 if (proc != null && proc.crashDialog != null) { 1072 Slog.e(TAG, "App already has crash dialog: " + proc); 1073 if (res != null) { 1074 res.set(0); 1075 } 1076 return; 1077 } 1078 if (!showBackground && UserHandle.getAppId(proc.uid) 1079 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1080 && proc.pid != MY_PID) { 1081 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1082 if (res != null) { 1083 res.set(0); 1084 } 1085 return; 1086 } 1087 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1088 Dialog d = new AppErrorDialog(mContext, 1089 ActivityManagerService.this, res, proc); 1090 d.show(); 1091 proc.crashDialog = d; 1092 } else { 1093 // The device is asleep, so just pretend that the user 1094 // saw a crash dialog and hit "force quit". 1095 if (res != null) { 1096 res.set(0); 1097 } 1098 } 1099 } 1100 1101 ensureBootCompleted(); 1102 } break; 1103 case SHOW_NOT_RESPONDING_MSG: { 1104 synchronized (ActivityManagerService.this) { 1105 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1106 ProcessRecord proc = (ProcessRecord)data.get("app"); 1107 if (proc != null && proc.anrDialog != null) { 1108 Slog.e(TAG, "App already has anr dialog: " + proc); 1109 return; 1110 } 1111 1112 Intent intent = new Intent("android.intent.action.ANR"); 1113 if (!mProcessesReady) { 1114 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1115 | Intent.FLAG_RECEIVER_FOREGROUND); 1116 } 1117 broadcastIntentLocked(null, null, intent, 1118 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1119 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1120 1121 if (mShowDialogs) { 1122 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1123 mContext, proc, (ActivityRecord)data.get("activity"), 1124 msg.arg1 != 0); 1125 d.show(); 1126 proc.anrDialog = d; 1127 } else { 1128 // Just kill the app if there is no dialog to be shown. 1129 killAppAtUsersRequest(proc, null); 1130 } 1131 } 1132 1133 ensureBootCompleted(); 1134 } break; 1135 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1136 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1137 synchronized (ActivityManagerService.this) { 1138 ProcessRecord proc = (ProcessRecord) data.get("app"); 1139 if (proc == null) { 1140 Slog.e(TAG, "App not found when showing strict mode dialog."); 1141 break; 1142 } 1143 if (proc.crashDialog != null) { 1144 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1145 return; 1146 } 1147 AppErrorResult res = (AppErrorResult) data.get("result"); 1148 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1149 Dialog d = new StrictModeViolationDialog(mContext, 1150 ActivityManagerService.this, res, proc); 1151 d.show(); 1152 proc.crashDialog = d; 1153 } else { 1154 // The device is asleep, so just pretend that the user 1155 // saw a crash dialog and hit "force quit". 1156 res.set(0); 1157 } 1158 } 1159 ensureBootCompleted(); 1160 } break; 1161 case SHOW_FACTORY_ERROR_MSG: { 1162 Dialog d = new FactoryErrorDialog( 1163 mContext, msg.getData().getCharSequence("msg")); 1164 d.show(); 1165 ensureBootCompleted(); 1166 } break; 1167 case UPDATE_CONFIGURATION_MSG: { 1168 final ContentResolver resolver = mContext.getContentResolver(); 1169 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1170 } break; 1171 case GC_BACKGROUND_PROCESSES_MSG: { 1172 synchronized (ActivityManagerService.this) { 1173 performAppGcsIfAppropriateLocked(); 1174 } 1175 } break; 1176 case WAIT_FOR_DEBUGGER_MSG: { 1177 synchronized (ActivityManagerService.this) { 1178 ProcessRecord app = (ProcessRecord)msg.obj; 1179 if (msg.arg1 != 0) { 1180 if (!app.waitedForDebugger) { 1181 Dialog d = new AppWaitingForDebuggerDialog( 1182 ActivityManagerService.this, 1183 mContext, app); 1184 app.waitDialog = d; 1185 app.waitedForDebugger = true; 1186 d.show(); 1187 } 1188 } else { 1189 if (app.waitDialog != null) { 1190 app.waitDialog.dismiss(); 1191 app.waitDialog = null; 1192 } 1193 } 1194 } 1195 } break; 1196 case SERVICE_TIMEOUT_MSG: { 1197 if (mDidDexOpt) { 1198 mDidDexOpt = false; 1199 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1200 nmsg.obj = msg.obj; 1201 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1202 return; 1203 } 1204 mServices.serviceTimeout((ProcessRecord)msg.obj); 1205 } break; 1206 case UPDATE_TIME_ZONE: { 1207 synchronized (ActivityManagerService.this) { 1208 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1209 ProcessRecord r = mLruProcesses.get(i); 1210 if (r.thread != null) { 1211 try { 1212 r.thread.updateTimeZone(); 1213 } catch (RemoteException ex) { 1214 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1215 } 1216 } 1217 } 1218 } 1219 } break; 1220 case CLEAR_DNS_CACHE_MSG: { 1221 synchronized (ActivityManagerService.this) { 1222 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1223 ProcessRecord r = mLruProcesses.get(i); 1224 if (r.thread != null) { 1225 try { 1226 r.thread.clearDnsCache(); 1227 } catch (RemoteException ex) { 1228 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1229 } 1230 } 1231 } 1232 } 1233 } break; 1234 case UPDATE_HTTP_PROXY_MSG: { 1235 ProxyProperties proxy = (ProxyProperties)msg.obj; 1236 String host = ""; 1237 String port = ""; 1238 String exclList = ""; 1239 String pacFileUrl = null; 1240 if (proxy != null) { 1241 host = proxy.getHost(); 1242 port = Integer.toString(proxy.getPort()); 1243 exclList = proxy.getExclusionList(); 1244 pacFileUrl = proxy.getPacFileUrl(); 1245 } 1246 synchronized (ActivityManagerService.this) { 1247 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1248 ProcessRecord r = mLruProcesses.get(i); 1249 if (r.thread != null) { 1250 try { 1251 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1252 } catch (RemoteException ex) { 1253 Slog.w(TAG, "Failed to update http proxy for: " + 1254 r.info.processName); 1255 } 1256 } 1257 } 1258 } 1259 } break; 1260 case SHOW_UID_ERROR_MSG: { 1261 String title = "System UIDs Inconsistent"; 1262 String text = "UIDs on the system are inconsistent, you need to wipe your" 1263 + " data partition or your device will be unstable."; 1264 Log.e(TAG, title + ": " + text); 1265 if (mShowDialogs) { 1266 // XXX This is a temporary dialog, no need to localize. 1267 AlertDialog d = new BaseErrorDialog(mContext); 1268 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1269 d.setCancelable(false); 1270 d.setTitle(title); 1271 d.setMessage(text); 1272 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1273 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1274 mUidAlert = d; 1275 d.show(); 1276 } 1277 } break; 1278 case IM_FEELING_LUCKY_MSG: { 1279 if (mUidAlert != null) { 1280 mUidAlert.dismiss(); 1281 mUidAlert = null; 1282 } 1283 } break; 1284 case PROC_START_TIMEOUT_MSG: { 1285 if (mDidDexOpt) { 1286 mDidDexOpt = false; 1287 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1288 nmsg.obj = msg.obj; 1289 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1290 return; 1291 } 1292 ProcessRecord app = (ProcessRecord)msg.obj; 1293 synchronized (ActivityManagerService.this) { 1294 processStartTimedOutLocked(app); 1295 } 1296 } break; 1297 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1298 synchronized (ActivityManagerService.this) { 1299 doPendingActivityLaunchesLocked(true); 1300 } 1301 } break; 1302 case KILL_APPLICATION_MSG: { 1303 synchronized (ActivityManagerService.this) { 1304 int appid = msg.arg1; 1305 boolean restart = (msg.arg2 == 1); 1306 Bundle bundle = (Bundle)msg.obj; 1307 String pkg = bundle.getString("pkg"); 1308 String reason = bundle.getString("reason"); 1309 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1310 UserHandle.USER_ALL, reason); 1311 } 1312 } break; 1313 case FINALIZE_PENDING_INTENT_MSG: { 1314 ((PendingIntentRecord)msg.obj).completeFinalize(); 1315 } break; 1316 case POST_HEAVY_NOTIFICATION_MSG: { 1317 INotificationManager inm = NotificationManager.getService(); 1318 if (inm == null) { 1319 return; 1320 } 1321 1322 ActivityRecord root = (ActivityRecord)msg.obj; 1323 ProcessRecord process = root.app; 1324 if (process == null) { 1325 return; 1326 } 1327 1328 try { 1329 Context context = mContext.createPackageContext(process.info.packageName, 0); 1330 String text = mContext.getString(R.string.heavy_weight_notification, 1331 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1332 Notification notification = new Notification(); 1333 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1334 notification.when = 0; 1335 notification.flags = Notification.FLAG_ONGOING_EVENT; 1336 notification.tickerText = text; 1337 notification.defaults = 0; // please be quiet 1338 notification.sound = null; 1339 notification.vibrate = null; 1340 notification.setLatestEventInfo(context, text, 1341 mContext.getText(R.string.heavy_weight_notification_detail), 1342 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1343 PendingIntent.FLAG_CANCEL_CURRENT, null, 1344 new UserHandle(root.userId))); 1345 1346 try { 1347 int[] outId = new int[1]; 1348 inm.enqueueNotificationWithTag("android", "android", null, 1349 R.string.heavy_weight_notification, 1350 notification, outId, root.userId); 1351 } catch (RuntimeException e) { 1352 Slog.w(ActivityManagerService.TAG, 1353 "Error showing notification for heavy-weight app", e); 1354 } catch (RemoteException e) { 1355 } 1356 } catch (NameNotFoundException e) { 1357 Slog.w(TAG, "Unable to create context for heavy notification", e); 1358 } 1359 } break; 1360 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1361 INotificationManager inm = NotificationManager.getService(); 1362 if (inm == null) { 1363 return; 1364 } 1365 try { 1366 inm.cancelNotificationWithTag("android", null, 1367 R.string.heavy_weight_notification, msg.arg1); 1368 } catch (RuntimeException e) { 1369 Slog.w(ActivityManagerService.TAG, 1370 "Error canceling notification for service", e); 1371 } catch (RemoteException e) { 1372 } 1373 } break; 1374 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1375 synchronized (ActivityManagerService.this) { 1376 checkExcessivePowerUsageLocked(true); 1377 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1378 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1379 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1380 } 1381 } break; 1382 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1383 synchronized (ActivityManagerService.this) { 1384 ActivityRecord ar = (ActivityRecord)msg.obj; 1385 if (mCompatModeDialog != null) { 1386 if (mCompatModeDialog.mAppInfo.packageName.equals( 1387 ar.info.applicationInfo.packageName)) { 1388 return; 1389 } 1390 mCompatModeDialog.dismiss(); 1391 mCompatModeDialog = null; 1392 } 1393 if (ar != null && false) { 1394 if (mCompatModePackages.getPackageAskCompatModeLocked( 1395 ar.packageName)) { 1396 int mode = mCompatModePackages.computeCompatModeLocked( 1397 ar.info.applicationInfo); 1398 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1399 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1400 mCompatModeDialog = new CompatModeDialog( 1401 ActivityManagerService.this, mContext, 1402 ar.info.applicationInfo); 1403 mCompatModeDialog.show(); 1404 } 1405 } 1406 } 1407 } 1408 break; 1409 } 1410 case DISPATCH_PROCESSES_CHANGED: { 1411 dispatchProcessesChanged(); 1412 break; 1413 } 1414 case DISPATCH_PROCESS_DIED: { 1415 final int pid = msg.arg1; 1416 final int uid = msg.arg2; 1417 dispatchProcessDied(pid, uid); 1418 break; 1419 } 1420 case REPORT_MEM_USAGE_MSG: { 1421 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1422 Thread thread = new Thread() { 1423 @Override public void run() { 1424 final SparseArray<ProcessMemInfo> infoMap 1425 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1426 for (int i=0, N=memInfos.size(); i<N; i++) { 1427 ProcessMemInfo mi = memInfos.get(i); 1428 infoMap.put(mi.pid, mi); 1429 } 1430 updateCpuStatsNow(); 1431 synchronized (mProcessCpuThread) { 1432 final int N = mProcessCpuTracker.countStats(); 1433 for (int i=0; i<N; i++) { 1434 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1435 if (st.vsize > 0) { 1436 long pss = Debug.getPss(st.pid, null); 1437 if (pss > 0) { 1438 if (infoMap.indexOfKey(st.pid) < 0) { 1439 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1440 ProcessList.NATIVE_ADJ, -1, "native", null); 1441 mi.pss = pss; 1442 memInfos.add(mi); 1443 } 1444 } 1445 } 1446 } 1447 } 1448 1449 long totalPss = 0; 1450 for (int i=0, N=memInfos.size(); i<N; i++) { 1451 ProcessMemInfo mi = memInfos.get(i); 1452 if (mi.pss == 0) { 1453 mi.pss = Debug.getPss(mi.pid, null); 1454 } 1455 totalPss += mi.pss; 1456 } 1457 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1458 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1459 if (lhs.oomAdj != rhs.oomAdj) { 1460 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1461 } 1462 if (lhs.pss != rhs.pss) { 1463 return lhs.pss < rhs.pss ? 1 : -1; 1464 } 1465 return 0; 1466 } 1467 }); 1468 1469 StringBuilder tag = new StringBuilder(128); 1470 StringBuilder stack = new StringBuilder(128); 1471 tag.append("Low on memory -- "); 1472 appendMemBucket(tag, totalPss, "total", false); 1473 appendMemBucket(stack, totalPss, "total", true); 1474 1475 StringBuilder logBuilder = new StringBuilder(1024); 1476 logBuilder.append("Low on memory:\n"); 1477 1478 boolean firstLine = true; 1479 int lastOomAdj = Integer.MIN_VALUE; 1480 for (int i=0, N=memInfos.size(); i<N; i++) { 1481 ProcessMemInfo mi = memInfos.get(i); 1482 1483 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1484 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1485 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1486 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1487 if (lastOomAdj != mi.oomAdj) { 1488 lastOomAdj = mi.oomAdj; 1489 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1490 tag.append(" / "); 1491 } 1492 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1493 if (firstLine) { 1494 stack.append(":"); 1495 firstLine = false; 1496 } 1497 stack.append("\n\t at "); 1498 } else { 1499 stack.append("$"); 1500 } 1501 } else { 1502 tag.append(" "); 1503 stack.append("$"); 1504 } 1505 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1506 appendMemBucket(tag, mi.pss, mi.name, false); 1507 } 1508 appendMemBucket(stack, mi.pss, mi.name, true); 1509 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1510 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1511 stack.append("("); 1512 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1513 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1514 stack.append(DUMP_MEM_OOM_LABEL[k]); 1515 stack.append(":"); 1516 stack.append(DUMP_MEM_OOM_ADJ[k]); 1517 } 1518 } 1519 stack.append(")"); 1520 } 1521 } 1522 1523 logBuilder.append(" "); 1524 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1525 logBuilder.append(' '); 1526 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1527 logBuilder.append(' '); 1528 ProcessList.appendRamKb(logBuilder, mi.pss); 1529 logBuilder.append(" kB: "); 1530 logBuilder.append(mi.name); 1531 logBuilder.append(" ("); 1532 logBuilder.append(mi.pid); 1533 logBuilder.append(") "); 1534 logBuilder.append(mi.adjType); 1535 logBuilder.append('\n'); 1536 if (mi.adjReason != null) { 1537 logBuilder.append(" "); 1538 logBuilder.append(mi.adjReason); 1539 logBuilder.append('\n'); 1540 } 1541 } 1542 1543 logBuilder.append(" "); 1544 ProcessList.appendRamKb(logBuilder, totalPss); 1545 logBuilder.append(" kB: TOTAL\n"); 1546 1547 long[] infos = new long[Debug.MEMINFO_COUNT]; 1548 Debug.getMemInfo(infos); 1549 logBuilder.append(" MemInfo: "); 1550 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1551 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1552 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1553 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1554 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1555 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1556 logBuilder.append(" ZRAM: "); 1557 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1558 logBuilder.append(" kB RAM, "); 1559 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1560 logBuilder.append(" kB swap total, "); 1561 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1562 logBuilder.append(" kB swap free\n"); 1563 } 1564 Slog.i(TAG, logBuilder.toString()); 1565 1566 StringBuilder dropBuilder = new StringBuilder(1024); 1567 /* 1568 StringWriter oomSw = new StringWriter(); 1569 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1570 StringWriter catSw = new StringWriter(); 1571 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1572 String[] emptyArgs = new String[] { }; 1573 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1574 oomPw.flush(); 1575 String oomString = oomSw.toString(); 1576 */ 1577 dropBuilder.append(stack); 1578 dropBuilder.append('\n'); 1579 dropBuilder.append('\n'); 1580 dropBuilder.append(logBuilder); 1581 dropBuilder.append('\n'); 1582 /* 1583 dropBuilder.append(oomString); 1584 dropBuilder.append('\n'); 1585 */ 1586 StringWriter catSw = new StringWriter(); 1587 synchronized (ActivityManagerService.this) { 1588 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1589 String[] emptyArgs = new String[] { }; 1590 catPw.println(); 1591 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1592 catPw.println(); 1593 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1594 false, false, null); 1595 catPw.println(); 1596 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1597 catPw.flush(); 1598 } 1599 dropBuilder.append(catSw.toString()); 1600 addErrorToDropBox("lowmem", null, "system_server", null, 1601 null, tag.toString(), dropBuilder.toString(), null, null); 1602 //Slog.i(TAG, "Sent to dropbox:"); 1603 //Slog.i(TAG, dropBuilder.toString()); 1604 synchronized (ActivityManagerService.this) { 1605 long now = SystemClock.uptimeMillis(); 1606 if (mLastMemUsageReportTime < now) { 1607 mLastMemUsageReportTime = now; 1608 } 1609 } 1610 } 1611 }; 1612 thread.start(); 1613 break; 1614 } 1615 case REPORT_USER_SWITCH_MSG: { 1616 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1617 break; 1618 } 1619 case CONTINUE_USER_SWITCH_MSG: { 1620 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1621 break; 1622 } 1623 case USER_SWITCH_TIMEOUT_MSG: { 1624 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1625 break; 1626 } 1627 case IMMERSIVE_MODE_LOCK_MSG: { 1628 final boolean nextState = (msg.arg1 != 0); 1629 if (mUpdateLock.isHeld() != nextState) { 1630 if (DEBUG_IMMERSIVE) { 1631 final ActivityRecord r = (ActivityRecord) msg.obj; 1632 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1633 } 1634 if (nextState) { 1635 mUpdateLock.acquire(); 1636 } else { 1637 mUpdateLock.release(); 1638 } 1639 } 1640 break; 1641 } 1642 case PERSIST_URI_GRANTS_MSG: { 1643 writeGrantedUriPermissions(); 1644 break; 1645 } 1646 case REQUEST_ALL_PSS_MSG: { 1647 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1648 break; 1649 } 1650 } 1651 } 1652 }; 1653 1654 static final int COLLECT_PSS_BG_MSG = 1; 1655 1656 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1657 @Override 1658 public void handleMessage(Message msg) { 1659 switch (msg.what) { 1660 case COLLECT_PSS_BG_MSG: { 1661 int i=0, num=0; 1662 long start = SystemClock.uptimeMillis(); 1663 long[] tmp = new long[1]; 1664 do { 1665 ProcessRecord proc; 1666 int procState; 1667 int pid; 1668 synchronized (ActivityManagerService.this) { 1669 if (i >= mPendingPssProcesses.size()) { 1670 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1671 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1672 mPendingPssProcesses.clear(); 1673 return; 1674 } 1675 proc = mPendingPssProcesses.get(i); 1676 procState = proc.pssProcState; 1677 if (proc.thread != null && procState == proc.setProcState) { 1678 pid = proc.pid; 1679 } else { 1680 proc = null; 1681 pid = 0; 1682 } 1683 i++; 1684 } 1685 if (proc != null) { 1686 long pss = Debug.getPss(pid, tmp); 1687 synchronized (ActivityManagerService.this) { 1688 if (proc.thread != null && proc.setProcState == procState 1689 && proc.pid == pid) { 1690 num++; 1691 proc.lastPssTime = SystemClock.uptimeMillis(); 1692 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1693 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1694 + ": " + pss + " lastPss=" + proc.lastPss 1695 + " state=" + ProcessList.makeProcStateString(procState)); 1696 if (proc.initialIdlePss == 0) { 1697 proc.initialIdlePss = pss; 1698 } 1699 proc.lastPss = pss; 1700 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1701 proc.lastCachedPss = pss; 1702 } 1703 } 1704 } 1705 } 1706 } while (true); 1707 } 1708 } 1709 } 1710 }; 1711 1712 public static void setSystemProcess() { 1713 try { 1714 ActivityManagerService m = mSelf; 1715 1716 ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true); 1717 ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats); 1718 ServiceManager.addService("meminfo", new MemBinder(m)); 1719 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1720 ServiceManager.addService("dbinfo", new DbBinder(m)); 1721 if (MONITOR_CPU_USAGE) { 1722 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1723 } 1724 ServiceManager.addService("permission", new PermissionController(m)); 1725 1726 ApplicationInfo info = 1727 mSelf.mContext.getPackageManager().getApplicationInfo( 1728 "android", STOCK_PM_FLAGS); 1729 mSystemThread.installSystemApplicationInfo(info); 1730 1731 synchronized (mSelf) { 1732 ProcessRecord app = mSelf.newProcessRecordLocked(info, 1733 info.processName, false); 1734 app.persistent = true; 1735 app.pid = MY_PID; 1736 app.maxAdj = ProcessList.SYSTEM_ADJ; 1737 app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats); 1738 mSelf.mProcessNames.put(app.processName, app.uid, app); 1739 synchronized (mSelf.mPidsSelfLocked) { 1740 mSelf.mPidsSelfLocked.put(app.pid, app); 1741 } 1742 mSelf.updateLruProcessLocked(app, true, false); 1743 } 1744 } catch (PackageManager.NameNotFoundException e) { 1745 throw new RuntimeException( 1746 "Unable to find android system package", e); 1747 } 1748 } 1749 1750 public void setWindowManager(WindowManagerService wm) { 1751 mWindowManager = wm; 1752 mStackSupervisor.setWindowManager(wm); 1753 wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f); 1754 } 1755 1756 public void startObservingNativeCrashes() { 1757 final NativeCrashListener ncl = new NativeCrashListener(); 1758 ncl.start(); 1759 } 1760 1761 public static final Context main(int factoryTest) { 1762 AThread thr = new AThread(); 1763 thr.start(); 1764 1765 synchronized (thr) { 1766 while (thr.mService == null) { 1767 try { 1768 thr.wait(); 1769 } catch (InterruptedException e) { 1770 } 1771 } 1772 } 1773 1774 ActivityManagerService m = thr.mService; 1775 mSelf = m; 1776 ActivityThread at = ActivityThread.systemMain(); 1777 mSystemThread = at; 1778 Context context = at.getSystemContext(); 1779 context.setTheme(android.R.style.Theme_Holo); 1780 m.mContext = context; 1781 m.mFactoryTest = factoryTest; 1782 m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface()); 1783 1784 m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper); 1785 1786 m.mBatteryStatsService.publish(context); 1787 m.mUsageStatsService.publish(context); 1788 m.mAppOpsService.publish(context); 1789 1790 synchronized (thr) { 1791 thr.mReady = true; 1792 thr.notifyAll(); 1793 } 1794 1795 m.startRunning(null, null, null, null); 1796 1797 return context; 1798 } 1799 1800 public static ActivityManagerService self() { 1801 return mSelf; 1802 } 1803 1804 public IAppOpsService getAppOpsService() { 1805 return mAppOpsService; 1806 } 1807 1808 static class AThread extends Thread { 1809 ActivityManagerService mService; 1810 Looper mLooper; 1811 boolean mReady = false; 1812 1813 public AThread() { 1814 super("ActivityManager"); 1815 } 1816 1817 @Override 1818 public void run() { 1819 Looper.prepare(); 1820 1821 android.os.Process.setThreadPriority( 1822 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1823 android.os.Process.setCanSelfBackground(false); 1824 1825 ActivityManagerService m = new ActivityManagerService(); 1826 1827 synchronized (this) { 1828 mService = m; 1829 mLooper = Looper.myLooper(); 1830 Watchdog.getInstance().addThread(new Handler(mLooper), getName()); 1831 notifyAll(); 1832 } 1833 1834 synchronized (this) { 1835 while (!mReady) { 1836 try { 1837 wait(); 1838 } catch (InterruptedException e) { 1839 } 1840 } 1841 } 1842 1843 // For debug builds, log event loop stalls to dropbox for analysis. 1844 if (StrictMode.conditionallyEnableDebugLogging()) { 1845 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1846 } 1847 1848 Looper.loop(); 1849 } 1850 } 1851 1852 static class MemBinder extends Binder { 1853 ActivityManagerService mActivityManagerService; 1854 MemBinder(ActivityManagerService activityManagerService) { 1855 mActivityManagerService = activityManagerService; 1856 } 1857 1858 @Override 1859 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1860 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1861 != PackageManager.PERMISSION_GRANTED) { 1862 pw.println("Permission Denial: can't dump meminfo from from pid=" 1863 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1864 + " without permission " + android.Manifest.permission.DUMP); 1865 return; 1866 } 1867 1868 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1869 } 1870 } 1871 1872 static class GraphicsBinder extends Binder { 1873 ActivityManagerService mActivityManagerService; 1874 GraphicsBinder(ActivityManagerService activityManagerService) { 1875 mActivityManagerService = activityManagerService; 1876 } 1877 1878 @Override 1879 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1880 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1881 != PackageManager.PERMISSION_GRANTED) { 1882 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1883 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1884 + " without permission " + android.Manifest.permission.DUMP); 1885 return; 1886 } 1887 1888 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1889 } 1890 } 1891 1892 static class DbBinder extends Binder { 1893 ActivityManagerService mActivityManagerService; 1894 DbBinder(ActivityManagerService activityManagerService) { 1895 mActivityManagerService = activityManagerService; 1896 } 1897 1898 @Override 1899 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1900 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1901 != PackageManager.PERMISSION_GRANTED) { 1902 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1903 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1904 + " without permission " + android.Manifest.permission.DUMP); 1905 return; 1906 } 1907 1908 mActivityManagerService.dumpDbInfo(fd, pw, args); 1909 } 1910 } 1911 1912 static class CpuBinder extends Binder { 1913 ActivityManagerService mActivityManagerService; 1914 CpuBinder(ActivityManagerService activityManagerService) { 1915 mActivityManagerService = activityManagerService; 1916 } 1917 1918 @Override 1919 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1920 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1921 != PackageManager.PERMISSION_GRANTED) { 1922 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1923 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1924 + " without permission " + android.Manifest.permission.DUMP); 1925 return; 1926 } 1927 1928 synchronized (mActivityManagerService.mProcessCpuThread) { 1929 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1930 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1931 SystemClock.uptimeMillis())); 1932 } 1933 } 1934 } 1935 1936 private ActivityManagerService() { 1937 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1938 1939 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false); 1940 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true); 1941 mBroadcastQueues[0] = mFgBroadcastQueue; 1942 mBroadcastQueues[1] = mBgBroadcastQueue; 1943 1944 mServices = new ActiveServices(this); 1945 mProviderMap = new ProviderMap(this); 1946 1947 File dataDir = Environment.getDataDirectory(); 1948 File systemDir = new File(dataDir, "system"); 1949 systemDir.mkdirs(); 1950 mBatteryStatsService = new BatteryStatsService(new File( 1951 systemDir, "batterystats.bin").toString()); 1952 mBatteryStatsService.getActiveStatistics().readLocked(); 1953 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1954 mOnBattery = DEBUG_POWER ? true 1955 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1956 mBatteryStatsService.getActiveStatistics().setCallback(this); 1957 1958 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1959 1960 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1961 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml")); 1962 1963 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1964 1965 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1966 1967 // User 0 is the first and only user that runs at boot. 1968 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1969 mUserLru.add(Integer.valueOf(0)); 1970 updateStartedUserArrayLocked(); 1971 1972 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1973 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1974 1975 mConfiguration.setToDefaults(); 1976 mConfiguration.setLocale(Locale.getDefault()); 1977 1978 mConfigurationSeq = mConfiguration.seq = 1; 1979 mProcessCpuTracker.init(); 1980 1981 mCompatModePackages = new CompatModePackages(this, systemDir); 1982 1983 // Add ourself to the Watchdog monitors. 1984 Watchdog.getInstance().addMonitor(this); 1985 1986 mProcessCpuThread = new Thread("CpuTracker") { 1987 @Override 1988 public void run() { 1989 while (true) { 1990 try { 1991 try { 1992 synchronized(this) { 1993 final long now = SystemClock.uptimeMillis(); 1994 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1995 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1996 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1997 // + ", write delay=" + nextWriteDelay); 1998 if (nextWriteDelay < nextCpuDelay) { 1999 nextCpuDelay = nextWriteDelay; 2000 } 2001 if (nextCpuDelay > 0) { 2002 mProcessCpuMutexFree.set(true); 2003 this.wait(nextCpuDelay); 2004 } 2005 } 2006 } catch (InterruptedException e) { 2007 } 2008 updateCpuStatsNow(); 2009 } catch (Exception e) { 2010 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2011 } 2012 } 2013 } 2014 }; 2015 mProcessCpuThread.start(); 2016 } 2017 2018 @Override 2019 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2020 throws RemoteException { 2021 if (code == SYSPROPS_TRANSACTION) { 2022 // We need to tell all apps about the system property change. 2023 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2024 synchronized(this) { 2025 final int NP = mProcessNames.getMap().size(); 2026 for (int ip=0; ip<NP; ip++) { 2027 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2028 final int NA = apps.size(); 2029 for (int ia=0; ia<NA; ia++) { 2030 ProcessRecord app = apps.valueAt(ia); 2031 if (app.thread != null) { 2032 procs.add(app.thread.asBinder()); 2033 } 2034 } 2035 } 2036 } 2037 2038 int N = procs.size(); 2039 for (int i=0; i<N; i++) { 2040 Parcel data2 = Parcel.obtain(); 2041 try { 2042 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2043 } catch (RemoteException e) { 2044 } 2045 data2.recycle(); 2046 } 2047 } 2048 try { 2049 return super.onTransact(code, data, reply, flags); 2050 } catch (RuntimeException e) { 2051 // The activity manager only throws security exceptions, so let's 2052 // log all others. 2053 if (!(e instanceof SecurityException)) { 2054 Slog.wtf(TAG, "Activity Manager Crash", e); 2055 } 2056 throw e; 2057 } 2058 } 2059 2060 void updateCpuStats() { 2061 final long now = SystemClock.uptimeMillis(); 2062 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2063 return; 2064 } 2065 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2066 synchronized (mProcessCpuThread) { 2067 mProcessCpuThread.notify(); 2068 } 2069 } 2070 } 2071 2072 void updateCpuStatsNow() { 2073 synchronized (mProcessCpuThread) { 2074 mProcessCpuMutexFree.set(false); 2075 final long now = SystemClock.uptimeMillis(); 2076 boolean haveNewCpuStats = false; 2077 2078 if (MONITOR_CPU_USAGE && 2079 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2080 mLastCpuTime.set(now); 2081 haveNewCpuStats = true; 2082 mProcessCpuTracker.update(); 2083 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2084 //Slog.i(TAG, "Total CPU usage: " 2085 // + mProcessCpu.getTotalCpuPercent() + "%"); 2086 2087 // Slog the cpu usage if the property is set. 2088 if ("true".equals(SystemProperties.get("events.cpu"))) { 2089 int user = mProcessCpuTracker.getLastUserTime(); 2090 int system = mProcessCpuTracker.getLastSystemTime(); 2091 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2092 int irq = mProcessCpuTracker.getLastIrqTime(); 2093 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2094 int idle = mProcessCpuTracker.getLastIdleTime(); 2095 2096 int total = user + system + iowait + irq + softIrq + idle; 2097 if (total == 0) total = 1; 2098 2099 EventLog.writeEvent(EventLogTags.CPU, 2100 ((user+system+iowait+irq+softIrq) * 100) / total, 2101 (user * 100) / total, 2102 (system * 100) / total, 2103 (iowait * 100) / total, 2104 (irq * 100) / total, 2105 (softIrq * 100) / total); 2106 } 2107 } 2108 2109 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2110 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2111 synchronized(bstats) { 2112 synchronized(mPidsSelfLocked) { 2113 if (haveNewCpuStats) { 2114 if (mOnBattery) { 2115 int perc = bstats.startAddingCpuLocked(); 2116 int totalUTime = 0; 2117 int totalSTime = 0; 2118 final int N = mProcessCpuTracker.countStats(); 2119 for (int i=0; i<N; i++) { 2120 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2121 if (!st.working) { 2122 continue; 2123 } 2124 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2125 int otherUTime = (st.rel_utime*perc)/100; 2126 int otherSTime = (st.rel_stime*perc)/100; 2127 totalUTime += otherUTime; 2128 totalSTime += otherSTime; 2129 if (pr != null) { 2130 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 2131 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2132 st.rel_stime-otherSTime); 2133 ps.addSpeedStepTimes(cpuSpeedTimes); 2134 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2135 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2136 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2137 if (ps == null) { 2138 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2139 "(Unknown)"); 2140 } 2141 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2142 st.rel_stime-otherSTime); 2143 ps.addSpeedStepTimes(cpuSpeedTimes); 2144 } else { 2145 BatteryStatsImpl.Uid.Proc ps = 2146 bstats.getProcessStatsLocked(st.name, st.pid); 2147 if (ps != null) { 2148 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2149 st.rel_stime-otherSTime); 2150 ps.addSpeedStepTimes(cpuSpeedTimes); 2151 } 2152 } 2153 } 2154 bstats.finishAddingCpuLocked(perc, totalUTime, 2155 totalSTime, cpuSpeedTimes); 2156 } 2157 } 2158 } 2159 2160 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2161 mLastWriteTime = now; 2162 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2163 } 2164 } 2165 } 2166 } 2167 2168 @Override 2169 public void batteryNeedsCpuUpdate() { 2170 updateCpuStatsNow(); 2171 } 2172 2173 @Override 2174 public void batteryPowerChanged(boolean onBattery) { 2175 // When plugging in, update the CPU stats first before changing 2176 // the plug state. 2177 updateCpuStatsNow(); 2178 synchronized (this) { 2179 synchronized(mPidsSelfLocked) { 2180 mOnBattery = DEBUG_POWER ? true : onBattery; 2181 } 2182 } 2183 } 2184 2185 /** 2186 * Initialize the application bind args. These are passed to each 2187 * process when the bindApplication() IPC is sent to the process. They're 2188 * lazily setup to make sure the services are running when they're asked for. 2189 */ 2190 private HashMap<String, IBinder> getCommonServicesLocked() { 2191 if (mAppBindArgs == null) { 2192 mAppBindArgs = new HashMap<String, IBinder>(); 2193 2194 // Setup the application init args 2195 mAppBindArgs.put("package", ServiceManager.getService("package")); 2196 mAppBindArgs.put("window", ServiceManager.getService("window")); 2197 mAppBindArgs.put(Context.ALARM_SERVICE, 2198 ServiceManager.getService(Context.ALARM_SERVICE)); 2199 } 2200 return mAppBindArgs; 2201 } 2202 2203 final void setFocusedActivityLocked(ActivityRecord r) { 2204 if (mFocusedActivity != r) { 2205 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2206 mFocusedActivity = r; 2207 mStackSupervisor.setFocusedStack(r); 2208 if (r != null) { 2209 mWindowManager.setFocusedApp(r.appToken, true); 2210 } 2211 applyUpdateLockStateLocked(r); 2212 } 2213 } 2214 2215 @Override 2216 public void setFocusedStack(int stackId) { 2217 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2218 synchronized (ActivityManagerService.this) { 2219 ActivityStack stack = mStackSupervisor.getStack(stackId); 2220 if (stack != null) { 2221 ActivityRecord r = stack.topRunningActivityLocked(null); 2222 if (r != null) { 2223 setFocusedActivityLocked(r); 2224 } 2225 } 2226 } 2227 } 2228 2229 @Override 2230 public void notifyActivityDrawn(IBinder token) { 2231 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2232 synchronized (this) { 2233 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2234 if (r != null) { 2235 r.task.stack.notifyActivityDrawnLocked(r); 2236 } 2237 } 2238 } 2239 2240 final void applyUpdateLockStateLocked(ActivityRecord r) { 2241 // Modifications to the UpdateLock state are done on our handler, outside 2242 // the activity manager's locks. The new state is determined based on the 2243 // state *now* of the relevant activity record. The object is passed to 2244 // the handler solely for logging detail, not to be consulted/modified. 2245 final boolean nextState = r != null && r.immersive; 2246 mHandler.sendMessage( 2247 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2248 } 2249 2250 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2251 Message msg = Message.obtain(); 2252 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2253 msg.obj = r.task.askedCompatMode ? null : r; 2254 mHandler.sendMessage(msg); 2255 } 2256 2257 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2258 String what, Object obj, ProcessRecord srcApp) { 2259 app.lastActivityTime = now; 2260 2261 if (app.activities.size() > 0) { 2262 // Don't want to touch dependent processes that are hosting activities. 2263 return index; 2264 } 2265 2266 int lrui = mLruProcesses.lastIndexOf(app); 2267 if (lrui < 0) { 2268 Log.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2269 + what + " " + obj + " from " + srcApp); 2270 return index; 2271 } 2272 2273 if (lrui >= index) { 2274 // Don't want to cause this to move dependent processes *back* in the 2275 // list as if they were less frequently used. 2276 return index; 2277 } 2278 2279 if (lrui >= mLruProcessActivityStart) { 2280 // Don't want to touch dependent processes that are hosting activities. 2281 return index; 2282 } 2283 2284 mLruProcesses.remove(lrui); 2285 if (index > 0) { 2286 index--; 2287 } 2288 mLruProcesses.add(index, app); 2289 return index; 2290 } 2291 2292 final void removeLruProcessLocked(ProcessRecord app) { 2293 int lrui = mLruProcesses.lastIndexOf(app); 2294 if (lrui >= 0) { 2295 if (lrui <= mLruProcessActivityStart) { 2296 mLruProcessActivityStart--; 2297 } 2298 if (lrui <= mLruProcessServiceStart) { 2299 mLruProcessServiceStart--; 2300 } 2301 mLruProcesses.remove(lrui); 2302 } 2303 } 2304 2305 final void updateLruProcessLocked(ProcessRecord app, boolean oomAdj, boolean activityChange) { 2306 final boolean hasActivity = app.activities.size() > 0; 2307 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2308 if (!activityChange && hasActivity) { 2309 // The process has activties, so we are only going to allow activity-based 2310 // adjustments move it. It should be kept in the front of the list with other 2311 // processes that have activities, and we don't want those to change their 2312 // order except due to activity operations. 2313 return; 2314 } 2315 2316 mLruSeq++; 2317 final long now = SystemClock.uptimeMillis(); 2318 app.lastActivityTime = now; 2319 2320 int lrui = mLruProcesses.lastIndexOf(app); 2321 2322 if (lrui >= 0) { 2323 if (lrui < mLruProcessActivityStart) { 2324 mLruProcessActivityStart--; 2325 } 2326 if (lrui < mLruProcessServiceStart) { 2327 mLruProcessServiceStart--; 2328 } 2329 mLruProcesses.remove(lrui); 2330 } 2331 2332 int nextIndex; 2333 if (hasActivity) { 2334 // Process has activities, put it at the very tipsy-top. 2335 mLruProcesses.add(app); 2336 nextIndex = mLruProcessActivityStart; 2337 } else if (hasService) { 2338 // Process has services, put it at the top of the service list. 2339 mLruProcesses.add(mLruProcessActivityStart, app); 2340 nextIndex = mLruProcessServiceStart; 2341 mLruProcessActivityStart++; 2342 } else { 2343 // Process not otherwise of interest, it goes to the top of the non-service area. 2344 mLruProcesses.add(mLruProcessServiceStart, app); 2345 nextIndex = mLruProcessServiceStart-1; 2346 mLruProcessActivityStart++; 2347 mLruProcessServiceStart++; 2348 } 2349 2350 // If the app is currently using a content provider or service, 2351 // bump those processes as well. 2352 for (int j=app.connections.size()-1; j>=0; j--) { 2353 ConnectionRecord cr = app.connections.valueAt(j); 2354 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2355 && cr.binding.service.app != null 2356 && cr.binding.service.app.lruSeq != mLruSeq) { 2357 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2358 "service connection", cr, app); 2359 } 2360 } 2361 for (int j=app.conProviders.size()-1; j>=0; j--) { 2362 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2363 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { 2364 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2365 "provider reference", cpr, app); 2366 } 2367 } 2368 2369 //Slog.i(TAG, "Putting proc to front: " + app.processName); 2370 if (oomAdj) { 2371 updateOomAdjLocked(); 2372 } 2373 } 2374 2375 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2376 if (uid == Process.SYSTEM_UID) { 2377 // The system gets to run in any process. If there are multiple 2378 // processes with the same uid, just pick the first (this 2379 // should never happen). 2380 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2381 if (procs == null) return null; 2382 final int N = procs.size(); 2383 for (int i = 0; i < N; i++) { 2384 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2385 } 2386 } 2387 ProcessRecord proc = mProcessNames.get(processName, uid); 2388 if (false && proc != null && !keepIfLarge 2389 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2390 && proc.lastCachedPss >= 4000) { 2391 // Turn this condition on to cause killing to happen regularly, for testing. 2392 if (proc.baseProcessTracker != null) { 2393 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2394 } 2395 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2396 + "k from cached"); 2397 } else if (proc != null && !keepIfLarge 2398 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2399 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2400 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2401 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2402 if (proc.baseProcessTracker != null) { 2403 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2404 } 2405 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2406 + "k from cached"); 2407 } 2408 } 2409 return proc; 2410 } 2411 2412 void ensurePackageDexOpt(String packageName) { 2413 IPackageManager pm = AppGlobals.getPackageManager(); 2414 try { 2415 if (pm.performDexOpt(packageName)) { 2416 mDidDexOpt = true; 2417 } 2418 } catch (RemoteException e) { 2419 } 2420 } 2421 2422 boolean isNextTransitionForward() { 2423 int transit = mWindowManager.getPendingAppTransition(); 2424 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2425 || transit == AppTransition.TRANSIT_TASK_OPEN 2426 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2427 } 2428 2429 final ProcessRecord startProcessLocked(String processName, 2430 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2431 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2432 boolean isolated, boolean keepIfLarge) { 2433 ProcessRecord app; 2434 if (!isolated) { 2435 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2436 } else { 2437 // If this is an isolated process, it can't re-use an existing process. 2438 app = null; 2439 } 2440 // We don't have to do anything more if: 2441 // (1) There is an existing application record; and 2442 // (2) The caller doesn't think it is dead, OR there is no thread 2443 // object attached to it so we know it couldn't have crashed; and 2444 // (3) There is a pid assigned to it, so it is either starting or 2445 // already running. 2446 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2447 + " app=" + app + " knownToBeDead=" + knownToBeDead 2448 + " thread=" + (app != null ? app.thread : null) 2449 + " pid=" + (app != null ? app.pid : -1)); 2450 if (app != null && app.pid > 0) { 2451 if (!knownToBeDead || app.thread == null) { 2452 // We already have the app running, or are waiting for it to 2453 // come up (we have a pid but not yet its thread), so keep it. 2454 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2455 // If this is a new package in the process, add the package to the list 2456 app.addPackage(info.packageName, mProcessStats); 2457 return app; 2458 } 2459 2460 // An application record is attached to a previous process, 2461 // clean it up now. 2462 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2463 handleAppDiedLocked(app, true, true); 2464 } 2465 2466 String hostingNameStr = hostingName != null 2467 ? hostingName.flattenToShortString() : null; 2468 2469 if (!isolated) { 2470 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2471 // If we are in the background, then check to see if this process 2472 // is bad. If so, we will just silently fail. 2473 if (mBadProcesses.get(info.processName, info.uid) != null) { 2474 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2475 + "/" + info.processName); 2476 return null; 2477 } 2478 } else { 2479 // When the user is explicitly starting a process, then clear its 2480 // crash count so that we won't make it bad until they see at 2481 // least one crash dialog again, and make the process good again 2482 // if it had been bad. 2483 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2484 + "/" + info.processName); 2485 mProcessCrashTimes.remove(info.processName, info.uid); 2486 if (mBadProcesses.get(info.processName, info.uid) != null) { 2487 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2488 UserHandle.getUserId(info.uid), info.uid, 2489 info.processName); 2490 mBadProcesses.remove(info.processName, info.uid); 2491 if (app != null) { 2492 app.bad = false; 2493 } 2494 } 2495 } 2496 } 2497 2498 if (app == null) { 2499 app = newProcessRecordLocked(info, processName, isolated); 2500 if (app == null) { 2501 Slog.w(TAG, "Failed making new process record for " 2502 + processName + "/" + info.uid + " isolated=" + isolated); 2503 return null; 2504 } 2505 mProcessNames.put(processName, app.uid, app); 2506 if (isolated) { 2507 mIsolatedProcesses.put(app.uid, app); 2508 } 2509 } else { 2510 // If this is a new package in the process, add the package to the list 2511 app.addPackage(info.packageName, mProcessStats); 2512 } 2513 2514 // If the system is not ready yet, then hold off on starting this 2515 // process until it is. 2516 if (!mProcessesReady 2517 && !isAllowedWhileBooting(info) 2518 && !allowWhileBooting) { 2519 if (!mProcessesOnHold.contains(app)) { 2520 mProcessesOnHold.add(app); 2521 } 2522 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2523 return app; 2524 } 2525 2526 startProcessLocked(app, hostingType, hostingNameStr); 2527 return (app.pid != 0) ? app : null; 2528 } 2529 2530 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2531 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2532 } 2533 2534 private final void startProcessLocked(ProcessRecord app, 2535 String hostingType, String hostingNameStr) { 2536 if (app.pid > 0 && app.pid != MY_PID) { 2537 synchronized (mPidsSelfLocked) { 2538 mPidsSelfLocked.remove(app.pid); 2539 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2540 } 2541 app.setPid(0); 2542 } 2543 2544 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2545 "startProcessLocked removing on hold: " + app); 2546 mProcessesOnHold.remove(app); 2547 2548 updateCpuStats(); 2549 2550 try { 2551 int uid = app.uid; 2552 2553 int[] gids = null; 2554 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2555 if (!app.isolated) { 2556 int[] permGids = null; 2557 try { 2558 final PackageManager pm = mContext.getPackageManager(); 2559 permGids = pm.getPackageGids(app.info.packageName); 2560 2561 if (Environment.isExternalStorageEmulated()) { 2562 if (pm.checkPermission( 2563 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2564 app.info.packageName) == PERMISSION_GRANTED) { 2565 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2566 } else { 2567 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2568 } 2569 } 2570 } catch (PackageManager.NameNotFoundException e) { 2571 Slog.w(TAG, "Unable to retrieve gids", e); 2572 } 2573 2574 /* 2575 * Add shared application GID so applications can share some 2576 * resources like shared libraries 2577 */ 2578 if (permGids == null) { 2579 gids = new int[1]; 2580 } else { 2581 gids = new int[permGids.length + 1]; 2582 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2583 } 2584 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2585 } 2586 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2587 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2588 && mTopComponent != null 2589 && app.processName.equals(mTopComponent.getPackageName())) { 2590 uid = 0; 2591 } 2592 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2593 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2594 uid = 0; 2595 } 2596 } 2597 int debugFlags = 0; 2598 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2599 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2600 // Also turn on CheckJNI for debuggable apps. It's quite 2601 // awkward to turn on otherwise. 2602 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2603 } 2604 // Run the app in safe mode if its manifest requests so or the 2605 // system is booted in safe mode. 2606 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2607 Zygote.systemInSafeMode == true) { 2608 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2609 } 2610 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2611 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2612 } 2613 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2614 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2615 } 2616 if ("1".equals(SystemProperties.get("debug.assert"))) { 2617 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2618 } 2619 2620 // Start the process. It will either succeed and return a result containing 2621 // the PID of the new process, or else throw a RuntimeException. 2622 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2623 app.processName, uid, uid, gids, debugFlags, mountExternal, 2624 app.info.targetSdkVersion, app.info.seinfo, null); 2625 2626 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2627 synchronized (bs) { 2628 if (bs.isOnBattery()) { 2629 app.batteryStats.incStartsLocked(); 2630 } 2631 } 2632 2633 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2634 UserHandle.getUserId(uid), startResult.pid, uid, 2635 app.processName, hostingType, 2636 hostingNameStr != null ? hostingNameStr : ""); 2637 2638 if (app.persistent) { 2639 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2640 } 2641 2642 StringBuilder buf = mStringBuilder; 2643 buf.setLength(0); 2644 buf.append("Start proc "); 2645 buf.append(app.processName); 2646 buf.append(" for "); 2647 buf.append(hostingType); 2648 if (hostingNameStr != null) { 2649 buf.append(" "); 2650 buf.append(hostingNameStr); 2651 } 2652 buf.append(": pid="); 2653 buf.append(startResult.pid); 2654 buf.append(" uid="); 2655 buf.append(uid); 2656 buf.append(" gids={"); 2657 if (gids != null) { 2658 for (int gi=0; gi<gids.length; gi++) { 2659 if (gi != 0) buf.append(", "); 2660 buf.append(gids[gi]); 2661 2662 } 2663 } 2664 buf.append("}"); 2665 Slog.i(TAG, buf.toString()); 2666 app.setPid(startResult.pid); 2667 app.usingWrapper = startResult.usingWrapper; 2668 app.removed = false; 2669 synchronized (mPidsSelfLocked) { 2670 this.mPidsSelfLocked.put(startResult.pid, app); 2671 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2672 msg.obj = app; 2673 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2674 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2675 } 2676 } catch (RuntimeException e) { 2677 // XXX do better error recovery. 2678 app.setPid(0); 2679 Slog.e(TAG, "Failure starting process " + app.processName, e); 2680 } 2681 } 2682 2683 void updateUsageStats(ActivityRecord component, boolean resumed) { 2684 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2685 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2686 if (resumed) { 2687 mUsageStatsService.noteResumeComponent(component.realActivity); 2688 synchronized (stats) { 2689 stats.noteActivityResumedLocked(component.app.uid); 2690 } 2691 } else { 2692 mUsageStatsService.notePauseComponent(component.realActivity); 2693 synchronized (stats) { 2694 stats.noteActivityPausedLocked(component.app.uid); 2695 } 2696 } 2697 } 2698 2699 Intent getHomeIntent() { 2700 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2701 intent.setComponent(mTopComponent); 2702 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2703 intent.addCategory(Intent.CATEGORY_HOME); 2704 } 2705 return intent; 2706 } 2707 2708 boolean startHomeActivityLocked(int userId) { 2709 if (mHeadless) { 2710 // Added because none of the other calls to ensureBootCompleted seem to fire 2711 // when running headless. 2712 ensureBootCompleted(); 2713 return false; 2714 } 2715 2716 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2717 && mTopAction == null) { 2718 // We are running in factory test mode, but unable to find 2719 // the factory test app, so just sit around displaying the 2720 // error message and don't try to start anything. 2721 return false; 2722 } 2723 Intent intent = getHomeIntent(); 2724 ActivityInfo aInfo = 2725 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2726 if (aInfo != null) { 2727 intent.setComponent(new ComponentName( 2728 aInfo.applicationInfo.packageName, aInfo.name)); 2729 // Don't do this if the home app is currently being 2730 // instrumented. 2731 aInfo = new ActivityInfo(aInfo); 2732 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2733 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2734 aInfo.applicationInfo.uid, true); 2735 if (app == null || app.instrumentationClass == null) { 2736 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2737 mStackSupervisor.startHomeActivity(intent, aInfo); 2738 } 2739 } 2740 2741 return true; 2742 } 2743 2744 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2745 ActivityInfo ai = null; 2746 ComponentName comp = intent.getComponent(); 2747 try { 2748 if (comp != null) { 2749 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2750 } else { 2751 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2752 intent, 2753 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2754 flags, userId); 2755 2756 if (info != null) { 2757 ai = info.activityInfo; 2758 } 2759 } 2760 } catch (RemoteException e) { 2761 // ignore 2762 } 2763 2764 return ai; 2765 } 2766 2767 /** 2768 * Starts the "new version setup screen" if appropriate. 2769 */ 2770 void startSetupActivityLocked() { 2771 // Only do this once per boot. 2772 if (mCheckedForSetup) { 2773 return; 2774 } 2775 2776 // We will show this screen if the current one is a different 2777 // version than the last one shown, and we are not running in 2778 // low-level factory test mode. 2779 final ContentResolver resolver = mContext.getContentResolver(); 2780 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2781 Settings.Global.getInt(resolver, 2782 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2783 mCheckedForSetup = true; 2784 2785 // See if we should be showing the platform update setup UI. 2786 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2787 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2788 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2789 2790 // We don't allow third party apps to replace this. 2791 ResolveInfo ri = null; 2792 for (int i=0; ris != null && i<ris.size(); i++) { 2793 if ((ris.get(i).activityInfo.applicationInfo.flags 2794 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2795 ri = ris.get(i); 2796 break; 2797 } 2798 } 2799 2800 if (ri != null) { 2801 String vers = ri.activityInfo.metaData != null 2802 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2803 : null; 2804 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2805 vers = ri.activityInfo.applicationInfo.metaData.getString( 2806 Intent.METADATA_SETUP_VERSION); 2807 } 2808 String lastVers = Settings.Secure.getString( 2809 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2810 if (vers != null && !vers.equals(lastVers)) { 2811 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2812 intent.setComponent(new ComponentName( 2813 ri.activityInfo.packageName, ri.activityInfo.name)); 2814 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2815 null, null, 0, 0, 0, null, 0, null, false, null); 2816 } 2817 } 2818 } 2819 } 2820 2821 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2822 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2823 } 2824 2825 void enforceNotIsolatedCaller(String caller) { 2826 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2827 throw new SecurityException("Isolated process not allowed to call " + caller); 2828 } 2829 } 2830 2831 @Override 2832 public int getFrontActivityScreenCompatMode() { 2833 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2834 synchronized (this) { 2835 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2836 } 2837 } 2838 2839 @Override 2840 public void setFrontActivityScreenCompatMode(int mode) { 2841 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2842 "setFrontActivityScreenCompatMode"); 2843 synchronized (this) { 2844 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2845 } 2846 } 2847 2848 @Override 2849 public int getPackageScreenCompatMode(String packageName) { 2850 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2851 synchronized (this) { 2852 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2853 } 2854 } 2855 2856 @Override 2857 public void setPackageScreenCompatMode(String packageName, int mode) { 2858 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2859 "setPackageScreenCompatMode"); 2860 synchronized (this) { 2861 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2862 } 2863 } 2864 2865 @Override 2866 public boolean getPackageAskScreenCompat(String packageName) { 2867 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2868 synchronized (this) { 2869 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 2870 } 2871 } 2872 2873 @Override 2874 public void setPackageAskScreenCompat(String packageName, boolean ask) { 2875 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2876 "setPackageAskScreenCompat"); 2877 synchronized (this) { 2878 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 2879 } 2880 } 2881 2882 private void dispatchProcessesChanged() { 2883 int N; 2884 synchronized (this) { 2885 N = mPendingProcessChanges.size(); 2886 if (mActiveProcessChanges.length < N) { 2887 mActiveProcessChanges = new ProcessChangeItem[N]; 2888 } 2889 mPendingProcessChanges.toArray(mActiveProcessChanges); 2890 mAvailProcessChanges.addAll(mPendingProcessChanges); 2891 mPendingProcessChanges.clear(); 2892 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 2893 } 2894 2895 int i = mProcessObservers.beginBroadcast(); 2896 while (i > 0) { 2897 i--; 2898 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2899 if (observer != null) { 2900 try { 2901 for (int j=0; j<N; j++) { 2902 ProcessChangeItem item = mActiveProcessChanges[j]; 2903 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 2904 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 2905 + item.pid + " uid=" + item.uid + ": " 2906 + item.foregroundActivities); 2907 observer.onForegroundActivitiesChanged(item.pid, item.uid, 2908 item.foregroundActivities); 2909 } 2910 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 2911 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 2912 + item.pid + " uid=" + item.uid + ": " + item.importance); 2913 observer.onImportanceChanged(item.pid, item.uid, 2914 item.importance); 2915 } 2916 } 2917 } catch (RemoteException e) { 2918 } 2919 } 2920 } 2921 mProcessObservers.finishBroadcast(); 2922 } 2923 2924 private void dispatchProcessDied(int pid, int uid) { 2925 int i = mProcessObservers.beginBroadcast(); 2926 while (i > 0) { 2927 i--; 2928 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 2929 if (observer != null) { 2930 try { 2931 observer.onProcessDied(pid, uid); 2932 } catch (RemoteException e) { 2933 } 2934 } 2935 } 2936 mProcessObservers.finishBroadcast(); 2937 } 2938 2939 final void doPendingActivityLaunchesLocked(boolean doResume) { 2940 final int N = mPendingActivityLaunches.size(); 2941 if (N <= 0) { 2942 return; 2943 } 2944 for (int i=0; i<N; i++) { 2945 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 2946 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 2947 doResume && i == (N-1), null); 2948 } 2949 mPendingActivityLaunches.clear(); 2950 } 2951 2952 @Override 2953 public final int startActivity(IApplicationThread caller, String callingPackage, 2954 Intent intent, String resolvedType, IBinder resultTo, 2955 String resultWho, int requestCode, int startFlags, 2956 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 2957 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 2958 resultWho, requestCode, 2959 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 2960 } 2961 2962 @Override 2963 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 2964 Intent intent, String resolvedType, IBinder resultTo, 2965 String resultWho, int requestCode, int startFlags, 2966 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 2967 enforceNotIsolatedCaller("startActivity"); 2968 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2969 false, true, "startActivity", null); 2970 // TODO: Switch to user app stacks here. 2971 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 2972 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2973 null, null, options, userId); 2974 } 2975 2976 @Override 2977 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 2978 Intent intent, String resolvedType, IBinder resultTo, 2979 String resultWho, int requestCode, int startFlags, String profileFile, 2980 ParcelFileDescriptor profileFd, Bundle options, int userId) { 2981 enforceNotIsolatedCaller("startActivityAndWait"); 2982 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2983 false, true, "startActivityAndWait", null); 2984 WaitResult res = new WaitResult(); 2985 // TODO: Switch to user app stacks here. 2986 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 2987 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 2988 res, null, options, UserHandle.getCallingUserId()); 2989 return res; 2990 } 2991 2992 @Override 2993 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 2994 Intent intent, String resolvedType, IBinder resultTo, 2995 String resultWho, int requestCode, int startFlags, Configuration config, 2996 Bundle options, int userId) { 2997 enforceNotIsolatedCaller("startActivityWithConfig"); 2998 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 2999 false, true, "startActivityWithConfig", null); 3000 // TODO: Switch to user app stacks here. 3001 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3002 resolvedType, resultTo, resultWho, requestCode, startFlags, 3003 null, null, null, config, options, userId); 3004 return ret; 3005 } 3006 3007 @Override 3008 public int startActivityIntentSender(IApplicationThread caller, 3009 IntentSender intent, Intent fillInIntent, String resolvedType, 3010 IBinder resultTo, String resultWho, int requestCode, 3011 int flagsMask, int flagsValues, Bundle options) { 3012 enforceNotIsolatedCaller("startActivityIntentSender"); 3013 // Refuse possible leaked file descriptors 3014 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3015 throw new IllegalArgumentException("File descriptors passed in Intent"); 3016 } 3017 3018 IIntentSender sender = intent.getTarget(); 3019 if (!(sender instanceof PendingIntentRecord)) { 3020 throw new IllegalArgumentException("Bad PendingIntent object"); 3021 } 3022 3023 PendingIntentRecord pir = (PendingIntentRecord)sender; 3024 3025 synchronized (this) { 3026 // If this is coming from the currently resumed activity, it is 3027 // effectively saying that app switches are allowed at this point. 3028 final ActivityStack stack = getFocusedStack(); 3029 if (stack.mResumedActivity != null && 3030 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3031 mAppSwitchesAllowedTime = 0; 3032 } 3033 } 3034 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3035 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 3036 return ret; 3037 } 3038 3039 @Override 3040 public boolean startNextMatchingActivity(IBinder callingActivity, 3041 Intent intent, Bundle options) { 3042 // Refuse possible leaked file descriptors 3043 if (intent != null && intent.hasFileDescriptors() == true) { 3044 throw new IllegalArgumentException("File descriptors passed in Intent"); 3045 } 3046 3047 synchronized (this) { 3048 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3049 if (r == null) { 3050 ActivityOptions.abort(options); 3051 return false; 3052 } 3053 if (r.app == null || r.app.thread == null) { 3054 // The caller is not running... d'oh! 3055 ActivityOptions.abort(options); 3056 return false; 3057 } 3058 intent = new Intent(intent); 3059 // The caller is not allowed to change the data. 3060 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3061 // And we are resetting to find the next component... 3062 intent.setComponent(null); 3063 3064 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3065 3066 ActivityInfo aInfo = null; 3067 try { 3068 List<ResolveInfo> resolves = 3069 AppGlobals.getPackageManager().queryIntentActivities( 3070 intent, r.resolvedType, 3071 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3072 UserHandle.getCallingUserId()); 3073 3074 // Look for the original activity in the list... 3075 final int N = resolves != null ? resolves.size() : 0; 3076 for (int i=0; i<N; i++) { 3077 ResolveInfo rInfo = resolves.get(i); 3078 if (rInfo.activityInfo.packageName.equals(r.packageName) 3079 && rInfo.activityInfo.name.equals(r.info.name)) { 3080 // We found the current one... the next matching is 3081 // after it. 3082 i++; 3083 if (i<N) { 3084 aInfo = resolves.get(i).activityInfo; 3085 } 3086 if (debug) { 3087 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3088 + "/" + r.info.name); 3089 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3090 + "/" + aInfo.name); 3091 } 3092 break; 3093 } 3094 } 3095 } catch (RemoteException e) { 3096 } 3097 3098 if (aInfo == null) { 3099 // Nobody who is next! 3100 ActivityOptions.abort(options); 3101 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3102 return false; 3103 } 3104 3105 intent.setComponent(new ComponentName( 3106 aInfo.applicationInfo.packageName, aInfo.name)); 3107 intent.setFlags(intent.getFlags()&~( 3108 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3109 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3110 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3111 Intent.FLAG_ACTIVITY_NEW_TASK)); 3112 3113 // Okay now we need to start the new activity, replacing the 3114 // currently running activity. This is a little tricky because 3115 // we want to start the new one as if the current one is finished, 3116 // but not finish the current one first so that there is no flicker. 3117 // And thus... 3118 final boolean wasFinishing = r.finishing; 3119 r.finishing = true; 3120 3121 // Propagate reply information over to the new activity. 3122 final ActivityRecord resultTo = r.resultTo; 3123 final String resultWho = r.resultWho; 3124 final int requestCode = r.requestCode; 3125 r.resultTo = null; 3126 if (resultTo != null) { 3127 resultTo.removeResultsLocked(r, resultWho, requestCode); 3128 } 3129 3130 final long origId = Binder.clearCallingIdentity(); 3131 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3132 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3133 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3134 options, false, null); 3135 Binder.restoreCallingIdentity(origId); 3136 3137 r.finishing = wasFinishing; 3138 if (res != ActivityManager.START_SUCCESS) { 3139 return false; 3140 } 3141 return true; 3142 } 3143 } 3144 3145 final int startActivityInPackage(int uid, String callingPackage, 3146 Intent intent, String resolvedType, IBinder resultTo, 3147 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 3148 3149 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3150 false, true, "startActivityInPackage", null); 3151 3152 // TODO: Switch to user app stacks here. 3153 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3154 resultTo, resultWho, requestCode, startFlags, 3155 null, null, null, null, options, userId); 3156 return ret; 3157 } 3158 3159 @Override 3160 public final int startActivities(IApplicationThread caller, String callingPackage, 3161 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3162 int userId) { 3163 enforceNotIsolatedCaller("startActivities"); 3164 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3165 false, true, "startActivity", null); 3166 // TODO: Switch to user app stacks here. 3167 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3168 resolvedTypes, resultTo, options, userId); 3169 return ret; 3170 } 3171 3172 final int startActivitiesInPackage(int uid, String callingPackage, 3173 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3174 Bundle options, int userId) { 3175 3176 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3177 false, true, "startActivityInPackage", null); 3178 // TODO: Switch to user app stacks here. 3179 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3180 resultTo, options, userId); 3181 return ret; 3182 } 3183 3184 final void addRecentTaskLocked(TaskRecord task) { 3185 int N = mRecentTasks.size(); 3186 // Quick case: check if the top-most recent task is the same. 3187 if (N > 0 && mRecentTasks.get(0) == task) { 3188 return; 3189 } 3190 // Remove any existing entries that are the same kind of task. 3191 for (int i=0; i<N; i++) { 3192 TaskRecord tr = mRecentTasks.get(i); 3193 if (task.userId == tr.userId 3194 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3195 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3196 tr.disposeThumbnail(); 3197 mRecentTasks.remove(i); 3198 i--; 3199 N--; 3200 if (task.intent == null) { 3201 // If the new recent task we are adding is not fully 3202 // specified, then replace it with the existing recent task. 3203 task = tr; 3204 } 3205 } 3206 } 3207 if (N >= MAX_RECENT_TASKS) { 3208 mRecentTasks.remove(N-1).disposeThumbnail(); 3209 } 3210 mRecentTasks.add(0, task); 3211 } 3212 3213 @Override 3214 public void reportActivityFullyDrawn(IBinder token) { 3215 synchronized (this) { 3216 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3217 if (r == null) { 3218 return; 3219 } 3220 r.reportFullyDrawnLocked(); 3221 } 3222 } 3223 3224 @Override 3225 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3226 synchronized (this) { 3227 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3228 if (r == null) { 3229 return; 3230 } 3231 final long origId = Binder.clearCallingIdentity(); 3232 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3233 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3234 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3235 if (config != null) { 3236 r.frozenBeforeDestroy = true; 3237 if (!updateConfigurationLocked(config, r, false, false)) { 3238 mStackSupervisor.resumeTopActivitiesLocked(); 3239 } 3240 } 3241 Binder.restoreCallingIdentity(origId); 3242 } 3243 } 3244 3245 @Override 3246 public int getRequestedOrientation(IBinder token) { 3247 synchronized (this) { 3248 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3249 if (r == null) { 3250 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3251 } 3252 return mWindowManager.getAppOrientation(r.appToken); 3253 } 3254 } 3255 3256 /** 3257 * This is the internal entry point for handling Activity.finish(). 3258 * 3259 * @param token The Binder token referencing the Activity we want to finish. 3260 * @param resultCode Result code, if any, from this Activity. 3261 * @param resultData Result data (Intent), if any, from this Activity. 3262 * 3263 * @return Returns true if the activity successfully finished, or false if it is still running. 3264 */ 3265 @Override 3266 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3267 // Refuse possible leaked file descriptors 3268 if (resultData != null && resultData.hasFileDescriptors() == true) { 3269 throw new IllegalArgumentException("File descriptors passed in Intent"); 3270 } 3271 3272 synchronized(this) { 3273 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3274 if (r == null) { 3275 return true; 3276 } 3277 if (mController != null) { 3278 // Find the first activity that is not finishing. 3279 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3280 if (next != null) { 3281 // ask watcher if this is allowed 3282 boolean resumeOK = true; 3283 try { 3284 resumeOK = mController.activityResuming(next.packageName); 3285 } catch (RemoteException e) { 3286 mController = null; 3287 Watchdog.getInstance().setActivityController(null); 3288 } 3289 3290 if (!resumeOK) { 3291 return false; 3292 } 3293 } 3294 } 3295 final long origId = Binder.clearCallingIdentity(); 3296 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3297 resultData, "app-request", true); 3298 Binder.restoreCallingIdentity(origId); 3299 return res; 3300 } 3301 } 3302 3303 @Override 3304 public final void finishHeavyWeightApp() { 3305 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3306 != PackageManager.PERMISSION_GRANTED) { 3307 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3308 + Binder.getCallingPid() 3309 + ", uid=" + Binder.getCallingUid() 3310 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3311 Slog.w(TAG, msg); 3312 throw new SecurityException(msg); 3313 } 3314 3315 synchronized(this) { 3316 if (mHeavyWeightProcess == null) { 3317 return; 3318 } 3319 3320 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3321 mHeavyWeightProcess.activities); 3322 for (int i=0; i<activities.size(); i++) { 3323 ActivityRecord r = activities.get(i); 3324 if (!r.finishing) { 3325 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3326 null, "finish-heavy", true); 3327 } 3328 } 3329 3330 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3331 mHeavyWeightProcess.userId, 0)); 3332 mHeavyWeightProcess = null; 3333 } 3334 } 3335 3336 @Override 3337 public void crashApplication(int uid, int initialPid, String packageName, 3338 String message) { 3339 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3340 != PackageManager.PERMISSION_GRANTED) { 3341 String msg = "Permission Denial: crashApplication() from pid=" 3342 + Binder.getCallingPid() 3343 + ", uid=" + Binder.getCallingUid() 3344 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3345 Slog.w(TAG, msg); 3346 throw new SecurityException(msg); 3347 } 3348 3349 synchronized(this) { 3350 ProcessRecord proc = null; 3351 3352 // Figure out which process to kill. We don't trust that initialPid 3353 // still has any relation to current pids, so must scan through the 3354 // list. 3355 synchronized (mPidsSelfLocked) { 3356 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3357 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3358 if (p.uid != uid) { 3359 continue; 3360 } 3361 if (p.pid == initialPid) { 3362 proc = p; 3363 break; 3364 } 3365 if (p.pkgList.containsKey(packageName)) { 3366 proc = p; 3367 } 3368 } 3369 } 3370 3371 if (proc == null) { 3372 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3373 + " initialPid=" + initialPid 3374 + " packageName=" + packageName); 3375 return; 3376 } 3377 3378 if (proc.thread != null) { 3379 if (proc.pid == Process.myPid()) { 3380 Log.w(TAG, "crashApplication: trying to crash self!"); 3381 return; 3382 } 3383 long ident = Binder.clearCallingIdentity(); 3384 try { 3385 proc.thread.scheduleCrash(message); 3386 } catch (RemoteException e) { 3387 } 3388 Binder.restoreCallingIdentity(ident); 3389 } 3390 } 3391 } 3392 3393 @Override 3394 public final void finishSubActivity(IBinder token, String resultWho, 3395 int requestCode) { 3396 synchronized(this) { 3397 final long origId = Binder.clearCallingIdentity(); 3398 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3399 if (r != null) { 3400 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3401 } 3402 Binder.restoreCallingIdentity(origId); 3403 } 3404 } 3405 3406 @Override 3407 public boolean finishActivityAffinity(IBinder token) { 3408 synchronized(this) { 3409 final long origId = Binder.clearCallingIdentity(); 3410 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3411 boolean res = false; 3412 if (r != null) { 3413 res = r.task.stack.finishActivityAffinityLocked(r); 3414 } 3415 Binder.restoreCallingIdentity(origId); 3416 return res; 3417 } 3418 } 3419 3420 @Override 3421 public boolean willActivityBeVisible(IBinder token) { 3422 synchronized(this) { 3423 ActivityStack stack = ActivityRecord.getStackLocked(token); 3424 if (stack != null) { 3425 return stack.willActivityBeVisibleLocked(token); 3426 } 3427 return false; 3428 } 3429 } 3430 3431 @Override 3432 public void overridePendingTransition(IBinder token, String packageName, 3433 int enterAnim, int exitAnim) { 3434 synchronized(this) { 3435 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3436 if (self == null) { 3437 return; 3438 } 3439 3440 final long origId = Binder.clearCallingIdentity(); 3441 3442 if (self.state == ActivityState.RESUMED 3443 || self.state == ActivityState.PAUSING) { 3444 mWindowManager.overridePendingAppTransition(packageName, 3445 enterAnim, exitAnim, null); 3446 } 3447 3448 Binder.restoreCallingIdentity(origId); 3449 } 3450 } 3451 3452 /** 3453 * Main function for removing an existing process from the activity manager 3454 * as a result of that process going away. Clears out all connections 3455 * to the process. 3456 */ 3457 private final void handleAppDiedLocked(ProcessRecord app, 3458 boolean restarting, boolean allowRestart) { 3459 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3460 if (!restarting) { 3461 removeLruProcessLocked(app); 3462 } 3463 3464 if (mProfileProc == app) { 3465 clearProfilerLocked(); 3466 } 3467 3468 // Remove this application's activities from active lists. 3469 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3470 3471 app.activities.clear(); 3472 3473 if (app.instrumentationClass != null) { 3474 Slog.w(TAG, "Crash of app " + app.processName 3475 + " running instrumentation " + app.instrumentationClass); 3476 Bundle info = new Bundle(); 3477 info.putString("shortMsg", "Process crashed."); 3478 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3479 } 3480 3481 if (!restarting) { 3482 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3483 // If there was nothing to resume, and we are not already 3484 // restarting this process, but there is a visible activity that 3485 // is hosted by the process... then make sure all visible 3486 // activities are running, taking care of restarting this 3487 // process. 3488 if (hasVisibleActivities) { 3489 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3490 } 3491 } 3492 } 3493 } 3494 3495 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3496 IBinder threadBinder = thread.asBinder(); 3497 // Find the application record. 3498 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3499 ProcessRecord rec = mLruProcesses.get(i); 3500 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3501 return i; 3502 } 3503 } 3504 return -1; 3505 } 3506 3507 final ProcessRecord getRecordForAppLocked( 3508 IApplicationThread thread) { 3509 if (thread == null) { 3510 return null; 3511 } 3512 3513 int appIndex = getLRURecordIndexForAppLocked(thread); 3514 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3515 } 3516 3517 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3518 // If there are no longer any background processes running, 3519 // and the app that died was not running instrumentation, 3520 // then tell everyone we are now low on memory. 3521 boolean haveBg = false; 3522 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3523 ProcessRecord rec = mLruProcesses.get(i); 3524 if (rec.thread != null 3525 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3526 haveBg = true; 3527 break; 3528 } 3529 } 3530 3531 if (!haveBg) { 3532 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3533 if (doReport) { 3534 long now = SystemClock.uptimeMillis(); 3535 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3536 doReport = false; 3537 } else { 3538 mLastMemUsageReportTime = now; 3539 } 3540 } 3541 final ArrayList<ProcessMemInfo> memInfos 3542 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3543 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3544 long now = SystemClock.uptimeMillis(); 3545 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3546 ProcessRecord rec = mLruProcesses.get(i); 3547 if (rec == dyingProc || rec.thread == null) { 3548 continue; 3549 } 3550 if (doReport) { 3551 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3552 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3553 } 3554 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3555 // The low memory report is overriding any current 3556 // state for a GC request. Make sure to do 3557 // heavy/important/visible/foreground processes first. 3558 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3559 rec.lastRequestedGc = 0; 3560 } else { 3561 rec.lastRequestedGc = rec.lastLowMemory; 3562 } 3563 rec.reportLowMemory = true; 3564 rec.lastLowMemory = now; 3565 mProcessesToGc.remove(rec); 3566 addProcessToGcListLocked(rec); 3567 } 3568 } 3569 if (doReport) { 3570 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3571 mHandler.sendMessage(msg); 3572 } 3573 scheduleAppGcsLocked(); 3574 } 3575 } 3576 3577 final void appDiedLocked(ProcessRecord app, int pid, 3578 IApplicationThread thread) { 3579 3580 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3581 synchronized (stats) { 3582 stats.noteProcessDiedLocked(app.info.uid, pid); 3583 } 3584 3585 // Clean up already done if the process has been re-started. 3586 if (app.pid == pid && app.thread != null && 3587 app.thread.asBinder() == thread.asBinder()) { 3588 boolean doLowMem = app.instrumentationClass == null; 3589 boolean doOomAdj = doLowMem; 3590 if (!app.killedByAm) { 3591 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3592 + ") has died."); 3593 mAllowLowerMemLevel = true; 3594 } else { 3595 // Note that we always want to do oom adj to update our state with the 3596 // new number of procs. 3597 mAllowLowerMemLevel = false; 3598 doLowMem = false; 3599 } 3600 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3601 if (DEBUG_CLEANUP) Slog.v( 3602 TAG, "Dying app: " + app + ", pid: " + pid 3603 + ", thread: " + thread.asBinder()); 3604 handleAppDiedLocked(app, false, true); 3605 3606 if (doOomAdj) { 3607 updateOomAdjLocked(); 3608 } 3609 if (doLowMem) { 3610 doLowMemReportIfNeededLocked(app); 3611 } 3612 } else if (app.pid != pid) { 3613 // A new process has already been started. 3614 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3615 + ") has died and restarted (pid " + app.pid + ")."); 3616 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3617 } else if (DEBUG_PROCESSES) { 3618 Slog.d(TAG, "Received spurious death notification for thread " 3619 + thread.asBinder()); 3620 } 3621 } 3622 3623 /** 3624 * If a stack trace dump file is configured, dump process stack traces. 3625 * @param clearTraces causes the dump file to be erased prior to the new 3626 * traces being written, if true; when false, the new traces will be 3627 * appended to any existing file content. 3628 * @param firstPids of dalvik VM processes to dump stack traces for first 3629 * @param lastPids of dalvik VM processes to dump stack traces for last 3630 * @param nativeProcs optional list of native process names to dump stack crawls 3631 * @return file containing stack traces, or null if no dump file is configured 3632 */ 3633 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3634 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3635 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3636 if (tracesPath == null || tracesPath.length() == 0) { 3637 return null; 3638 } 3639 3640 File tracesFile = new File(tracesPath); 3641 try { 3642 File tracesDir = tracesFile.getParentFile(); 3643 if (!tracesDir.exists()) { 3644 tracesFile.mkdirs(); 3645 if (!SELinux.restorecon(tracesDir)) { 3646 return null; 3647 } 3648 } 3649 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3650 3651 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3652 tracesFile.createNewFile(); 3653 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3654 } catch (IOException e) { 3655 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3656 return null; 3657 } 3658 3659 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3660 return tracesFile; 3661 } 3662 3663 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3664 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3665 // Use a FileObserver to detect when traces finish writing. 3666 // The order of traces is considered important to maintain for legibility. 3667 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3668 @Override 3669 public synchronized void onEvent(int event, String path) { notify(); } 3670 }; 3671 3672 try { 3673 observer.startWatching(); 3674 3675 // First collect all of the stacks of the most important pids. 3676 if (firstPids != null) { 3677 try { 3678 int num = firstPids.size(); 3679 for (int i = 0; i < num; i++) { 3680 synchronized (observer) { 3681 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3682 observer.wait(200); // Wait for write-close, give up after 200msec 3683 } 3684 } 3685 } catch (InterruptedException e) { 3686 Log.wtf(TAG, e); 3687 } 3688 } 3689 3690 // Next measure CPU usage. 3691 if (processCpuTracker != null) { 3692 processCpuTracker.init(); 3693 System.gc(); 3694 processCpuTracker.update(); 3695 try { 3696 synchronized (processCpuTracker) { 3697 processCpuTracker.wait(500); // measure over 1/2 second. 3698 } 3699 } catch (InterruptedException e) { 3700 } 3701 processCpuTracker.update(); 3702 3703 // We'll take the stack crawls of just the top apps using CPU. 3704 final int N = processCpuTracker.countWorkingStats(); 3705 int numProcs = 0; 3706 for (int i=0; i<N && numProcs<5; i++) { 3707 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3708 if (lastPids.indexOfKey(stats.pid) >= 0) { 3709 numProcs++; 3710 try { 3711 synchronized (observer) { 3712 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3713 observer.wait(200); // Wait for write-close, give up after 200msec 3714 } 3715 } catch (InterruptedException e) { 3716 Log.wtf(TAG, e); 3717 } 3718 3719 } 3720 } 3721 } 3722 3723 } finally { 3724 observer.stopWatching(); 3725 } 3726 3727 if (nativeProcs != null) { 3728 int[] pids = Process.getPidsForCommands(nativeProcs); 3729 if (pids != null) { 3730 for (int pid : pids) { 3731 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3732 } 3733 } 3734 } 3735 } 3736 3737 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3738 if (true || IS_USER_BUILD) { 3739 return; 3740 } 3741 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3742 if (tracesPath == null || tracesPath.length() == 0) { 3743 return; 3744 } 3745 3746 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3747 StrictMode.allowThreadDiskWrites(); 3748 try { 3749 final File tracesFile = new File(tracesPath); 3750 final File tracesDir = tracesFile.getParentFile(); 3751 final File tracesTmp = new File(tracesDir, "__tmp__"); 3752 try { 3753 if (!tracesDir.exists()) { 3754 tracesFile.mkdirs(); 3755 if (!SELinux.restorecon(tracesDir.getPath())) { 3756 return; 3757 } 3758 } 3759 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3760 3761 if (tracesFile.exists()) { 3762 tracesTmp.delete(); 3763 tracesFile.renameTo(tracesTmp); 3764 } 3765 StringBuilder sb = new StringBuilder(); 3766 Time tobj = new Time(); 3767 tobj.set(System.currentTimeMillis()); 3768 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3769 sb.append(": "); 3770 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3771 sb.append(" since "); 3772 sb.append(msg); 3773 FileOutputStream fos = new FileOutputStream(tracesFile); 3774 fos.write(sb.toString().getBytes()); 3775 if (app == null) { 3776 fos.write("\n*** No application process!".getBytes()); 3777 } 3778 fos.close(); 3779 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3780 } catch (IOException e) { 3781 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3782 return; 3783 } 3784 3785 if (app != null) { 3786 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3787 firstPids.add(app.pid); 3788 dumpStackTraces(tracesPath, firstPids, null, null, null); 3789 } 3790 3791 File lastTracesFile = null; 3792 File curTracesFile = null; 3793 for (int i=9; i>=0; i--) { 3794 String name = String.format(Locale.US, "slow%02d.txt", i); 3795 curTracesFile = new File(tracesDir, name); 3796 if (curTracesFile.exists()) { 3797 if (lastTracesFile != null) { 3798 curTracesFile.renameTo(lastTracesFile); 3799 } else { 3800 curTracesFile.delete(); 3801 } 3802 } 3803 lastTracesFile = curTracesFile; 3804 } 3805 tracesFile.renameTo(curTracesFile); 3806 if (tracesTmp.exists()) { 3807 tracesTmp.renameTo(tracesFile); 3808 } 3809 } finally { 3810 StrictMode.setThreadPolicy(oldPolicy); 3811 } 3812 } 3813 3814 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3815 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3816 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3817 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3818 3819 if (mController != null) { 3820 try { 3821 // 0 == continue, -1 = kill process immediately 3822 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3823 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3824 } catch (RemoteException e) { 3825 mController = null; 3826 Watchdog.getInstance().setActivityController(null); 3827 } 3828 } 3829 3830 long anrTime = SystemClock.uptimeMillis(); 3831 if (MONITOR_CPU_USAGE) { 3832 updateCpuStatsNow(); 3833 } 3834 3835 synchronized (this) { 3836 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3837 if (mShuttingDown) { 3838 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3839 return; 3840 } else if (app.notResponding) { 3841 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3842 return; 3843 } else if (app.crashing) { 3844 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3845 return; 3846 } 3847 3848 // In case we come through here for the same app before completing 3849 // this one, mark as anring now so we will bail out. 3850 app.notResponding = true; 3851 3852 // Log the ANR to the event log. 3853 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3854 app.processName, app.info.flags, annotation); 3855 3856 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3857 firstPids.add(app.pid); 3858 3859 int parentPid = app.pid; 3860 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3861 if (parentPid != app.pid) firstPids.add(parentPid); 3862 3863 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3864 3865 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3866 ProcessRecord r = mLruProcesses.get(i); 3867 if (r != null && r.thread != null) { 3868 int pid = r.pid; 3869 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 3870 if (r.persistent) { 3871 firstPids.add(pid); 3872 } else { 3873 lastPids.put(pid, Boolean.TRUE); 3874 } 3875 } 3876 } 3877 } 3878 } 3879 3880 // Log the ANR to the main log. 3881 StringBuilder info = new StringBuilder(); 3882 info.setLength(0); 3883 info.append("ANR in ").append(app.processName); 3884 if (activity != null && activity.shortComponentName != null) { 3885 info.append(" (").append(activity.shortComponentName).append(")"); 3886 } 3887 info.append("\n"); 3888 info.append("PID: ").append(app.pid).append("\n"); 3889 if (annotation != null) { 3890 info.append("Reason: ").append(annotation).append("\n"); 3891 } 3892 if (parent != null && parent != activity) { 3893 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 3894 } 3895 3896 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 3897 3898 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, null); 3899 3900 String cpuInfo = null; 3901 if (MONITOR_CPU_USAGE) { 3902 updateCpuStatsNow(); 3903 synchronized (mProcessCpuThread) { 3904 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 3905 } 3906 info.append(processCpuTracker.printCurrentLoad()); 3907 info.append(cpuInfo); 3908 } 3909 3910 info.append(processCpuTracker.printCurrentState(anrTime)); 3911 3912 Slog.e(TAG, info.toString()); 3913 if (tracesFile == null) { 3914 // There is no trace file, so dump (only) the alleged culprit's threads to the log 3915 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 3916 } 3917 3918 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 3919 cpuInfo, tracesFile, null); 3920 3921 if (mController != null) { 3922 try { 3923 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 3924 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 3925 if (res != 0) { 3926 if (res < 0 && app.pid != MY_PID) { 3927 Process.killProcess(app.pid); 3928 } else { 3929 synchronized (this) { 3930 mServices.scheduleServiceTimeoutLocked(app); 3931 } 3932 } 3933 return; 3934 } 3935 } catch (RemoteException e) { 3936 mController = null; 3937 Watchdog.getInstance().setActivityController(null); 3938 } 3939 } 3940 3941 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 3942 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 3943 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 3944 3945 synchronized (this) { 3946 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 3947 killUnneededProcessLocked(app, "background ANR"); 3948 return; 3949 } 3950 3951 // Set the app's notResponding state, and look up the errorReportReceiver 3952 makeAppNotRespondingLocked(app, 3953 activity != null ? activity.shortComponentName : null, 3954 annotation != null ? "ANR " + annotation : "ANR", 3955 info.toString()); 3956 3957 // Bring up the infamous App Not Responding dialog 3958 Message msg = Message.obtain(); 3959 HashMap<String, Object> map = new HashMap<String, Object>(); 3960 msg.what = SHOW_NOT_RESPONDING_MSG; 3961 msg.obj = map; 3962 msg.arg1 = aboveSystem ? 1 : 0; 3963 map.put("app", app); 3964 if (activity != null) { 3965 map.put("activity", activity); 3966 } 3967 3968 mHandler.sendMessage(msg); 3969 } 3970 } 3971 3972 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 3973 if (!mLaunchWarningShown) { 3974 mLaunchWarningShown = true; 3975 mHandler.post(new Runnable() { 3976 @Override 3977 public void run() { 3978 synchronized (ActivityManagerService.this) { 3979 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 3980 d.show(); 3981 mHandler.postDelayed(new Runnable() { 3982 @Override 3983 public void run() { 3984 synchronized (ActivityManagerService.this) { 3985 d.dismiss(); 3986 mLaunchWarningShown = false; 3987 } 3988 } 3989 }, 4000); 3990 } 3991 } 3992 }); 3993 } 3994 } 3995 3996 @Override 3997 public boolean clearApplicationUserData(final String packageName, 3998 final IPackageDataObserver observer, int userId) { 3999 enforceNotIsolatedCaller("clearApplicationUserData"); 4000 int uid = Binder.getCallingUid(); 4001 int pid = Binder.getCallingPid(); 4002 userId = handleIncomingUser(pid, uid, 4003 userId, false, true, "clearApplicationUserData", null); 4004 long callingId = Binder.clearCallingIdentity(); 4005 try { 4006 IPackageManager pm = AppGlobals.getPackageManager(); 4007 int pkgUid = -1; 4008 synchronized(this) { 4009 try { 4010 pkgUid = pm.getPackageUid(packageName, userId); 4011 } catch (RemoteException e) { 4012 } 4013 if (pkgUid == -1) { 4014 Slog.w(TAG, "Invalid packageName: " + packageName); 4015 if (observer != null) { 4016 try { 4017 observer.onRemoveCompleted(packageName, false); 4018 } catch (RemoteException e) { 4019 Slog.i(TAG, "Observer no longer exists."); 4020 } 4021 } 4022 return false; 4023 } 4024 if (uid == pkgUid || checkComponentPermission( 4025 android.Manifest.permission.CLEAR_APP_USER_DATA, 4026 pid, uid, -1, true) 4027 == PackageManager.PERMISSION_GRANTED) { 4028 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4029 } else { 4030 throw new SecurityException(pid+" does not have permission:"+ 4031 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 4032 "for process:"+packageName); 4033 } 4034 } 4035 4036 try { 4037 // Clear application user data 4038 pm.clearApplicationUserData(packageName, observer, userId); 4039 4040 // Remove all permissions granted from/to this package 4041 removeUriPermissionsForPackageLocked(packageName, userId, true); 4042 4043 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4044 Uri.fromParts("package", packageName, null)); 4045 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4046 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4047 null, null, 0, null, null, null, false, false, userId); 4048 } catch (RemoteException e) { 4049 } 4050 } finally { 4051 Binder.restoreCallingIdentity(callingId); 4052 } 4053 return true; 4054 } 4055 4056 @Override 4057 public void killBackgroundProcesses(final String packageName, int userId) { 4058 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4059 != PackageManager.PERMISSION_GRANTED && 4060 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4061 != PackageManager.PERMISSION_GRANTED) { 4062 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4063 + Binder.getCallingPid() 4064 + ", uid=" + Binder.getCallingUid() 4065 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4066 Slog.w(TAG, msg); 4067 throw new SecurityException(msg); 4068 } 4069 4070 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4071 userId, true, true, "killBackgroundProcesses", null); 4072 long callingId = Binder.clearCallingIdentity(); 4073 try { 4074 IPackageManager pm = AppGlobals.getPackageManager(); 4075 synchronized(this) { 4076 int appId = -1; 4077 try { 4078 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4079 } catch (RemoteException e) { 4080 } 4081 if (appId == -1) { 4082 Slog.w(TAG, "Invalid packageName: " + packageName); 4083 return; 4084 } 4085 killPackageProcessesLocked(packageName, appId, userId, 4086 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4087 } 4088 } finally { 4089 Binder.restoreCallingIdentity(callingId); 4090 } 4091 } 4092 4093 @Override 4094 public void killAllBackgroundProcesses() { 4095 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4096 != PackageManager.PERMISSION_GRANTED) { 4097 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4098 + Binder.getCallingPid() 4099 + ", uid=" + Binder.getCallingUid() 4100 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4101 Slog.w(TAG, msg); 4102 throw new SecurityException(msg); 4103 } 4104 4105 long callingId = Binder.clearCallingIdentity(); 4106 try { 4107 synchronized(this) { 4108 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4109 final int NP = mProcessNames.getMap().size(); 4110 for (int ip=0; ip<NP; ip++) { 4111 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4112 final int NA = apps.size(); 4113 for (int ia=0; ia<NA; ia++) { 4114 ProcessRecord app = apps.valueAt(ia); 4115 if (app.persistent) { 4116 // we don't kill persistent processes 4117 continue; 4118 } 4119 if (app.removed) { 4120 procs.add(app); 4121 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4122 app.removed = true; 4123 procs.add(app); 4124 } 4125 } 4126 } 4127 4128 int N = procs.size(); 4129 for (int i=0; i<N; i++) { 4130 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4131 } 4132 mAllowLowerMemLevel = true; 4133 updateOomAdjLocked(); 4134 doLowMemReportIfNeededLocked(null); 4135 } 4136 } finally { 4137 Binder.restoreCallingIdentity(callingId); 4138 } 4139 } 4140 4141 @Override 4142 public void forceStopPackage(final String packageName, int userId) { 4143 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4144 != PackageManager.PERMISSION_GRANTED) { 4145 String msg = "Permission Denial: forceStopPackage() from pid=" 4146 + Binder.getCallingPid() 4147 + ", uid=" + Binder.getCallingUid() 4148 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4149 Slog.w(TAG, msg); 4150 throw new SecurityException(msg); 4151 } 4152 final int callingPid = Binder.getCallingPid(); 4153 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4154 userId, true, true, "forceStopPackage", null); 4155 long callingId = Binder.clearCallingIdentity(); 4156 try { 4157 IPackageManager pm = AppGlobals.getPackageManager(); 4158 synchronized(this) { 4159 int[] users = userId == UserHandle.USER_ALL 4160 ? getUsersLocked() : new int[] { userId }; 4161 for (int user : users) { 4162 int pkgUid = -1; 4163 try { 4164 pkgUid = pm.getPackageUid(packageName, user); 4165 } catch (RemoteException e) { 4166 } 4167 if (pkgUid == -1) { 4168 Slog.w(TAG, "Invalid packageName: " + packageName); 4169 continue; 4170 } 4171 try { 4172 pm.setPackageStoppedState(packageName, true, user); 4173 } catch (RemoteException e) { 4174 } catch (IllegalArgumentException e) { 4175 Slog.w(TAG, "Failed trying to unstop package " 4176 + packageName + ": " + e); 4177 } 4178 if (isUserRunningLocked(user, false)) { 4179 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4180 } 4181 } 4182 } 4183 } finally { 4184 Binder.restoreCallingIdentity(callingId); 4185 } 4186 } 4187 4188 /* 4189 * The pkg name and app id have to be specified. 4190 */ 4191 @Override 4192 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4193 if (pkg == null) { 4194 return; 4195 } 4196 // Make sure the uid is valid. 4197 if (appid < 0) { 4198 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4199 return; 4200 } 4201 int callerUid = Binder.getCallingUid(); 4202 // Only the system server can kill an application 4203 if (callerUid == Process.SYSTEM_UID) { 4204 // Post an aysnc message to kill the application 4205 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4206 msg.arg1 = appid; 4207 msg.arg2 = 0; 4208 Bundle bundle = new Bundle(); 4209 bundle.putString("pkg", pkg); 4210 bundle.putString("reason", reason); 4211 msg.obj = bundle; 4212 mHandler.sendMessage(msg); 4213 } else { 4214 throw new SecurityException(callerUid + " cannot kill pkg: " + 4215 pkg); 4216 } 4217 } 4218 4219 @Override 4220 public void closeSystemDialogs(String reason) { 4221 enforceNotIsolatedCaller("closeSystemDialogs"); 4222 4223 final int pid = Binder.getCallingPid(); 4224 final int uid = Binder.getCallingUid(); 4225 final long origId = Binder.clearCallingIdentity(); 4226 try { 4227 synchronized (this) { 4228 // Only allow this from foreground processes, so that background 4229 // applications can't abuse it to prevent system UI from being shown. 4230 if (uid >= Process.FIRST_APPLICATION_UID) { 4231 ProcessRecord proc; 4232 synchronized (mPidsSelfLocked) { 4233 proc = mPidsSelfLocked.get(pid); 4234 } 4235 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4236 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4237 + " from background process " + proc); 4238 return; 4239 } 4240 } 4241 closeSystemDialogsLocked(reason); 4242 } 4243 } finally { 4244 Binder.restoreCallingIdentity(origId); 4245 } 4246 } 4247 4248 void closeSystemDialogsLocked(String reason) { 4249 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4250 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4251 | Intent.FLAG_RECEIVER_FOREGROUND); 4252 if (reason != null) { 4253 intent.putExtra("reason", reason); 4254 } 4255 mWindowManager.closeSystemDialogs(reason); 4256 4257 mStackSupervisor.closeSystemDialogsLocked(); 4258 4259 broadcastIntentLocked(null, null, intent, null, 4260 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4261 Process.SYSTEM_UID, UserHandle.USER_ALL); 4262 } 4263 4264 @Override 4265 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4266 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4267 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4268 for (int i=pids.length-1; i>=0; i--) { 4269 ProcessRecord proc; 4270 int oomAdj; 4271 synchronized (this) { 4272 synchronized (mPidsSelfLocked) { 4273 proc = mPidsSelfLocked.get(pids[i]); 4274 oomAdj = proc != null ? proc.setAdj : 0; 4275 } 4276 } 4277 infos[i] = new Debug.MemoryInfo(); 4278 Debug.getMemoryInfo(pids[i], infos[i]); 4279 if (proc != null) { 4280 synchronized (this) { 4281 if (proc.thread != null && proc.setAdj == oomAdj) { 4282 // Record this for posterity if the process has been stable. 4283 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4284 infos[i].getTotalUss(), false, proc.pkgList); 4285 } 4286 } 4287 } 4288 } 4289 return infos; 4290 } 4291 4292 @Override 4293 public long[] getProcessPss(int[] pids) { 4294 enforceNotIsolatedCaller("getProcessPss"); 4295 long[] pss = new long[pids.length]; 4296 for (int i=pids.length-1; i>=0; i--) { 4297 ProcessRecord proc; 4298 int oomAdj; 4299 synchronized (this) { 4300 synchronized (mPidsSelfLocked) { 4301 proc = mPidsSelfLocked.get(pids[i]); 4302 oomAdj = proc != null ? proc.setAdj : 0; 4303 } 4304 } 4305 long[] tmpUss = new long[1]; 4306 pss[i] = Debug.getPss(pids[i], tmpUss); 4307 if (proc != null) { 4308 synchronized (this) { 4309 if (proc.thread != null && proc.setAdj == oomAdj) { 4310 // Record this for posterity if the process has been stable. 4311 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4312 } 4313 } 4314 } 4315 } 4316 return pss; 4317 } 4318 4319 @Override 4320 public void killApplicationProcess(String processName, int uid) { 4321 if (processName == null) { 4322 return; 4323 } 4324 4325 int callerUid = Binder.getCallingUid(); 4326 // Only the system server can kill an application 4327 if (callerUid == Process.SYSTEM_UID) { 4328 synchronized (this) { 4329 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4330 if (app != null && app.thread != null) { 4331 try { 4332 app.thread.scheduleSuicide(); 4333 } catch (RemoteException e) { 4334 // If the other end already died, then our work here is done. 4335 } 4336 } else { 4337 Slog.w(TAG, "Process/uid not found attempting kill of " 4338 + processName + " / " + uid); 4339 } 4340 } 4341 } else { 4342 throw new SecurityException(callerUid + " cannot kill app process: " + 4343 processName); 4344 } 4345 } 4346 4347 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4348 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4349 false, true, false, UserHandle.getUserId(uid), reason); 4350 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4351 Uri.fromParts("package", packageName, null)); 4352 if (!mProcessesReady) { 4353 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4354 | Intent.FLAG_RECEIVER_FOREGROUND); 4355 } 4356 intent.putExtra(Intent.EXTRA_UID, uid); 4357 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4358 broadcastIntentLocked(null, null, intent, 4359 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4360 false, false, 4361 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4362 } 4363 4364 private void forceStopUserLocked(int userId, String reason) { 4365 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4366 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4367 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4368 | Intent.FLAG_RECEIVER_FOREGROUND); 4369 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4370 broadcastIntentLocked(null, null, intent, 4371 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4372 false, false, 4373 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4374 } 4375 4376 private final boolean killPackageProcessesLocked(String packageName, int appId, 4377 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4378 boolean doit, boolean evenPersistent, String reason) { 4379 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4380 4381 // Remove all processes this package may have touched: all with the 4382 // same UID (except for the system or root user), and all whose name 4383 // matches the package name. 4384 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4385 final int NP = mProcessNames.getMap().size(); 4386 for (int ip=0; ip<NP; ip++) { 4387 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4388 final int NA = apps.size(); 4389 for (int ia=0; ia<NA; ia++) { 4390 ProcessRecord app = apps.valueAt(ia); 4391 if (app.persistent && !evenPersistent) { 4392 // we don't kill persistent processes 4393 continue; 4394 } 4395 if (app.removed) { 4396 if (doit) { 4397 procs.add(app); 4398 } 4399 continue; 4400 } 4401 4402 // Skip process if it doesn't meet our oom adj requirement. 4403 if (app.setAdj < minOomAdj) { 4404 continue; 4405 } 4406 4407 // If no package is specified, we call all processes under the 4408 // give user id. 4409 if (packageName == null) { 4410 if (app.userId != userId) { 4411 continue; 4412 } 4413 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4414 continue; 4415 } 4416 // Package has been specified, we want to hit all processes 4417 // that match it. We need to qualify this by the processes 4418 // that are running under the specified app and user ID. 4419 } else { 4420 if (UserHandle.getAppId(app.uid) != appId) { 4421 continue; 4422 } 4423 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4424 continue; 4425 } 4426 if (!app.pkgList.containsKey(packageName)) { 4427 continue; 4428 } 4429 } 4430 4431 // Process has passed all conditions, kill it! 4432 if (!doit) { 4433 return true; 4434 } 4435 app.removed = true; 4436 procs.add(app); 4437 } 4438 } 4439 4440 int N = procs.size(); 4441 for (int i=0; i<N; i++) { 4442 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4443 } 4444 updateOomAdjLocked(); 4445 return N > 0; 4446 } 4447 4448 private final boolean forceStopPackageLocked(String name, int appId, 4449 boolean callerWillRestart, boolean purgeCache, boolean doit, 4450 boolean evenPersistent, int userId, String reason) { 4451 int i; 4452 int N; 4453 4454 if (userId == UserHandle.USER_ALL && name == null) { 4455 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4456 } 4457 4458 if (appId < 0 && name != null) { 4459 try { 4460 appId = UserHandle.getAppId( 4461 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4462 } catch (RemoteException e) { 4463 } 4464 } 4465 4466 if (doit) { 4467 if (name != null) { 4468 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4469 + " user=" + userId + ": " + reason); 4470 } else { 4471 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4472 } 4473 4474 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4475 for (int ip=pmap.size()-1; ip>=0; ip--) { 4476 SparseArray<Long> ba = pmap.valueAt(ip); 4477 for (i=ba.size()-1; i>=0; i--) { 4478 boolean remove = false; 4479 final int entUid = ba.keyAt(i); 4480 if (name != null) { 4481 if (userId == UserHandle.USER_ALL) { 4482 if (UserHandle.getAppId(entUid) == appId) { 4483 remove = true; 4484 } 4485 } else { 4486 if (entUid == UserHandle.getUid(userId, appId)) { 4487 remove = true; 4488 } 4489 } 4490 } else if (UserHandle.getUserId(entUid) == userId) { 4491 remove = true; 4492 } 4493 if (remove) { 4494 ba.removeAt(i); 4495 } 4496 } 4497 if (ba.size() == 0) { 4498 pmap.removeAt(ip); 4499 } 4500 } 4501 } 4502 4503 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4504 -100, callerWillRestart, true, doit, evenPersistent, 4505 name == null ? ("stop user " + userId) : ("stop " + name)); 4506 4507 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4508 if (!doit) { 4509 return true; 4510 } 4511 didSomething = true; 4512 } 4513 4514 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4515 if (!doit) { 4516 return true; 4517 } 4518 didSomething = true; 4519 } 4520 4521 if (name == null) { 4522 // Remove all sticky broadcasts from this user. 4523 mStickyBroadcasts.remove(userId); 4524 } 4525 4526 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4527 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4528 userId, providers)) { 4529 if (!doit) { 4530 return true; 4531 } 4532 didSomething = true; 4533 } 4534 N = providers.size(); 4535 for (i=0; i<N; i++) { 4536 removeDyingProviderLocked(null, providers.get(i), true); 4537 } 4538 4539 // Remove transient permissions granted from/to this package/user 4540 removeUriPermissionsForPackageLocked(name, userId, false); 4541 4542 if (name == null) { 4543 // Remove pending intents. For now we only do this when force 4544 // stopping users, because we have some problems when doing this 4545 // for packages -- app widgets are not currently cleaned up for 4546 // such packages, so they can be left with bad pending intents. 4547 if (mIntentSenderRecords.size() > 0) { 4548 Iterator<WeakReference<PendingIntentRecord>> it 4549 = mIntentSenderRecords.values().iterator(); 4550 while (it.hasNext()) { 4551 WeakReference<PendingIntentRecord> wpir = it.next(); 4552 if (wpir == null) { 4553 it.remove(); 4554 continue; 4555 } 4556 PendingIntentRecord pir = wpir.get(); 4557 if (pir == null) { 4558 it.remove(); 4559 continue; 4560 } 4561 if (name == null) { 4562 // Stopping user, remove all objects for the user. 4563 if (pir.key.userId != userId) { 4564 // Not the same user, skip it. 4565 continue; 4566 } 4567 } else { 4568 if (UserHandle.getAppId(pir.uid) != appId) { 4569 // Different app id, skip it. 4570 continue; 4571 } 4572 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4573 // Different user, skip it. 4574 continue; 4575 } 4576 if (!pir.key.packageName.equals(name)) { 4577 // Different package, skip it. 4578 continue; 4579 } 4580 } 4581 if (!doit) { 4582 return true; 4583 } 4584 didSomething = true; 4585 it.remove(); 4586 pir.canceled = true; 4587 if (pir.key.activity != null) { 4588 pir.key.activity.pendingResults.remove(pir.ref); 4589 } 4590 } 4591 } 4592 } 4593 4594 if (doit) { 4595 if (purgeCache && name != null) { 4596 AttributeCache ac = AttributeCache.instance(); 4597 if (ac != null) { 4598 ac.removePackage(name); 4599 } 4600 } 4601 if (mBooted) { 4602 mStackSupervisor.resumeTopActivitiesLocked(); 4603 mStackSupervisor.scheduleIdleLocked(); 4604 } 4605 } 4606 4607 return didSomething; 4608 } 4609 4610 private final boolean removeProcessLocked(ProcessRecord app, 4611 boolean callerWillRestart, boolean allowRestart, String reason) { 4612 final String name = app.processName; 4613 final int uid = app.uid; 4614 if (DEBUG_PROCESSES) Slog.d( 4615 TAG, "Force removing proc " + app.toShortString() + " (" + name 4616 + "/" + uid + ")"); 4617 4618 mProcessNames.remove(name, uid); 4619 mIsolatedProcesses.remove(app.uid); 4620 if (mHeavyWeightProcess == app) { 4621 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4622 mHeavyWeightProcess.userId, 0)); 4623 mHeavyWeightProcess = null; 4624 } 4625 boolean needRestart = false; 4626 if (app.pid > 0 && app.pid != MY_PID) { 4627 int pid = app.pid; 4628 synchronized (mPidsSelfLocked) { 4629 mPidsSelfLocked.remove(pid); 4630 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4631 } 4632 killUnneededProcessLocked(app, reason); 4633 handleAppDiedLocked(app, true, allowRestart); 4634 removeLruProcessLocked(app); 4635 4636 if (app.persistent && !app.isolated) { 4637 if (!callerWillRestart) { 4638 addAppLocked(app.info, false); 4639 } else { 4640 needRestart = true; 4641 } 4642 } 4643 } else { 4644 mRemovedProcesses.add(app); 4645 } 4646 4647 return needRestart; 4648 } 4649 4650 private final void processStartTimedOutLocked(ProcessRecord app) { 4651 final int pid = app.pid; 4652 boolean gone = false; 4653 synchronized (mPidsSelfLocked) { 4654 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4655 if (knownApp != null && knownApp.thread == null) { 4656 mPidsSelfLocked.remove(pid); 4657 gone = true; 4658 } 4659 } 4660 4661 if (gone) { 4662 Slog.w(TAG, "Process " + app + " failed to attach"); 4663 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4664 pid, app.uid, app.processName); 4665 mProcessNames.remove(app.processName, app.uid); 4666 mIsolatedProcesses.remove(app.uid); 4667 if (mHeavyWeightProcess == app) { 4668 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4669 mHeavyWeightProcess.userId, 0)); 4670 mHeavyWeightProcess = null; 4671 } 4672 // Take care of any launching providers waiting for this process. 4673 checkAppInLaunchingProvidersLocked(app, true); 4674 // Take care of any services that are waiting for the process. 4675 mServices.processStartTimedOutLocked(app); 4676 killUnneededProcessLocked(app, "start timeout"); 4677 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4678 Slog.w(TAG, "Unattached app died before backup, skipping"); 4679 try { 4680 IBackupManager bm = IBackupManager.Stub.asInterface( 4681 ServiceManager.getService(Context.BACKUP_SERVICE)); 4682 bm.agentDisconnected(app.info.packageName); 4683 } catch (RemoteException e) { 4684 // Can't happen; the backup manager is local 4685 } 4686 } 4687 if (isPendingBroadcastProcessLocked(pid)) { 4688 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4689 skipPendingBroadcastLocked(pid); 4690 } 4691 } else { 4692 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4693 } 4694 } 4695 4696 private final boolean attachApplicationLocked(IApplicationThread thread, 4697 int pid) { 4698 4699 // Find the application record that is being attached... either via 4700 // the pid if we are running in multiple processes, or just pull the 4701 // next app record if we are emulating process with anonymous threads. 4702 ProcessRecord app; 4703 if (pid != MY_PID && pid >= 0) { 4704 synchronized (mPidsSelfLocked) { 4705 app = mPidsSelfLocked.get(pid); 4706 } 4707 } else { 4708 app = null; 4709 } 4710 4711 if (app == null) { 4712 Slog.w(TAG, "No pending application record for pid " + pid 4713 + " (IApplicationThread " + thread + "); dropping process"); 4714 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4715 if (pid > 0 && pid != MY_PID) { 4716 Process.killProcessQuiet(pid); 4717 } else { 4718 try { 4719 thread.scheduleExit(); 4720 } catch (Exception e) { 4721 // Ignore exceptions. 4722 } 4723 } 4724 return false; 4725 } 4726 4727 // If this application record is still attached to a previous 4728 // process, clean it up now. 4729 if (app.thread != null) { 4730 handleAppDiedLocked(app, true, true); 4731 } 4732 4733 // Tell the process all about itself. 4734 4735 if (localLOGV) Slog.v( 4736 TAG, "Binding process pid " + pid + " to record " + app); 4737 4738 final String processName = app.processName; 4739 try { 4740 AppDeathRecipient adr = new AppDeathRecipient( 4741 app, pid, thread); 4742 thread.asBinder().linkToDeath(adr, 0); 4743 app.deathRecipient = adr; 4744 } catch (RemoteException e) { 4745 app.resetPackageList(mProcessStats); 4746 startProcessLocked(app, "link fail", processName); 4747 return false; 4748 } 4749 4750 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4751 4752 app.makeActive(thread, mProcessStats); 4753 app.curAdj = app.setAdj = -100; 4754 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4755 app.forcingToForeground = null; 4756 app.foregroundServices = false; 4757 app.hasShownUi = false; 4758 app.debugging = false; 4759 app.cached = false; 4760 4761 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4762 4763 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4764 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4765 4766 if (!normalMode) { 4767 Slog.i(TAG, "Launching preboot mode app: " + app); 4768 } 4769 4770 if (localLOGV) Slog.v( 4771 TAG, "New app record " + app 4772 + " thread=" + thread.asBinder() + " pid=" + pid); 4773 try { 4774 int testMode = IApplicationThread.DEBUG_OFF; 4775 if (mDebugApp != null && mDebugApp.equals(processName)) { 4776 testMode = mWaitForDebugger 4777 ? IApplicationThread.DEBUG_WAIT 4778 : IApplicationThread.DEBUG_ON; 4779 app.debugging = true; 4780 if (mDebugTransient) { 4781 mDebugApp = mOrigDebugApp; 4782 mWaitForDebugger = mOrigWaitForDebugger; 4783 } 4784 } 4785 String profileFile = app.instrumentationProfileFile; 4786 ParcelFileDescriptor profileFd = null; 4787 boolean profileAutoStop = false; 4788 if (mProfileApp != null && mProfileApp.equals(processName)) { 4789 mProfileProc = app; 4790 profileFile = mProfileFile; 4791 profileFd = mProfileFd; 4792 profileAutoStop = mAutoStopProfiler; 4793 } 4794 boolean enableOpenGlTrace = false; 4795 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4796 enableOpenGlTrace = true; 4797 mOpenGlTraceApp = null; 4798 } 4799 4800 // If the app is being launched for restore or full backup, set it up specially 4801 boolean isRestrictedBackupMode = false; 4802 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4803 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4804 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4805 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4806 } 4807 4808 ensurePackageDexOpt(app.instrumentationInfo != null 4809 ? app.instrumentationInfo.packageName 4810 : app.info.packageName); 4811 if (app.instrumentationClass != null) { 4812 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4813 } 4814 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4815 + processName + " with config " + mConfiguration); 4816 ApplicationInfo appInfo = app.instrumentationInfo != null 4817 ? app.instrumentationInfo : app.info; 4818 app.compat = compatibilityInfoForPackageLocked(appInfo); 4819 if (profileFd != null) { 4820 profileFd = profileFd.dup(); 4821 } 4822 thread.bindApplication(processName, appInfo, providers, 4823 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4824 app.instrumentationArguments, app.instrumentationWatcher, 4825 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4826 isRestrictedBackupMode || !normalMode, app.persistent, 4827 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4828 mCoreSettingsObserver.getCoreSettingsLocked()); 4829 updateLruProcessLocked(app, false, false); 4830 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4831 } catch (Exception e) { 4832 // todo: Yikes! What should we do? For now we will try to 4833 // start another process, but that could easily get us in 4834 // an infinite loop of restarting processes... 4835 Slog.w(TAG, "Exception thrown during bind!", e); 4836 4837 app.resetPackageList(mProcessStats); 4838 app.unlinkDeathRecipient(); 4839 startProcessLocked(app, "bind fail", processName); 4840 return false; 4841 } 4842 4843 // Remove this record from the list of starting applications. 4844 mPersistentStartingProcesses.remove(app); 4845 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4846 "Attach application locked removing on hold: " + app); 4847 mProcessesOnHold.remove(app); 4848 4849 boolean badApp = false; 4850 boolean didSomething = false; 4851 4852 // See if the top visible activity is waiting to run in this process... 4853 if (normalMode) { 4854 try { 4855 if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) { 4856 didSomething = true; 4857 } 4858 } catch (Exception e) { 4859 badApp = true; 4860 } 4861 } 4862 4863 // Find any services that should be running in this process... 4864 if (!badApp) { 4865 try { 4866 didSomething |= mServices.attachApplicationLocked(app, processName); 4867 } catch (Exception e) { 4868 badApp = true; 4869 } 4870 } 4871 4872 // Check if a next-broadcast receiver is in this process... 4873 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 4874 try { 4875 didSomething |= sendPendingBroadcastsLocked(app); 4876 } catch (Exception e) { 4877 // If the app died trying to launch the receiver we declare it 'bad' 4878 badApp = true; 4879 } 4880 } 4881 4882 // Check whether the next backup agent is in this process... 4883 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 4884 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 4885 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 4886 try { 4887 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 4888 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 4889 mBackupTarget.backupMode); 4890 } catch (Exception e) { 4891 Slog.w(TAG, "Exception scheduling backup agent creation: "); 4892 e.printStackTrace(); 4893 } 4894 } 4895 4896 if (badApp) { 4897 // todo: Also need to kill application to deal with all 4898 // kinds of exceptions. 4899 handleAppDiedLocked(app, false, true); 4900 return false; 4901 } 4902 4903 if (!didSomething) { 4904 updateOomAdjLocked(); 4905 } 4906 4907 return true; 4908 } 4909 4910 @Override 4911 public final void attachApplication(IApplicationThread thread) { 4912 synchronized (this) { 4913 int callingPid = Binder.getCallingPid(); 4914 final long origId = Binder.clearCallingIdentity(); 4915 attachApplicationLocked(thread, callingPid); 4916 Binder.restoreCallingIdentity(origId); 4917 } 4918 } 4919 4920 @Override 4921 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 4922 final long origId = Binder.clearCallingIdentity(); 4923 synchronized (this) { 4924 ActivityStack stack = ActivityRecord.getStackLocked(token); 4925 if (stack != null) { 4926 ActivityRecord r = 4927 mStackSupervisor.activityIdleInternalLocked(token, false, config); 4928 if (stopProfiling) { 4929 if ((mProfileProc == r.app) && (mProfileFd != null)) { 4930 try { 4931 mProfileFd.close(); 4932 } catch (IOException e) { 4933 } 4934 clearProfilerLocked(); 4935 } 4936 } 4937 } 4938 } 4939 Binder.restoreCallingIdentity(origId); 4940 } 4941 4942 void enableScreenAfterBoot() { 4943 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 4944 SystemClock.uptimeMillis()); 4945 mWindowManager.enableScreenAfterBoot(); 4946 4947 synchronized (this) { 4948 updateEventDispatchingLocked(); 4949 } 4950 } 4951 4952 @Override 4953 public void showBootMessage(final CharSequence msg, final boolean always) { 4954 enforceNotIsolatedCaller("showBootMessage"); 4955 mWindowManager.showBootMessage(msg, always); 4956 } 4957 4958 @Override 4959 public void dismissKeyguardOnNextActivity() { 4960 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 4961 final long token = Binder.clearCallingIdentity(); 4962 try { 4963 synchronized (this) { 4964 if (DEBUG_LOCKSCREEN) logLockScreen(""); 4965 if (mLockScreenShown) { 4966 mLockScreenShown = false; 4967 comeOutOfSleepIfNeededLocked(); 4968 } 4969 mStackSupervisor.setDismissKeyguard(true); 4970 } 4971 } finally { 4972 Binder.restoreCallingIdentity(token); 4973 } 4974 } 4975 4976 final void finishBooting() { 4977 IntentFilter pkgFilter = new IntentFilter(); 4978 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4979 pkgFilter.addDataScheme("package"); 4980 mContext.registerReceiver(new BroadcastReceiver() { 4981 @Override 4982 public void onReceive(Context context, Intent intent) { 4983 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4984 if (pkgs != null) { 4985 for (String pkg : pkgs) { 4986 synchronized (ActivityManagerService.this) { 4987 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 4988 "finished booting")) { 4989 setResultCode(Activity.RESULT_OK); 4990 return; 4991 } 4992 } 4993 } 4994 } 4995 } 4996 }, pkgFilter); 4997 4998 synchronized (this) { 4999 // Ensure that any processes we had put on hold are now started 5000 // up. 5001 final int NP = mProcessesOnHold.size(); 5002 if (NP > 0) { 5003 ArrayList<ProcessRecord> procs = 5004 new ArrayList<ProcessRecord>(mProcessesOnHold); 5005 for (int ip=0; ip<NP; ip++) { 5006 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5007 + procs.get(ip)); 5008 startProcessLocked(procs.get(ip), "on-hold", null); 5009 } 5010 } 5011 5012 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5013 // Start looking for apps that are abusing wake locks. 5014 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5015 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5016 // Tell anyone interested that we are done booting! 5017 SystemProperties.set("sys.boot_completed", "1"); 5018 SystemProperties.set("dev.bootcomplete", "1"); 5019 for (int i=0; i<mStartedUsers.size(); i++) { 5020 UserStartedState uss = mStartedUsers.valueAt(i); 5021 if (uss.mState == UserStartedState.STATE_BOOTING) { 5022 uss.mState = UserStartedState.STATE_RUNNING; 5023 final int userId = mStartedUsers.keyAt(i); 5024 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5025 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5026 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5027 broadcastIntentLocked(null, null, intent, null, 5028 new IIntentReceiver.Stub() { 5029 @Override 5030 public void performReceive(Intent intent, int resultCode, 5031 String data, Bundle extras, boolean ordered, 5032 boolean sticky, int sendingUser) { 5033 synchronized (ActivityManagerService.this) { 5034 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5035 true, false); 5036 } 5037 } 5038 }, 5039 0, null, null, 5040 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5041 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5042 userId); 5043 } 5044 } 5045 } 5046 } 5047 } 5048 5049 final void ensureBootCompleted() { 5050 boolean booting; 5051 boolean enableScreen; 5052 synchronized (this) { 5053 booting = mBooting; 5054 mBooting = false; 5055 enableScreen = !mBooted; 5056 mBooted = true; 5057 } 5058 5059 if (booting) { 5060 finishBooting(); 5061 } 5062 5063 if (enableScreen) { 5064 enableScreenAfterBoot(); 5065 } 5066 } 5067 5068 @Override 5069 public final void activityResumed(IBinder token) { 5070 final long origId = Binder.clearCallingIdentity(); 5071 synchronized(this) { 5072 ActivityStack stack = ActivityRecord.getStackLocked(token); 5073 if (stack != null) { 5074 ActivityRecord.activityResumedLocked(token); 5075 } 5076 } 5077 Binder.restoreCallingIdentity(origId); 5078 } 5079 5080 @Override 5081 public final void activityPaused(IBinder token) { 5082 final long origId = Binder.clearCallingIdentity(); 5083 synchronized(this) { 5084 ActivityStack stack = ActivityRecord.getStackLocked(token); 5085 if (stack != null) { 5086 stack.activityPausedLocked(token, false); 5087 } 5088 } 5089 Binder.restoreCallingIdentity(origId); 5090 } 5091 5092 @Override 5093 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5094 CharSequence description) { 5095 if (localLOGV) Slog.v( 5096 TAG, "Activity stopped: token=" + token); 5097 5098 // Refuse possible leaked file descriptors 5099 if (icicle != null && icicle.hasFileDescriptors()) { 5100 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5101 } 5102 5103 ActivityRecord r = null; 5104 5105 final long origId = Binder.clearCallingIdentity(); 5106 5107 synchronized (this) { 5108 r = ActivityRecord.isInStackLocked(token); 5109 if (r != null) { 5110 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5111 } 5112 } 5113 5114 if (r != null) { 5115 sendPendingThumbnail(r, null, null, null, false); 5116 } 5117 5118 trimApplications(); 5119 5120 Binder.restoreCallingIdentity(origId); 5121 } 5122 5123 @Override 5124 public final void activityDestroyed(IBinder token) { 5125 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5126 synchronized (this) { 5127 ActivityStack stack = ActivityRecord.getStackLocked(token); 5128 if (stack != null) { 5129 stack.activityDestroyedLocked(token); 5130 } 5131 } 5132 } 5133 5134 @Override 5135 public String getCallingPackage(IBinder token) { 5136 synchronized (this) { 5137 ActivityRecord r = getCallingRecordLocked(token); 5138 return r != null ? r.info.packageName : null; 5139 } 5140 } 5141 5142 @Override 5143 public ComponentName getCallingActivity(IBinder token) { 5144 synchronized (this) { 5145 ActivityRecord r = getCallingRecordLocked(token); 5146 return r != null ? r.intent.getComponent() : null; 5147 } 5148 } 5149 5150 private ActivityRecord getCallingRecordLocked(IBinder token) { 5151 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5152 if (r == null) { 5153 return null; 5154 } 5155 return r.resultTo; 5156 } 5157 5158 @Override 5159 public ComponentName getActivityClassForToken(IBinder token) { 5160 synchronized(this) { 5161 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5162 if (r == null) { 5163 return null; 5164 } 5165 return r.intent.getComponent(); 5166 } 5167 } 5168 5169 @Override 5170 public String getPackageForToken(IBinder token) { 5171 synchronized(this) { 5172 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5173 if (r == null) { 5174 return null; 5175 } 5176 return r.packageName; 5177 } 5178 } 5179 5180 @Override 5181 public IIntentSender getIntentSender(int type, 5182 String packageName, IBinder token, String resultWho, 5183 int requestCode, Intent[] intents, String[] resolvedTypes, 5184 int flags, Bundle options, int userId) { 5185 enforceNotIsolatedCaller("getIntentSender"); 5186 // Refuse possible leaked file descriptors 5187 if (intents != null) { 5188 if (intents.length < 1) { 5189 throw new IllegalArgumentException("Intents array length must be >= 1"); 5190 } 5191 for (int i=0; i<intents.length; i++) { 5192 Intent intent = intents[i]; 5193 if (intent != null) { 5194 if (intent.hasFileDescriptors()) { 5195 throw new IllegalArgumentException("File descriptors passed in Intent"); 5196 } 5197 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5198 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5199 throw new IllegalArgumentException( 5200 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5201 } 5202 intents[i] = new Intent(intent); 5203 } 5204 } 5205 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5206 throw new IllegalArgumentException( 5207 "Intent array length does not match resolvedTypes length"); 5208 } 5209 } 5210 if (options != null) { 5211 if (options.hasFileDescriptors()) { 5212 throw new IllegalArgumentException("File descriptors passed in options"); 5213 } 5214 } 5215 5216 synchronized(this) { 5217 int callingUid = Binder.getCallingUid(); 5218 int origUserId = userId; 5219 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5220 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5221 "getIntentSender", null); 5222 if (origUserId == UserHandle.USER_CURRENT) { 5223 // We don't want to evaluate this until the pending intent is 5224 // actually executed. However, we do want to always do the 5225 // security checking for it above. 5226 userId = UserHandle.USER_CURRENT; 5227 } 5228 try { 5229 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5230 int uid = AppGlobals.getPackageManager() 5231 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5232 if (!UserHandle.isSameApp(callingUid, uid)) { 5233 String msg = "Permission Denial: getIntentSender() from pid=" 5234 + Binder.getCallingPid() 5235 + ", uid=" + Binder.getCallingUid() 5236 + ", (need uid=" + uid + ")" 5237 + " is not allowed to send as package " + packageName; 5238 Slog.w(TAG, msg); 5239 throw new SecurityException(msg); 5240 } 5241 } 5242 5243 return getIntentSenderLocked(type, packageName, callingUid, userId, 5244 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5245 5246 } catch (RemoteException e) { 5247 throw new SecurityException(e); 5248 } 5249 } 5250 } 5251 5252 IIntentSender getIntentSenderLocked(int type, String packageName, 5253 int callingUid, int userId, IBinder token, String resultWho, 5254 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5255 Bundle options) { 5256 if (DEBUG_MU) 5257 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5258 ActivityRecord activity = null; 5259 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5260 activity = ActivityRecord.isInStackLocked(token); 5261 if (activity == null) { 5262 return null; 5263 } 5264 if (activity.finishing) { 5265 return null; 5266 } 5267 } 5268 5269 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5270 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5271 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5272 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5273 |PendingIntent.FLAG_UPDATE_CURRENT); 5274 5275 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5276 type, packageName, activity, resultWho, 5277 requestCode, intents, resolvedTypes, flags, options, userId); 5278 WeakReference<PendingIntentRecord> ref; 5279 ref = mIntentSenderRecords.get(key); 5280 PendingIntentRecord rec = ref != null ? ref.get() : null; 5281 if (rec != null) { 5282 if (!cancelCurrent) { 5283 if (updateCurrent) { 5284 if (rec.key.requestIntent != null) { 5285 rec.key.requestIntent.replaceExtras(intents != null ? 5286 intents[intents.length - 1] : null); 5287 } 5288 if (intents != null) { 5289 intents[intents.length-1] = rec.key.requestIntent; 5290 rec.key.allIntents = intents; 5291 rec.key.allResolvedTypes = resolvedTypes; 5292 } else { 5293 rec.key.allIntents = null; 5294 rec.key.allResolvedTypes = null; 5295 } 5296 } 5297 return rec; 5298 } 5299 rec.canceled = true; 5300 mIntentSenderRecords.remove(key); 5301 } 5302 if (noCreate) { 5303 return rec; 5304 } 5305 rec = new PendingIntentRecord(this, key, callingUid); 5306 mIntentSenderRecords.put(key, rec.ref); 5307 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5308 if (activity.pendingResults == null) { 5309 activity.pendingResults 5310 = new HashSet<WeakReference<PendingIntentRecord>>(); 5311 } 5312 activity.pendingResults.add(rec.ref); 5313 } 5314 return rec; 5315 } 5316 5317 @Override 5318 public void cancelIntentSender(IIntentSender sender) { 5319 if (!(sender instanceof PendingIntentRecord)) { 5320 return; 5321 } 5322 synchronized(this) { 5323 PendingIntentRecord rec = (PendingIntentRecord)sender; 5324 try { 5325 int uid = AppGlobals.getPackageManager() 5326 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5327 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5328 String msg = "Permission Denial: cancelIntentSender() from pid=" 5329 + Binder.getCallingPid() 5330 + ", uid=" + Binder.getCallingUid() 5331 + " is not allowed to cancel packges " 5332 + rec.key.packageName; 5333 Slog.w(TAG, msg); 5334 throw new SecurityException(msg); 5335 } 5336 } catch (RemoteException e) { 5337 throw new SecurityException(e); 5338 } 5339 cancelIntentSenderLocked(rec, true); 5340 } 5341 } 5342 5343 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5344 rec.canceled = true; 5345 mIntentSenderRecords.remove(rec.key); 5346 if (cleanActivity && rec.key.activity != null) { 5347 rec.key.activity.pendingResults.remove(rec.ref); 5348 } 5349 } 5350 5351 @Override 5352 public String getPackageForIntentSender(IIntentSender pendingResult) { 5353 if (!(pendingResult instanceof PendingIntentRecord)) { 5354 return null; 5355 } 5356 try { 5357 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5358 return res.key.packageName; 5359 } catch (ClassCastException e) { 5360 } 5361 return null; 5362 } 5363 5364 @Override 5365 public int getUidForIntentSender(IIntentSender sender) { 5366 if (sender instanceof PendingIntentRecord) { 5367 try { 5368 PendingIntentRecord res = (PendingIntentRecord)sender; 5369 return res.uid; 5370 } catch (ClassCastException e) { 5371 } 5372 } 5373 return -1; 5374 } 5375 5376 @Override 5377 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5378 if (!(pendingResult instanceof PendingIntentRecord)) { 5379 return false; 5380 } 5381 try { 5382 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5383 if (res.key.allIntents == null) { 5384 return false; 5385 } 5386 for (int i=0; i<res.key.allIntents.length; i++) { 5387 Intent intent = res.key.allIntents[i]; 5388 if (intent.getPackage() != null && intent.getComponent() != null) { 5389 return false; 5390 } 5391 } 5392 return true; 5393 } catch (ClassCastException e) { 5394 } 5395 return false; 5396 } 5397 5398 @Override 5399 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5400 if (!(pendingResult instanceof PendingIntentRecord)) { 5401 return false; 5402 } 5403 try { 5404 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5405 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5406 return true; 5407 } 5408 return false; 5409 } catch (ClassCastException e) { 5410 } 5411 return false; 5412 } 5413 5414 @Override 5415 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5416 if (!(pendingResult instanceof PendingIntentRecord)) { 5417 return null; 5418 } 5419 try { 5420 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5421 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5422 } catch (ClassCastException e) { 5423 } 5424 return null; 5425 } 5426 5427 @Override 5428 public void setProcessLimit(int max) { 5429 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5430 "setProcessLimit()"); 5431 synchronized (this) { 5432 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5433 mProcessLimitOverride = max; 5434 } 5435 trimApplications(); 5436 } 5437 5438 @Override 5439 public int getProcessLimit() { 5440 synchronized (this) { 5441 return mProcessLimitOverride; 5442 } 5443 } 5444 5445 void foregroundTokenDied(ForegroundToken token) { 5446 synchronized (ActivityManagerService.this) { 5447 synchronized (mPidsSelfLocked) { 5448 ForegroundToken cur 5449 = mForegroundProcesses.get(token.pid); 5450 if (cur != token) { 5451 return; 5452 } 5453 mForegroundProcesses.remove(token.pid); 5454 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5455 if (pr == null) { 5456 return; 5457 } 5458 pr.forcingToForeground = null; 5459 pr.foregroundServices = false; 5460 } 5461 updateOomAdjLocked(); 5462 } 5463 } 5464 5465 @Override 5466 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5467 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5468 "setProcessForeground()"); 5469 synchronized(this) { 5470 boolean changed = false; 5471 5472 synchronized (mPidsSelfLocked) { 5473 ProcessRecord pr = mPidsSelfLocked.get(pid); 5474 if (pr == null && isForeground) { 5475 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5476 return; 5477 } 5478 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5479 if (oldToken != null) { 5480 oldToken.token.unlinkToDeath(oldToken, 0); 5481 mForegroundProcesses.remove(pid); 5482 if (pr != null) { 5483 pr.forcingToForeground = null; 5484 } 5485 changed = true; 5486 } 5487 if (isForeground && token != null) { 5488 ForegroundToken newToken = new ForegroundToken() { 5489 @Override 5490 public void binderDied() { 5491 foregroundTokenDied(this); 5492 } 5493 }; 5494 newToken.pid = pid; 5495 newToken.token = token; 5496 try { 5497 token.linkToDeath(newToken, 0); 5498 mForegroundProcesses.put(pid, newToken); 5499 pr.forcingToForeground = token; 5500 changed = true; 5501 } catch (RemoteException e) { 5502 // If the process died while doing this, we will later 5503 // do the cleanup with the process death link. 5504 } 5505 } 5506 } 5507 5508 if (changed) { 5509 updateOomAdjLocked(); 5510 } 5511 } 5512 } 5513 5514 // ========================================================= 5515 // PERMISSIONS 5516 // ========================================================= 5517 5518 static class PermissionController extends IPermissionController.Stub { 5519 ActivityManagerService mActivityManagerService; 5520 PermissionController(ActivityManagerService activityManagerService) { 5521 mActivityManagerService = activityManagerService; 5522 } 5523 5524 @Override 5525 public boolean checkPermission(String permission, int pid, int uid) { 5526 return mActivityManagerService.checkPermission(permission, pid, 5527 uid) == PackageManager.PERMISSION_GRANTED; 5528 } 5529 } 5530 5531 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5532 @Override 5533 public int checkComponentPermission(String permission, int pid, int uid, 5534 int owningUid, boolean exported) { 5535 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5536 owningUid, exported); 5537 } 5538 5539 @Override 5540 public Object getAMSLock() { 5541 return ActivityManagerService.this; 5542 } 5543 } 5544 5545 /** 5546 * This can be called with or without the global lock held. 5547 */ 5548 int checkComponentPermission(String permission, int pid, int uid, 5549 int owningUid, boolean exported) { 5550 // We might be performing an operation on behalf of an indirect binder 5551 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5552 // client identity accordingly before proceeding. 5553 Identity tlsIdentity = sCallerIdentity.get(); 5554 if (tlsIdentity != null) { 5555 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5556 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5557 uid = tlsIdentity.uid; 5558 pid = tlsIdentity.pid; 5559 } 5560 5561 if (pid == MY_PID) { 5562 return PackageManager.PERMISSION_GRANTED; 5563 } 5564 5565 return ActivityManager.checkComponentPermission(permission, uid, 5566 owningUid, exported); 5567 } 5568 5569 /** 5570 * As the only public entry point for permissions checking, this method 5571 * can enforce the semantic that requesting a check on a null global 5572 * permission is automatically denied. (Internally a null permission 5573 * string is used when calling {@link #checkComponentPermission} in cases 5574 * when only uid-based security is needed.) 5575 * 5576 * This can be called with or without the global lock held. 5577 */ 5578 @Override 5579 public int checkPermission(String permission, int pid, int uid) { 5580 if (permission == null) { 5581 return PackageManager.PERMISSION_DENIED; 5582 } 5583 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5584 } 5585 5586 /** 5587 * Binder IPC calls go through the public entry point. 5588 * This can be called with or without the global lock held. 5589 */ 5590 int checkCallingPermission(String permission) { 5591 return checkPermission(permission, 5592 Binder.getCallingPid(), 5593 UserHandle.getAppId(Binder.getCallingUid())); 5594 } 5595 5596 /** 5597 * This can be called with or without the global lock held. 5598 */ 5599 void enforceCallingPermission(String permission, String func) { 5600 if (checkCallingPermission(permission) 5601 == PackageManager.PERMISSION_GRANTED) { 5602 return; 5603 } 5604 5605 String msg = "Permission Denial: " + func + " from pid=" 5606 + Binder.getCallingPid() 5607 + ", uid=" + Binder.getCallingUid() 5608 + " requires " + permission; 5609 Slog.w(TAG, msg); 5610 throw new SecurityException(msg); 5611 } 5612 5613 /** 5614 * Determine if UID is holding permissions required to access {@link Uri} in 5615 * the given {@link ProviderInfo}. Final permission checking is always done 5616 * in {@link ContentProvider}. 5617 */ 5618 private final boolean checkHoldingPermissionsLocked( 5619 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5620 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5621 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5622 5623 if (pi.applicationInfo.uid == uid) { 5624 return true; 5625 } else if (!pi.exported) { 5626 return false; 5627 } 5628 5629 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5630 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5631 try { 5632 // check if target holds top-level <provider> permissions 5633 if (!readMet && pi.readPermission != null 5634 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5635 readMet = true; 5636 } 5637 if (!writeMet && pi.writePermission != null 5638 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5639 writeMet = true; 5640 } 5641 5642 // track if unprotected read/write is allowed; any denied 5643 // <path-permission> below removes this ability 5644 boolean allowDefaultRead = pi.readPermission == null; 5645 boolean allowDefaultWrite = pi.writePermission == null; 5646 5647 // check if target holds any <path-permission> that match uri 5648 final PathPermission[] pps = pi.pathPermissions; 5649 if (pps != null) { 5650 final String path = uri.getPath(); 5651 int i = pps.length; 5652 while (i > 0 && (!readMet || !writeMet)) { 5653 i--; 5654 PathPermission pp = pps[i]; 5655 if (pp.match(path)) { 5656 if (!readMet) { 5657 final String pprperm = pp.getReadPermission(); 5658 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5659 + pprperm + " for " + pp.getPath() 5660 + ": match=" + pp.match(path) 5661 + " check=" + pm.checkUidPermission(pprperm, uid)); 5662 if (pprperm != null) { 5663 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5664 readMet = true; 5665 } else { 5666 allowDefaultRead = false; 5667 } 5668 } 5669 } 5670 if (!writeMet) { 5671 final String ppwperm = pp.getWritePermission(); 5672 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5673 + ppwperm + " for " + pp.getPath() 5674 + ": match=" + pp.match(path) 5675 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5676 if (ppwperm != null) { 5677 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5678 writeMet = true; 5679 } else { 5680 allowDefaultWrite = false; 5681 } 5682 } 5683 } 5684 } 5685 } 5686 } 5687 5688 // grant unprotected <provider> read/write, if not blocked by 5689 // <path-permission> above 5690 if (allowDefaultRead) readMet = true; 5691 if (allowDefaultWrite) writeMet = true; 5692 5693 } catch (RemoteException e) { 5694 return false; 5695 } 5696 5697 return readMet && writeMet; 5698 } 5699 5700 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5701 ProviderInfo pi = null; 5702 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5703 if (cpr != null) { 5704 pi = cpr.info; 5705 } else { 5706 try { 5707 pi = AppGlobals.getPackageManager().resolveContentProvider( 5708 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5709 } catch (RemoteException ex) { 5710 } 5711 } 5712 return pi; 5713 } 5714 5715 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5716 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5717 if (targetUris != null) { 5718 return targetUris.get(uri); 5719 } else { 5720 return null; 5721 } 5722 } 5723 5724 private UriPermission findOrCreateUriPermissionLocked( 5725 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5726 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5727 if (targetUris == null) { 5728 targetUris = Maps.newArrayMap(); 5729 mGrantedUriPermissions.put(targetUid, targetUris); 5730 } 5731 5732 UriPermission perm = targetUris.get(uri); 5733 if (perm == null) { 5734 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5735 targetUris.put(uri, perm); 5736 } 5737 5738 return perm; 5739 } 5740 5741 private final boolean checkUriPermissionLocked( 5742 Uri uri, int uid, int modeFlags, int minStrength) { 5743 // Root gets to do everything. 5744 if (uid == 0) { 5745 return true; 5746 } 5747 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5748 if (perms == null) return false; 5749 UriPermission perm = perms.get(uri); 5750 if (perm == null) return false; 5751 return perm.getStrength(modeFlags) >= minStrength; 5752 } 5753 5754 @Override 5755 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5756 enforceNotIsolatedCaller("checkUriPermission"); 5757 5758 // Another redirected-binder-call permissions check as in 5759 // {@link checkComponentPermission}. 5760 Identity tlsIdentity = sCallerIdentity.get(); 5761 if (tlsIdentity != null) { 5762 uid = tlsIdentity.uid; 5763 pid = tlsIdentity.pid; 5764 } 5765 5766 // Our own process gets to do everything. 5767 if (pid == MY_PID) { 5768 return PackageManager.PERMISSION_GRANTED; 5769 } 5770 synchronized(this) { 5771 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5772 ? PackageManager.PERMISSION_GRANTED 5773 : PackageManager.PERMISSION_DENIED; 5774 } 5775 } 5776 5777 /** 5778 * Check if the targetPkg can be granted permission to access uri by 5779 * the callingUid using the given modeFlags. Throws a security exception 5780 * if callingUid is not allowed to do this. Returns the uid of the target 5781 * if the URI permission grant should be performed; returns -1 if it is not 5782 * needed (for example targetPkg already has permission to access the URI). 5783 * If you already know the uid of the target, you can supply it in 5784 * lastTargetUid else set that to -1. 5785 */ 5786 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5787 Uri uri, int modeFlags, int lastTargetUid) { 5788 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5789 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5790 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5791 if (modeFlags == 0) { 5792 return -1; 5793 } 5794 5795 if (targetPkg != null) { 5796 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5797 "Checking grant " + targetPkg + " permission to " + uri); 5798 } 5799 5800 final IPackageManager pm = AppGlobals.getPackageManager(); 5801 5802 // If this is not a content: uri, we can't do anything with it. 5803 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5804 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5805 "Can't grant URI permission for non-content URI: " + uri); 5806 return -1; 5807 } 5808 5809 final String authority = uri.getAuthority(); 5810 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5811 if (pi == null) { 5812 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5813 return -1; 5814 } 5815 5816 int targetUid = lastTargetUid; 5817 if (targetUid < 0 && targetPkg != null) { 5818 try { 5819 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5820 if (targetUid < 0) { 5821 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5822 "Can't grant URI permission no uid for: " + targetPkg); 5823 return -1; 5824 } 5825 } catch (RemoteException ex) { 5826 return -1; 5827 } 5828 } 5829 5830 if (targetUid >= 0) { 5831 // First... does the target actually need this permission? 5832 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5833 // No need to grant the target this permission. 5834 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5835 "Target " + targetPkg + " already has full permission to " + uri); 5836 return -1; 5837 } 5838 } else { 5839 // First... there is no target package, so can anyone access it? 5840 boolean allowed = pi.exported; 5841 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5842 if (pi.readPermission != null) { 5843 allowed = false; 5844 } 5845 } 5846 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5847 if (pi.writePermission != null) { 5848 allowed = false; 5849 } 5850 } 5851 if (allowed) { 5852 return -1; 5853 } 5854 } 5855 5856 // Second... is the provider allowing granting of URI permissions? 5857 if (!pi.grantUriPermissions) { 5858 throw new SecurityException("Provider " + pi.packageName 5859 + "/" + pi.name 5860 + " does not allow granting of Uri permissions (uri " 5861 + uri + ")"); 5862 } 5863 if (pi.uriPermissionPatterns != null) { 5864 final int N = pi.uriPermissionPatterns.length; 5865 boolean allowed = false; 5866 for (int i=0; i<N; i++) { 5867 if (pi.uriPermissionPatterns[i] != null 5868 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5869 allowed = true; 5870 break; 5871 } 5872 } 5873 if (!allowed) { 5874 throw new SecurityException("Provider " + pi.packageName 5875 + "/" + pi.name 5876 + " does not allow granting of permission to path of Uri " 5877 + uri); 5878 } 5879 } 5880 5881 // Third... does the caller itself have permission to access 5882 // this uri? 5883 if (callingUid != Process.myUid()) { 5884 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 5885 // Require they hold a strong enough Uri permission 5886 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 5887 : UriPermission.STRENGTH_OWNED; 5888 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 5889 throw new SecurityException("Uid " + callingUid 5890 + " does not have permission to uri " + uri); 5891 } 5892 } 5893 } 5894 5895 return targetUid; 5896 } 5897 5898 @Override 5899 public int checkGrantUriPermission(int callingUid, String targetPkg, 5900 Uri uri, int modeFlags) { 5901 enforceNotIsolatedCaller("checkGrantUriPermission"); 5902 synchronized(this) { 5903 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5904 } 5905 } 5906 5907 void grantUriPermissionUncheckedLocked( 5908 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 5909 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5910 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5911 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5912 if (modeFlags == 0) { 5913 return; 5914 } 5915 5916 // So here we are: the caller has the assumed permission 5917 // to the uri, and the target doesn't. Let's now give this to 5918 // the target. 5919 5920 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5921 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 5922 5923 final String authority = uri.getAuthority(); 5924 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 5925 if (pi == null) { 5926 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 5927 return; 5928 } 5929 5930 final UriPermission perm = findOrCreateUriPermissionLocked( 5931 pi.packageName, targetPkg, targetUid, uri); 5932 perm.grantModes(modeFlags, persistable, owner); 5933 } 5934 5935 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 5936 int modeFlags, UriPermissionOwner owner) { 5937 if (targetPkg == null) { 5938 throw new NullPointerException("targetPkg"); 5939 } 5940 5941 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 5942 if (targetUid < 0) { 5943 return; 5944 } 5945 5946 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 5947 } 5948 5949 static class NeededUriGrants extends ArrayList<Uri> { 5950 final String targetPkg; 5951 final int targetUid; 5952 final int flags; 5953 5954 NeededUriGrants(String targetPkg, int targetUid, int flags) { 5955 this.targetPkg = targetPkg; 5956 this.targetUid = targetUid; 5957 this.flags = flags; 5958 } 5959 } 5960 5961 /** 5962 * Like checkGrantUriPermissionLocked, but takes an Intent. 5963 */ 5964 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 5965 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 5966 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5967 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 5968 + " clip=" + (intent != null ? intent.getClipData() : null) 5969 + " from " + intent + "; flags=0x" 5970 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 5971 5972 if (targetPkg == null) { 5973 throw new NullPointerException("targetPkg"); 5974 } 5975 5976 if (intent == null) { 5977 return null; 5978 } 5979 Uri data = intent.getData(); 5980 ClipData clip = intent.getClipData(); 5981 if (data == null && clip == null) { 5982 return null; 5983 } 5984 5985 if (data != null) { 5986 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 5987 mode, needed != null ? needed.targetUid : -1); 5988 if (targetUid > 0) { 5989 if (needed == null) { 5990 needed = new NeededUriGrants(targetPkg, targetUid, mode); 5991 } 5992 needed.add(data); 5993 } 5994 } 5995 if (clip != null) { 5996 for (int i=0; i<clip.getItemCount(); i++) { 5997 Uri uri = clip.getItemAt(i).getUri(); 5998 if (uri != null) { 5999 int targetUid = -1; 6000 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6001 mode, needed != null ? needed.targetUid : -1); 6002 if (targetUid > 0) { 6003 if (needed == null) { 6004 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6005 } 6006 needed.add(uri); 6007 } 6008 } else { 6009 Intent clipIntent = clip.getItemAt(i).getIntent(); 6010 if (clipIntent != null) { 6011 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6012 callingUid, targetPkg, clipIntent, mode, needed); 6013 if (newNeeded != null) { 6014 needed = newNeeded; 6015 } 6016 } 6017 } 6018 } 6019 } 6020 6021 return needed; 6022 } 6023 6024 /** 6025 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6026 */ 6027 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6028 UriPermissionOwner owner) { 6029 if (needed != null) { 6030 for (int i=0; i<needed.size(); i++) { 6031 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6032 needed.get(i), needed.flags, owner); 6033 } 6034 } 6035 } 6036 6037 void grantUriPermissionFromIntentLocked(int callingUid, 6038 String targetPkg, Intent intent, UriPermissionOwner owner) { 6039 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6040 intent, intent != null ? intent.getFlags() : 0, null); 6041 if (needed == null) { 6042 return; 6043 } 6044 6045 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6046 } 6047 6048 @Override 6049 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6050 Uri uri, int modeFlags) { 6051 enforceNotIsolatedCaller("grantUriPermission"); 6052 synchronized(this) { 6053 final ProcessRecord r = getRecordForAppLocked(caller); 6054 if (r == null) { 6055 throw new SecurityException("Unable to find app for caller " 6056 + caller 6057 + " when granting permission to uri " + uri); 6058 } 6059 if (targetPkg == null) { 6060 throw new IllegalArgumentException("null target"); 6061 } 6062 if (uri == null) { 6063 throw new IllegalArgumentException("null uri"); 6064 } 6065 6066 // Persistable only supported through Intents 6067 Preconditions.checkFlagsArgument(modeFlags, 6068 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6069 6070 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6071 null); 6072 } 6073 } 6074 6075 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6076 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6077 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6078 ArrayMap<Uri, UriPermission> perms 6079 = mGrantedUriPermissions.get(perm.targetUid); 6080 if (perms != null) { 6081 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6082 "Removing " + perm.targetUid + " permission to " + perm.uri); 6083 perms.remove(perm.uri); 6084 if (perms.size() == 0) { 6085 mGrantedUriPermissions.remove(perm.targetUid); 6086 } 6087 } 6088 } 6089 } 6090 6091 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6092 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6093 6094 final IPackageManager pm = AppGlobals.getPackageManager(); 6095 final String authority = uri.getAuthority(); 6096 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6097 if (pi == null) { 6098 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6099 return; 6100 } 6101 6102 // Does the caller have this permission on the URI? 6103 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6104 // Right now, if you are not the original owner of the permission, 6105 // you are not allowed to revoke it. 6106 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6107 throw new SecurityException("Uid " + callingUid 6108 + " does not have permission to uri " + uri); 6109 //} 6110 } 6111 6112 boolean persistChanged = false; 6113 6114 // Go through all of the permissions and remove any that match. 6115 final List<String> SEGMENTS = uri.getPathSegments(); 6116 if (SEGMENTS != null) { 6117 final int NS = SEGMENTS.size(); 6118 int N = mGrantedUriPermissions.size(); 6119 for (int i=0; i<N; i++) { 6120 ArrayMap<Uri, UriPermission> perms 6121 = mGrantedUriPermissions.valueAt(i); 6122 Iterator<UriPermission> it = perms.values().iterator(); 6123 toploop: 6124 while (it.hasNext()) { 6125 UriPermission perm = it.next(); 6126 Uri targetUri = perm.uri; 6127 if (!authority.equals(targetUri.getAuthority())) { 6128 continue; 6129 } 6130 List<String> targetSegments = targetUri.getPathSegments(); 6131 if (targetSegments == null) { 6132 continue; 6133 } 6134 if (targetSegments.size() < NS) { 6135 continue; 6136 } 6137 for (int j=0; j<NS; j++) { 6138 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6139 continue toploop; 6140 } 6141 } 6142 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6143 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6144 persistChanged |= perm.clearModes(modeFlags, true); 6145 if (perm.modeFlags == 0) { 6146 it.remove(); 6147 } 6148 } 6149 if (perms.size() == 0) { 6150 mGrantedUriPermissions.remove( 6151 mGrantedUriPermissions.keyAt(i)); 6152 N--; 6153 i--; 6154 } 6155 } 6156 } 6157 6158 if (persistChanged) { 6159 schedulePersistUriGrants(); 6160 } 6161 } 6162 6163 @Override 6164 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6165 int modeFlags) { 6166 enforceNotIsolatedCaller("revokeUriPermission"); 6167 synchronized(this) { 6168 final ProcessRecord r = getRecordForAppLocked(caller); 6169 if (r == null) { 6170 throw new SecurityException("Unable to find app for caller " 6171 + caller 6172 + " when revoking permission to uri " + uri); 6173 } 6174 if (uri == null) { 6175 Slog.w(TAG, "revokeUriPermission: null uri"); 6176 return; 6177 } 6178 6179 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6180 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6181 if (modeFlags == 0) { 6182 return; 6183 } 6184 6185 final IPackageManager pm = AppGlobals.getPackageManager(); 6186 final String authority = uri.getAuthority(); 6187 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6188 if (pi == null) { 6189 Slog.w(TAG, "No content provider found for permission revoke: " 6190 + uri.toSafeString()); 6191 return; 6192 } 6193 6194 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6195 } 6196 } 6197 6198 /** 6199 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6200 * given package. 6201 * 6202 * @param packageName Package name to match, or {@code null} to apply to all 6203 * packages. 6204 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6205 * to all users. 6206 * @param persistable If persistable grants should be removed. 6207 */ 6208 private void removeUriPermissionsForPackageLocked( 6209 String packageName, int userHandle, boolean persistable) { 6210 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6211 throw new IllegalArgumentException("Must narrow by either package or user"); 6212 } 6213 6214 boolean persistChanged = false; 6215 6216 final int size = mGrantedUriPermissions.size(); 6217 for (int i = 0; i < size; i++) { 6218 // Only inspect grants matching user 6219 if (userHandle == UserHandle.USER_ALL 6220 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6221 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6222 .values().iterator(); 6223 while (it.hasNext()) { 6224 final UriPermission perm = it.next(); 6225 6226 // Only inspect grants matching package 6227 if (packageName == null || perm.sourcePkg.equals(packageName) 6228 || perm.targetPkg.equals(packageName)) { 6229 persistChanged |= perm.clearModes(~0, persistable); 6230 6231 // Only remove when no modes remain; any persisted grants 6232 // will keep this alive. 6233 if (perm.modeFlags == 0) { 6234 it.remove(); 6235 } 6236 } 6237 } 6238 } 6239 } 6240 6241 if (persistChanged) { 6242 schedulePersistUriGrants(); 6243 } 6244 } 6245 6246 @Override 6247 public IBinder newUriPermissionOwner(String name) { 6248 enforceNotIsolatedCaller("newUriPermissionOwner"); 6249 synchronized(this) { 6250 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6251 return owner.getExternalTokenLocked(); 6252 } 6253 } 6254 6255 @Override 6256 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6257 Uri uri, int modeFlags) { 6258 synchronized(this) { 6259 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6260 if (owner == null) { 6261 throw new IllegalArgumentException("Unknown owner: " + token); 6262 } 6263 if (fromUid != Binder.getCallingUid()) { 6264 if (Binder.getCallingUid() != Process.myUid()) { 6265 // Only system code can grant URI permissions on behalf 6266 // of other users. 6267 throw new SecurityException("nice try"); 6268 } 6269 } 6270 if (targetPkg == null) { 6271 throw new IllegalArgumentException("null target"); 6272 } 6273 if (uri == null) { 6274 throw new IllegalArgumentException("null uri"); 6275 } 6276 6277 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6278 } 6279 } 6280 6281 @Override 6282 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6283 synchronized(this) { 6284 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6285 if (owner == null) { 6286 throw new IllegalArgumentException("Unknown owner: " + token); 6287 } 6288 6289 if (uri == null) { 6290 owner.removeUriPermissionsLocked(mode); 6291 } else { 6292 owner.removeUriPermissionLocked(uri, mode); 6293 } 6294 } 6295 } 6296 6297 private void schedulePersistUriGrants() { 6298 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6299 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6300 10 * DateUtils.SECOND_IN_MILLIS); 6301 } 6302 } 6303 6304 private void writeGrantedUriPermissions() { 6305 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6306 6307 // Snapshot permissions so we can persist without lock 6308 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6309 synchronized (this) { 6310 final int size = mGrantedUriPermissions.size(); 6311 for (int i = 0 ; i < size; i++) { 6312 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6313 if (perm.persistedModeFlags != 0) { 6314 persist.add(perm.snapshot()); 6315 } 6316 } 6317 } 6318 } 6319 6320 FileOutputStream fos = null; 6321 try { 6322 fos = mGrantFile.startWrite(); 6323 6324 XmlSerializer out = new FastXmlSerializer(); 6325 out.setOutput(fos, "utf-8"); 6326 out.startDocument(null, true); 6327 out.startTag(null, TAG_URI_GRANTS); 6328 for (UriPermission.Snapshot perm : persist) { 6329 out.startTag(null, TAG_URI_GRANT); 6330 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6331 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6332 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6333 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6334 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6335 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6336 out.endTag(null, TAG_URI_GRANT); 6337 } 6338 out.endTag(null, TAG_URI_GRANTS); 6339 out.endDocument(); 6340 6341 mGrantFile.finishWrite(fos); 6342 } catch (IOException e) { 6343 if (fos != null) { 6344 mGrantFile.failWrite(fos); 6345 } 6346 } 6347 } 6348 6349 private void readGrantedUriPermissionsLocked() { 6350 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6351 6352 final long now = System.currentTimeMillis(); 6353 6354 FileInputStream fis = null; 6355 try { 6356 fis = mGrantFile.openRead(); 6357 final XmlPullParser in = Xml.newPullParser(); 6358 in.setInput(fis, null); 6359 6360 int type; 6361 while ((type = in.next()) != END_DOCUMENT) { 6362 final String tag = in.getName(); 6363 if (type == START_TAG) { 6364 if (TAG_URI_GRANT.equals(tag)) { 6365 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6366 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6367 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6368 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6369 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6370 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6371 6372 // Sanity check that provider still belongs to source package 6373 final ProviderInfo pi = getProviderInfoLocked( 6374 uri.getAuthority(), userHandle); 6375 if (pi != null && sourcePkg.equals(pi.packageName)) { 6376 int targetUid = -1; 6377 try { 6378 targetUid = AppGlobals.getPackageManager() 6379 .getPackageUid(targetPkg, userHandle); 6380 } catch (RemoteException e) { 6381 } 6382 if (targetUid != -1) { 6383 final UriPermission perm = findOrCreateUriPermissionLocked( 6384 sourcePkg, targetPkg, targetUid, uri); 6385 perm.initPersistedModes(modeFlags, createdTime); 6386 } 6387 } else { 6388 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6389 + " but instead found " + pi); 6390 } 6391 } 6392 } 6393 } 6394 } catch (FileNotFoundException e) { 6395 // Missing grants is okay 6396 } catch (IOException e) { 6397 Log.wtf(TAG, "Failed reading Uri grants", e); 6398 } catch (XmlPullParserException e) { 6399 Log.wtf(TAG, "Failed reading Uri grants", e); 6400 } finally { 6401 IoUtils.closeQuietly(fis); 6402 } 6403 } 6404 6405 @Override 6406 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6407 enforceNotIsolatedCaller("takePersistableUriPermission"); 6408 6409 Preconditions.checkFlagsArgument(modeFlags, 6410 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6411 6412 synchronized (this) { 6413 final int callingUid = Binder.getCallingUid(); 6414 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6415 if (perm == null) { 6416 throw new SecurityException("No permission grant found for UID " + callingUid 6417 + " and Uri " + uri.toSafeString()); 6418 } 6419 6420 boolean persistChanged = perm.takePersistableModes(modeFlags); 6421 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6422 6423 if (persistChanged) { 6424 schedulePersistUriGrants(); 6425 } 6426 } 6427 } 6428 6429 @Override 6430 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6431 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6432 6433 Preconditions.checkFlagsArgument(modeFlags, 6434 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6435 6436 synchronized (this) { 6437 final int callingUid = Binder.getCallingUid(); 6438 6439 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6440 if (perm == null) { 6441 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6442 + uri.toSafeString()); 6443 return; 6444 } 6445 6446 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6447 removeUriPermissionIfNeededLocked(perm); 6448 if (persistChanged) { 6449 schedulePersistUriGrants(); 6450 } 6451 } 6452 } 6453 6454 /** 6455 * Prune any older {@link UriPermission} for the given UID until outstanding 6456 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6457 * 6458 * @return if any mutations occured that require persisting. 6459 */ 6460 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6461 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6462 if (perms == null) return false; 6463 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6464 6465 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6466 for (UriPermission perm : perms.values()) { 6467 if (perm.persistedModeFlags != 0) { 6468 persisted.add(perm); 6469 } 6470 } 6471 6472 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6473 if (trimCount <= 0) return false; 6474 6475 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6476 for (int i = 0; i < trimCount; i++) { 6477 final UriPermission perm = persisted.get(i); 6478 6479 if (DEBUG_URI_PERMISSION) { 6480 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6481 } 6482 6483 perm.releasePersistableModes(~0); 6484 removeUriPermissionIfNeededLocked(perm); 6485 } 6486 6487 return true; 6488 } 6489 6490 @Override 6491 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6492 String packageName, boolean incoming) { 6493 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6494 Preconditions.checkNotNull(packageName, "packageName"); 6495 6496 final int callingUid = Binder.getCallingUid(); 6497 final IPackageManager pm = AppGlobals.getPackageManager(); 6498 try { 6499 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6500 if (packageUid != callingUid) { 6501 throw new SecurityException( 6502 "Package " + packageName + " does not belong to calling UID " + callingUid); 6503 } 6504 } catch (RemoteException e) { 6505 throw new SecurityException("Failed to verify package name ownership"); 6506 } 6507 6508 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6509 synchronized (this) { 6510 if (incoming) { 6511 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6512 if (perms == null) { 6513 Slog.w(TAG, "No permission grants found for " + packageName); 6514 } else { 6515 final int size = perms.size(); 6516 for (int i = 0; i < size; i++) { 6517 final UriPermission perm = perms.valueAt(i); 6518 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6519 result.add(perm.buildPersistedPublicApiObject()); 6520 } 6521 } 6522 } 6523 } else { 6524 final int size = mGrantedUriPermissions.size(); 6525 for (int i = 0; i < size; i++) { 6526 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6527 final int permsSize = perms.size(); 6528 for (int j = 0; j < permsSize; j++) { 6529 final UriPermission perm = perms.valueAt(j); 6530 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6531 result.add(perm.buildPersistedPublicApiObject()); 6532 } 6533 } 6534 } 6535 } 6536 } 6537 return new ParceledListSlice<android.content.UriPermission>(result); 6538 } 6539 6540 @Override 6541 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6542 synchronized (this) { 6543 ProcessRecord app = 6544 who != null ? getRecordForAppLocked(who) : null; 6545 if (app == null) return; 6546 6547 Message msg = Message.obtain(); 6548 msg.what = WAIT_FOR_DEBUGGER_MSG; 6549 msg.obj = app; 6550 msg.arg1 = waiting ? 1 : 0; 6551 mHandler.sendMessage(msg); 6552 } 6553 } 6554 6555 @Override 6556 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6557 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6558 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6559 outInfo.availMem = Process.getFreeMemory(); 6560 outInfo.totalMem = Process.getTotalMemory(); 6561 outInfo.threshold = homeAppMem; 6562 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6563 outInfo.hiddenAppThreshold = cachedAppMem; 6564 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6565 ProcessList.SERVICE_ADJ); 6566 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6567 ProcessList.VISIBLE_APP_ADJ); 6568 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6569 ProcessList.FOREGROUND_APP_ADJ); 6570 } 6571 6572 // ========================================================= 6573 // TASK MANAGEMENT 6574 // ========================================================= 6575 6576 @Override 6577 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6578 IThumbnailReceiver receiver) { 6579 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6580 6581 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6582 ActivityRecord topRecord = null; 6583 6584 synchronized(this) { 6585 if (localLOGV) Slog.v( 6586 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6587 + ", receiver=" + receiver); 6588 6589 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6590 != PackageManager.PERMISSION_GRANTED) { 6591 if (receiver != null) { 6592 // If the caller wants to wait for pending thumbnails, 6593 // it ain't gonna get them. 6594 try { 6595 receiver.finished(); 6596 } catch (RemoteException ex) { 6597 } 6598 } 6599 String msg = "Permission Denial: getTasks() from pid=" 6600 + Binder.getCallingPid() 6601 + ", uid=" + Binder.getCallingUid() 6602 + " requires " + android.Manifest.permission.GET_TASKS; 6603 Slog.w(TAG, msg); 6604 throw new SecurityException(msg); 6605 } 6606 6607 // TODO: Improve with MRU list from all ActivityStacks. 6608 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6609 6610 if (!pending.pendingRecords.isEmpty()) { 6611 mPendingThumbnails.add(pending); 6612 } 6613 } 6614 6615 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6616 6617 if (topRecord != null) { 6618 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6619 try { 6620 IApplicationThread topThumbnail = topRecord.app.thread; 6621 topThumbnail.requestThumbnail(topRecord.appToken); 6622 } catch (Exception e) { 6623 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6624 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6625 } 6626 } 6627 6628 if (pending == null && receiver != null) { 6629 // In this case all thumbnails were available and the client 6630 // is being asked to be told when the remaining ones come in... 6631 // which is unusually, since the top-most currently running 6632 // activity should never have a canned thumbnail! Oh well. 6633 try { 6634 receiver.finished(); 6635 } catch (RemoteException ex) { 6636 } 6637 } 6638 6639 return list; 6640 } 6641 6642 TaskRecord getMostRecentTask() { 6643 return mRecentTasks.get(0); 6644 } 6645 6646 @Override 6647 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6648 int flags, int userId) { 6649 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6650 false, true, "getRecentTasks", null); 6651 6652 synchronized (this) { 6653 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6654 "getRecentTasks()"); 6655 final boolean detailed = checkCallingPermission( 6656 android.Manifest.permission.GET_DETAILED_TASKS) 6657 == PackageManager.PERMISSION_GRANTED; 6658 6659 IPackageManager pm = AppGlobals.getPackageManager(); 6660 6661 final int N = mRecentTasks.size(); 6662 ArrayList<ActivityManager.RecentTaskInfo> res 6663 = new ArrayList<ActivityManager.RecentTaskInfo>( 6664 maxNum < N ? maxNum : N); 6665 for (int i=0; i<N && maxNum > 0; i++) { 6666 TaskRecord tr = mRecentTasks.get(i); 6667 // Only add calling user's recent tasks 6668 if (tr.userId != userId) continue; 6669 // Return the entry if desired by the caller. We always return 6670 // the first entry, because callers always expect this to be the 6671 // foreground app. We may filter others if the caller has 6672 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6673 // we should exclude the entry. 6674 6675 if (i == 0 6676 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6677 || (tr.intent == null) 6678 || ((tr.intent.getFlags() 6679 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6680 ActivityManager.RecentTaskInfo rti 6681 = new ActivityManager.RecentTaskInfo(); 6682 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6683 rti.persistentId = tr.taskId; 6684 rti.baseIntent = new Intent( 6685 tr.intent != null ? tr.intent : tr.affinityIntent); 6686 if (!detailed) { 6687 rti.baseIntent.replaceExtras((Bundle)null); 6688 } 6689 rti.origActivity = tr.origActivity; 6690 rti.description = tr.lastDescription; 6691 rti.stackId = tr.stack.mStackId; 6692 6693 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6694 // Check whether this activity is currently available. 6695 try { 6696 if (rti.origActivity != null) { 6697 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6698 == null) { 6699 continue; 6700 } 6701 } else if (rti.baseIntent != null) { 6702 if (pm.queryIntentActivities(rti.baseIntent, 6703 null, 0, userId) == null) { 6704 continue; 6705 } 6706 } 6707 } catch (RemoteException e) { 6708 // Will never happen. 6709 } 6710 } 6711 6712 res.add(rti); 6713 maxNum--; 6714 } 6715 } 6716 return res; 6717 } 6718 } 6719 6720 private TaskRecord recentTaskForIdLocked(int id) { 6721 final int N = mRecentTasks.size(); 6722 for (int i=0; i<N; i++) { 6723 TaskRecord tr = mRecentTasks.get(i); 6724 if (tr.taskId == id) { 6725 return tr; 6726 } 6727 } 6728 return null; 6729 } 6730 6731 @Override 6732 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6733 synchronized (this) { 6734 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6735 "getTaskThumbnails()"); 6736 TaskRecord tr = recentTaskForIdLocked(id); 6737 if (tr != null) { 6738 return tr.getTaskThumbnailsLocked(); 6739 } 6740 } 6741 return null; 6742 } 6743 6744 @Override 6745 public Bitmap getTaskTopThumbnail(int id) { 6746 synchronized (this) { 6747 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6748 "getTaskTopThumbnail()"); 6749 TaskRecord tr = recentTaskForIdLocked(id); 6750 if (tr != null) { 6751 return tr.getTaskTopThumbnailLocked(); 6752 } 6753 } 6754 return null; 6755 } 6756 6757 @Override 6758 public boolean removeSubTask(int taskId, int subTaskIndex) { 6759 synchronized (this) { 6760 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6761 "removeSubTask()"); 6762 long ident = Binder.clearCallingIdentity(); 6763 try { 6764 TaskRecord tr = recentTaskForIdLocked(taskId); 6765 if (tr != null) { 6766 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6767 } 6768 return false; 6769 } finally { 6770 Binder.restoreCallingIdentity(ident); 6771 } 6772 } 6773 } 6774 6775 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6776 if (!pr.killedByAm) { 6777 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6778 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6779 pr.processName, pr.setAdj, reason); 6780 pr.killedByAm = true; 6781 Process.killProcessQuiet(pr.pid); 6782 } 6783 } 6784 6785 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6786 tr.disposeThumbnail(); 6787 mRecentTasks.remove(tr); 6788 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6789 Intent baseIntent = new Intent( 6790 tr.intent != null ? tr.intent : tr.affinityIntent); 6791 ComponentName component = baseIntent.getComponent(); 6792 if (component == null) { 6793 Slog.w(TAG, "Now component for base intent of task: " + tr); 6794 return; 6795 } 6796 6797 // Find any running services associated with this app. 6798 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6799 6800 if (killProcesses) { 6801 // Find any running processes associated with this app. 6802 final String pkg = component.getPackageName(); 6803 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6804 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6805 for (int i=0; i<pmap.size(); i++) { 6806 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6807 for (int j=0; j<uids.size(); j++) { 6808 ProcessRecord proc = uids.valueAt(j); 6809 if (proc.userId != tr.userId) { 6810 continue; 6811 } 6812 if (!proc.pkgList.containsKey(pkg)) { 6813 continue; 6814 } 6815 procs.add(proc); 6816 } 6817 } 6818 6819 // Kill the running processes. 6820 for (int i=0; i<procs.size(); i++) { 6821 ProcessRecord pr = procs.get(i); 6822 if (pr == mHomeProcess) { 6823 // Don't kill the home process along with tasks from the same package. 6824 continue; 6825 } 6826 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6827 killUnneededProcessLocked(pr, "remove task"); 6828 } else { 6829 pr.waitingToKill = "remove task"; 6830 } 6831 } 6832 } 6833 } 6834 6835 @Override 6836 public boolean removeTask(int taskId, int flags) { 6837 synchronized (this) { 6838 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6839 "removeTask()"); 6840 long ident = Binder.clearCallingIdentity(); 6841 try { 6842 TaskRecord tr = recentTaskForIdLocked(taskId); 6843 if (tr != null) { 6844 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6845 if (r != null) { 6846 cleanUpRemovedTaskLocked(tr, flags); 6847 return true; 6848 } 6849 if (tr.mActivities.size() == 0) { 6850 // Caller is just removing a recent task that is 6851 // not actively running. That is easy! 6852 cleanUpRemovedTaskLocked(tr, flags); 6853 return true; 6854 } 6855 Slog.w(TAG, "removeTask: task " + taskId 6856 + " does not have activities to remove, " 6857 + " but numActivities=" + tr.numActivities 6858 + ": " + tr); 6859 } 6860 } finally { 6861 Binder.restoreCallingIdentity(ident); 6862 } 6863 } 6864 return false; 6865 } 6866 6867 /** 6868 * TODO: Add mController hook 6869 */ 6870 @Override 6871 public void moveTaskToFront(int task, int flags, Bundle options) { 6872 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6873 "moveTaskToFront()"); 6874 6875 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 6876 synchronized(this) { 6877 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6878 Binder.getCallingUid(), "Task to front")) { 6879 ActivityOptions.abort(options); 6880 return; 6881 } 6882 final long origId = Binder.clearCallingIdentity(); 6883 try { 6884 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 6885 } finally { 6886 Binder.restoreCallingIdentity(origId); 6887 } 6888 ActivityOptions.abort(options); 6889 } 6890 } 6891 6892 @Override 6893 public void moveTaskToBack(int taskId) { 6894 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6895 "moveTaskToBack()"); 6896 6897 synchronized(this) { 6898 TaskRecord tr = recentTaskForIdLocked(taskId); 6899 if (tr != null) { 6900 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 6901 ActivityStack stack = tr.stack; 6902 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 6903 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6904 Binder.getCallingUid(), "Task to back")) { 6905 return; 6906 } 6907 } 6908 final long origId = Binder.clearCallingIdentity(); 6909 try { 6910 stack.moveTaskToBackLocked(taskId, null); 6911 } finally { 6912 Binder.restoreCallingIdentity(origId); 6913 } 6914 } 6915 } 6916 } 6917 6918 /** 6919 * Moves an activity, and all of the other activities within the same task, to the bottom 6920 * of the history stack. The activity's order within the task is unchanged. 6921 * 6922 * @param token A reference to the activity we wish to move 6923 * @param nonRoot If false then this only works if the activity is the root 6924 * of a task; if true it will work for any activity in a task. 6925 * @return Returns true if the move completed, false if not. 6926 */ 6927 @Override 6928 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6929 enforceNotIsolatedCaller("moveActivityTaskToBack"); 6930 synchronized(this) { 6931 final long origId = Binder.clearCallingIdentity(); 6932 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 6933 if (taskId >= 0) { 6934 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 6935 } 6936 Binder.restoreCallingIdentity(origId); 6937 } 6938 return false; 6939 } 6940 6941 @Override 6942 public void moveTaskBackwards(int task) { 6943 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6944 "moveTaskBackwards()"); 6945 6946 synchronized(this) { 6947 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6948 Binder.getCallingUid(), "Task backwards")) { 6949 return; 6950 } 6951 final long origId = Binder.clearCallingIdentity(); 6952 moveTaskBackwardsLocked(task); 6953 Binder.restoreCallingIdentity(origId); 6954 } 6955 } 6956 6957 private final void moveTaskBackwardsLocked(int task) { 6958 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 6959 } 6960 6961 @Override 6962 public int createStack(int taskId, int relativeStackBoxId, int position, float weight) { 6963 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 6964 "createStack()"); 6965 if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId + " relStackBoxId=" + 6966 relativeStackBoxId + " position=" + position + " weight=" + weight); 6967 synchronized (this) { 6968 long ident = Binder.clearCallingIdentity(); 6969 try { 6970 int stackId = mStackSupervisor.createStack(); 6971 mWindowManager.createStack(stackId, relativeStackBoxId, position, weight); 6972 if (taskId > 0) { 6973 moveTaskToStack(taskId, stackId, true); 6974 } 6975 return stackId; 6976 } finally { 6977 Binder.restoreCallingIdentity(ident); 6978 } 6979 } 6980 } 6981 6982 @Override 6983 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 6984 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 6985 "moveTaskToStack()"); 6986 if (stackId == HOME_STACK_ID) { 6987 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 6988 new RuntimeException("here").fillInStackTrace()); 6989 } 6990 synchronized (this) { 6991 long ident = Binder.clearCallingIdentity(); 6992 try { 6993 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 6994 + stackId + " toTop=" + toTop); 6995 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 6996 } finally { 6997 Binder.restoreCallingIdentity(ident); 6998 } 6999 } 7000 } 7001 7002 @Override 7003 public void resizeStackBox(int stackBoxId, float weight) { 7004 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7005 "resizeStackBox()"); 7006 long ident = Binder.clearCallingIdentity(); 7007 try { 7008 mWindowManager.resizeStackBox(stackBoxId, weight); 7009 } finally { 7010 Binder.restoreCallingIdentity(ident); 7011 } 7012 } 7013 7014 private ArrayList<StackInfo> getStacks() { 7015 synchronized (this) { 7016 ArrayList<ActivityManager.StackInfo> list = new ArrayList<ActivityManager.StackInfo>(); 7017 ArrayList<ActivityStack> stacks = mStackSupervisor.getStacks(); 7018 for (ActivityStack stack : stacks) { 7019 ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo(); 7020 int stackId = stack.mStackId; 7021 stackInfo.stackId = stackId; 7022 stackInfo.bounds = mWindowManager.getStackBounds(stackId); 7023 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 7024 final int numTasks = tasks.size(); 7025 int[] taskIds = new int[numTasks]; 7026 String[] taskNames = new String[numTasks]; 7027 for (int i = 0; i < numTasks; ++i) { 7028 final TaskRecord task = tasks.get(i); 7029 taskIds[i] = task.taskId; 7030 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 7031 : task.realActivity != null ? task.realActivity.flattenToString() 7032 : task.getTopActivity() != null ? task.getTopActivity().packageName 7033 : "unknown"; 7034 } 7035 stackInfo.taskIds = taskIds; 7036 stackInfo.taskNames = taskNames; 7037 list.add(stackInfo); 7038 } 7039 return list; 7040 } 7041 } 7042 7043 private void addStackInfoToStackBoxInfo(StackBoxInfo stackBoxInfo, List<StackInfo> stackInfos) { 7044 final int stackId = stackBoxInfo.stackId; 7045 if (stackId >= 0) { 7046 for (StackInfo stackInfo : stackInfos) { 7047 if (stackId == stackInfo.stackId) { 7048 stackBoxInfo.stack = stackInfo; 7049 stackInfos.remove(stackInfo); 7050 return; 7051 } 7052 } 7053 } else { 7054 addStackInfoToStackBoxInfo(stackBoxInfo.children[0], stackInfos); 7055 addStackInfoToStackBoxInfo(stackBoxInfo.children[1], stackInfos); 7056 } 7057 } 7058 7059 @Override 7060 public List<StackBoxInfo> getStackBoxes() { 7061 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7062 "getStackBoxes()"); 7063 long ident = Binder.clearCallingIdentity(); 7064 try { 7065 List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos(); 7066 synchronized (this) { 7067 List<StackInfo> stackInfos = getStacks(); 7068 for (StackBoxInfo stackBoxInfo : stackBoxInfos) { 7069 addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos); 7070 } 7071 } 7072 return stackBoxInfos; 7073 } finally { 7074 Binder.restoreCallingIdentity(ident); 7075 } 7076 } 7077 7078 @Override 7079 public StackBoxInfo getStackBoxInfo(int stackBoxId) { 7080 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7081 "getStackBoxInfo()"); 7082 long ident = Binder.clearCallingIdentity(); 7083 try { 7084 List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos(); 7085 StackBoxInfo info = null; 7086 synchronized (this) { 7087 List<StackInfo> stackInfos = getStacks(); 7088 for (StackBoxInfo stackBoxInfo : stackBoxInfos) { 7089 addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos); 7090 if (stackBoxInfo.stackBoxId == stackBoxId) { 7091 info = stackBoxInfo; 7092 } 7093 } 7094 } 7095 return info; 7096 } finally { 7097 Binder.restoreCallingIdentity(ident); 7098 } 7099 } 7100 7101 @Override 7102 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7103 synchronized(this) { 7104 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7105 } 7106 } 7107 7108 // ========================================================= 7109 // THUMBNAILS 7110 // ========================================================= 7111 7112 public void reportThumbnail(IBinder token, 7113 Bitmap thumbnail, CharSequence description) { 7114 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7115 final long origId = Binder.clearCallingIdentity(); 7116 sendPendingThumbnail(null, token, thumbnail, description, true); 7117 Binder.restoreCallingIdentity(origId); 7118 } 7119 7120 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7121 Bitmap thumbnail, CharSequence description, boolean always) { 7122 TaskRecord task; 7123 ArrayList<PendingThumbnailsRecord> receivers = null; 7124 7125 //System.out.println("Send pending thumbnail: " + r); 7126 7127 synchronized(this) { 7128 if (r == null) { 7129 r = ActivityRecord.isInStackLocked(token); 7130 if (r == null) { 7131 return; 7132 } 7133 } 7134 if (thumbnail == null && r.thumbHolder != null) { 7135 thumbnail = r.thumbHolder.lastThumbnail; 7136 description = r.thumbHolder.lastDescription; 7137 } 7138 if (thumbnail == null && !always) { 7139 // If there is no thumbnail, and this entry is not actually 7140 // going away, then abort for now and pick up the next 7141 // thumbnail we get. 7142 return; 7143 } 7144 task = r.task; 7145 7146 int N = mPendingThumbnails.size(); 7147 int i=0; 7148 while (i<N) { 7149 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7150 //System.out.println("Looking in " + pr.pendingRecords); 7151 if (pr.pendingRecords.remove(r)) { 7152 if (receivers == null) { 7153 receivers = new ArrayList<PendingThumbnailsRecord>(); 7154 } 7155 receivers.add(pr); 7156 if (pr.pendingRecords.size() == 0) { 7157 pr.finished = true; 7158 mPendingThumbnails.remove(i); 7159 N--; 7160 continue; 7161 } 7162 } 7163 i++; 7164 } 7165 } 7166 7167 if (receivers != null) { 7168 final int N = receivers.size(); 7169 for (int i=0; i<N; i++) { 7170 try { 7171 PendingThumbnailsRecord pr = receivers.get(i); 7172 pr.receiver.newThumbnail( 7173 task != null ? task.taskId : -1, thumbnail, description); 7174 if (pr.finished) { 7175 pr.receiver.finished(); 7176 } 7177 } catch (Exception e) { 7178 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7179 } 7180 } 7181 } 7182 } 7183 7184 // ========================================================= 7185 // CONTENT PROVIDERS 7186 // ========================================================= 7187 7188 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7189 List<ProviderInfo> providers = null; 7190 try { 7191 providers = AppGlobals.getPackageManager(). 7192 queryContentProviders(app.processName, app.uid, 7193 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7194 } catch (RemoteException ex) { 7195 } 7196 if (DEBUG_MU) 7197 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7198 int userId = app.userId; 7199 if (providers != null) { 7200 int N = providers.size(); 7201 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7202 for (int i=0; i<N; i++) { 7203 ProviderInfo cpi = 7204 (ProviderInfo)providers.get(i); 7205 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7206 cpi.name, cpi.flags); 7207 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7208 // This is a singleton provider, but a user besides the 7209 // default user is asking to initialize a process it runs 7210 // in... well, no, it doesn't actually run in this process, 7211 // it runs in the process of the default user. Get rid of it. 7212 providers.remove(i); 7213 N--; 7214 i--; 7215 continue; 7216 } 7217 7218 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7219 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7220 if (cpr == null) { 7221 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7222 mProviderMap.putProviderByClass(comp, cpr); 7223 } 7224 if (DEBUG_MU) 7225 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7226 app.pubProviders.put(cpi.name, cpr); 7227 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7228 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7229 } 7230 } 7231 return providers; 7232 } 7233 7234 /** 7235 * Check if {@link ProcessRecord} has a possible chance at accessing the 7236 * given {@link ProviderInfo}. Final permission checking is always done 7237 * in {@link ContentProvider}. 7238 */ 7239 private final String checkContentProviderPermissionLocked( 7240 ProviderInfo cpi, ProcessRecord r) { 7241 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7242 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7243 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7244 cpi.applicationInfo.uid, cpi.exported) 7245 == PackageManager.PERMISSION_GRANTED) { 7246 return null; 7247 } 7248 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7249 cpi.applicationInfo.uid, cpi.exported) 7250 == PackageManager.PERMISSION_GRANTED) { 7251 return null; 7252 } 7253 7254 PathPermission[] pps = cpi.pathPermissions; 7255 if (pps != null) { 7256 int i = pps.length; 7257 while (i > 0) { 7258 i--; 7259 PathPermission pp = pps[i]; 7260 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7261 cpi.applicationInfo.uid, cpi.exported) 7262 == PackageManager.PERMISSION_GRANTED) { 7263 return null; 7264 } 7265 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7266 cpi.applicationInfo.uid, cpi.exported) 7267 == PackageManager.PERMISSION_GRANTED) { 7268 return null; 7269 } 7270 } 7271 } 7272 7273 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7274 if (perms != null) { 7275 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7276 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7277 return null; 7278 } 7279 } 7280 } 7281 7282 String msg; 7283 if (!cpi.exported) { 7284 msg = "Permission Denial: opening provider " + cpi.name 7285 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7286 + ", uid=" + callingUid + ") that is not exported from uid " 7287 + cpi.applicationInfo.uid; 7288 } else { 7289 msg = "Permission Denial: opening provider " + cpi.name 7290 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7291 + ", uid=" + callingUid + ") requires " 7292 + cpi.readPermission + " or " + cpi.writePermission; 7293 } 7294 Slog.w(TAG, msg); 7295 return msg; 7296 } 7297 7298 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7299 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7300 if (r != null) { 7301 for (int i=0; i<r.conProviders.size(); i++) { 7302 ContentProviderConnection conn = r.conProviders.get(i); 7303 if (conn.provider == cpr) { 7304 if (DEBUG_PROVIDER) Slog.v(TAG, 7305 "Adding provider requested by " 7306 + r.processName + " from process " 7307 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7308 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7309 if (stable) { 7310 conn.stableCount++; 7311 conn.numStableIncs++; 7312 } else { 7313 conn.unstableCount++; 7314 conn.numUnstableIncs++; 7315 } 7316 return conn; 7317 } 7318 } 7319 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7320 if (stable) { 7321 conn.stableCount = 1; 7322 conn.numStableIncs = 1; 7323 } else { 7324 conn.unstableCount = 1; 7325 conn.numUnstableIncs = 1; 7326 } 7327 cpr.connections.add(conn); 7328 r.conProviders.add(conn); 7329 return conn; 7330 } 7331 cpr.addExternalProcessHandleLocked(externalProcessToken); 7332 return null; 7333 } 7334 7335 boolean decProviderCountLocked(ContentProviderConnection conn, 7336 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7337 if (conn != null) { 7338 cpr = conn.provider; 7339 if (DEBUG_PROVIDER) Slog.v(TAG, 7340 "Removing provider requested by " 7341 + conn.client.processName + " from process " 7342 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7343 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7344 if (stable) { 7345 conn.stableCount--; 7346 } else { 7347 conn.unstableCount--; 7348 } 7349 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7350 cpr.connections.remove(conn); 7351 conn.client.conProviders.remove(conn); 7352 return true; 7353 } 7354 return false; 7355 } 7356 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7357 return false; 7358 } 7359 7360 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7361 String name, IBinder token, boolean stable, int userId) { 7362 ContentProviderRecord cpr; 7363 ContentProviderConnection conn = null; 7364 ProviderInfo cpi = null; 7365 7366 synchronized(this) { 7367 ProcessRecord r = null; 7368 if (caller != null) { 7369 r = getRecordForAppLocked(caller); 7370 if (r == null) { 7371 throw new SecurityException( 7372 "Unable to find app for caller " + caller 7373 + " (pid=" + Binder.getCallingPid() 7374 + ") when getting content provider " + name); 7375 } 7376 } 7377 7378 // First check if this content provider has been published... 7379 cpr = mProviderMap.getProviderByName(name, userId); 7380 boolean providerRunning = cpr != null; 7381 if (providerRunning) { 7382 cpi = cpr.info; 7383 String msg; 7384 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7385 throw new SecurityException(msg); 7386 } 7387 7388 if (r != null && cpr.canRunHere(r)) { 7389 // This provider has been published or is in the process 7390 // of being published... but it is also allowed to run 7391 // in the caller's process, so don't make a connection 7392 // and just let the caller instantiate its own instance. 7393 ContentProviderHolder holder = cpr.newHolder(null); 7394 // don't give caller the provider object, it needs 7395 // to make its own. 7396 holder.provider = null; 7397 return holder; 7398 } 7399 7400 final long origId = Binder.clearCallingIdentity(); 7401 7402 // In this case the provider instance already exists, so we can 7403 // return it right away. 7404 conn = incProviderCountLocked(r, cpr, token, stable); 7405 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7406 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7407 // If this is a perceptible app accessing the provider, 7408 // make sure to count it as being accessed and thus 7409 // back up on the LRU list. This is good because 7410 // content providers are often expensive to start. 7411 updateLruProcessLocked(cpr.proc, false, false); 7412 } 7413 } 7414 7415 if (cpr.proc != null) { 7416 if (false) { 7417 if (cpr.name.flattenToShortString().equals( 7418 "com.android.providers.calendar/.CalendarProvider2")) { 7419 Slog.v(TAG, "****************** KILLING " 7420 + cpr.name.flattenToShortString()); 7421 Process.killProcess(cpr.proc.pid); 7422 } 7423 } 7424 boolean success = updateOomAdjLocked(cpr.proc); 7425 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7426 // NOTE: there is still a race here where a signal could be 7427 // pending on the process even though we managed to update its 7428 // adj level. Not sure what to do about this, but at least 7429 // the race is now smaller. 7430 if (!success) { 7431 // Uh oh... it looks like the provider's process 7432 // has been killed on us. We need to wait for a new 7433 // process to be started, and make sure its death 7434 // doesn't kill our process. 7435 Slog.i(TAG, 7436 "Existing provider " + cpr.name.flattenToShortString() 7437 + " is crashing; detaching " + r); 7438 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7439 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7440 if (!lastRef) { 7441 // This wasn't the last ref our process had on 7442 // the provider... we have now been killed, bail. 7443 return null; 7444 } 7445 providerRunning = false; 7446 conn = null; 7447 } 7448 } 7449 7450 Binder.restoreCallingIdentity(origId); 7451 } 7452 7453 boolean singleton; 7454 if (!providerRunning) { 7455 try { 7456 cpi = AppGlobals.getPackageManager(). 7457 resolveContentProvider(name, 7458 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7459 } catch (RemoteException ex) { 7460 } 7461 if (cpi == null) { 7462 return null; 7463 } 7464 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7465 cpi.name, cpi.flags); 7466 if (singleton) { 7467 userId = 0; 7468 } 7469 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7470 7471 String msg; 7472 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7473 throw new SecurityException(msg); 7474 } 7475 7476 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7477 && !cpi.processName.equals("system")) { 7478 // If this content provider does not run in the system 7479 // process, and the system is not yet ready to run other 7480 // processes, then fail fast instead of hanging. 7481 throw new IllegalArgumentException( 7482 "Attempt to launch content provider before system ready"); 7483 } 7484 7485 // Make sure that the user who owns this provider is started. If not, 7486 // we don't want to allow it to run. 7487 if (mStartedUsers.get(userId) == null) { 7488 Slog.w(TAG, "Unable to launch app " 7489 + cpi.applicationInfo.packageName + "/" 7490 + cpi.applicationInfo.uid + " for provider " 7491 + name + ": user " + userId + " is stopped"); 7492 return null; 7493 } 7494 7495 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7496 cpr = mProviderMap.getProviderByClass(comp, userId); 7497 final boolean firstClass = cpr == null; 7498 if (firstClass) { 7499 try { 7500 ApplicationInfo ai = 7501 AppGlobals.getPackageManager(). 7502 getApplicationInfo( 7503 cpi.applicationInfo.packageName, 7504 STOCK_PM_FLAGS, userId); 7505 if (ai == null) { 7506 Slog.w(TAG, "No package info for content provider " 7507 + cpi.name); 7508 return null; 7509 } 7510 ai = getAppInfoForUser(ai, userId); 7511 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7512 } catch (RemoteException ex) { 7513 // pm is in same process, this will never happen. 7514 } 7515 } 7516 7517 if (r != null && cpr.canRunHere(r)) { 7518 // If this is a multiprocess provider, then just return its 7519 // info and allow the caller to instantiate it. Only do 7520 // this if the provider is the same user as the caller's 7521 // process, or can run as root (so can be in any process). 7522 return cpr.newHolder(null); 7523 } 7524 7525 if (DEBUG_PROVIDER) { 7526 RuntimeException e = new RuntimeException("here"); 7527 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7528 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7529 } 7530 7531 // This is single process, and our app is now connecting to it. 7532 // See if we are already in the process of launching this 7533 // provider. 7534 final int N = mLaunchingProviders.size(); 7535 int i; 7536 for (i=0; i<N; i++) { 7537 if (mLaunchingProviders.get(i) == cpr) { 7538 break; 7539 } 7540 } 7541 7542 // If the provider is not already being launched, then get it 7543 // started. 7544 if (i >= N) { 7545 final long origId = Binder.clearCallingIdentity(); 7546 7547 try { 7548 // Content provider is now in use, its package can't be stopped. 7549 try { 7550 AppGlobals.getPackageManager().setPackageStoppedState( 7551 cpr.appInfo.packageName, false, userId); 7552 } catch (RemoteException e) { 7553 } catch (IllegalArgumentException e) { 7554 Slog.w(TAG, "Failed trying to unstop package " 7555 + cpr.appInfo.packageName + ": " + e); 7556 } 7557 7558 // Use existing process if already started 7559 ProcessRecord proc = getProcessRecordLocked( 7560 cpi.processName, cpr.appInfo.uid, false); 7561 if (proc != null && proc.thread != null) { 7562 if (DEBUG_PROVIDER) { 7563 Slog.d(TAG, "Installing in existing process " + proc); 7564 } 7565 proc.pubProviders.put(cpi.name, cpr); 7566 try { 7567 proc.thread.scheduleInstallProvider(cpi); 7568 } catch (RemoteException e) { 7569 } 7570 } else { 7571 proc = startProcessLocked(cpi.processName, 7572 cpr.appInfo, false, 0, "content provider", 7573 new ComponentName(cpi.applicationInfo.packageName, 7574 cpi.name), false, false, false); 7575 if (proc == null) { 7576 Slog.w(TAG, "Unable to launch app " 7577 + cpi.applicationInfo.packageName + "/" 7578 + cpi.applicationInfo.uid + " for provider " 7579 + name + ": process is bad"); 7580 return null; 7581 } 7582 } 7583 cpr.launchingApp = proc; 7584 mLaunchingProviders.add(cpr); 7585 } finally { 7586 Binder.restoreCallingIdentity(origId); 7587 } 7588 } 7589 7590 // Make sure the provider is published (the same provider class 7591 // may be published under multiple names). 7592 if (firstClass) { 7593 mProviderMap.putProviderByClass(comp, cpr); 7594 } 7595 7596 mProviderMap.putProviderByName(name, cpr); 7597 conn = incProviderCountLocked(r, cpr, token, stable); 7598 if (conn != null) { 7599 conn.waiting = true; 7600 } 7601 } 7602 } 7603 7604 // Wait for the provider to be published... 7605 synchronized (cpr) { 7606 while (cpr.provider == null) { 7607 if (cpr.launchingApp == null) { 7608 Slog.w(TAG, "Unable to launch app " 7609 + cpi.applicationInfo.packageName + "/" 7610 + cpi.applicationInfo.uid + " for provider " 7611 + name + ": launching app became null"); 7612 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7613 UserHandle.getUserId(cpi.applicationInfo.uid), 7614 cpi.applicationInfo.packageName, 7615 cpi.applicationInfo.uid, name); 7616 return null; 7617 } 7618 try { 7619 if (DEBUG_MU) { 7620 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7621 + cpr.launchingApp); 7622 } 7623 if (conn != null) { 7624 conn.waiting = true; 7625 } 7626 cpr.wait(); 7627 } catch (InterruptedException ex) { 7628 } finally { 7629 if (conn != null) { 7630 conn.waiting = false; 7631 } 7632 } 7633 } 7634 } 7635 return cpr != null ? cpr.newHolder(conn) : null; 7636 } 7637 7638 public final ContentProviderHolder getContentProvider( 7639 IApplicationThread caller, String name, int userId, boolean stable) { 7640 enforceNotIsolatedCaller("getContentProvider"); 7641 if (caller == null) { 7642 String msg = "null IApplicationThread when getting content provider " 7643 + name; 7644 Slog.w(TAG, msg); 7645 throw new SecurityException(msg); 7646 } 7647 7648 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7649 false, true, "getContentProvider", null); 7650 return getContentProviderImpl(caller, name, null, stable, userId); 7651 } 7652 7653 public ContentProviderHolder getContentProviderExternal( 7654 String name, int userId, IBinder token) { 7655 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7656 "Do not have permission in call getContentProviderExternal()"); 7657 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7658 false, true, "getContentProvider", null); 7659 return getContentProviderExternalUnchecked(name, token, userId); 7660 } 7661 7662 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7663 IBinder token, int userId) { 7664 return getContentProviderImpl(null, name, token, true, userId); 7665 } 7666 7667 /** 7668 * Drop a content provider from a ProcessRecord's bookkeeping 7669 */ 7670 public void removeContentProvider(IBinder connection, boolean stable) { 7671 enforceNotIsolatedCaller("removeContentProvider"); 7672 synchronized (this) { 7673 ContentProviderConnection conn; 7674 try { 7675 conn = (ContentProviderConnection)connection; 7676 } catch (ClassCastException e) { 7677 String msg ="removeContentProvider: " + connection 7678 + " not a ContentProviderConnection"; 7679 Slog.w(TAG, msg); 7680 throw new IllegalArgumentException(msg); 7681 } 7682 if (conn == null) { 7683 throw new NullPointerException("connection is null"); 7684 } 7685 if (decProviderCountLocked(conn, null, null, stable)) { 7686 updateOomAdjLocked(); 7687 } 7688 } 7689 } 7690 7691 public void removeContentProviderExternal(String name, IBinder token) { 7692 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7693 "Do not have permission in call removeContentProviderExternal()"); 7694 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7695 } 7696 7697 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7698 synchronized (this) { 7699 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7700 if(cpr == null) { 7701 //remove from mProvidersByClass 7702 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7703 return; 7704 } 7705 7706 //update content provider record entry info 7707 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7708 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7709 if (localCpr.hasExternalProcessHandles()) { 7710 if (localCpr.removeExternalProcessHandleLocked(token)) { 7711 updateOomAdjLocked(); 7712 } else { 7713 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7714 + " with no external reference for token: " 7715 + token + "."); 7716 } 7717 } else { 7718 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7719 + " with no external references."); 7720 } 7721 } 7722 } 7723 7724 public final void publishContentProviders(IApplicationThread caller, 7725 List<ContentProviderHolder> providers) { 7726 if (providers == null) { 7727 return; 7728 } 7729 7730 enforceNotIsolatedCaller("publishContentProviders"); 7731 synchronized (this) { 7732 final ProcessRecord r = getRecordForAppLocked(caller); 7733 if (DEBUG_MU) 7734 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7735 if (r == null) { 7736 throw new SecurityException( 7737 "Unable to find app for caller " + caller 7738 + " (pid=" + Binder.getCallingPid() 7739 + ") when publishing content providers"); 7740 } 7741 7742 final long origId = Binder.clearCallingIdentity(); 7743 7744 final int N = providers.size(); 7745 for (int i=0; i<N; i++) { 7746 ContentProviderHolder src = providers.get(i); 7747 if (src == null || src.info == null || src.provider == null) { 7748 continue; 7749 } 7750 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7751 if (DEBUG_MU) 7752 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7753 if (dst != null) { 7754 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7755 mProviderMap.putProviderByClass(comp, dst); 7756 String names[] = dst.info.authority.split(";"); 7757 for (int j = 0; j < names.length; j++) { 7758 mProviderMap.putProviderByName(names[j], dst); 7759 } 7760 7761 int NL = mLaunchingProviders.size(); 7762 int j; 7763 for (j=0; j<NL; j++) { 7764 if (mLaunchingProviders.get(j) == dst) { 7765 mLaunchingProviders.remove(j); 7766 j--; 7767 NL--; 7768 } 7769 } 7770 synchronized (dst) { 7771 dst.provider = src.provider; 7772 dst.proc = r; 7773 dst.notifyAll(); 7774 } 7775 updateOomAdjLocked(r); 7776 } 7777 } 7778 7779 Binder.restoreCallingIdentity(origId); 7780 } 7781 } 7782 7783 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7784 ContentProviderConnection conn; 7785 try { 7786 conn = (ContentProviderConnection)connection; 7787 } catch (ClassCastException e) { 7788 String msg ="refContentProvider: " + connection 7789 + " not a ContentProviderConnection"; 7790 Slog.w(TAG, msg); 7791 throw new IllegalArgumentException(msg); 7792 } 7793 if (conn == null) { 7794 throw new NullPointerException("connection is null"); 7795 } 7796 7797 synchronized (this) { 7798 if (stable > 0) { 7799 conn.numStableIncs += stable; 7800 } 7801 stable = conn.stableCount + stable; 7802 if (stable < 0) { 7803 throw new IllegalStateException("stableCount < 0: " + stable); 7804 } 7805 7806 if (unstable > 0) { 7807 conn.numUnstableIncs += unstable; 7808 } 7809 unstable = conn.unstableCount + unstable; 7810 if (unstable < 0) { 7811 throw new IllegalStateException("unstableCount < 0: " + unstable); 7812 } 7813 7814 if ((stable+unstable) <= 0) { 7815 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7816 + stable + " unstable=" + unstable); 7817 } 7818 conn.stableCount = stable; 7819 conn.unstableCount = unstable; 7820 return !conn.dead; 7821 } 7822 } 7823 7824 public void unstableProviderDied(IBinder connection) { 7825 ContentProviderConnection conn; 7826 try { 7827 conn = (ContentProviderConnection)connection; 7828 } catch (ClassCastException e) { 7829 String msg ="refContentProvider: " + connection 7830 + " not a ContentProviderConnection"; 7831 Slog.w(TAG, msg); 7832 throw new IllegalArgumentException(msg); 7833 } 7834 if (conn == null) { 7835 throw new NullPointerException("connection is null"); 7836 } 7837 7838 // Safely retrieve the content provider associated with the connection. 7839 IContentProvider provider; 7840 synchronized (this) { 7841 provider = conn.provider.provider; 7842 } 7843 7844 if (provider == null) { 7845 // Um, yeah, we're way ahead of you. 7846 return; 7847 } 7848 7849 // Make sure the caller is being honest with us. 7850 if (provider.asBinder().pingBinder()) { 7851 // Er, no, still looks good to us. 7852 synchronized (this) { 7853 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 7854 + " says " + conn + " died, but we don't agree"); 7855 return; 7856 } 7857 } 7858 7859 // Well look at that! It's dead! 7860 synchronized (this) { 7861 if (conn.provider.provider != provider) { 7862 // But something changed... good enough. 7863 return; 7864 } 7865 7866 ProcessRecord proc = conn.provider.proc; 7867 if (proc == null || proc.thread == null) { 7868 // Seems like the process is already cleaned up. 7869 return; 7870 } 7871 7872 // As far as we're concerned, this is just like receiving a 7873 // death notification... just a bit prematurely. 7874 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 7875 + ") early provider death"); 7876 final long ident = Binder.clearCallingIdentity(); 7877 try { 7878 appDiedLocked(proc, proc.pid, proc.thread); 7879 } finally { 7880 Binder.restoreCallingIdentity(ident); 7881 } 7882 } 7883 } 7884 7885 @Override 7886 public void appNotRespondingViaProvider(IBinder connection) { 7887 enforceCallingPermission( 7888 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 7889 7890 final ContentProviderConnection conn = (ContentProviderConnection) connection; 7891 if (conn == null) { 7892 Slog.w(TAG, "ContentProviderConnection is null"); 7893 return; 7894 } 7895 7896 final ProcessRecord host = conn.provider.proc; 7897 if (host == null) { 7898 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 7899 return; 7900 } 7901 7902 final long token = Binder.clearCallingIdentity(); 7903 try { 7904 appNotResponding(host, null, null, false, "ContentProvider not responding"); 7905 } finally { 7906 Binder.restoreCallingIdentity(token); 7907 } 7908 } 7909 7910 public static final void installSystemProviders() { 7911 List<ProviderInfo> providers; 7912 synchronized (mSelf) { 7913 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 7914 providers = mSelf.generateApplicationProvidersLocked(app); 7915 if (providers != null) { 7916 for (int i=providers.size()-1; i>=0; i--) { 7917 ProviderInfo pi = (ProviderInfo)providers.get(i); 7918 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7919 Slog.w(TAG, "Not installing system proc provider " + pi.name 7920 + ": not system .apk"); 7921 providers.remove(i); 7922 } 7923 } 7924 } 7925 } 7926 if (providers != null) { 7927 mSystemThread.installSystemProviders(providers); 7928 } 7929 7930 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 7931 7932 mSelf.mUsageStatsService.monitorPackages(); 7933 } 7934 7935 /** 7936 * Allows app to retrieve the MIME type of a URI without having permission 7937 * to access its content provider. 7938 * 7939 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 7940 * 7941 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 7942 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 7943 */ 7944 public String getProviderMimeType(Uri uri, int userId) { 7945 enforceNotIsolatedCaller("getProviderMimeType"); 7946 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7947 userId, false, true, "getProviderMimeType", null); 7948 final String name = uri.getAuthority(); 7949 final long ident = Binder.clearCallingIdentity(); 7950 ContentProviderHolder holder = null; 7951 7952 try { 7953 holder = getContentProviderExternalUnchecked(name, null, userId); 7954 if (holder != null) { 7955 return holder.provider.getType(uri); 7956 } 7957 } catch (RemoteException e) { 7958 Log.w(TAG, "Content provider dead retrieving " + uri, e); 7959 return null; 7960 } finally { 7961 if (holder != null) { 7962 removeContentProviderExternalUnchecked(name, null, userId); 7963 } 7964 Binder.restoreCallingIdentity(ident); 7965 } 7966 7967 return null; 7968 } 7969 7970 // ========================================================= 7971 // GLOBAL MANAGEMENT 7972 // ========================================================= 7973 7974 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 7975 boolean isolated) { 7976 String proc = customProcess != null ? customProcess : info.processName; 7977 BatteryStatsImpl.Uid.Proc ps = null; 7978 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7979 int uid = info.uid; 7980 if (isolated) { 7981 int userId = UserHandle.getUserId(uid); 7982 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 7983 while (true) { 7984 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 7985 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 7986 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 7987 } 7988 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 7989 mNextIsolatedProcessUid++; 7990 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 7991 // No process for this uid, use it. 7992 break; 7993 } 7994 stepsLeft--; 7995 if (stepsLeft <= 0) { 7996 return null; 7997 } 7998 } 7999 } 8000 synchronized (stats) { 8001 ps = stats.getProcessStatsLocked(info.uid, proc); 8002 } 8003 return new ProcessRecord(ps, info, proc, uid); 8004 } 8005 8006 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8007 ProcessRecord app; 8008 if (!isolated) { 8009 app = getProcessRecordLocked(info.processName, info.uid, true); 8010 } else { 8011 app = null; 8012 } 8013 8014 if (app == null) { 8015 app = newProcessRecordLocked(info, null, isolated); 8016 mProcessNames.put(info.processName, app.uid, app); 8017 if (isolated) { 8018 mIsolatedProcesses.put(app.uid, app); 8019 } 8020 updateLruProcessLocked(app, true, false); 8021 } 8022 8023 // This package really, really can not be stopped. 8024 try { 8025 AppGlobals.getPackageManager().setPackageStoppedState( 8026 info.packageName, false, UserHandle.getUserId(app.uid)); 8027 } catch (RemoteException e) { 8028 } catch (IllegalArgumentException e) { 8029 Slog.w(TAG, "Failed trying to unstop package " 8030 + info.packageName + ": " + e); 8031 } 8032 8033 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8034 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8035 app.persistent = true; 8036 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8037 } 8038 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8039 mPersistentStartingProcesses.add(app); 8040 startProcessLocked(app, "added application", app.processName); 8041 } 8042 8043 return app; 8044 } 8045 8046 public void unhandledBack() { 8047 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8048 "unhandledBack()"); 8049 8050 synchronized(this) { 8051 final long origId = Binder.clearCallingIdentity(); 8052 try { 8053 getFocusedStack().unhandledBackLocked(); 8054 } finally { 8055 Binder.restoreCallingIdentity(origId); 8056 } 8057 } 8058 } 8059 8060 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8061 enforceNotIsolatedCaller("openContentUri"); 8062 final int userId = UserHandle.getCallingUserId(); 8063 String name = uri.getAuthority(); 8064 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8065 ParcelFileDescriptor pfd = null; 8066 if (cph != null) { 8067 // We record the binder invoker's uid in thread-local storage before 8068 // going to the content provider to open the file. Later, in the code 8069 // that handles all permissions checks, we look for this uid and use 8070 // that rather than the Activity Manager's own uid. The effect is that 8071 // we do the check against the caller's permissions even though it looks 8072 // to the content provider like the Activity Manager itself is making 8073 // the request. 8074 sCallerIdentity.set(new Identity( 8075 Binder.getCallingPid(), Binder.getCallingUid())); 8076 try { 8077 pfd = cph.provider.openFile(null, uri, "r", null); 8078 } catch (FileNotFoundException e) { 8079 // do nothing; pfd will be returned null 8080 } finally { 8081 // Ensure that whatever happens, we clean up the identity state 8082 sCallerIdentity.remove(); 8083 } 8084 8085 // We've got the fd now, so we're done with the provider. 8086 removeContentProviderExternalUnchecked(name, null, userId); 8087 } else { 8088 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8089 } 8090 return pfd; 8091 } 8092 8093 // Actually is sleeping or shutting down or whatever else in the future 8094 // is an inactive state. 8095 public boolean isSleepingOrShuttingDown() { 8096 return mSleeping || mShuttingDown; 8097 } 8098 8099 public void goingToSleep() { 8100 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8101 != PackageManager.PERMISSION_GRANTED) { 8102 throw new SecurityException("Requires permission " 8103 + android.Manifest.permission.DEVICE_POWER); 8104 } 8105 8106 synchronized(this) { 8107 mWentToSleep = true; 8108 updateEventDispatchingLocked(); 8109 8110 if (!mSleeping) { 8111 mSleeping = true; 8112 mStackSupervisor.goingToSleepLocked(); 8113 8114 // Initialize the wake times of all processes. 8115 checkExcessivePowerUsageLocked(false); 8116 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8117 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8118 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8119 } 8120 } 8121 } 8122 8123 @Override 8124 public boolean shutdown(int timeout) { 8125 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8126 != PackageManager.PERMISSION_GRANTED) { 8127 throw new SecurityException("Requires permission " 8128 + android.Manifest.permission.SHUTDOWN); 8129 } 8130 8131 boolean timedout = false; 8132 8133 synchronized(this) { 8134 mShuttingDown = true; 8135 updateEventDispatchingLocked(); 8136 timedout = mStackSupervisor.shutdownLocked(timeout); 8137 } 8138 8139 mAppOpsService.shutdown(); 8140 mUsageStatsService.shutdown(); 8141 mBatteryStatsService.shutdown(); 8142 synchronized (this) { 8143 mProcessStats.shutdownLocked(); 8144 } 8145 8146 return timedout; 8147 } 8148 8149 public final void activitySlept(IBinder token) { 8150 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8151 8152 final long origId = Binder.clearCallingIdentity(); 8153 8154 synchronized (this) { 8155 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8156 if (r != null) { 8157 mStackSupervisor.activitySleptLocked(r); 8158 } 8159 } 8160 8161 Binder.restoreCallingIdentity(origId); 8162 } 8163 8164 void logLockScreen(String msg) { 8165 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8166 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8167 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8168 mStackSupervisor.mDismissKeyguardOnNextActivity); 8169 } 8170 8171 private void comeOutOfSleepIfNeededLocked() { 8172 if (!mWentToSleep && !mLockScreenShown) { 8173 if (mSleeping) { 8174 mSleeping = false; 8175 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8176 } 8177 } 8178 } 8179 8180 public void wakingUp() { 8181 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8182 != PackageManager.PERMISSION_GRANTED) { 8183 throw new SecurityException("Requires permission " 8184 + android.Manifest.permission.DEVICE_POWER); 8185 } 8186 8187 synchronized(this) { 8188 mWentToSleep = false; 8189 updateEventDispatchingLocked(); 8190 comeOutOfSleepIfNeededLocked(); 8191 } 8192 } 8193 8194 private void updateEventDispatchingLocked() { 8195 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8196 } 8197 8198 public void setLockScreenShown(boolean shown) { 8199 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8200 != PackageManager.PERMISSION_GRANTED) { 8201 throw new SecurityException("Requires permission " 8202 + android.Manifest.permission.DEVICE_POWER); 8203 } 8204 8205 synchronized(this) { 8206 long ident = Binder.clearCallingIdentity(); 8207 try { 8208 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8209 mLockScreenShown = shown; 8210 comeOutOfSleepIfNeededLocked(); 8211 } finally { 8212 Binder.restoreCallingIdentity(ident); 8213 } 8214 } 8215 } 8216 8217 public void stopAppSwitches() { 8218 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8219 != PackageManager.PERMISSION_GRANTED) { 8220 throw new SecurityException("Requires permission " 8221 + android.Manifest.permission.STOP_APP_SWITCHES); 8222 } 8223 8224 synchronized(this) { 8225 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8226 + APP_SWITCH_DELAY_TIME; 8227 mDidAppSwitch = false; 8228 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8229 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8230 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8231 } 8232 } 8233 8234 public void resumeAppSwitches() { 8235 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8236 != PackageManager.PERMISSION_GRANTED) { 8237 throw new SecurityException("Requires permission " 8238 + android.Manifest.permission.STOP_APP_SWITCHES); 8239 } 8240 8241 synchronized(this) { 8242 // Note that we don't execute any pending app switches... we will 8243 // let those wait until either the timeout, or the next start 8244 // activity request. 8245 mAppSwitchesAllowedTime = 0; 8246 } 8247 } 8248 8249 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8250 String name) { 8251 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8252 return true; 8253 } 8254 8255 final int perm = checkComponentPermission( 8256 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8257 callingUid, -1, true); 8258 if (perm == PackageManager.PERMISSION_GRANTED) { 8259 return true; 8260 } 8261 8262 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8263 return false; 8264 } 8265 8266 public void setDebugApp(String packageName, boolean waitForDebugger, 8267 boolean persistent) { 8268 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8269 "setDebugApp()"); 8270 8271 long ident = Binder.clearCallingIdentity(); 8272 try { 8273 // Note that this is not really thread safe if there are multiple 8274 // callers into it at the same time, but that's not a situation we 8275 // care about. 8276 if (persistent) { 8277 final ContentResolver resolver = mContext.getContentResolver(); 8278 Settings.Global.putString( 8279 resolver, Settings.Global.DEBUG_APP, 8280 packageName); 8281 Settings.Global.putInt( 8282 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8283 waitForDebugger ? 1 : 0); 8284 } 8285 8286 synchronized (this) { 8287 if (!persistent) { 8288 mOrigDebugApp = mDebugApp; 8289 mOrigWaitForDebugger = mWaitForDebugger; 8290 } 8291 mDebugApp = packageName; 8292 mWaitForDebugger = waitForDebugger; 8293 mDebugTransient = !persistent; 8294 if (packageName != null) { 8295 forceStopPackageLocked(packageName, -1, false, false, true, true, 8296 UserHandle.USER_ALL, "set debug app"); 8297 } 8298 } 8299 } finally { 8300 Binder.restoreCallingIdentity(ident); 8301 } 8302 } 8303 8304 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8305 synchronized (this) { 8306 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8307 if (!isDebuggable) { 8308 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8309 throw new SecurityException("Process not debuggable: " + app.packageName); 8310 } 8311 } 8312 8313 mOpenGlTraceApp = processName; 8314 } 8315 } 8316 8317 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8318 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8319 synchronized (this) { 8320 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8321 if (!isDebuggable) { 8322 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8323 throw new SecurityException("Process not debuggable: " + app.packageName); 8324 } 8325 } 8326 mProfileApp = processName; 8327 mProfileFile = profileFile; 8328 if (mProfileFd != null) { 8329 try { 8330 mProfileFd.close(); 8331 } catch (IOException e) { 8332 } 8333 mProfileFd = null; 8334 } 8335 mProfileFd = profileFd; 8336 mProfileType = 0; 8337 mAutoStopProfiler = autoStopProfiler; 8338 } 8339 } 8340 8341 @Override 8342 public void setAlwaysFinish(boolean enabled) { 8343 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8344 "setAlwaysFinish()"); 8345 8346 Settings.Global.putInt( 8347 mContext.getContentResolver(), 8348 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8349 8350 synchronized (this) { 8351 mAlwaysFinishActivities = enabled; 8352 } 8353 } 8354 8355 @Override 8356 public void setActivityController(IActivityController controller) { 8357 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8358 "setActivityController()"); 8359 synchronized (this) { 8360 mController = controller; 8361 Watchdog.getInstance().setActivityController(controller); 8362 } 8363 } 8364 8365 @Override 8366 public void setUserIsMonkey(boolean userIsMonkey) { 8367 synchronized (this) { 8368 synchronized (mPidsSelfLocked) { 8369 final int callingPid = Binder.getCallingPid(); 8370 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8371 if (precessRecord == null) { 8372 throw new SecurityException("Unknown process: " + callingPid); 8373 } 8374 if (precessRecord.instrumentationUiAutomationConnection == null) { 8375 throw new SecurityException("Only an instrumentation process " 8376 + "with a UiAutomation can call setUserIsMonkey"); 8377 } 8378 } 8379 mUserIsMonkey = userIsMonkey; 8380 } 8381 } 8382 8383 @Override 8384 public boolean isUserAMonkey() { 8385 synchronized (this) { 8386 // If there is a controller also implies the user is a monkey. 8387 return (mUserIsMonkey || mController != null); 8388 } 8389 } 8390 8391 public void requestBugReport() { 8392 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8393 SystemProperties.set("ctl.start", "bugreport"); 8394 } 8395 8396 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8397 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8398 } 8399 8400 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8401 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8402 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8403 } 8404 return KEY_DISPATCHING_TIMEOUT; 8405 } 8406 8407 @Override 8408 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8409 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8410 != PackageManager.PERMISSION_GRANTED) { 8411 throw new SecurityException("Requires permission " 8412 + android.Manifest.permission.FILTER_EVENTS); 8413 } 8414 ProcessRecord proc; 8415 long timeout; 8416 synchronized (this) { 8417 synchronized (mPidsSelfLocked) { 8418 proc = mPidsSelfLocked.get(pid); 8419 } 8420 timeout = getInputDispatchingTimeoutLocked(proc); 8421 } 8422 8423 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8424 return -1; 8425 } 8426 8427 return timeout; 8428 } 8429 8430 /** 8431 * Handle input dispatching timeouts. 8432 * Returns whether input dispatching should be aborted or not. 8433 */ 8434 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8435 final ActivityRecord activity, final ActivityRecord parent, 8436 final boolean aboveSystem, String reason) { 8437 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8438 != PackageManager.PERMISSION_GRANTED) { 8439 throw new SecurityException("Requires permission " 8440 + android.Manifest.permission.FILTER_EVENTS); 8441 } 8442 8443 final String annotation; 8444 if (reason == null) { 8445 annotation = "Input dispatching timed out"; 8446 } else { 8447 annotation = "Input dispatching timed out (" + reason + ")"; 8448 } 8449 8450 if (proc != null) { 8451 synchronized (this) { 8452 if (proc.debugging) { 8453 return false; 8454 } 8455 8456 if (mDidDexOpt) { 8457 // Give more time since we were dexopting. 8458 mDidDexOpt = false; 8459 return false; 8460 } 8461 8462 if (proc.instrumentationClass != null) { 8463 Bundle info = new Bundle(); 8464 info.putString("shortMsg", "keyDispatchingTimedOut"); 8465 info.putString("longMsg", annotation); 8466 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8467 return true; 8468 } 8469 } 8470 mHandler.post(new Runnable() { 8471 @Override 8472 public void run() { 8473 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8474 } 8475 }); 8476 } 8477 8478 return true; 8479 } 8480 8481 public Bundle getAssistContextExtras(int requestType) { 8482 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8483 "getAssistContextExtras()"); 8484 PendingAssistExtras pae; 8485 Bundle extras = new Bundle(); 8486 synchronized (this) { 8487 ActivityRecord activity = getFocusedStack().mResumedActivity; 8488 if (activity == null) { 8489 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8490 return null; 8491 } 8492 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8493 if (activity.app == null || activity.app.thread == null) { 8494 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8495 return extras; 8496 } 8497 if (activity.app.pid == Binder.getCallingPid()) { 8498 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8499 return extras; 8500 } 8501 pae = new PendingAssistExtras(activity); 8502 try { 8503 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8504 requestType); 8505 mPendingAssistExtras.add(pae); 8506 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8507 } catch (RemoteException e) { 8508 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8509 return extras; 8510 } 8511 } 8512 synchronized (pae) { 8513 while (!pae.haveResult) { 8514 try { 8515 pae.wait(); 8516 } catch (InterruptedException e) { 8517 } 8518 } 8519 if (pae.result != null) { 8520 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8521 } 8522 } 8523 synchronized (this) { 8524 mPendingAssistExtras.remove(pae); 8525 mHandler.removeCallbacks(pae); 8526 } 8527 return extras; 8528 } 8529 8530 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8531 PendingAssistExtras pae = (PendingAssistExtras)token; 8532 synchronized (pae) { 8533 pae.result = extras; 8534 pae.haveResult = true; 8535 pae.notifyAll(); 8536 } 8537 } 8538 8539 public void registerProcessObserver(IProcessObserver observer) { 8540 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8541 "registerProcessObserver()"); 8542 synchronized (this) { 8543 mProcessObservers.register(observer); 8544 } 8545 } 8546 8547 @Override 8548 public void unregisterProcessObserver(IProcessObserver observer) { 8549 synchronized (this) { 8550 mProcessObservers.unregister(observer); 8551 } 8552 } 8553 8554 @Override 8555 public boolean convertFromTranslucent(IBinder token) { 8556 final long origId = Binder.clearCallingIdentity(); 8557 try { 8558 synchronized (this) { 8559 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8560 if (r == null) { 8561 return false; 8562 } 8563 if (r.changeWindowTranslucency(true)) { 8564 mWindowManager.setAppFullscreen(token, true); 8565 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8566 return true; 8567 } 8568 return false; 8569 } 8570 } finally { 8571 Binder.restoreCallingIdentity(origId); 8572 } 8573 } 8574 8575 @Override 8576 public boolean convertToTranslucent(IBinder token) { 8577 final long origId = Binder.clearCallingIdentity(); 8578 try { 8579 synchronized (this) { 8580 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8581 if (r == null) { 8582 return false; 8583 } 8584 if (r.changeWindowTranslucency(false)) { 8585 r.task.stack.convertToTranslucent(r); 8586 mWindowManager.setAppFullscreen(token, false); 8587 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8588 return true; 8589 } 8590 return false; 8591 } 8592 } finally { 8593 Binder.restoreCallingIdentity(origId); 8594 } 8595 } 8596 8597 @Override 8598 public void setImmersive(IBinder token, boolean immersive) { 8599 synchronized(this) { 8600 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8601 if (r == null) { 8602 throw new IllegalArgumentException(); 8603 } 8604 r.immersive = immersive; 8605 8606 // update associated state if we're frontmost 8607 if (r == mFocusedActivity) { 8608 if (DEBUG_IMMERSIVE) { 8609 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8610 } 8611 applyUpdateLockStateLocked(r); 8612 } 8613 } 8614 } 8615 8616 @Override 8617 public boolean isImmersive(IBinder token) { 8618 synchronized (this) { 8619 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8620 if (r == null) { 8621 throw new IllegalArgumentException(); 8622 } 8623 return r.immersive; 8624 } 8625 } 8626 8627 public boolean isTopActivityImmersive() { 8628 enforceNotIsolatedCaller("startActivity"); 8629 synchronized (this) { 8630 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8631 return (r != null) ? r.immersive : false; 8632 } 8633 } 8634 8635 public final void enterSafeMode() { 8636 synchronized(this) { 8637 // It only makes sense to do this before the system is ready 8638 // and started launching other packages. 8639 if (!mSystemReady) { 8640 try { 8641 AppGlobals.getPackageManager().enterSafeMode(); 8642 } catch (RemoteException e) { 8643 } 8644 } 8645 } 8646 } 8647 8648 public final void showSafeModeOverlay() { 8649 View v = LayoutInflater.from(mContext).inflate( 8650 com.android.internal.R.layout.safe_mode, null); 8651 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8652 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8653 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8654 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8655 lp.gravity = Gravity.BOTTOM | Gravity.START; 8656 lp.format = v.getBackground().getOpacity(); 8657 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8658 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8659 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8660 ((WindowManager)mContext.getSystemService( 8661 Context.WINDOW_SERVICE)).addView(v, lp); 8662 } 8663 8664 public void noteWakeupAlarm(IIntentSender sender) { 8665 if (!(sender instanceof PendingIntentRecord)) { 8666 return; 8667 } 8668 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8669 synchronized (stats) { 8670 if (mBatteryStatsService.isOnBattery()) { 8671 mBatteryStatsService.enforceCallingPermission(); 8672 PendingIntentRecord rec = (PendingIntentRecord)sender; 8673 int MY_UID = Binder.getCallingUid(); 8674 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8675 BatteryStatsImpl.Uid.Pkg pkg = 8676 stats.getPackageStatsLocked(uid, rec.key.packageName); 8677 pkg.incWakeupsLocked(); 8678 } 8679 } 8680 } 8681 8682 public boolean killPids(int[] pids, String pReason, boolean secure) { 8683 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8684 throw new SecurityException("killPids only available to the system"); 8685 } 8686 String reason = (pReason == null) ? "Unknown" : pReason; 8687 // XXX Note: don't acquire main activity lock here, because the window 8688 // manager calls in with its locks held. 8689 8690 boolean killed = false; 8691 synchronized (mPidsSelfLocked) { 8692 int[] types = new int[pids.length]; 8693 int worstType = 0; 8694 for (int i=0; i<pids.length; i++) { 8695 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8696 if (proc != null) { 8697 int type = proc.setAdj; 8698 types[i] = type; 8699 if (type > worstType) { 8700 worstType = type; 8701 } 8702 } 8703 } 8704 8705 // If the worst oom_adj is somewhere in the cached proc LRU range, 8706 // then constrain it so we will kill all cached procs. 8707 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8708 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8709 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8710 } 8711 8712 // If this is not a secure call, don't let it kill processes that 8713 // are important. 8714 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8715 worstType = ProcessList.SERVICE_ADJ; 8716 } 8717 8718 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8719 for (int i=0; i<pids.length; i++) { 8720 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8721 if (proc == null) { 8722 continue; 8723 } 8724 int adj = proc.setAdj; 8725 if (adj >= worstType && !proc.killedByAm) { 8726 killUnneededProcessLocked(proc, reason); 8727 killed = true; 8728 } 8729 } 8730 } 8731 return killed; 8732 } 8733 8734 @Override 8735 public void killUid(int uid, String reason) { 8736 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8737 throw new SecurityException("killUid only available to the system"); 8738 } 8739 synchronized (this) { 8740 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8741 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8742 reason != null ? reason : "kill uid"); 8743 } 8744 } 8745 8746 @Override 8747 public boolean killProcessesBelowForeground(String reason) { 8748 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8749 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8750 } 8751 8752 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8753 } 8754 8755 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8756 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8757 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8758 } 8759 8760 boolean killed = false; 8761 synchronized (mPidsSelfLocked) { 8762 final int size = mPidsSelfLocked.size(); 8763 for (int i = 0; i < size; i++) { 8764 final int pid = mPidsSelfLocked.keyAt(i); 8765 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8766 if (proc == null) continue; 8767 8768 final int adj = proc.setAdj; 8769 if (adj > belowAdj && !proc.killedByAm) { 8770 killUnneededProcessLocked(proc, reason); 8771 killed = true; 8772 } 8773 } 8774 } 8775 return killed; 8776 } 8777 8778 @Override 8779 public void hang(final IBinder who, boolean allowRestart) { 8780 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8781 != PackageManager.PERMISSION_GRANTED) { 8782 throw new SecurityException("Requires permission " 8783 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8784 } 8785 8786 final IBinder.DeathRecipient death = new DeathRecipient() { 8787 @Override 8788 public void binderDied() { 8789 synchronized (this) { 8790 notifyAll(); 8791 } 8792 } 8793 }; 8794 8795 try { 8796 who.linkToDeath(death, 0); 8797 } catch (RemoteException e) { 8798 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8799 return; 8800 } 8801 8802 synchronized (this) { 8803 Watchdog.getInstance().setAllowRestart(allowRestart); 8804 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8805 synchronized (death) { 8806 while (who.isBinderAlive()) { 8807 try { 8808 death.wait(); 8809 } catch (InterruptedException e) { 8810 } 8811 } 8812 } 8813 Watchdog.getInstance().setAllowRestart(true); 8814 } 8815 } 8816 8817 @Override 8818 public void restart() { 8819 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8820 != PackageManager.PERMISSION_GRANTED) { 8821 throw new SecurityException("Requires permission " 8822 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8823 } 8824 8825 Log.i(TAG, "Sending shutdown broadcast..."); 8826 8827 BroadcastReceiver br = new BroadcastReceiver() { 8828 @Override public void onReceive(Context context, Intent intent) { 8829 // Now the broadcast is done, finish up the low-level shutdown. 8830 Log.i(TAG, "Shutting down activity manager..."); 8831 shutdown(10000); 8832 Log.i(TAG, "Shutdown complete, restarting!"); 8833 Process.killProcess(Process.myPid()); 8834 System.exit(10); 8835 } 8836 }; 8837 8838 // First send the high-level shut down broadcast. 8839 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8840 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8841 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8842 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8843 mContext.sendOrderedBroadcastAsUser(intent, 8844 UserHandle.ALL, null, br, mHandler, 0, null, null); 8845 */ 8846 br.onReceive(mContext, intent); 8847 } 8848 8849 private long getLowRamTimeSinceIdle(long now) { 8850 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 8851 } 8852 8853 @Override 8854 public void performIdleMaintenance() { 8855 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8856 != PackageManager.PERMISSION_GRANTED) { 8857 throw new SecurityException("Requires permission " 8858 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8859 } 8860 8861 synchronized (this) { 8862 final long now = SystemClock.uptimeMillis(); 8863 final long timeSinceLastIdle = now - mLastIdleTime; 8864 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 8865 mLastIdleTime = now; 8866 mLowRamTimeSinceLastIdle = 0; 8867 if (mLowRamStartTime != 0) { 8868 mLowRamStartTime = now; 8869 } 8870 8871 StringBuilder sb = new StringBuilder(128); 8872 sb.append("Idle maintenance over "); 8873 TimeUtils.formatDuration(timeSinceLastIdle, sb); 8874 sb.append(" low RAM for "); 8875 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 8876 Slog.i(TAG, sb.toString()); 8877 8878 // If at least 1/3 of our time since the last idle period has been spent 8879 // with RAM low, then we want to kill processes. 8880 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 8881 8882 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 8883 ProcessRecord proc = mLruProcesses.get(i); 8884 if (proc.notCachedSinceIdle) { 8885 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 8886 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 8887 if (doKilling && proc.initialIdlePss != 0 8888 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 8889 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 8890 + " from " + proc.initialIdlePss + ")"); 8891 } 8892 } 8893 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 8894 proc.notCachedSinceIdle = true; 8895 proc.initialIdlePss = 0; 8896 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 8897 mSleeping, now); 8898 } 8899 } 8900 8901 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 8902 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 8903 } 8904 } 8905 8906 public final void startRunning(String pkg, String cls, String action, 8907 String data) { 8908 synchronized(this) { 8909 if (mStartRunning) { 8910 return; 8911 } 8912 mStartRunning = true; 8913 mTopComponent = pkg != null && cls != null 8914 ? new ComponentName(pkg, cls) : null; 8915 mTopAction = action != null ? action : Intent.ACTION_MAIN; 8916 mTopData = data; 8917 if (!mSystemReady) { 8918 return; 8919 } 8920 } 8921 8922 systemReady(null); 8923 } 8924 8925 private void retrieveSettings() { 8926 final ContentResolver resolver = mContext.getContentResolver(); 8927 String debugApp = Settings.Global.getString( 8928 resolver, Settings.Global.DEBUG_APP); 8929 boolean waitForDebugger = Settings.Global.getInt( 8930 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 8931 boolean alwaysFinishActivities = Settings.Global.getInt( 8932 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8933 boolean forceRtl = Settings.Global.getInt( 8934 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 8935 // Transfer any global setting for forcing RTL layout, into a System Property 8936 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 8937 8938 Configuration configuration = new Configuration(); 8939 Settings.System.getConfiguration(resolver, configuration); 8940 if (forceRtl) { 8941 // This will take care of setting the correct layout direction flags 8942 configuration.setLayoutDirection(configuration.locale); 8943 } 8944 8945 synchronized (this) { 8946 mDebugApp = mOrigDebugApp = debugApp; 8947 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8948 mAlwaysFinishActivities = alwaysFinishActivities; 8949 // This happens before any activities are started, so we can 8950 // change mConfiguration in-place. 8951 updateConfigurationLocked(configuration, null, false, true); 8952 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 8953 } 8954 } 8955 8956 public boolean testIsSystemReady() { 8957 // no need to synchronize(this) just to read & return the value 8958 return mSystemReady; 8959 } 8960 8961 private static File getCalledPreBootReceiversFile() { 8962 File dataDir = Environment.getDataDirectory(); 8963 File systemDir = new File(dataDir, "system"); 8964 File fname = new File(systemDir, "called_pre_boots.dat"); 8965 return fname; 8966 } 8967 8968 static final int LAST_DONE_VERSION = 10000; 8969 8970 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 8971 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 8972 File file = getCalledPreBootReceiversFile(); 8973 FileInputStream fis = null; 8974 try { 8975 fis = new FileInputStream(file); 8976 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 8977 int fvers = dis.readInt(); 8978 if (fvers == LAST_DONE_VERSION) { 8979 String vers = dis.readUTF(); 8980 String codename = dis.readUTF(); 8981 String build = dis.readUTF(); 8982 if (android.os.Build.VERSION.RELEASE.equals(vers) 8983 && android.os.Build.VERSION.CODENAME.equals(codename) 8984 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 8985 int num = dis.readInt(); 8986 while (num > 0) { 8987 num--; 8988 String pkg = dis.readUTF(); 8989 String cls = dis.readUTF(); 8990 lastDoneReceivers.add(new ComponentName(pkg, cls)); 8991 } 8992 } 8993 } 8994 } catch (FileNotFoundException e) { 8995 } catch (IOException e) { 8996 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 8997 } finally { 8998 if (fis != null) { 8999 try { 9000 fis.close(); 9001 } catch (IOException e) { 9002 } 9003 } 9004 } 9005 return lastDoneReceivers; 9006 } 9007 9008 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9009 File file = getCalledPreBootReceiversFile(); 9010 FileOutputStream fos = null; 9011 DataOutputStream dos = null; 9012 try { 9013 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9014 fos = new FileOutputStream(file); 9015 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9016 dos.writeInt(LAST_DONE_VERSION); 9017 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9018 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9019 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9020 dos.writeInt(list.size()); 9021 for (int i=0; i<list.size(); i++) { 9022 dos.writeUTF(list.get(i).getPackageName()); 9023 dos.writeUTF(list.get(i).getClassName()); 9024 } 9025 } catch (IOException e) { 9026 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9027 file.delete(); 9028 } finally { 9029 FileUtils.sync(fos); 9030 if (dos != null) { 9031 try { 9032 dos.close(); 9033 } catch (IOException e) { 9034 // TODO Auto-generated catch block 9035 e.printStackTrace(); 9036 } 9037 } 9038 } 9039 } 9040 9041 public void systemReady(final Runnable goingCallback) { 9042 synchronized(this) { 9043 if (mSystemReady) { 9044 if (goingCallback != null) goingCallback.run(); 9045 return; 9046 } 9047 9048 // Check to see if there are any update receivers to run. 9049 if (!mDidUpdate) { 9050 if (mWaitingUpdate) { 9051 return; 9052 } 9053 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9054 List<ResolveInfo> ris = null; 9055 try { 9056 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9057 intent, null, 0, 0); 9058 } catch (RemoteException e) { 9059 } 9060 if (ris != null) { 9061 for (int i=ris.size()-1; i>=0; i--) { 9062 if ((ris.get(i).activityInfo.applicationInfo.flags 9063 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9064 ris.remove(i); 9065 } 9066 } 9067 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9068 9069 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9070 9071 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9072 for (int i=0; i<ris.size(); i++) { 9073 ActivityInfo ai = ris.get(i).activityInfo; 9074 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9075 if (lastDoneReceivers.contains(comp)) { 9076 ris.remove(i); 9077 i--; 9078 } 9079 } 9080 9081 final int[] users = getUsersLocked(); 9082 for (int i=0; i<ris.size(); i++) { 9083 ActivityInfo ai = ris.get(i).activityInfo; 9084 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9085 doneReceivers.add(comp); 9086 intent.setComponent(comp); 9087 for (int j=0; j<users.length; j++) { 9088 IIntentReceiver finisher = null; 9089 if (i == ris.size()-1 && j == users.length-1) { 9090 finisher = new IIntentReceiver.Stub() { 9091 public void performReceive(Intent intent, int resultCode, 9092 String data, Bundle extras, boolean ordered, 9093 boolean sticky, int sendingUser) { 9094 // The raw IIntentReceiver interface is called 9095 // with the AM lock held, so redispatch to 9096 // execute our code without the lock. 9097 mHandler.post(new Runnable() { 9098 public void run() { 9099 synchronized (ActivityManagerService.this) { 9100 mDidUpdate = true; 9101 } 9102 writeLastDonePreBootReceivers(doneReceivers); 9103 showBootMessage(mContext.getText( 9104 R.string.android_upgrading_complete), 9105 false); 9106 systemReady(goingCallback); 9107 } 9108 }); 9109 } 9110 }; 9111 } 9112 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9113 + " for user " + users[j]); 9114 broadcastIntentLocked(null, null, intent, null, finisher, 9115 0, null, null, null, AppOpsManager.OP_NONE, 9116 true, false, MY_PID, Process.SYSTEM_UID, 9117 users[j]); 9118 if (finisher != null) { 9119 mWaitingUpdate = true; 9120 } 9121 } 9122 } 9123 } 9124 if (mWaitingUpdate) { 9125 return; 9126 } 9127 mDidUpdate = true; 9128 } 9129 9130 mAppOpsService.systemReady(); 9131 mSystemReady = true; 9132 if (!mStartRunning) { 9133 return; 9134 } 9135 } 9136 9137 ArrayList<ProcessRecord> procsToKill = null; 9138 synchronized(mPidsSelfLocked) { 9139 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9140 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9141 if (!isAllowedWhileBooting(proc.info)){ 9142 if (procsToKill == null) { 9143 procsToKill = new ArrayList<ProcessRecord>(); 9144 } 9145 procsToKill.add(proc); 9146 } 9147 } 9148 } 9149 9150 synchronized(this) { 9151 if (procsToKill != null) { 9152 for (int i=procsToKill.size()-1; i>=0; i--) { 9153 ProcessRecord proc = procsToKill.get(i); 9154 Slog.i(TAG, "Removing system update proc: " + proc); 9155 removeProcessLocked(proc, true, false, "system update done"); 9156 } 9157 } 9158 9159 // Now that we have cleaned up any update processes, we 9160 // are ready to start launching real processes and know that 9161 // we won't trample on them any more. 9162 mProcessesReady = true; 9163 } 9164 9165 Slog.i(TAG, "System now ready"); 9166 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9167 SystemClock.uptimeMillis()); 9168 9169 synchronized(this) { 9170 // Make sure we have no pre-ready processes sitting around. 9171 9172 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 9173 ResolveInfo ri = mContext.getPackageManager() 9174 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9175 STOCK_PM_FLAGS); 9176 CharSequence errorMsg = null; 9177 if (ri != null) { 9178 ActivityInfo ai = ri.activityInfo; 9179 ApplicationInfo app = ai.applicationInfo; 9180 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9181 mTopAction = Intent.ACTION_FACTORY_TEST; 9182 mTopData = null; 9183 mTopComponent = new ComponentName(app.packageName, 9184 ai.name); 9185 } else { 9186 errorMsg = mContext.getResources().getText( 9187 com.android.internal.R.string.factorytest_not_system); 9188 } 9189 } else { 9190 errorMsg = mContext.getResources().getText( 9191 com.android.internal.R.string.factorytest_no_action); 9192 } 9193 if (errorMsg != null) { 9194 mTopAction = null; 9195 mTopData = null; 9196 mTopComponent = null; 9197 Message msg = Message.obtain(); 9198 msg.what = SHOW_FACTORY_ERROR_MSG; 9199 msg.getData().putCharSequence("msg", errorMsg); 9200 mHandler.sendMessage(msg); 9201 } 9202 } 9203 } 9204 9205 retrieveSettings(); 9206 9207 synchronized (this) { 9208 readGrantedUriPermissionsLocked(); 9209 } 9210 9211 if (goingCallback != null) goingCallback.run(); 9212 9213 synchronized (this) { 9214 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 9215 try { 9216 List apps = AppGlobals.getPackageManager(). 9217 getPersistentApplications(STOCK_PM_FLAGS); 9218 if (apps != null) { 9219 int N = apps.size(); 9220 int i; 9221 for (i=0; i<N; i++) { 9222 ApplicationInfo info 9223 = (ApplicationInfo)apps.get(i); 9224 if (info != null && 9225 !info.packageName.equals("android")) { 9226 addAppLocked(info, false); 9227 } 9228 } 9229 } 9230 } catch (RemoteException ex) { 9231 // pm is in same process, this will never happen. 9232 } 9233 } 9234 9235 // Start up initial activity. 9236 mBooting = true; 9237 9238 try { 9239 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9240 Message msg = Message.obtain(); 9241 msg.what = SHOW_UID_ERROR_MSG; 9242 mHandler.sendMessage(msg); 9243 } 9244 } catch (RemoteException e) { 9245 } 9246 9247 long ident = Binder.clearCallingIdentity(); 9248 try { 9249 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9250 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9251 | Intent.FLAG_RECEIVER_FOREGROUND); 9252 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9253 broadcastIntentLocked(null, null, intent, 9254 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9255 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9256 intent = new Intent(Intent.ACTION_USER_STARTING); 9257 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9258 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9259 broadcastIntentLocked(null, null, intent, 9260 null, new IIntentReceiver.Stub() { 9261 @Override 9262 public void performReceive(Intent intent, int resultCode, String data, 9263 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9264 throws RemoteException { 9265 } 9266 }, 0, null, null, 9267 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9268 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9269 } finally { 9270 Binder.restoreCallingIdentity(ident); 9271 } 9272 mStackSupervisor.resumeTopActivitiesLocked(); 9273 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9274 } 9275 } 9276 9277 private boolean makeAppCrashingLocked(ProcessRecord app, 9278 String shortMsg, String longMsg, String stackTrace) { 9279 app.crashing = true; 9280 app.crashingReport = generateProcessError(app, 9281 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9282 startAppProblemLocked(app); 9283 app.stopFreezingAllLocked(); 9284 return handleAppCrashLocked(app); 9285 } 9286 9287 private void makeAppNotRespondingLocked(ProcessRecord app, 9288 String activity, String shortMsg, String longMsg) { 9289 app.notResponding = true; 9290 app.notRespondingReport = generateProcessError(app, 9291 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9292 activity, shortMsg, longMsg, null); 9293 startAppProblemLocked(app); 9294 app.stopFreezingAllLocked(); 9295 } 9296 9297 /** 9298 * Generate a process error record, suitable for attachment to a ProcessRecord. 9299 * 9300 * @param app The ProcessRecord in which the error occurred. 9301 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9302 * ActivityManager.AppErrorStateInfo 9303 * @param activity The activity associated with the crash, if known. 9304 * @param shortMsg Short message describing the crash. 9305 * @param longMsg Long message describing the crash. 9306 * @param stackTrace Full crash stack trace, may be null. 9307 * 9308 * @return Returns a fully-formed AppErrorStateInfo record. 9309 */ 9310 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9311 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9312 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9313 9314 report.condition = condition; 9315 report.processName = app.processName; 9316 report.pid = app.pid; 9317 report.uid = app.info.uid; 9318 report.tag = activity; 9319 report.shortMsg = shortMsg; 9320 report.longMsg = longMsg; 9321 report.stackTrace = stackTrace; 9322 9323 return report; 9324 } 9325 9326 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9327 synchronized (this) { 9328 app.crashing = false; 9329 app.crashingReport = null; 9330 app.notResponding = false; 9331 app.notRespondingReport = null; 9332 if (app.anrDialog == fromDialog) { 9333 app.anrDialog = null; 9334 } 9335 if (app.waitDialog == fromDialog) { 9336 app.waitDialog = null; 9337 } 9338 if (app.pid > 0 && app.pid != MY_PID) { 9339 handleAppCrashLocked(app); 9340 killUnneededProcessLocked(app, "user request after error"); 9341 } 9342 } 9343 } 9344 9345 private boolean handleAppCrashLocked(ProcessRecord app) { 9346 if (mHeadless) { 9347 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 9348 return false; 9349 } 9350 long now = SystemClock.uptimeMillis(); 9351 9352 Long crashTime; 9353 if (!app.isolated) { 9354 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9355 } else { 9356 crashTime = null; 9357 } 9358 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9359 // This process loses! 9360 Slog.w(TAG, "Process " + app.info.processName 9361 + " has crashed too many times: killing!"); 9362 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9363 app.userId, app.info.processName, app.uid); 9364 mStackSupervisor.handleAppCrashLocked(app); 9365 if (!app.persistent) { 9366 // We don't want to start this process again until the user 9367 // explicitly does so... but for persistent process, we really 9368 // need to keep it running. If a persistent process is actually 9369 // repeatedly crashing, then badness for everyone. 9370 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9371 app.info.processName); 9372 if (!app.isolated) { 9373 // XXX We don't have a way to mark isolated processes 9374 // as bad, since they don't have a peristent identity. 9375 mBadProcesses.put(app.info.processName, app.uid, now); 9376 mProcessCrashTimes.remove(app.info.processName, app.uid); 9377 } 9378 app.bad = true; 9379 app.removed = true; 9380 // Don't let services in this process be restarted and potentially 9381 // annoy the user repeatedly. Unless it is persistent, since those 9382 // processes run critical code. 9383 removeProcessLocked(app, false, false, "crash"); 9384 mStackSupervisor.resumeTopActivitiesLocked(); 9385 return false; 9386 } 9387 mStackSupervisor.resumeTopActivitiesLocked(); 9388 } else { 9389 mStackSupervisor.finishTopRunningActivityLocked(app); 9390 } 9391 9392 // Bump up the crash count of any services currently running in the proc. 9393 for (int i=app.services.size()-1; i>=0; i--) { 9394 // Any services running in the application need to be placed 9395 // back in the pending list. 9396 ServiceRecord sr = app.services.valueAt(i); 9397 sr.crashCount++; 9398 } 9399 9400 // If the crashing process is what we consider to be the "home process" and it has been 9401 // replaced by a third-party app, clear the package preferred activities from packages 9402 // with a home activity running in the process to prevent a repeatedly crashing app 9403 // from blocking the user to manually clear the list. 9404 final ArrayList<ActivityRecord> activities = app.activities; 9405 if (app == mHomeProcess && activities.size() > 0 9406 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9407 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9408 final ActivityRecord r = activities.get(activityNdx); 9409 if (r.isHomeActivity()) { 9410 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9411 try { 9412 ActivityThread.getPackageManager() 9413 .clearPackagePreferredActivities(r.packageName); 9414 } catch (RemoteException c) { 9415 // pm is in same process, this will never happen. 9416 } 9417 } 9418 } 9419 } 9420 9421 if (!app.isolated) { 9422 // XXX Can't keep track of crash times for isolated processes, 9423 // because they don't have a perisistent identity. 9424 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9425 } 9426 9427 return true; 9428 } 9429 9430 void startAppProblemLocked(ProcessRecord app) { 9431 if (app.userId == mCurrentUserId) { 9432 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9433 mContext, app.info.packageName, app.info.flags); 9434 } else { 9435 // If this app is not running under the current user, then we 9436 // can't give it a report button because that would require 9437 // launching the report UI under a different user. 9438 app.errorReportReceiver = null; 9439 } 9440 skipCurrentReceiverLocked(app); 9441 } 9442 9443 void skipCurrentReceiverLocked(ProcessRecord app) { 9444 for (BroadcastQueue queue : mBroadcastQueues) { 9445 queue.skipCurrentReceiverLocked(app); 9446 } 9447 } 9448 9449 /** 9450 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9451 * The application process will exit immediately after this call returns. 9452 * @param app object of the crashing app, null for the system server 9453 * @param crashInfo describing the exception 9454 */ 9455 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9456 ProcessRecord r = findAppProcess(app, "Crash"); 9457 final String processName = app == null ? "system_server" 9458 : (r == null ? "unknown" : r.processName); 9459 9460 handleApplicationCrashInner("crash", r, processName, crashInfo); 9461 } 9462 9463 /* Native crash reporting uses this inner version because it needs to be somewhat 9464 * decoupled from the AM-managed cleanup lifecycle 9465 */ 9466 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9467 ApplicationErrorReport.CrashInfo crashInfo) { 9468 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9469 UserHandle.getUserId(Binder.getCallingUid()), processName, 9470 r == null ? -1 : r.info.flags, 9471 crashInfo.exceptionClassName, 9472 crashInfo.exceptionMessage, 9473 crashInfo.throwFileName, 9474 crashInfo.throwLineNumber); 9475 9476 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9477 9478 crashApplication(r, crashInfo); 9479 } 9480 9481 public void handleApplicationStrictModeViolation( 9482 IBinder app, 9483 int violationMask, 9484 StrictMode.ViolationInfo info) { 9485 ProcessRecord r = findAppProcess(app, "StrictMode"); 9486 if (r == null) { 9487 return; 9488 } 9489 9490 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9491 Integer stackFingerprint = info.hashCode(); 9492 boolean logIt = true; 9493 synchronized (mAlreadyLoggedViolatedStacks) { 9494 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9495 logIt = false; 9496 // TODO: sub-sample into EventLog for these, with 9497 // the info.durationMillis? Then we'd get 9498 // the relative pain numbers, without logging all 9499 // the stack traces repeatedly. We'd want to do 9500 // likewise in the client code, which also does 9501 // dup suppression, before the Binder call. 9502 } else { 9503 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9504 mAlreadyLoggedViolatedStacks.clear(); 9505 } 9506 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9507 } 9508 } 9509 if (logIt) { 9510 logStrictModeViolationToDropBox(r, info); 9511 } 9512 } 9513 9514 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9515 AppErrorResult result = new AppErrorResult(); 9516 synchronized (this) { 9517 final long origId = Binder.clearCallingIdentity(); 9518 9519 Message msg = Message.obtain(); 9520 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9521 HashMap<String, Object> data = new HashMap<String, Object>(); 9522 data.put("result", result); 9523 data.put("app", r); 9524 data.put("violationMask", violationMask); 9525 data.put("info", info); 9526 msg.obj = data; 9527 mHandler.sendMessage(msg); 9528 9529 Binder.restoreCallingIdentity(origId); 9530 } 9531 int res = result.get(); 9532 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9533 } 9534 } 9535 9536 // Depending on the policy in effect, there could be a bunch of 9537 // these in quick succession so we try to batch these together to 9538 // minimize disk writes, number of dropbox entries, and maximize 9539 // compression, by having more fewer, larger records. 9540 private void logStrictModeViolationToDropBox( 9541 ProcessRecord process, 9542 StrictMode.ViolationInfo info) { 9543 if (info == null) { 9544 return; 9545 } 9546 final boolean isSystemApp = process == null || 9547 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9548 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9549 final String processName = process == null ? "unknown" : process.processName; 9550 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9551 final DropBoxManager dbox = (DropBoxManager) 9552 mContext.getSystemService(Context.DROPBOX_SERVICE); 9553 9554 // Exit early if the dropbox isn't configured to accept this report type. 9555 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9556 9557 boolean bufferWasEmpty; 9558 boolean needsFlush; 9559 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9560 synchronized (sb) { 9561 bufferWasEmpty = sb.length() == 0; 9562 appendDropBoxProcessHeaders(process, processName, sb); 9563 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9564 sb.append("System-App: ").append(isSystemApp).append("\n"); 9565 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9566 if (info.violationNumThisLoop != 0) { 9567 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9568 } 9569 if (info.numAnimationsRunning != 0) { 9570 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9571 } 9572 if (info.broadcastIntentAction != null) { 9573 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9574 } 9575 if (info.durationMillis != -1) { 9576 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9577 } 9578 if (info.numInstances != -1) { 9579 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9580 } 9581 if (info.tags != null) { 9582 for (String tag : info.tags) { 9583 sb.append("Span-Tag: ").append(tag).append("\n"); 9584 } 9585 } 9586 sb.append("\n"); 9587 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9588 sb.append(info.crashInfo.stackTrace); 9589 } 9590 sb.append("\n"); 9591 9592 // Only buffer up to ~64k. Various logging bits truncate 9593 // things at 128k. 9594 needsFlush = (sb.length() > 64 * 1024); 9595 } 9596 9597 // Flush immediately if the buffer's grown too large, or this 9598 // is a non-system app. Non-system apps are isolated with a 9599 // different tag & policy and not batched. 9600 // 9601 // Batching is useful during internal testing with 9602 // StrictMode settings turned up high. Without batching, 9603 // thousands of separate files could be created on boot. 9604 if (!isSystemApp || needsFlush) { 9605 new Thread("Error dump: " + dropboxTag) { 9606 @Override 9607 public void run() { 9608 String report; 9609 synchronized (sb) { 9610 report = sb.toString(); 9611 sb.delete(0, sb.length()); 9612 sb.trimToSize(); 9613 } 9614 if (report.length() != 0) { 9615 dbox.addText(dropboxTag, report); 9616 } 9617 } 9618 }.start(); 9619 return; 9620 } 9621 9622 // System app batching: 9623 if (!bufferWasEmpty) { 9624 // An existing dropbox-writing thread is outstanding, so 9625 // we don't need to start it up. The existing thread will 9626 // catch the buffer appends we just did. 9627 return; 9628 } 9629 9630 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9631 // (After this point, we shouldn't access AMS internal data structures.) 9632 new Thread("Error dump: " + dropboxTag) { 9633 @Override 9634 public void run() { 9635 // 5 second sleep to let stacks arrive and be batched together 9636 try { 9637 Thread.sleep(5000); // 5 seconds 9638 } catch (InterruptedException e) {} 9639 9640 String errorReport; 9641 synchronized (mStrictModeBuffer) { 9642 errorReport = mStrictModeBuffer.toString(); 9643 if (errorReport.length() == 0) { 9644 return; 9645 } 9646 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9647 mStrictModeBuffer.trimToSize(); 9648 } 9649 dbox.addText(dropboxTag, errorReport); 9650 } 9651 }.start(); 9652 } 9653 9654 /** 9655 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9656 * @param app object of the crashing app, null for the system server 9657 * @param tag reported by the caller 9658 * @param crashInfo describing the context of the error 9659 * @return true if the process should exit immediately (WTF is fatal) 9660 */ 9661 public boolean handleApplicationWtf(IBinder app, String tag, 9662 ApplicationErrorReport.CrashInfo crashInfo) { 9663 ProcessRecord r = findAppProcess(app, "WTF"); 9664 final String processName = app == null ? "system_server" 9665 : (r == null ? "unknown" : r.processName); 9666 9667 EventLog.writeEvent(EventLogTags.AM_WTF, 9668 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9669 processName, 9670 r == null ? -1 : r.info.flags, 9671 tag, crashInfo.exceptionMessage); 9672 9673 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9674 9675 if (r != null && r.pid != Process.myPid() && 9676 Settings.Global.getInt(mContext.getContentResolver(), 9677 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9678 crashApplication(r, crashInfo); 9679 return true; 9680 } else { 9681 return false; 9682 } 9683 } 9684 9685 /** 9686 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9687 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9688 */ 9689 private ProcessRecord findAppProcess(IBinder app, String reason) { 9690 if (app == null) { 9691 return null; 9692 } 9693 9694 synchronized (this) { 9695 final int NP = mProcessNames.getMap().size(); 9696 for (int ip=0; ip<NP; ip++) { 9697 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9698 final int NA = apps.size(); 9699 for (int ia=0; ia<NA; ia++) { 9700 ProcessRecord p = apps.valueAt(ia); 9701 if (p.thread != null && p.thread.asBinder() == app) { 9702 return p; 9703 } 9704 } 9705 } 9706 9707 Slog.w(TAG, "Can't find mystery application for " + reason 9708 + " from pid=" + Binder.getCallingPid() 9709 + " uid=" + Binder.getCallingUid() + ": " + app); 9710 return null; 9711 } 9712 } 9713 9714 /** 9715 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9716 * to append various headers to the dropbox log text. 9717 */ 9718 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9719 StringBuilder sb) { 9720 // Watchdog thread ends up invoking this function (with 9721 // a null ProcessRecord) to add the stack file to dropbox. 9722 // Do not acquire a lock on this (am) in such cases, as it 9723 // could cause a potential deadlock, if and when watchdog 9724 // is invoked due to unavailability of lock on am and it 9725 // would prevent watchdog from killing system_server. 9726 if (process == null) { 9727 sb.append("Process: ").append(processName).append("\n"); 9728 return; 9729 } 9730 // Note: ProcessRecord 'process' is guarded by the service 9731 // instance. (notably process.pkgList, which could otherwise change 9732 // concurrently during execution of this method) 9733 synchronized (this) { 9734 sb.append("Process: ").append(processName).append("\n"); 9735 int flags = process.info.flags; 9736 IPackageManager pm = AppGlobals.getPackageManager(); 9737 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9738 for (int ip=0; ip<process.pkgList.size(); ip++) { 9739 String pkg = process.pkgList.keyAt(ip); 9740 sb.append("Package: ").append(pkg); 9741 try { 9742 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9743 if (pi != null) { 9744 sb.append(" v").append(pi.versionCode); 9745 if (pi.versionName != null) { 9746 sb.append(" (").append(pi.versionName).append(")"); 9747 } 9748 } 9749 } catch (RemoteException e) { 9750 Slog.e(TAG, "Error getting package info: " + pkg, e); 9751 } 9752 sb.append("\n"); 9753 } 9754 } 9755 } 9756 9757 private static String processClass(ProcessRecord process) { 9758 if (process == null || process.pid == MY_PID) { 9759 return "system_server"; 9760 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9761 return "system_app"; 9762 } else { 9763 return "data_app"; 9764 } 9765 } 9766 9767 /** 9768 * Write a description of an error (crash, WTF, ANR) to the drop box. 9769 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9770 * @param process which caused the error, null means the system server 9771 * @param activity which triggered the error, null if unknown 9772 * @param parent activity related to the error, null if unknown 9773 * @param subject line related to the error, null if absent 9774 * @param report in long form describing the error, null if absent 9775 * @param logFile to include in the report, null if none 9776 * @param crashInfo giving an application stack trace, null if absent 9777 */ 9778 public void addErrorToDropBox(String eventType, 9779 ProcessRecord process, String processName, ActivityRecord activity, 9780 ActivityRecord parent, String subject, 9781 final String report, final File logFile, 9782 final ApplicationErrorReport.CrashInfo crashInfo) { 9783 // NOTE -- this must never acquire the ActivityManagerService lock, 9784 // otherwise the watchdog may be prevented from resetting the system. 9785 9786 final String dropboxTag = processClass(process) + "_" + eventType; 9787 final DropBoxManager dbox = (DropBoxManager) 9788 mContext.getSystemService(Context.DROPBOX_SERVICE); 9789 9790 // Exit early if the dropbox isn't configured to accept this report type. 9791 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9792 9793 final StringBuilder sb = new StringBuilder(1024); 9794 appendDropBoxProcessHeaders(process, processName, sb); 9795 if (activity != null) { 9796 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9797 } 9798 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9799 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9800 } 9801 if (parent != null && parent != activity) { 9802 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9803 } 9804 if (subject != null) { 9805 sb.append("Subject: ").append(subject).append("\n"); 9806 } 9807 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9808 if (Debug.isDebuggerConnected()) { 9809 sb.append("Debugger: Connected\n"); 9810 } 9811 sb.append("\n"); 9812 9813 // Do the rest in a worker thread to avoid blocking the caller on I/O 9814 // (After this point, we shouldn't access AMS internal data structures.) 9815 Thread worker = new Thread("Error dump: " + dropboxTag) { 9816 @Override 9817 public void run() { 9818 if (report != null) { 9819 sb.append(report); 9820 } 9821 if (logFile != null) { 9822 try { 9823 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 9824 } catch (IOException e) { 9825 Slog.e(TAG, "Error reading " + logFile, e); 9826 } 9827 } 9828 if (crashInfo != null && crashInfo.stackTrace != null) { 9829 sb.append(crashInfo.stackTrace); 9830 } 9831 9832 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9833 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9834 if (lines > 0) { 9835 sb.append("\n"); 9836 9837 // Merge several logcat streams, and take the last N lines 9838 InputStreamReader input = null; 9839 try { 9840 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9841 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9842 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9843 9844 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9845 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9846 input = new InputStreamReader(logcat.getInputStream()); 9847 9848 int num; 9849 char[] buf = new char[8192]; 9850 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9851 } catch (IOException e) { 9852 Slog.e(TAG, "Error running logcat", e); 9853 } finally { 9854 if (input != null) try { input.close(); } catch (IOException e) {} 9855 } 9856 } 9857 9858 dbox.addText(dropboxTag, sb.toString()); 9859 } 9860 }; 9861 9862 if (process == null) { 9863 // If process is null, we are being called from some internal code 9864 // and may be about to die -- run this synchronously. 9865 worker.run(); 9866 } else { 9867 worker.start(); 9868 } 9869 } 9870 9871 /** 9872 * Bring up the "unexpected error" dialog box for a crashing app. 9873 * Deal with edge cases (intercepts from instrumented applications, 9874 * ActivityController, error intent receivers, that sort of thing). 9875 * @param r the application crashing 9876 * @param crashInfo describing the failure 9877 */ 9878 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9879 long timeMillis = System.currentTimeMillis(); 9880 String shortMsg = crashInfo.exceptionClassName; 9881 String longMsg = crashInfo.exceptionMessage; 9882 String stackTrace = crashInfo.stackTrace; 9883 if (shortMsg != null && longMsg != null) { 9884 longMsg = shortMsg + ": " + longMsg; 9885 } else if (shortMsg != null) { 9886 longMsg = shortMsg; 9887 } 9888 9889 AppErrorResult result = new AppErrorResult(); 9890 synchronized (this) { 9891 if (mController != null) { 9892 try { 9893 String name = r != null ? r.processName : null; 9894 int pid = r != null ? r.pid : Binder.getCallingPid(); 9895 if (!mController.appCrashed(name, pid, 9896 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9897 Slog.w(TAG, "Force-killing crashed app " + name 9898 + " at watcher's request"); 9899 Process.killProcess(pid); 9900 return; 9901 } 9902 } catch (RemoteException e) { 9903 mController = null; 9904 Watchdog.getInstance().setActivityController(null); 9905 } 9906 } 9907 9908 final long origId = Binder.clearCallingIdentity(); 9909 9910 // If this process is running instrumentation, finish it. 9911 if (r != null && r.instrumentationClass != null) { 9912 Slog.w(TAG, "Error in app " + r.processName 9913 + " running instrumentation " + r.instrumentationClass + ":"); 9914 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9915 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9916 Bundle info = new Bundle(); 9917 info.putString("shortMsg", shortMsg); 9918 info.putString("longMsg", longMsg); 9919 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9920 Binder.restoreCallingIdentity(origId); 9921 return; 9922 } 9923 9924 // If we can't identify the process or it's already exceeded its crash quota, 9925 // quit right away without showing a crash dialog. 9926 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 9927 Binder.restoreCallingIdentity(origId); 9928 return; 9929 } 9930 9931 Message msg = Message.obtain(); 9932 msg.what = SHOW_ERROR_MSG; 9933 HashMap data = new HashMap(); 9934 data.put("result", result); 9935 data.put("app", r); 9936 msg.obj = data; 9937 mHandler.sendMessage(msg); 9938 9939 Binder.restoreCallingIdentity(origId); 9940 } 9941 9942 int res = result.get(); 9943 9944 Intent appErrorIntent = null; 9945 synchronized (this) { 9946 if (r != null && !r.isolated) { 9947 // XXX Can't keep track of crash time for isolated processes, 9948 // since they don't have a persistent identity. 9949 mProcessCrashTimes.put(r.info.processName, r.uid, 9950 SystemClock.uptimeMillis()); 9951 } 9952 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 9953 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 9954 } 9955 } 9956 9957 if (appErrorIntent != null) { 9958 try { 9959 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 9960 } catch (ActivityNotFoundException e) { 9961 Slog.w(TAG, "bug report receiver dissappeared", e); 9962 } 9963 } 9964 } 9965 9966 Intent createAppErrorIntentLocked(ProcessRecord r, 9967 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 9968 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 9969 if (report == null) { 9970 return null; 9971 } 9972 Intent result = new Intent(Intent.ACTION_APP_ERROR); 9973 result.setComponent(r.errorReportReceiver); 9974 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 9975 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 9976 return result; 9977 } 9978 9979 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 9980 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 9981 if (r.errorReportReceiver == null) { 9982 return null; 9983 } 9984 9985 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 9986 return null; 9987 } 9988 9989 ApplicationErrorReport report = new ApplicationErrorReport(); 9990 report.packageName = r.info.packageName; 9991 report.installerPackageName = r.errorReportReceiver.getPackageName(); 9992 report.processName = r.processName; 9993 report.time = timeMillis; 9994 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 9995 9996 if (r.crashing || r.forceCrashReport) { 9997 report.type = ApplicationErrorReport.TYPE_CRASH; 9998 report.crashInfo = crashInfo; 9999 } else if (r.notResponding) { 10000 report.type = ApplicationErrorReport.TYPE_ANR; 10001 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10002 10003 report.anrInfo.activity = r.notRespondingReport.tag; 10004 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10005 report.anrInfo.info = r.notRespondingReport.longMsg; 10006 } 10007 10008 return report; 10009 } 10010 10011 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10012 enforceNotIsolatedCaller("getProcessesInErrorState"); 10013 // assume our apps are happy - lazy create the list 10014 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10015 10016 final boolean allUsers = ActivityManager.checkUidPermission( 10017 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10018 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10019 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10020 10021 synchronized (this) { 10022 10023 // iterate across all processes 10024 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10025 ProcessRecord app = mLruProcesses.get(i); 10026 if (!allUsers && app.userId != userId) { 10027 continue; 10028 } 10029 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10030 // This one's in trouble, so we'll generate a report for it 10031 // crashes are higher priority (in case there's a crash *and* an anr) 10032 ActivityManager.ProcessErrorStateInfo report = null; 10033 if (app.crashing) { 10034 report = app.crashingReport; 10035 } else if (app.notResponding) { 10036 report = app.notRespondingReport; 10037 } 10038 10039 if (report != null) { 10040 if (errList == null) { 10041 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10042 } 10043 errList.add(report); 10044 } else { 10045 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10046 " crashing = " + app.crashing + 10047 " notResponding = " + app.notResponding); 10048 } 10049 } 10050 } 10051 } 10052 10053 return errList; 10054 } 10055 10056 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10057 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10058 if (currApp != null) { 10059 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10060 } 10061 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10062 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10063 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10064 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10065 if (currApp != null) { 10066 currApp.lru = 0; 10067 } 10068 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10069 } else if (adj >= ProcessList.SERVICE_ADJ) { 10070 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10071 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10072 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10073 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10074 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10075 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10076 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10077 } else { 10078 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10079 } 10080 } 10081 10082 private void fillInProcMemInfo(ProcessRecord app, 10083 ActivityManager.RunningAppProcessInfo outInfo) { 10084 outInfo.pid = app.pid; 10085 outInfo.uid = app.info.uid; 10086 if (mHeavyWeightProcess == app) { 10087 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10088 } 10089 if (app.persistent) { 10090 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10091 } 10092 if (app.hasActivities) { 10093 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10094 } 10095 outInfo.lastTrimLevel = app.trimMemoryLevel; 10096 int adj = app.curAdj; 10097 outInfo.importance = oomAdjToImportance(adj, outInfo); 10098 outInfo.importanceReasonCode = app.adjTypeCode; 10099 } 10100 10101 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10102 enforceNotIsolatedCaller("getRunningAppProcesses"); 10103 // Lazy instantiation of list 10104 List<ActivityManager.RunningAppProcessInfo> runList = null; 10105 final boolean allUsers = ActivityManager.checkUidPermission( 10106 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10107 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10108 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10109 synchronized (this) { 10110 // Iterate across all processes 10111 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10112 ProcessRecord app = mLruProcesses.get(i); 10113 if (!allUsers && app.userId != userId) { 10114 continue; 10115 } 10116 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10117 // Generate process state info for running application 10118 ActivityManager.RunningAppProcessInfo currApp = 10119 new ActivityManager.RunningAppProcessInfo(app.processName, 10120 app.pid, app.getPackageList()); 10121 fillInProcMemInfo(app, currApp); 10122 if (app.adjSource instanceof ProcessRecord) { 10123 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10124 currApp.importanceReasonImportance = oomAdjToImportance( 10125 app.adjSourceOom, null); 10126 } else if (app.adjSource instanceof ActivityRecord) { 10127 ActivityRecord r = (ActivityRecord)app.adjSource; 10128 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10129 } 10130 if (app.adjTarget instanceof ComponentName) { 10131 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10132 } 10133 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10134 // + " lru=" + currApp.lru); 10135 if (runList == null) { 10136 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10137 } 10138 runList.add(currApp); 10139 } 10140 } 10141 } 10142 return runList; 10143 } 10144 10145 public List<ApplicationInfo> getRunningExternalApplications() { 10146 enforceNotIsolatedCaller("getRunningExternalApplications"); 10147 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10148 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10149 if (runningApps != null && runningApps.size() > 0) { 10150 Set<String> extList = new HashSet<String>(); 10151 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10152 if (app.pkgList != null) { 10153 for (String pkg : app.pkgList) { 10154 extList.add(pkg); 10155 } 10156 } 10157 } 10158 IPackageManager pm = AppGlobals.getPackageManager(); 10159 for (String pkg : extList) { 10160 try { 10161 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10162 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10163 retList.add(info); 10164 } 10165 } catch (RemoteException e) { 10166 } 10167 } 10168 } 10169 return retList; 10170 } 10171 10172 @Override 10173 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10174 enforceNotIsolatedCaller("getMyMemoryState"); 10175 synchronized (this) { 10176 ProcessRecord proc; 10177 synchronized (mPidsSelfLocked) { 10178 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10179 } 10180 fillInProcMemInfo(proc, outInfo); 10181 } 10182 } 10183 10184 @Override 10185 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10186 if (checkCallingPermission(android.Manifest.permission.DUMP) 10187 != PackageManager.PERMISSION_GRANTED) { 10188 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10189 + Binder.getCallingPid() 10190 + ", uid=" + Binder.getCallingUid() 10191 + " without permission " 10192 + android.Manifest.permission.DUMP); 10193 return; 10194 } 10195 10196 boolean dumpAll = false; 10197 boolean dumpClient = false; 10198 String dumpPackage = null; 10199 10200 int opti = 0; 10201 while (opti < args.length) { 10202 String opt = args[opti]; 10203 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10204 break; 10205 } 10206 opti++; 10207 if ("-a".equals(opt)) { 10208 dumpAll = true; 10209 } else if ("-c".equals(opt)) { 10210 dumpClient = true; 10211 } else if ("-h".equals(opt)) { 10212 pw.println("Activity manager dump options:"); 10213 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10214 pw.println(" cmd may be one of:"); 10215 pw.println(" a[ctivities]: activity stack state"); 10216 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10217 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10218 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10219 pw.println(" o[om]: out of memory management"); 10220 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10221 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10222 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10223 pw.println(" service [COMP_SPEC]: service client-side state"); 10224 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10225 pw.println(" all: dump all activities"); 10226 pw.println(" top: dump the top activity"); 10227 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10228 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10229 pw.println(" a partial substring in a component name, a"); 10230 pw.println(" hex object identifier."); 10231 pw.println(" -a: include all available server state."); 10232 pw.println(" -c: include client state."); 10233 return; 10234 } else { 10235 pw.println("Unknown argument: " + opt + "; use -h for help"); 10236 } 10237 } 10238 10239 long origId = Binder.clearCallingIdentity(); 10240 boolean more = false; 10241 // Is the caller requesting to dump a particular piece of data? 10242 if (opti < args.length) { 10243 String cmd = args[opti]; 10244 opti++; 10245 if ("activities".equals(cmd) || "a".equals(cmd)) { 10246 synchronized (this) { 10247 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10248 } 10249 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10250 String[] newArgs; 10251 String name; 10252 if (opti >= args.length) { 10253 name = null; 10254 newArgs = EMPTY_STRING_ARRAY; 10255 } else { 10256 name = args[opti]; 10257 opti++; 10258 newArgs = new String[args.length - opti]; 10259 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10260 args.length - opti); 10261 } 10262 synchronized (this) { 10263 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10264 } 10265 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10266 String[] newArgs; 10267 String name; 10268 if (opti >= args.length) { 10269 name = null; 10270 newArgs = EMPTY_STRING_ARRAY; 10271 } else { 10272 name = args[opti]; 10273 opti++; 10274 newArgs = new String[args.length - opti]; 10275 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10276 args.length - opti); 10277 } 10278 synchronized (this) { 10279 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10280 } 10281 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10282 String[] newArgs; 10283 String name; 10284 if (opti >= args.length) { 10285 name = null; 10286 newArgs = EMPTY_STRING_ARRAY; 10287 } else { 10288 name = args[opti]; 10289 opti++; 10290 newArgs = new String[args.length - opti]; 10291 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10292 args.length - opti); 10293 } 10294 synchronized (this) { 10295 dumpProcessesLocked(fd, pw, args, opti, true, name); 10296 } 10297 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10298 synchronized (this) { 10299 dumpOomLocked(fd, pw, args, opti, true); 10300 } 10301 } else if ("provider".equals(cmd)) { 10302 String[] newArgs; 10303 String name; 10304 if (opti >= args.length) { 10305 name = null; 10306 newArgs = EMPTY_STRING_ARRAY; 10307 } else { 10308 name = args[opti]; 10309 opti++; 10310 newArgs = new String[args.length - opti]; 10311 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10312 } 10313 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10314 pw.println("No providers match: " + name); 10315 pw.println("Use -h for help."); 10316 } 10317 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10318 synchronized (this) { 10319 dumpProvidersLocked(fd, pw, args, opti, true, null); 10320 } 10321 } else if ("service".equals(cmd)) { 10322 String[] newArgs; 10323 String name; 10324 if (opti >= args.length) { 10325 name = null; 10326 newArgs = EMPTY_STRING_ARRAY; 10327 } else { 10328 name = args[opti]; 10329 opti++; 10330 newArgs = new String[args.length - opti]; 10331 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10332 args.length - opti); 10333 } 10334 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10335 pw.println("No services match: " + name); 10336 pw.println("Use -h for help."); 10337 } 10338 } else if ("package".equals(cmd)) { 10339 String[] newArgs; 10340 if (opti >= args.length) { 10341 pw.println("package: no package name specified"); 10342 pw.println("Use -h for help."); 10343 } else { 10344 dumpPackage = args[opti]; 10345 opti++; 10346 newArgs = new String[args.length - opti]; 10347 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10348 args.length - opti); 10349 args = newArgs; 10350 opti = 0; 10351 more = true; 10352 } 10353 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10354 synchronized (this) { 10355 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10356 } 10357 } else { 10358 // Dumping a single activity? 10359 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10360 pw.println("Bad activity command, or no activities match: " + cmd); 10361 pw.println("Use -h for help."); 10362 } 10363 } 10364 if (!more) { 10365 Binder.restoreCallingIdentity(origId); 10366 return; 10367 } 10368 } 10369 10370 // No piece of data specified, dump everything. 10371 synchronized (this) { 10372 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10373 pw.println(); 10374 if (dumpAll) { 10375 pw.println("-------------------------------------------------------------------------------"); 10376 } 10377 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10378 pw.println(); 10379 if (dumpAll) { 10380 pw.println("-------------------------------------------------------------------------------"); 10381 } 10382 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10383 pw.println(); 10384 if (dumpAll) { 10385 pw.println("-------------------------------------------------------------------------------"); 10386 } 10387 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10388 pw.println(); 10389 if (dumpAll) { 10390 pw.println("-------------------------------------------------------------------------------"); 10391 } 10392 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10393 pw.println(); 10394 if (dumpAll) { 10395 pw.println("-------------------------------------------------------------------------------"); 10396 } 10397 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10398 } 10399 Binder.restoreCallingIdentity(origId); 10400 } 10401 10402 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10403 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10404 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10405 10406 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10407 dumpPackage); 10408 boolean needSep = printedAnything; 10409 10410 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10411 dumpPackage, needSep, " mFocusedActivity: "); 10412 if (printed) { 10413 printedAnything = true; 10414 needSep = false; 10415 } 10416 10417 if (dumpPackage == null) { 10418 if (needSep) { 10419 pw.println(); 10420 } 10421 needSep = true; 10422 printedAnything = true; 10423 mStackSupervisor.dump(pw, " "); 10424 } 10425 10426 if (mRecentTasks.size() > 0) { 10427 boolean printedHeader = false; 10428 10429 final int N = mRecentTasks.size(); 10430 for (int i=0; i<N; i++) { 10431 TaskRecord tr = mRecentTasks.get(i); 10432 if (dumpPackage != null) { 10433 if (tr.realActivity == null || 10434 !dumpPackage.equals(tr.realActivity)) { 10435 continue; 10436 } 10437 } 10438 if (!printedHeader) { 10439 if (needSep) { 10440 pw.println(); 10441 } 10442 pw.println(" Recent tasks:"); 10443 printedHeader = true; 10444 printedAnything = true; 10445 } 10446 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10447 pw.println(tr); 10448 if (dumpAll) { 10449 mRecentTasks.get(i).dump(pw, " "); 10450 } 10451 } 10452 } 10453 10454 if (!printedAnything) { 10455 pw.println(" (nothing)"); 10456 } 10457 } 10458 10459 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10460 int opti, boolean dumpAll, String dumpPackage) { 10461 boolean needSep = false; 10462 boolean printedAnything = false; 10463 int numPers = 0; 10464 10465 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10466 10467 if (dumpAll) { 10468 final int NP = mProcessNames.getMap().size(); 10469 for (int ip=0; ip<NP; ip++) { 10470 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10471 final int NA = procs.size(); 10472 for (int ia=0; ia<NA; ia++) { 10473 ProcessRecord r = procs.valueAt(ia); 10474 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10475 continue; 10476 } 10477 if (!needSep) { 10478 pw.println(" All known processes:"); 10479 needSep = true; 10480 printedAnything = true; 10481 } 10482 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10483 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10484 pw.print(" "); pw.println(r); 10485 r.dump(pw, " "); 10486 if (r.persistent) { 10487 numPers++; 10488 } 10489 } 10490 } 10491 } 10492 10493 if (mIsolatedProcesses.size() > 0) { 10494 boolean printed = false; 10495 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10496 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10497 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10498 continue; 10499 } 10500 if (!printed) { 10501 if (needSep) { 10502 pw.println(); 10503 } 10504 pw.println(" Isolated process list (sorted by uid):"); 10505 printedAnything = true; 10506 printed = true; 10507 needSep = true; 10508 } 10509 pw.println(String.format("%sIsolated #%2d: %s", 10510 " ", i, r.toString())); 10511 } 10512 } 10513 10514 if (mLruProcesses.size() > 0) { 10515 if (needSep) { 10516 pw.println(); 10517 } 10518 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10519 pw.print(" total, non-act at "); 10520 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10521 pw.print(", non-svc at "); 10522 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10523 pw.println("):"); 10524 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10525 needSep = true; 10526 printedAnything = true; 10527 } 10528 10529 if (dumpAll || dumpPackage != null) { 10530 synchronized (mPidsSelfLocked) { 10531 boolean printed = false; 10532 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10533 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10534 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10535 continue; 10536 } 10537 if (!printed) { 10538 if (needSep) pw.println(); 10539 needSep = true; 10540 pw.println(" PID mappings:"); 10541 printed = true; 10542 printedAnything = true; 10543 } 10544 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10545 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10546 } 10547 } 10548 } 10549 10550 if (mForegroundProcesses.size() > 0) { 10551 synchronized (mPidsSelfLocked) { 10552 boolean printed = false; 10553 for (int i=0; i<mForegroundProcesses.size(); i++) { 10554 ProcessRecord r = mPidsSelfLocked.get( 10555 mForegroundProcesses.valueAt(i).pid); 10556 if (dumpPackage != null && (r == null 10557 || !r.pkgList.containsKey(dumpPackage))) { 10558 continue; 10559 } 10560 if (!printed) { 10561 if (needSep) pw.println(); 10562 needSep = true; 10563 pw.println(" Foreground Processes:"); 10564 printed = true; 10565 printedAnything = true; 10566 } 10567 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10568 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10569 } 10570 } 10571 } 10572 10573 if (mPersistentStartingProcesses.size() > 0) { 10574 if (needSep) pw.println(); 10575 needSep = true; 10576 printedAnything = true; 10577 pw.println(" Persisent processes that are starting:"); 10578 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10579 "Starting Norm", "Restarting PERS", dumpPackage); 10580 } 10581 10582 if (mRemovedProcesses.size() > 0) { 10583 if (needSep) pw.println(); 10584 needSep = true; 10585 printedAnything = true; 10586 pw.println(" Processes that are being removed:"); 10587 dumpProcessList(pw, this, mRemovedProcesses, " ", 10588 "Removed Norm", "Removed PERS", dumpPackage); 10589 } 10590 10591 if (mProcessesOnHold.size() > 0) { 10592 if (needSep) pw.println(); 10593 needSep = true; 10594 printedAnything = true; 10595 pw.println(" Processes that are on old until the system is ready:"); 10596 dumpProcessList(pw, this, mProcessesOnHold, " ", 10597 "OnHold Norm", "OnHold PERS", dumpPackage); 10598 } 10599 10600 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10601 10602 if (mProcessCrashTimes.getMap().size() > 0) { 10603 boolean printed = false; 10604 long now = SystemClock.uptimeMillis(); 10605 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10606 final int NP = pmap.size(); 10607 for (int ip=0; ip<NP; ip++) { 10608 String pname = pmap.keyAt(ip); 10609 SparseArray<Long> uids = pmap.valueAt(ip); 10610 final int N = uids.size(); 10611 for (int i=0; i<N; i++) { 10612 int puid = uids.keyAt(i); 10613 ProcessRecord r = mProcessNames.get(pname, puid); 10614 if (dumpPackage != null && (r == null 10615 || !r.pkgList.containsKey(dumpPackage))) { 10616 continue; 10617 } 10618 if (!printed) { 10619 if (needSep) pw.println(); 10620 needSep = true; 10621 pw.println(" Time since processes crashed:"); 10622 printed = true; 10623 printedAnything = true; 10624 } 10625 pw.print(" Process "); pw.print(pname); 10626 pw.print(" uid "); pw.print(puid); 10627 pw.print(": last crashed "); 10628 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10629 pw.println(" ago"); 10630 } 10631 } 10632 } 10633 10634 if (mBadProcesses.getMap().size() > 0) { 10635 boolean printed = false; 10636 final ArrayMap<String, SparseArray<Long>> pmap = mBadProcesses.getMap(); 10637 final int NP = pmap.size(); 10638 for (int ip=0; ip<NP; ip++) { 10639 String pname = pmap.keyAt(ip); 10640 SparseArray<Long> uids = pmap.valueAt(ip); 10641 final int N = uids.size(); 10642 for (int i=0; i<N; i++) { 10643 int puid = uids.keyAt(i); 10644 ProcessRecord r = mProcessNames.get(pname, puid); 10645 if (dumpPackage != null && (r == null 10646 || !r.pkgList.containsKey(dumpPackage))) { 10647 continue; 10648 } 10649 if (!printed) { 10650 if (needSep) pw.println(); 10651 needSep = true; 10652 pw.println(" Bad processes:"); 10653 printedAnything = true; 10654 } 10655 pw.print(" Bad process "); pw.print(pname); 10656 pw.print(" uid "); pw.print(puid); 10657 pw.print(": crashed at time "); 10658 pw.println(uids.valueAt(i)); 10659 } 10660 } 10661 } 10662 10663 if (dumpPackage == null) { 10664 pw.println(); 10665 needSep = false; 10666 pw.println(" mStartedUsers:"); 10667 for (int i=0; i<mStartedUsers.size(); i++) { 10668 UserStartedState uss = mStartedUsers.valueAt(i); 10669 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10670 pw.print(": "); uss.dump("", pw); 10671 } 10672 pw.print(" mStartedUserArray: ["); 10673 for (int i=0; i<mStartedUserArray.length; i++) { 10674 if (i > 0) pw.print(", "); 10675 pw.print(mStartedUserArray[i]); 10676 } 10677 pw.println("]"); 10678 pw.print(" mUserLru: ["); 10679 for (int i=0; i<mUserLru.size(); i++) { 10680 if (i > 0) pw.print(", "); 10681 pw.print(mUserLru.get(i)); 10682 } 10683 pw.println("]"); 10684 if (dumpAll) { 10685 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10686 } 10687 } 10688 if (mHomeProcess != null && (dumpPackage == null 10689 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10690 if (needSep) { 10691 pw.println(); 10692 needSep = false; 10693 } 10694 pw.println(" mHomeProcess: " + mHomeProcess); 10695 } 10696 if (mPreviousProcess != null && (dumpPackage == null 10697 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10698 if (needSep) { 10699 pw.println(); 10700 needSep = false; 10701 } 10702 pw.println(" mPreviousProcess: " + mPreviousProcess); 10703 } 10704 if (dumpAll) { 10705 StringBuilder sb = new StringBuilder(128); 10706 sb.append(" mPreviousProcessVisibleTime: "); 10707 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10708 pw.println(sb); 10709 } 10710 if (mHeavyWeightProcess != null && (dumpPackage == null 10711 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10712 if (needSep) { 10713 pw.println(); 10714 needSep = false; 10715 } 10716 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10717 } 10718 if (dumpPackage == null) { 10719 pw.println(" mConfiguration: " + mConfiguration); 10720 } 10721 if (dumpAll) { 10722 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10723 if (mCompatModePackages.getPackages().size() > 0) { 10724 boolean printed = false; 10725 for (Map.Entry<String, Integer> entry 10726 : mCompatModePackages.getPackages().entrySet()) { 10727 String pkg = entry.getKey(); 10728 int mode = entry.getValue(); 10729 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10730 continue; 10731 } 10732 if (!printed) { 10733 pw.println(" mScreenCompatPackages:"); 10734 printed = true; 10735 } 10736 pw.print(" "); pw.print(pkg); pw.print(": "); 10737 pw.print(mode); pw.println(); 10738 } 10739 } 10740 } 10741 if (dumpPackage == null) { 10742 if (mSleeping || mWentToSleep || mLockScreenShown) { 10743 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10744 + " mLockScreenShown " + mLockScreenShown); 10745 } 10746 if (mShuttingDown) { 10747 pw.println(" mShuttingDown=" + mShuttingDown); 10748 } 10749 } 10750 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10751 || mOrigWaitForDebugger) { 10752 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10753 || dumpPackage.equals(mOrigDebugApp)) { 10754 if (needSep) { 10755 pw.println(); 10756 needSep = false; 10757 } 10758 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10759 + " mDebugTransient=" + mDebugTransient 10760 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10761 } 10762 } 10763 if (mOpenGlTraceApp != null) { 10764 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10765 if (needSep) { 10766 pw.println(); 10767 needSep = false; 10768 } 10769 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10770 } 10771 } 10772 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10773 || mProfileFd != null) { 10774 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10775 if (needSep) { 10776 pw.println(); 10777 needSep = false; 10778 } 10779 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10780 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10781 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10782 + mAutoStopProfiler); 10783 } 10784 } 10785 if (dumpPackage == null) { 10786 if (mAlwaysFinishActivities || mController != null) { 10787 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10788 + " mController=" + mController); 10789 } 10790 if (dumpAll) { 10791 pw.println(" Total persistent processes: " + numPers); 10792 pw.println(" mStartRunning=" + mStartRunning 10793 + " mProcessesReady=" + mProcessesReady 10794 + " mSystemReady=" + mSystemReady); 10795 pw.println(" mBooting=" + mBooting 10796 + " mBooted=" + mBooted 10797 + " mFactoryTest=" + mFactoryTest); 10798 pw.print(" mLastPowerCheckRealtime="); 10799 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10800 pw.println(""); 10801 pw.print(" mLastPowerCheckUptime="); 10802 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10803 pw.println(""); 10804 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10805 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10806 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10807 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10808 + " (" + mLruProcesses.size() + " total)" 10809 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10810 + " mNumServiceProcs=" + mNumServiceProcs 10811 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10812 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10813 + " mLastMemoryLevel" + mLastMemoryLevel 10814 + " mLastNumProcesses" + mLastNumProcesses); 10815 long now = SystemClock.uptimeMillis(); 10816 pw.print(" mLastIdleTime="); 10817 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10818 pw.print(" mLowRamSinceLastIdle="); 10819 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10820 pw.println(); 10821 } 10822 } 10823 10824 if (!printedAnything) { 10825 pw.println(" (nothing)"); 10826 } 10827 } 10828 10829 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 10830 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 10831 if (mProcessesToGc.size() > 0) { 10832 boolean printed = false; 10833 long now = SystemClock.uptimeMillis(); 10834 for (int i=0; i<mProcessesToGc.size(); i++) { 10835 ProcessRecord proc = mProcessesToGc.get(i); 10836 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 10837 continue; 10838 } 10839 if (!printed) { 10840 if (needSep) pw.println(); 10841 needSep = true; 10842 pw.println(" Processes that are waiting to GC:"); 10843 printed = true; 10844 } 10845 pw.print(" Process "); pw.println(proc); 10846 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 10847 pw.print(", last gced="); 10848 pw.print(now-proc.lastRequestedGc); 10849 pw.print(" ms ago, last lowMem="); 10850 pw.print(now-proc.lastLowMemory); 10851 pw.println(" ms ago"); 10852 10853 } 10854 } 10855 return needSep; 10856 } 10857 10858 void printOomLevel(PrintWriter pw, String name, int adj) { 10859 pw.print(" "); 10860 if (adj >= 0) { 10861 pw.print(' '); 10862 if (adj < 10) pw.print(' '); 10863 } else { 10864 if (adj > -10) pw.print(' '); 10865 } 10866 pw.print(adj); 10867 pw.print(": "); 10868 pw.print(name); 10869 pw.print(" ("); 10870 pw.print(mProcessList.getMemLevel(adj)/1024); 10871 pw.println(" kB)"); 10872 } 10873 10874 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10875 int opti, boolean dumpAll) { 10876 boolean needSep = false; 10877 10878 if (mLruProcesses.size() > 0) { 10879 if (needSep) pw.println(); 10880 needSep = true; 10881 pw.println(" OOM levels:"); 10882 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 10883 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 10884 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 10885 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 10886 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 10887 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 10888 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 10889 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 10890 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 10891 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 10892 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 10893 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 10894 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 10895 10896 if (needSep) pw.println(); 10897 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 10898 pw.print(" total, non-act at "); 10899 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10900 pw.print(", non-svc at "); 10901 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10902 pw.println("):"); 10903 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 10904 needSep = true; 10905 } 10906 10907 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 10908 10909 pw.println(); 10910 pw.println(" mHomeProcess: " + mHomeProcess); 10911 pw.println(" mPreviousProcess: " + mPreviousProcess); 10912 if (mHeavyWeightProcess != null) { 10913 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10914 } 10915 10916 return true; 10917 } 10918 10919 /** 10920 * There are three ways to call this: 10921 * - no provider specified: dump all the providers 10922 * - a flattened component name that matched an existing provider was specified as the 10923 * first arg: dump that one provider 10924 * - the first arg isn't the flattened component name of an existing provider: 10925 * dump all providers whose component contains the first arg as a substring 10926 */ 10927 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 10928 int opti, boolean dumpAll) { 10929 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 10930 } 10931 10932 static class ItemMatcher { 10933 ArrayList<ComponentName> components; 10934 ArrayList<String> strings; 10935 ArrayList<Integer> objects; 10936 boolean all; 10937 10938 ItemMatcher() { 10939 all = true; 10940 } 10941 10942 void build(String name) { 10943 ComponentName componentName = ComponentName.unflattenFromString(name); 10944 if (componentName != null) { 10945 if (components == null) { 10946 components = new ArrayList<ComponentName>(); 10947 } 10948 components.add(componentName); 10949 all = false; 10950 } else { 10951 int objectId = 0; 10952 // Not a '/' separated full component name; maybe an object ID? 10953 try { 10954 objectId = Integer.parseInt(name, 16); 10955 if (objects == null) { 10956 objects = new ArrayList<Integer>(); 10957 } 10958 objects.add(objectId); 10959 all = false; 10960 } catch (RuntimeException e) { 10961 // Not an integer; just do string match. 10962 if (strings == null) { 10963 strings = new ArrayList<String>(); 10964 } 10965 strings.add(name); 10966 all = false; 10967 } 10968 } 10969 } 10970 10971 int build(String[] args, int opti) { 10972 for (; opti<args.length; opti++) { 10973 String name = args[opti]; 10974 if ("--".equals(name)) { 10975 return opti+1; 10976 } 10977 build(name); 10978 } 10979 return opti; 10980 } 10981 10982 boolean match(Object object, ComponentName comp) { 10983 if (all) { 10984 return true; 10985 } 10986 if (components != null) { 10987 for (int i=0; i<components.size(); i++) { 10988 if (components.get(i).equals(comp)) { 10989 return true; 10990 } 10991 } 10992 } 10993 if (objects != null) { 10994 for (int i=0; i<objects.size(); i++) { 10995 if (System.identityHashCode(object) == objects.get(i)) { 10996 return true; 10997 } 10998 } 10999 } 11000 if (strings != null) { 11001 String flat = comp.flattenToString(); 11002 for (int i=0; i<strings.size(); i++) { 11003 if (flat.contains(strings.get(i))) { 11004 return true; 11005 } 11006 } 11007 } 11008 return false; 11009 } 11010 } 11011 11012 /** 11013 * There are three things that cmd can be: 11014 * - a flattened component name that matches an existing activity 11015 * - the cmd arg isn't the flattened component name of an existing activity: 11016 * dump all activity whose component contains the cmd as a substring 11017 * - A hex number of the ActivityRecord object instance. 11018 */ 11019 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11020 int opti, boolean dumpAll) { 11021 ArrayList<ActivityRecord> activities; 11022 11023 synchronized (this) { 11024 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11025 } 11026 11027 if (activities.size() <= 0) { 11028 return false; 11029 } 11030 11031 String[] newArgs = new String[args.length - opti]; 11032 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11033 11034 TaskRecord lastTask = null; 11035 boolean needSep = false; 11036 for (int i=activities.size()-1; i>=0; i--) { 11037 ActivityRecord r = activities.get(i); 11038 if (needSep) { 11039 pw.println(); 11040 } 11041 needSep = true; 11042 synchronized (this) { 11043 if (lastTask != r.task) { 11044 lastTask = r.task; 11045 pw.print("TASK "); pw.print(lastTask.affinity); 11046 pw.print(" id="); pw.println(lastTask.taskId); 11047 if (dumpAll) { 11048 lastTask.dump(pw, " "); 11049 } 11050 } 11051 } 11052 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11053 } 11054 return true; 11055 } 11056 11057 /** 11058 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11059 * there is a thread associated with the activity. 11060 */ 11061 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11062 final ActivityRecord r, String[] args, boolean dumpAll) { 11063 String innerPrefix = prefix + " "; 11064 synchronized (this) { 11065 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11066 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11067 pw.print(" pid="); 11068 if (r.app != null) pw.println(r.app.pid); 11069 else pw.println("(not running)"); 11070 if (dumpAll) { 11071 r.dump(pw, innerPrefix); 11072 } 11073 } 11074 if (r.app != null && r.app.thread != null) { 11075 // flush anything that is already in the PrintWriter since the thread is going 11076 // to write to the file descriptor directly 11077 pw.flush(); 11078 try { 11079 TransferPipe tp = new TransferPipe(); 11080 try { 11081 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11082 r.appToken, innerPrefix, args); 11083 tp.go(fd); 11084 } finally { 11085 tp.kill(); 11086 } 11087 } catch (IOException e) { 11088 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11089 } catch (RemoteException e) { 11090 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11091 } 11092 } 11093 } 11094 11095 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11096 int opti, boolean dumpAll, String dumpPackage) { 11097 boolean needSep = false; 11098 boolean onlyHistory = false; 11099 boolean printedAnything = false; 11100 11101 if ("history".equals(dumpPackage)) { 11102 if (opti < args.length && "-s".equals(args[opti])) { 11103 dumpAll = false; 11104 } 11105 onlyHistory = true; 11106 dumpPackage = null; 11107 } 11108 11109 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11110 if (!onlyHistory && dumpAll) { 11111 if (mRegisteredReceivers.size() > 0) { 11112 boolean printed = false; 11113 Iterator it = mRegisteredReceivers.values().iterator(); 11114 while (it.hasNext()) { 11115 ReceiverList r = (ReceiverList)it.next(); 11116 if (dumpPackage != null && (r.app == null || 11117 !dumpPackage.equals(r.app.info.packageName))) { 11118 continue; 11119 } 11120 if (!printed) { 11121 pw.println(" Registered Receivers:"); 11122 needSep = true; 11123 printed = true; 11124 printedAnything = true; 11125 } 11126 pw.print(" * "); pw.println(r); 11127 r.dump(pw, " "); 11128 } 11129 } 11130 11131 if (mReceiverResolver.dump(pw, needSep ? 11132 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11133 " ", dumpPackage, false)) { 11134 needSep = true; 11135 printedAnything = true; 11136 } 11137 } 11138 11139 for (BroadcastQueue q : mBroadcastQueues) { 11140 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11141 printedAnything |= needSep; 11142 } 11143 11144 needSep = true; 11145 11146 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11147 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11148 if (needSep) { 11149 pw.println(); 11150 } 11151 needSep = true; 11152 printedAnything = true; 11153 pw.print(" Sticky broadcasts for user "); 11154 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11155 StringBuilder sb = new StringBuilder(128); 11156 for (Map.Entry<String, ArrayList<Intent>> ent 11157 : mStickyBroadcasts.valueAt(user).entrySet()) { 11158 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11159 if (dumpAll) { 11160 pw.println(":"); 11161 ArrayList<Intent> intents = ent.getValue(); 11162 final int N = intents.size(); 11163 for (int i=0; i<N; i++) { 11164 sb.setLength(0); 11165 sb.append(" Intent: "); 11166 intents.get(i).toShortString(sb, false, true, false, false); 11167 pw.println(sb.toString()); 11168 Bundle bundle = intents.get(i).getExtras(); 11169 if (bundle != null) { 11170 pw.print(" "); 11171 pw.println(bundle.toString()); 11172 } 11173 } 11174 } else { 11175 pw.println(""); 11176 } 11177 } 11178 } 11179 } 11180 11181 if (!onlyHistory && dumpAll) { 11182 pw.println(); 11183 for (BroadcastQueue queue : mBroadcastQueues) { 11184 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11185 + queue.mBroadcastsScheduled); 11186 } 11187 pw.println(" mHandler:"); 11188 mHandler.dump(new PrintWriterPrinter(pw), " "); 11189 needSep = true; 11190 printedAnything = true; 11191 } 11192 11193 if (!printedAnything) { 11194 pw.println(" (nothing)"); 11195 } 11196 } 11197 11198 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11199 int opti, boolean dumpAll, String dumpPackage) { 11200 boolean needSep; 11201 boolean printedAnything = false; 11202 11203 ItemMatcher matcher = new ItemMatcher(); 11204 matcher.build(args, opti); 11205 11206 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11207 11208 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11209 printedAnything |= needSep; 11210 11211 if (mLaunchingProviders.size() > 0) { 11212 boolean printed = false; 11213 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11214 ContentProviderRecord r = mLaunchingProviders.get(i); 11215 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11216 continue; 11217 } 11218 if (!printed) { 11219 if (needSep) pw.println(); 11220 needSep = true; 11221 pw.println(" Launching content providers:"); 11222 printed = true; 11223 printedAnything = true; 11224 } 11225 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11226 pw.println(r); 11227 } 11228 } 11229 11230 if (mGrantedUriPermissions.size() > 0) { 11231 boolean printed = false; 11232 int dumpUid = -2; 11233 if (dumpPackage != null) { 11234 try { 11235 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11236 } catch (NameNotFoundException e) { 11237 dumpUid = -1; 11238 } 11239 } 11240 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11241 int uid = mGrantedUriPermissions.keyAt(i); 11242 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11243 continue; 11244 } 11245 ArrayMap<Uri, UriPermission> perms 11246 = mGrantedUriPermissions.valueAt(i); 11247 if (!printed) { 11248 if (needSep) pw.println(); 11249 needSep = true; 11250 pw.println(" Granted Uri Permissions:"); 11251 printed = true; 11252 printedAnything = true; 11253 } 11254 pw.print(" * UID "); pw.print(uid); 11255 pw.println(" holds:"); 11256 for (UriPermission perm : perms.values()) { 11257 pw.print(" "); pw.println(perm); 11258 if (dumpAll) { 11259 perm.dump(pw, " "); 11260 } 11261 } 11262 } 11263 } 11264 11265 if (!printedAnything) { 11266 pw.println(" (nothing)"); 11267 } 11268 } 11269 11270 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11271 int opti, boolean dumpAll, String dumpPackage) { 11272 boolean printed = false; 11273 11274 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11275 11276 if (mIntentSenderRecords.size() > 0) { 11277 Iterator<WeakReference<PendingIntentRecord>> it 11278 = mIntentSenderRecords.values().iterator(); 11279 while (it.hasNext()) { 11280 WeakReference<PendingIntentRecord> ref = it.next(); 11281 PendingIntentRecord rec = ref != null ? ref.get(): null; 11282 if (dumpPackage != null && (rec == null 11283 || !dumpPackage.equals(rec.key.packageName))) { 11284 continue; 11285 } 11286 printed = true; 11287 if (rec != null) { 11288 pw.print(" * "); pw.println(rec); 11289 if (dumpAll) { 11290 rec.dump(pw, " "); 11291 } 11292 } else { 11293 pw.print(" * "); pw.println(ref); 11294 } 11295 } 11296 } 11297 11298 if (!printed) { 11299 pw.println(" (nothing)"); 11300 } 11301 } 11302 11303 private static final int dumpProcessList(PrintWriter pw, 11304 ActivityManagerService service, List list, 11305 String prefix, String normalLabel, String persistentLabel, 11306 String dumpPackage) { 11307 int numPers = 0; 11308 final int N = list.size()-1; 11309 for (int i=N; i>=0; i--) { 11310 ProcessRecord r = (ProcessRecord)list.get(i); 11311 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11312 continue; 11313 } 11314 pw.println(String.format("%s%s #%2d: %s", 11315 prefix, (r.persistent ? persistentLabel : normalLabel), 11316 i, r.toString())); 11317 if (r.persistent) { 11318 numPers++; 11319 } 11320 } 11321 return numPers; 11322 } 11323 11324 private static final boolean dumpProcessOomList(PrintWriter pw, 11325 ActivityManagerService service, List<ProcessRecord> origList, 11326 String prefix, String normalLabel, String persistentLabel, 11327 boolean inclDetails, String dumpPackage) { 11328 11329 ArrayList<Pair<ProcessRecord, Integer>> list 11330 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11331 for (int i=0; i<origList.size(); i++) { 11332 ProcessRecord r = origList.get(i); 11333 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11334 continue; 11335 } 11336 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11337 } 11338 11339 if (list.size() <= 0) { 11340 return false; 11341 } 11342 11343 Comparator<Pair<ProcessRecord, Integer>> comparator 11344 = new Comparator<Pair<ProcessRecord, Integer>>() { 11345 @Override 11346 public int compare(Pair<ProcessRecord, Integer> object1, 11347 Pair<ProcessRecord, Integer> object2) { 11348 if (object1.first.setAdj != object2.first.setAdj) { 11349 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11350 } 11351 if (object1.second.intValue() != object2.second.intValue()) { 11352 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11353 } 11354 return 0; 11355 } 11356 }; 11357 11358 Collections.sort(list, comparator); 11359 11360 final long curRealtime = SystemClock.elapsedRealtime(); 11361 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11362 final long curUptime = SystemClock.uptimeMillis(); 11363 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11364 11365 for (int i=list.size()-1; i>=0; i--) { 11366 ProcessRecord r = list.get(i).first; 11367 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11368 char schedGroup; 11369 switch (r.setSchedGroup) { 11370 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11371 schedGroup = 'B'; 11372 break; 11373 case Process.THREAD_GROUP_DEFAULT: 11374 schedGroup = 'F'; 11375 break; 11376 default: 11377 schedGroup = '?'; 11378 break; 11379 } 11380 char foreground; 11381 if (r.foregroundActivities) { 11382 foreground = 'A'; 11383 } else if (r.foregroundServices) { 11384 foreground = 'S'; 11385 } else { 11386 foreground = ' '; 11387 } 11388 String procState = ProcessList.makeProcStateString(r.curProcState); 11389 pw.print(prefix); 11390 pw.print(r.persistent ? persistentLabel : normalLabel); 11391 pw.print(" #"); 11392 int num = (origList.size()-1)-list.get(i).second; 11393 if (num < 10) pw.print(' '); 11394 pw.print(num); 11395 pw.print(": "); 11396 pw.print(oomAdj); 11397 pw.print(' '); 11398 pw.print(schedGroup); 11399 pw.print('/'); 11400 pw.print(foreground); 11401 pw.print('/'); 11402 pw.print(procState); 11403 pw.print(" trm:"); 11404 if (r.trimMemoryLevel < 10) pw.print(' '); 11405 pw.print(r.trimMemoryLevel); 11406 pw.print(' '); 11407 pw.print(r.toShortString()); 11408 pw.print(" ("); 11409 pw.print(r.adjType); 11410 pw.println(')'); 11411 if (r.adjSource != null || r.adjTarget != null) { 11412 pw.print(prefix); 11413 pw.print(" "); 11414 if (r.adjTarget instanceof ComponentName) { 11415 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11416 } else if (r.adjTarget != null) { 11417 pw.print(r.adjTarget.toString()); 11418 } else { 11419 pw.print("{null}"); 11420 } 11421 pw.print("<="); 11422 if (r.adjSource instanceof ProcessRecord) { 11423 pw.print("Proc{"); 11424 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11425 pw.println("}"); 11426 } else if (r.adjSource != null) { 11427 pw.println(r.adjSource.toString()); 11428 } else { 11429 pw.println("{null}"); 11430 } 11431 } 11432 if (inclDetails) { 11433 pw.print(prefix); 11434 pw.print(" "); 11435 pw.print("oom: max="); pw.print(r.maxAdj); 11436 pw.print(" curRaw="); pw.print(r.curRawAdj); 11437 pw.print(" setRaw="); pw.print(r.setRawAdj); 11438 pw.print(" cur="); pw.print(r.curAdj); 11439 pw.print(" set="); pw.println(r.setAdj); 11440 pw.print(prefix); 11441 pw.print(" "); 11442 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11443 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11444 pw.print(" lastPss="); pw.print(r.lastPss); 11445 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11446 pw.print(prefix); 11447 pw.print(" "); 11448 pw.print("keeping="); pw.print(r.keeping); 11449 pw.print(" cached="); pw.print(r.cached); 11450 pw.print(" empty="); pw.print(r.empty); 11451 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11452 11453 if (!r.keeping) { 11454 if (r.lastWakeTime != 0) { 11455 long wtime; 11456 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11457 synchronized (stats) { 11458 wtime = stats.getProcessWakeTime(r.info.uid, 11459 r.pid, curRealtime); 11460 } 11461 long timeUsed = wtime - r.lastWakeTime; 11462 pw.print(prefix); 11463 pw.print(" "); 11464 pw.print("keep awake over "); 11465 TimeUtils.formatDuration(realtimeSince, pw); 11466 pw.print(" used "); 11467 TimeUtils.formatDuration(timeUsed, pw); 11468 pw.print(" ("); 11469 pw.print((timeUsed*100)/realtimeSince); 11470 pw.println("%)"); 11471 } 11472 if (r.lastCpuTime != 0) { 11473 long timeUsed = r.curCpuTime - r.lastCpuTime; 11474 pw.print(prefix); 11475 pw.print(" "); 11476 pw.print("run cpu over "); 11477 TimeUtils.formatDuration(uptimeSince, pw); 11478 pw.print(" used "); 11479 TimeUtils.formatDuration(timeUsed, pw); 11480 pw.print(" ("); 11481 pw.print((timeUsed*100)/uptimeSince); 11482 pw.println("%)"); 11483 } 11484 } 11485 } 11486 } 11487 return true; 11488 } 11489 11490 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11491 ArrayList<ProcessRecord> procs; 11492 synchronized (this) { 11493 if (args != null && args.length > start 11494 && args[start].charAt(0) != '-') { 11495 procs = new ArrayList<ProcessRecord>(); 11496 int pid = -1; 11497 try { 11498 pid = Integer.parseInt(args[start]); 11499 } catch (NumberFormatException e) { 11500 11501 } 11502 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11503 ProcessRecord proc = mLruProcesses.get(i); 11504 if (proc.pid == pid) { 11505 procs.add(proc); 11506 } else if (proc.processName.equals(args[start])) { 11507 procs.add(proc); 11508 } 11509 } 11510 if (procs.size() <= 0) { 11511 pw.println("No process found for: " + args[start]); 11512 return null; 11513 } 11514 } else { 11515 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11516 } 11517 } 11518 return procs; 11519 } 11520 11521 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11522 PrintWriter pw, String[] args) { 11523 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11524 if (procs == null) { 11525 return; 11526 } 11527 11528 long uptime = SystemClock.uptimeMillis(); 11529 long realtime = SystemClock.elapsedRealtime(); 11530 pw.println("Applications Graphics Acceleration Info:"); 11531 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11532 11533 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11534 ProcessRecord r = procs.get(i); 11535 if (r.thread != null) { 11536 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11537 pw.flush(); 11538 try { 11539 TransferPipe tp = new TransferPipe(); 11540 try { 11541 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11542 tp.go(fd); 11543 } finally { 11544 tp.kill(); 11545 } 11546 } catch (IOException e) { 11547 pw.println("Failure while dumping the app: " + r); 11548 pw.flush(); 11549 } catch (RemoteException e) { 11550 pw.println("Got a RemoteException while dumping the app " + r); 11551 pw.flush(); 11552 } 11553 } 11554 } 11555 } 11556 11557 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11558 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11559 if (procs == null) { 11560 return; 11561 } 11562 11563 pw.println("Applications Database Info:"); 11564 11565 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11566 ProcessRecord r = procs.get(i); 11567 if (r.thread != null) { 11568 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11569 pw.flush(); 11570 try { 11571 TransferPipe tp = new TransferPipe(); 11572 try { 11573 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11574 tp.go(fd); 11575 } finally { 11576 tp.kill(); 11577 } 11578 } catch (IOException e) { 11579 pw.println("Failure while dumping the app: " + r); 11580 pw.flush(); 11581 } catch (RemoteException e) { 11582 pw.println("Got a RemoteException while dumping the app " + r); 11583 pw.flush(); 11584 } 11585 } 11586 } 11587 } 11588 11589 final static class MemItem { 11590 final boolean isProc; 11591 final String label; 11592 final String shortLabel; 11593 final long pss; 11594 final int id; 11595 final boolean hasActivities; 11596 ArrayList<MemItem> subitems; 11597 11598 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11599 boolean _hasActivities) { 11600 isProc = true; 11601 label = _label; 11602 shortLabel = _shortLabel; 11603 pss = _pss; 11604 id = _id; 11605 hasActivities = _hasActivities; 11606 } 11607 11608 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11609 isProc = false; 11610 label = _label; 11611 shortLabel = _shortLabel; 11612 pss = _pss; 11613 id = _id; 11614 hasActivities = false; 11615 } 11616 } 11617 11618 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11619 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11620 if (sort && !isCompact) { 11621 Collections.sort(items, new Comparator<MemItem>() { 11622 @Override 11623 public int compare(MemItem lhs, MemItem rhs) { 11624 if (lhs.pss < rhs.pss) { 11625 return 1; 11626 } else if (lhs.pss > rhs.pss) { 11627 return -1; 11628 } 11629 return 0; 11630 } 11631 }); 11632 } 11633 11634 for (int i=0; i<items.size(); i++) { 11635 MemItem mi = items.get(i); 11636 if (!isCompact) { 11637 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11638 } else if (mi.isProc) { 11639 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11640 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11641 pw.println(mi.hasActivities ? ",a" : ",e"); 11642 } else { 11643 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11644 pw.println(mi.pss); 11645 } 11646 if (mi.subitems != null) { 11647 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11648 true, isCompact); 11649 } 11650 } 11651 } 11652 11653 // These are in KB. 11654 static final long[] DUMP_MEM_BUCKETS = new long[] { 11655 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11656 120*1024, 160*1024, 200*1024, 11657 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11658 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11659 }; 11660 11661 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11662 boolean stackLike) { 11663 int start = label.lastIndexOf('.'); 11664 if (start >= 0) start++; 11665 else start = 0; 11666 int end = label.length(); 11667 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11668 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11669 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11670 out.append(bucket); 11671 out.append(stackLike ? "MB." : "MB "); 11672 out.append(label, start, end); 11673 return; 11674 } 11675 } 11676 out.append(memKB/1024); 11677 out.append(stackLike ? "MB." : "MB "); 11678 out.append(label, start, end); 11679 } 11680 11681 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11682 ProcessList.NATIVE_ADJ, 11683 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11684 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11685 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11686 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11687 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11688 }; 11689 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11690 "Native", 11691 "System", "Persistent", "Foreground", 11692 "Visible", "Perceptible", 11693 "Heavy Weight", "Backup", 11694 "A Services", "Home", 11695 "Previous", "B Services", "Cached" 11696 }; 11697 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11698 "native", 11699 "sys", "pers", "fore", 11700 "vis", "percept", 11701 "heavy", "backup", 11702 "servicea", "home", 11703 "prev", "serviceb", "cached" 11704 }; 11705 11706 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11707 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11708 boolean dumpDetails = false; 11709 boolean dumpFullDetails = false; 11710 boolean dumpDalvik = false; 11711 boolean oomOnly = false; 11712 boolean isCompact = false; 11713 11714 int opti = 0; 11715 while (opti < args.length) { 11716 String opt = args[opti]; 11717 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11718 break; 11719 } 11720 opti++; 11721 if ("-a".equals(opt)) { 11722 dumpDetails = true; 11723 dumpFullDetails = true; 11724 dumpDalvik = true; 11725 } else if ("-d".equals(opt)) { 11726 dumpDalvik = true; 11727 } else if ("-c".equals(opt)) { 11728 isCompact = true; 11729 } else if ("--oom".equals(opt)) { 11730 oomOnly = true; 11731 } else if ("-h".equals(opt)) { 11732 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11733 pw.println(" -a: include all available information for each process."); 11734 pw.println(" -d: include dalvik details when dumping process details."); 11735 pw.println(" -c: dump in a compact machine-parseable representation."); 11736 pw.println(" --oom: only show processes organized by oom adj."); 11737 pw.println("If [process] is specified it can be the name or "); 11738 pw.println("pid of a specific process to dump."); 11739 return; 11740 } else { 11741 pw.println("Unknown argument: " + opt + "; use -h for help"); 11742 } 11743 } 11744 11745 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11746 if (procs == null) { 11747 return; 11748 } 11749 11750 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11751 long uptime = SystemClock.uptimeMillis(); 11752 long realtime = SystemClock.elapsedRealtime(); 11753 11754 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11755 dumpDetails = true; 11756 } 11757 11758 if (isCheckinRequest || isCompact) { 11759 // short checkin version 11760 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11761 } else { 11762 pw.println("Applications Memory Usage (kB):"); 11763 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11764 } 11765 11766 String[] innerArgs = new String[args.length-opti]; 11767 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 11768 11769 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 11770 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 11771 long nativePss=0, dalvikPss=0, otherPss=0; 11772 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 11773 11774 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 11775 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 11776 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 11777 final long[] tmpLong = new long[1]; 11778 11779 long totalPss = 0; 11780 long cachedPss = 0; 11781 11782 Debug.MemoryInfo mi = null; 11783 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11784 final ProcessRecord r = procs.get(i); 11785 final IApplicationThread thread; 11786 final int pid; 11787 final int oomAdj; 11788 final boolean hasActivities; 11789 synchronized (this) { 11790 thread = r.thread; 11791 pid = r.pid; 11792 oomAdj = r.getSetAdjWithServices(); 11793 hasActivities = r.hasActivities; 11794 } 11795 if (thread != null) { 11796 if (!isCheckinRequest && dumpDetails) { 11797 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 11798 } 11799 if (mi == null) { 11800 mi = new Debug.MemoryInfo(); 11801 } 11802 if (dumpDetails || (!brief && !oomOnly)) { 11803 Debug.getMemoryInfo(pid, mi); 11804 } else { 11805 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11806 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11807 } 11808 if (dumpDetails) { 11809 try { 11810 pw.flush(); 11811 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 11812 dumpDalvik, innerArgs); 11813 } catch (RemoteException e) { 11814 if (!isCheckinRequest) { 11815 pw.println("Got RemoteException!"); 11816 pw.flush(); 11817 } 11818 } 11819 } 11820 11821 final long myTotalPss = mi.getTotalPss(); 11822 final long myTotalUss = mi.getTotalUss(); 11823 11824 synchronized (this) { 11825 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 11826 // Record this for posterity if the process has been stable. 11827 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 11828 } 11829 } 11830 11831 if (!isCheckinRequest && mi != null) { 11832 totalPss += myTotalPss; 11833 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 11834 (hasActivities ? " / activities)" : ")"), 11835 r.processName, myTotalPss, pid, hasActivities); 11836 procMems.add(pssItem); 11837 procMemsMap.put(pid, pssItem); 11838 11839 nativePss += mi.nativePss; 11840 dalvikPss += mi.dalvikPss; 11841 otherPss += mi.otherPss; 11842 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 11843 long mem = mi.getOtherPss(j); 11844 miscPss[j] += mem; 11845 otherPss -= mem; 11846 } 11847 11848 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 11849 cachedPss += myTotalPss; 11850 } 11851 11852 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 11853 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 11854 || oomIndex == (oomPss.length-1)) { 11855 oomPss[oomIndex] += myTotalPss; 11856 if (oomProcs[oomIndex] == null) { 11857 oomProcs[oomIndex] = new ArrayList<MemItem>(); 11858 } 11859 oomProcs[oomIndex].add(pssItem); 11860 break; 11861 } 11862 } 11863 } 11864 } 11865 } 11866 11867 if (!isCheckinRequest && procs.size() > 1) { 11868 // If we are showing aggregations, also look for native processes to 11869 // include so that our aggregations are more accurate. 11870 updateCpuStatsNow(); 11871 synchronized (mProcessCpuThread) { 11872 final int N = mProcessCpuTracker.countStats(); 11873 for (int i=0; i<N; i++) { 11874 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11875 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 11876 if (mi == null) { 11877 mi = new Debug.MemoryInfo(); 11878 } 11879 if (!brief && !oomOnly) { 11880 Debug.getMemoryInfo(st.pid, mi); 11881 } else { 11882 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 11883 mi.nativePrivateDirty = (int)tmpLong[0]; 11884 } 11885 11886 final long myTotalPss = mi.getTotalPss(); 11887 totalPss += myTotalPss; 11888 11889 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 11890 st.name, myTotalPss, st.pid, false); 11891 procMems.add(pssItem); 11892 11893 nativePss += mi.nativePss; 11894 dalvikPss += mi.dalvikPss; 11895 otherPss += mi.otherPss; 11896 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 11897 long mem = mi.getOtherPss(j); 11898 miscPss[j] += mem; 11899 otherPss -= mem; 11900 } 11901 oomPss[0] += myTotalPss; 11902 if (oomProcs[0] == null) { 11903 oomProcs[0] = new ArrayList<MemItem>(); 11904 } 11905 oomProcs[0].add(pssItem); 11906 } 11907 } 11908 } 11909 11910 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 11911 11912 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 11913 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 11914 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 11915 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 11916 String label = Debug.MemoryInfo.getOtherLabel(j); 11917 catMems.add(new MemItem(label, label, miscPss[j], j)); 11918 } 11919 11920 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 11921 for (int j=0; j<oomPss.length; j++) { 11922 if (oomPss[j] != 0) { 11923 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 11924 : DUMP_MEM_OOM_LABEL[j]; 11925 MemItem item = new MemItem(label, label, oomPss[j], 11926 DUMP_MEM_OOM_ADJ[j]); 11927 item.subitems = oomProcs[j]; 11928 oomMems.add(item); 11929 } 11930 } 11931 11932 if (!brief && !oomOnly && !isCompact) { 11933 pw.println(); 11934 pw.println("Total PSS by process:"); 11935 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 11936 pw.println(); 11937 } 11938 if (!isCompact) { 11939 pw.println("Total PSS by OOM adjustment:"); 11940 } 11941 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 11942 if (!brief && !oomOnly) { 11943 PrintWriter out = categoryPw != null ? categoryPw : pw; 11944 if (!isCompact) { 11945 out.println(); 11946 out.println("Total PSS by category:"); 11947 } 11948 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 11949 } 11950 if (!isCompact) { 11951 pw.println(); 11952 } 11953 MemInfoReader memInfo = new MemInfoReader(); 11954 memInfo.readMemInfo(); 11955 if (!brief) { 11956 if (!isCompact) { 11957 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 11958 pw.println(" kB"); 11959 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 11960 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 11961 pw.print(cachedPss); pw.print(" cached pss + "); 11962 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 11963 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 11964 } else { 11965 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 11966 pw.print(cachedPss + memInfo.getCachedSizeKb() 11967 + memInfo.getFreeSizeKb()); pw.print(","); 11968 pw.println(totalPss - cachedPss); 11969 } 11970 } 11971 if (!isCompact) { 11972 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 11973 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 11974 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 11975 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 11976 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 11977 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 11978 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 11979 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 11980 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 11981 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 11982 - memInfo.getSlabSizeKb()); pw.println(" kB"); 11983 } 11984 if (!brief) { 11985 if (memInfo.getZramTotalSizeKb() != 0) { 11986 if (!isCompact) { 11987 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 11988 pw.print(" kB physical used for "); 11989 pw.print(memInfo.getSwapTotalSizeKb() 11990 - memInfo.getSwapFreeSizeKb()); 11991 pw.print(" kB in swap ("); 11992 pw.print(memInfo.getSwapTotalSizeKb()); 11993 pw.println(" kB total swap)"); 11994 } else { 11995 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 11996 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 11997 pw.println(memInfo.getSwapFreeSizeKb()); 11998 } 11999 } 12000 final int[] SINGLE_LONG_FORMAT = new int[] { 12001 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12002 }; 12003 long[] longOut = new long[1]; 12004 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12005 SINGLE_LONG_FORMAT, null, longOut, null); 12006 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12007 longOut[0] = 0; 12008 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12009 SINGLE_LONG_FORMAT, null, longOut, null); 12010 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12011 longOut[0] = 0; 12012 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12013 SINGLE_LONG_FORMAT, null, longOut, null); 12014 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12015 longOut[0] = 0; 12016 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12017 SINGLE_LONG_FORMAT, null, longOut, null); 12018 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12019 if (!isCompact) { 12020 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12021 pw.print(" KSM: "); pw.print(sharing); 12022 pw.print(" kB saved from shared "); 12023 pw.print(shared); pw.println(" kB"); 12024 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12025 pw.print(voltile); pw.println(" kB volatile"); 12026 } 12027 pw.print(" Tuning: "); 12028 pw.print(ActivityManager.staticGetMemoryClass()); 12029 pw.print(" (large "); 12030 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12031 pw.print("), oom "); 12032 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12033 pw.print(" kB"); 12034 pw.print(", restore limit "); 12035 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12036 pw.print(" kB"); 12037 if (ActivityManager.isLowRamDeviceStatic()) { 12038 pw.print(" (low-ram)"); 12039 } 12040 if (ActivityManager.isHighEndGfx()) { 12041 pw.print(" (high-end-gfx)"); 12042 } 12043 pw.println(); 12044 } else { 12045 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12046 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12047 pw.println(voltile); 12048 pw.print("tuning,"); 12049 pw.print(ActivityManager.staticGetMemoryClass()); 12050 pw.print(','); 12051 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12052 pw.print(','); 12053 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12054 if (ActivityManager.isLowRamDeviceStatic()) { 12055 pw.print(",low-ram"); 12056 } 12057 if (ActivityManager.isHighEndGfx()) { 12058 pw.print(",high-end-gfx"); 12059 } 12060 pw.println(); 12061 } 12062 } 12063 } 12064 } 12065 12066 /** 12067 * Searches array of arguments for the specified string 12068 * @param args array of argument strings 12069 * @param value value to search for 12070 * @return true if the value is contained in the array 12071 */ 12072 private static boolean scanArgs(String[] args, String value) { 12073 if (args != null) { 12074 for (String arg : args) { 12075 if (value.equals(arg)) { 12076 return true; 12077 } 12078 } 12079 } 12080 return false; 12081 } 12082 12083 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12084 ContentProviderRecord cpr, boolean always) { 12085 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12086 12087 if (!inLaunching || always) { 12088 synchronized (cpr) { 12089 cpr.launchingApp = null; 12090 cpr.notifyAll(); 12091 } 12092 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12093 String names[] = cpr.info.authority.split(";"); 12094 for (int j = 0; j < names.length; j++) { 12095 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12096 } 12097 } 12098 12099 for (int i=0; i<cpr.connections.size(); i++) { 12100 ContentProviderConnection conn = cpr.connections.get(i); 12101 if (conn.waiting) { 12102 // If this connection is waiting for the provider, then we don't 12103 // need to mess with its process unless we are always removing 12104 // or for some reason the provider is not currently launching. 12105 if (inLaunching && !always) { 12106 continue; 12107 } 12108 } 12109 ProcessRecord capp = conn.client; 12110 conn.dead = true; 12111 if (conn.stableCount > 0) { 12112 if (!capp.persistent && capp.thread != null 12113 && capp.pid != 0 12114 && capp.pid != MY_PID) { 12115 killUnneededProcessLocked(capp, "depends on provider " 12116 + cpr.name.flattenToShortString() 12117 + " in dying proc " + (proc != null ? proc.processName : "??")); 12118 } 12119 } else if (capp.thread != null && conn.provider.provider != null) { 12120 try { 12121 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12122 } catch (RemoteException e) { 12123 } 12124 // In the protocol here, we don't expect the client to correctly 12125 // clean up this connection, we'll just remove it. 12126 cpr.connections.remove(i); 12127 conn.client.conProviders.remove(conn); 12128 } 12129 } 12130 12131 if (inLaunching && always) { 12132 mLaunchingProviders.remove(cpr); 12133 } 12134 return inLaunching; 12135 } 12136 12137 /** 12138 * Main code for cleaning up a process when it has gone away. This is 12139 * called both as a result of the process dying, or directly when stopping 12140 * a process when running in single process mode. 12141 */ 12142 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12143 boolean restarting, boolean allowRestart, int index) { 12144 if (index >= 0) { 12145 removeLruProcessLocked(app); 12146 } 12147 12148 mProcessesToGc.remove(app); 12149 mPendingPssProcesses.remove(app); 12150 12151 // Dismiss any open dialogs. 12152 if (app.crashDialog != null && !app.forceCrashReport) { 12153 app.crashDialog.dismiss(); 12154 app.crashDialog = null; 12155 } 12156 if (app.anrDialog != null) { 12157 app.anrDialog.dismiss(); 12158 app.anrDialog = null; 12159 } 12160 if (app.waitDialog != null) { 12161 app.waitDialog.dismiss(); 12162 app.waitDialog = null; 12163 } 12164 12165 app.crashing = false; 12166 app.notResponding = false; 12167 12168 app.resetPackageList(mProcessStats); 12169 app.unlinkDeathRecipient(); 12170 app.makeInactive(mProcessStats); 12171 app.forcingToForeground = null; 12172 app.foregroundServices = false; 12173 app.foregroundActivities = false; 12174 app.hasShownUi = false; 12175 app.hasAboveClient = false; 12176 12177 mServices.killServicesLocked(app, allowRestart); 12178 12179 boolean restart = false; 12180 12181 // Remove published content providers. 12182 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12183 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12184 final boolean always = app.bad || !allowRestart; 12185 if (removeDyingProviderLocked(app, cpr, always) || always) { 12186 // We left the provider in the launching list, need to 12187 // restart it. 12188 restart = true; 12189 } 12190 12191 cpr.provider = null; 12192 cpr.proc = null; 12193 } 12194 app.pubProviders.clear(); 12195 12196 // Take care of any launching providers waiting for this process. 12197 if (checkAppInLaunchingProvidersLocked(app, false)) { 12198 restart = true; 12199 } 12200 12201 // Unregister from connected content providers. 12202 if (!app.conProviders.isEmpty()) { 12203 for (int i=0; i<app.conProviders.size(); i++) { 12204 ContentProviderConnection conn = app.conProviders.get(i); 12205 conn.provider.connections.remove(conn); 12206 } 12207 app.conProviders.clear(); 12208 } 12209 12210 // At this point there may be remaining entries in mLaunchingProviders 12211 // where we were the only one waiting, so they are no longer of use. 12212 // Look for these and clean up if found. 12213 // XXX Commented out for now. Trying to figure out a way to reproduce 12214 // the actual situation to identify what is actually going on. 12215 if (false) { 12216 for (int i=0; i<mLaunchingProviders.size(); i++) { 12217 ContentProviderRecord cpr = (ContentProviderRecord) 12218 mLaunchingProviders.get(i); 12219 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12220 synchronized (cpr) { 12221 cpr.launchingApp = null; 12222 cpr.notifyAll(); 12223 } 12224 } 12225 } 12226 } 12227 12228 skipCurrentReceiverLocked(app); 12229 12230 // Unregister any receivers. 12231 for (int i=app.receivers.size()-1; i>=0; i--) { 12232 removeReceiverLocked(app.receivers.valueAt(i)); 12233 } 12234 app.receivers.clear(); 12235 12236 // If the app is undergoing backup, tell the backup manager about it 12237 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12238 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12239 + mBackupTarget.appInfo + " died during backup"); 12240 try { 12241 IBackupManager bm = IBackupManager.Stub.asInterface( 12242 ServiceManager.getService(Context.BACKUP_SERVICE)); 12243 bm.agentDisconnected(app.info.packageName); 12244 } catch (RemoteException e) { 12245 // can't happen; backup manager is local 12246 } 12247 } 12248 12249 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12250 ProcessChangeItem item = mPendingProcessChanges.get(i); 12251 if (item.pid == app.pid) { 12252 mPendingProcessChanges.remove(i); 12253 mAvailProcessChanges.add(item); 12254 } 12255 } 12256 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12257 12258 // If the caller is restarting this app, then leave it in its 12259 // current lists and let the caller take care of it. 12260 if (restarting) { 12261 return; 12262 } 12263 12264 if (!app.persistent || app.isolated) { 12265 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12266 "Removing non-persistent process during cleanup: " + app); 12267 mProcessNames.remove(app.processName, app.uid); 12268 mIsolatedProcesses.remove(app.uid); 12269 if (mHeavyWeightProcess == app) { 12270 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12271 mHeavyWeightProcess.userId, 0)); 12272 mHeavyWeightProcess = null; 12273 } 12274 } else if (!app.removed) { 12275 // This app is persistent, so we need to keep its record around. 12276 // If it is not already on the pending app list, add it there 12277 // and start a new process for it. 12278 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12279 mPersistentStartingProcesses.add(app); 12280 restart = true; 12281 } 12282 } 12283 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12284 "Clean-up removing on hold: " + app); 12285 mProcessesOnHold.remove(app); 12286 12287 if (app == mHomeProcess) { 12288 mHomeProcess = null; 12289 } 12290 if (app == mPreviousProcess) { 12291 mPreviousProcess = null; 12292 } 12293 12294 if (restart && !app.isolated) { 12295 // We have components that still need to be running in the 12296 // process, so re-launch it. 12297 mProcessNames.put(app.processName, app.uid, app); 12298 startProcessLocked(app, "restart", app.processName); 12299 } else if (app.pid > 0 && app.pid != MY_PID) { 12300 // Goodbye! 12301 synchronized (mPidsSelfLocked) { 12302 mPidsSelfLocked.remove(app.pid); 12303 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12304 } 12305 app.setPid(0); 12306 } 12307 } 12308 12309 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12310 // Look through the content providers we are waiting to have launched, 12311 // and if any run in this process then either schedule a restart of 12312 // the process or kill the client waiting for it if this process has 12313 // gone bad. 12314 int NL = mLaunchingProviders.size(); 12315 boolean restart = false; 12316 for (int i=0; i<NL; i++) { 12317 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12318 if (cpr.launchingApp == app) { 12319 if (!alwaysBad && !app.bad) { 12320 restart = true; 12321 } else { 12322 removeDyingProviderLocked(app, cpr, true); 12323 // cpr should have been removed from mLaunchingProviders 12324 NL = mLaunchingProviders.size(); 12325 i--; 12326 } 12327 } 12328 } 12329 return restart; 12330 } 12331 12332 // ========================================================= 12333 // SERVICES 12334 // ========================================================= 12335 12336 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12337 int flags) { 12338 enforceNotIsolatedCaller("getServices"); 12339 synchronized (this) { 12340 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12341 } 12342 } 12343 12344 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12345 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12346 synchronized (this) { 12347 return mServices.getRunningServiceControlPanelLocked(name); 12348 } 12349 } 12350 12351 public ComponentName startService(IApplicationThread caller, Intent service, 12352 String resolvedType, int userId) { 12353 enforceNotIsolatedCaller("startService"); 12354 // Refuse possible leaked file descriptors 12355 if (service != null && service.hasFileDescriptors() == true) { 12356 throw new IllegalArgumentException("File descriptors passed in Intent"); 12357 } 12358 12359 if (DEBUG_SERVICE) 12360 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12361 synchronized(this) { 12362 final int callingPid = Binder.getCallingPid(); 12363 final int callingUid = Binder.getCallingUid(); 12364 checkValidCaller(callingUid, userId); 12365 final long origId = Binder.clearCallingIdentity(); 12366 ComponentName res = mServices.startServiceLocked(caller, service, 12367 resolvedType, callingPid, callingUid, userId); 12368 Binder.restoreCallingIdentity(origId); 12369 return res; 12370 } 12371 } 12372 12373 ComponentName startServiceInPackage(int uid, 12374 Intent service, String resolvedType, int userId) { 12375 synchronized(this) { 12376 if (DEBUG_SERVICE) 12377 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12378 final long origId = Binder.clearCallingIdentity(); 12379 ComponentName res = mServices.startServiceLocked(null, service, 12380 resolvedType, -1, uid, userId); 12381 Binder.restoreCallingIdentity(origId); 12382 return res; 12383 } 12384 } 12385 12386 public int stopService(IApplicationThread caller, Intent service, 12387 String resolvedType, int userId) { 12388 enforceNotIsolatedCaller("stopService"); 12389 // Refuse possible leaked file descriptors 12390 if (service != null && service.hasFileDescriptors() == true) { 12391 throw new IllegalArgumentException("File descriptors passed in Intent"); 12392 } 12393 12394 checkValidCaller(Binder.getCallingUid(), userId); 12395 12396 synchronized(this) { 12397 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12398 } 12399 } 12400 12401 public IBinder peekService(Intent service, String resolvedType) { 12402 enforceNotIsolatedCaller("peekService"); 12403 // Refuse possible leaked file descriptors 12404 if (service != null && service.hasFileDescriptors() == true) { 12405 throw new IllegalArgumentException("File descriptors passed in Intent"); 12406 } 12407 synchronized(this) { 12408 return mServices.peekServiceLocked(service, resolvedType); 12409 } 12410 } 12411 12412 public boolean stopServiceToken(ComponentName className, IBinder token, 12413 int startId) { 12414 synchronized(this) { 12415 return mServices.stopServiceTokenLocked(className, token, startId); 12416 } 12417 } 12418 12419 public void setServiceForeground(ComponentName className, IBinder token, 12420 int id, Notification notification, boolean removeNotification) { 12421 synchronized(this) { 12422 mServices.setServiceForegroundLocked(className, token, id, notification, 12423 removeNotification); 12424 } 12425 } 12426 12427 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12428 boolean requireFull, String name, String callerPackage) { 12429 final int callingUserId = UserHandle.getUserId(callingUid); 12430 if (callingUserId != userId) { 12431 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12432 if ((requireFull || checkComponentPermission( 12433 android.Manifest.permission.INTERACT_ACROSS_USERS, 12434 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12435 && checkComponentPermission( 12436 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12437 callingPid, callingUid, -1, true) 12438 != PackageManager.PERMISSION_GRANTED) { 12439 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12440 // In this case, they would like to just execute as their 12441 // owner user instead of failing. 12442 userId = callingUserId; 12443 } else { 12444 StringBuilder builder = new StringBuilder(128); 12445 builder.append("Permission Denial: "); 12446 builder.append(name); 12447 if (callerPackage != null) { 12448 builder.append(" from "); 12449 builder.append(callerPackage); 12450 } 12451 builder.append(" asks to run as user "); 12452 builder.append(userId); 12453 builder.append(" but is calling from user "); 12454 builder.append(UserHandle.getUserId(callingUid)); 12455 builder.append("; this requires "); 12456 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12457 if (!requireFull) { 12458 builder.append(" or "); 12459 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12460 } 12461 String msg = builder.toString(); 12462 Slog.w(TAG, msg); 12463 throw new SecurityException(msg); 12464 } 12465 } 12466 } 12467 if (userId == UserHandle.USER_CURRENT 12468 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12469 // Note that we may be accessing this outside of a lock... 12470 // shouldn't be a big deal, if this is being called outside 12471 // of a locked context there is intrinsically a race with 12472 // the value the caller will receive and someone else changing it. 12473 userId = mCurrentUserId; 12474 } 12475 if (!allowAll && userId < 0) { 12476 throw new IllegalArgumentException( 12477 "Call does not support special user #" + userId); 12478 } 12479 } 12480 return userId; 12481 } 12482 12483 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12484 String className, int flags) { 12485 boolean result = false; 12486 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12487 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12488 if (ActivityManager.checkUidPermission( 12489 android.Manifest.permission.INTERACT_ACROSS_USERS, 12490 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12491 ComponentName comp = new ComponentName(aInfo.packageName, className); 12492 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12493 + " requests FLAG_SINGLE_USER, but app does not hold " 12494 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12495 Slog.w(TAG, msg); 12496 throw new SecurityException(msg); 12497 } 12498 result = true; 12499 } 12500 } else if (componentProcessName == aInfo.packageName) { 12501 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12502 } else if ("system".equals(componentProcessName)) { 12503 result = true; 12504 } 12505 if (DEBUG_MU) { 12506 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12507 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12508 } 12509 return result; 12510 } 12511 12512 public int bindService(IApplicationThread caller, IBinder token, 12513 Intent service, String resolvedType, 12514 IServiceConnection connection, int flags, int userId) { 12515 enforceNotIsolatedCaller("bindService"); 12516 // Refuse possible leaked file descriptors 12517 if (service != null && service.hasFileDescriptors() == true) { 12518 throw new IllegalArgumentException("File descriptors passed in Intent"); 12519 } 12520 12521 synchronized(this) { 12522 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12523 connection, flags, userId); 12524 } 12525 } 12526 12527 public boolean unbindService(IServiceConnection connection) { 12528 synchronized (this) { 12529 return mServices.unbindServiceLocked(connection); 12530 } 12531 } 12532 12533 public void publishService(IBinder token, Intent intent, IBinder service) { 12534 // Refuse possible leaked file descriptors 12535 if (intent != null && intent.hasFileDescriptors() == true) { 12536 throw new IllegalArgumentException("File descriptors passed in Intent"); 12537 } 12538 12539 synchronized(this) { 12540 if (!(token instanceof ServiceRecord)) { 12541 throw new IllegalArgumentException("Invalid service token"); 12542 } 12543 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12544 } 12545 } 12546 12547 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12548 // Refuse possible leaked file descriptors 12549 if (intent != null && intent.hasFileDescriptors() == true) { 12550 throw new IllegalArgumentException("File descriptors passed in Intent"); 12551 } 12552 12553 synchronized(this) { 12554 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12555 } 12556 } 12557 12558 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12559 synchronized(this) { 12560 if (!(token instanceof ServiceRecord)) { 12561 throw new IllegalArgumentException("Invalid service token"); 12562 } 12563 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12564 } 12565 } 12566 12567 // ========================================================= 12568 // BACKUP AND RESTORE 12569 // ========================================================= 12570 12571 // Cause the target app to be launched if necessary and its backup agent 12572 // instantiated. The backup agent will invoke backupAgentCreated() on the 12573 // activity manager to announce its creation. 12574 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12575 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12576 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12577 12578 synchronized(this) { 12579 // !!! TODO: currently no check here that we're already bound 12580 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12581 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12582 synchronized (stats) { 12583 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12584 } 12585 12586 // Backup agent is now in use, its package can't be stopped. 12587 try { 12588 AppGlobals.getPackageManager().setPackageStoppedState( 12589 app.packageName, false, UserHandle.getUserId(app.uid)); 12590 } catch (RemoteException e) { 12591 } catch (IllegalArgumentException e) { 12592 Slog.w(TAG, "Failed trying to unstop package " 12593 + app.packageName + ": " + e); 12594 } 12595 12596 BackupRecord r = new BackupRecord(ss, app, backupMode); 12597 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12598 ? new ComponentName(app.packageName, app.backupAgentName) 12599 : new ComponentName("android", "FullBackupAgent"); 12600 // startProcessLocked() returns existing proc's record if it's already running 12601 ProcessRecord proc = startProcessLocked(app.processName, app, 12602 false, 0, "backup", hostingName, false, false, false); 12603 if (proc == null) { 12604 Slog.e(TAG, "Unable to start backup agent process " + r); 12605 return false; 12606 } 12607 12608 r.app = proc; 12609 mBackupTarget = r; 12610 mBackupAppName = app.packageName; 12611 12612 // Try not to kill the process during backup 12613 updateOomAdjLocked(proc); 12614 12615 // If the process is already attached, schedule the creation of the backup agent now. 12616 // If it is not yet live, this will be done when it attaches to the framework. 12617 if (proc.thread != null) { 12618 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12619 try { 12620 proc.thread.scheduleCreateBackupAgent(app, 12621 compatibilityInfoForPackageLocked(app), backupMode); 12622 } catch (RemoteException e) { 12623 // Will time out on the backup manager side 12624 } 12625 } else { 12626 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12627 } 12628 // Invariants: at this point, the target app process exists and the application 12629 // is either already running or in the process of coming up. mBackupTarget and 12630 // mBackupAppName describe the app, so that when it binds back to the AM we 12631 // know that it's scheduled for a backup-agent operation. 12632 } 12633 12634 return true; 12635 } 12636 12637 @Override 12638 public void clearPendingBackup() { 12639 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12640 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12641 12642 synchronized (this) { 12643 mBackupTarget = null; 12644 mBackupAppName = null; 12645 } 12646 } 12647 12648 // A backup agent has just come up 12649 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12650 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12651 + " = " + agent); 12652 12653 synchronized(this) { 12654 if (!agentPackageName.equals(mBackupAppName)) { 12655 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12656 return; 12657 } 12658 } 12659 12660 long oldIdent = Binder.clearCallingIdentity(); 12661 try { 12662 IBackupManager bm = IBackupManager.Stub.asInterface( 12663 ServiceManager.getService(Context.BACKUP_SERVICE)); 12664 bm.agentConnected(agentPackageName, agent); 12665 } catch (RemoteException e) { 12666 // can't happen; the backup manager service is local 12667 } catch (Exception e) { 12668 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12669 e.printStackTrace(); 12670 } finally { 12671 Binder.restoreCallingIdentity(oldIdent); 12672 } 12673 } 12674 12675 // done with this agent 12676 public void unbindBackupAgent(ApplicationInfo appInfo) { 12677 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12678 if (appInfo == null) { 12679 Slog.w(TAG, "unbind backup agent for null app"); 12680 return; 12681 } 12682 12683 synchronized(this) { 12684 try { 12685 if (mBackupAppName == null) { 12686 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12687 return; 12688 } 12689 12690 if (!mBackupAppName.equals(appInfo.packageName)) { 12691 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12692 return; 12693 } 12694 12695 // Not backing this app up any more; reset its OOM adjustment 12696 final ProcessRecord proc = mBackupTarget.app; 12697 updateOomAdjLocked(proc); 12698 12699 // If the app crashed during backup, 'thread' will be null here 12700 if (proc.thread != null) { 12701 try { 12702 proc.thread.scheduleDestroyBackupAgent(appInfo, 12703 compatibilityInfoForPackageLocked(appInfo)); 12704 } catch (Exception e) { 12705 Slog.e(TAG, "Exception when unbinding backup agent:"); 12706 e.printStackTrace(); 12707 } 12708 } 12709 } finally { 12710 mBackupTarget = null; 12711 mBackupAppName = null; 12712 } 12713 } 12714 } 12715 // ========================================================= 12716 // BROADCASTS 12717 // ========================================================= 12718 12719 private final List getStickiesLocked(String action, IntentFilter filter, 12720 List cur, int userId) { 12721 final ContentResolver resolver = mContext.getContentResolver(); 12722 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12723 if (stickies == null) { 12724 return cur; 12725 } 12726 final ArrayList<Intent> list = stickies.get(action); 12727 if (list == null) { 12728 return cur; 12729 } 12730 int N = list.size(); 12731 for (int i=0; i<N; i++) { 12732 Intent intent = list.get(i); 12733 if (filter.match(resolver, intent, true, TAG) >= 0) { 12734 if (cur == null) { 12735 cur = new ArrayList<Intent>(); 12736 } 12737 cur.add(intent); 12738 } 12739 } 12740 return cur; 12741 } 12742 12743 boolean isPendingBroadcastProcessLocked(int pid) { 12744 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12745 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12746 } 12747 12748 void skipPendingBroadcastLocked(int pid) { 12749 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12750 for (BroadcastQueue queue : mBroadcastQueues) { 12751 queue.skipPendingBroadcastLocked(pid); 12752 } 12753 } 12754 12755 // The app just attached; send any pending broadcasts that it should receive 12756 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12757 boolean didSomething = false; 12758 for (BroadcastQueue queue : mBroadcastQueues) { 12759 didSomething |= queue.sendPendingBroadcastsLocked(app); 12760 } 12761 return didSomething; 12762 } 12763 12764 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 12765 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 12766 enforceNotIsolatedCaller("registerReceiver"); 12767 int callingUid; 12768 int callingPid; 12769 synchronized(this) { 12770 ProcessRecord callerApp = null; 12771 if (caller != null) { 12772 callerApp = getRecordForAppLocked(caller); 12773 if (callerApp == null) { 12774 throw new SecurityException( 12775 "Unable to find app for caller " + caller 12776 + " (pid=" + Binder.getCallingPid() 12777 + ") when registering receiver " + receiver); 12778 } 12779 if (callerApp.info.uid != Process.SYSTEM_UID && 12780 !callerApp.pkgList.containsKey(callerPackage)) { 12781 throw new SecurityException("Given caller package " + callerPackage 12782 + " is not running in process " + callerApp); 12783 } 12784 callingUid = callerApp.info.uid; 12785 callingPid = callerApp.pid; 12786 } else { 12787 callerPackage = null; 12788 callingUid = Binder.getCallingUid(); 12789 callingPid = Binder.getCallingPid(); 12790 } 12791 12792 userId = this.handleIncomingUser(callingPid, callingUid, userId, 12793 true, true, "registerReceiver", callerPackage); 12794 12795 List allSticky = null; 12796 12797 // Look for any matching sticky broadcasts... 12798 Iterator actions = filter.actionsIterator(); 12799 if (actions != null) { 12800 while (actions.hasNext()) { 12801 String action = (String)actions.next(); 12802 allSticky = getStickiesLocked(action, filter, allSticky, 12803 UserHandle.USER_ALL); 12804 allSticky = getStickiesLocked(action, filter, allSticky, 12805 UserHandle.getUserId(callingUid)); 12806 } 12807 } else { 12808 allSticky = getStickiesLocked(null, filter, allSticky, 12809 UserHandle.USER_ALL); 12810 allSticky = getStickiesLocked(null, filter, allSticky, 12811 UserHandle.getUserId(callingUid)); 12812 } 12813 12814 // The first sticky in the list is returned directly back to 12815 // the client. 12816 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12817 12818 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12819 + ": " + sticky); 12820 12821 if (receiver == null) { 12822 return sticky; 12823 } 12824 12825 ReceiverList rl 12826 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12827 if (rl == null) { 12828 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 12829 userId, receiver); 12830 if (rl.app != null) { 12831 rl.app.receivers.add(rl); 12832 } else { 12833 try { 12834 receiver.asBinder().linkToDeath(rl, 0); 12835 } catch (RemoteException e) { 12836 return sticky; 12837 } 12838 rl.linkedToDeath = true; 12839 } 12840 mRegisteredReceivers.put(receiver.asBinder(), rl); 12841 } else if (rl.uid != callingUid) { 12842 throw new IllegalArgumentException( 12843 "Receiver requested to register for uid " + callingUid 12844 + " was previously registered for uid " + rl.uid); 12845 } else if (rl.pid != callingPid) { 12846 throw new IllegalArgumentException( 12847 "Receiver requested to register for pid " + callingPid 12848 + " was previously registered for pid " + rl.pid); 12849 } else if (rl.userId != userId) { 12850 throw new IllegalArgumentException( 12851 "Receiver requested to register for user " + userId 12852 + " was previously registered for user " + rl.userId); 12853 } 12854 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 12855 permission, callingUid, userId); 12856 rl.add(bf); 12857 if (!bf.debugCheck()) { 12858 Slog.w(TAG, "==> For Dynamic broadast"); 12859 } 12860 mReceiverResolver.addFilter(bf); 12861 12862 // Enqueue broadcasts for all existing stickies that match 12863 // this filter. 12864 if (allSticky != null) { 12865 ArrayList receivers = new ArrayList(); 12866 receivers.add(bf); 12867 12868 int N = allSticky.size(); 12869 for (int i=0; i<N; i++) { 12870 Intent intent = (Intent)allSticky.get(i); 12871 BroadcastQueue queue = broadcastQueueForIntent(intent); 12872 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 12873 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 12874 null, null, false, true, true, -1); 12875 queue.enqueueParallelBroadcastLocked(r); 12876 queue.scheduleBroadcastsLocked(); 12877 } 12878 } 12879 12880 return sticky; 12881 } 12882 } 12883 12884 public void unregisterReceiver(IIntentReceiver receiver) { 12885 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 12886 12887 final long origId = Binder.clearCallingIdentity(); 12888 try { 12889 boolean doTrim = false; 12890 12891 synchronized(this) { 12892 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 12893 if (rl != null) { 12894 if (rl.curBroadcast != null) { 12895 BroadcastRecord r = rl.curBroadcast; 12896 final boolean doNext = finishReceiverLocked( 12897 receiver.asBinder(), r.resultCode, r.resultData, 12898 r.resultExtras, r.resultAbort); 12899 if (doNext) { 12900 doTrim = true; 12901 r.queue.processNextBroadcast(false); 12902 } 12903 } 12904 12905 if (rl.app != null) { 12906 rl.app.receivers.remove(rl); 12907 } 12908 removeReceiverLocked(rl); 12909 if (rl.linkedToDeath) { 12910 rl.linkedToDeath = false; 12911 rl.receiver.asBinder().unlinkToDeath(rl, 0); 12912 } 12913 } 12914 } 12915 12916 // If we actually concluded any broadcasts, we might now be able 12917 // to trim the recipients' apps from our working set 12918 if (doTrim) { 12919 trimApplications(); 12920 return; 12921 } 12922 12923 } finally { 12924 Binder.restoreCallingIdentity(origId); 12925 } 12926 } 12927 12928 void removeReceiverLocked(ReceiverList rl) { 12929 mRegisteredReceivers.remove(rl.receiver.asBinder()); 12930 int N = rl.size(); 12931 for (int i=0; i<N; i++) { 12932 mReceiverResolver.removeFilter(rl.get(i)); 12933 } 12934 } 12935 12936 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 12937 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 12938 ProcessRecord r = mLruProcesses.get(i); 12939 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 12940 try { 12941 r.thread.dispatchPackageBroadcast(cmd, packages); 12942 } catch (RemoteException ex) { 12943 } 12944 } 12945 } 12946 } 12947 12948 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 12949 int[] users) { 12950 List<ResolveInfo> receivers = null; 12951 try { 12952 HashSet<ComponentName> singleUserReceivers = null; 12953 boolean scannedFirstReceivers = false; 12954 for (int user : users) { 12955 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 12956 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 12957 if (user != 0 && newReceivers != null) { 12958 // If this is not the primary user, we need to check for 12959 // any receivers that should be filtered out. 12960 for (int i=0; i<newReceivers.size(); i++) { 12961 ResolveInfo ri = newReceivers.get(i); 12962 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 12963 newReceivers.remove(i); 12964 i--; 12965 } 12966 } 12967 } 12968 if (newReceivers != null && newReceivers.size() == 0) { 12969 newReceivers = null; 12970 } 12971 if (receivers == null) { 12972 receivers = newReceivers; 12973 } else if (newReceivers != null) { 12974 // We need to concatenate the additional receivers 12975 // found with what we have do far. This would be easy, 12976 // but we also need to de-dup any receivers that are 12977 // singleUser. 12978 if (!scannedFirstReceivers) { 12979 // Collect any single user receivers we had already retrieved. 12980 scannedFirstReceivers = true; 12981 for (int i=0; i<receivers.size(); i++) { 12982 ResolveInfo ri = receivers.get(i); 12983 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 12984 ComponentName cn = new ComponentName( 12985 ri.activityInfo.packageName, ri.activityInfo.name); 12986 if (singleUserReceivers == null) { 12987 singleUserReceivers = new HashSet<ComponentName>(); 12988 } 12989 singleUserReceivers.add(cn); 12990 } 12991 } 12992 } 12993 // Add the new results to the existing results, tracking 12994 // and de-dupping single user receivers. 12995 for (int i=0; i<newReceivers.size(); i++) { 12996 ResolveInfo ri = newReceivers.get(i); 12997 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 12998 ComponentName cn = new ComponentName( 12999 ri.activityInfo.packageName, ri.activityInfo.name); 13000 if (singleUserReceivers == null) { 13001 singleUserReceivers = new HashSet<ComponentName>(); 13002 } 13003 if (!singleUserReceivers.contains(cn)) { 13004 singleUserReceivers.add(cn); 13005 receivers.add(ri); 13006 } 13007 } else { 13008 receivers.add(ri); 13009 } 13010 } 13011 } 13012 } 13013 } catch (RemoteException ex) { 13014 // pm is in same process, this will never happen. 13015 } 13016 return receivers; 13017 } 13018 13019 private final int broadcastIntentLocked(ProcessRecord callerApp, 13020 String callerPackage, Intent intent, String resolvedType, 13021 IIntentReceiver resultTo, int resultCode, String resultData, 13022 Bundle map, String requiredPermission, int appOp, 13023 boolean ordered, boolean sticky, int callingPid, int callingUid, 13024 int userId) { 13025 intent = new Intent(intent); 13026 13027 // By default broadcasts do not go to stopped apps. 13028 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13029 13030 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13031 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13032 + " ordered=" + ordered + " userid=" + userId); 13033 if ((resultTo != null) && !ordered) { 13034 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13035 } 13036 13037 userId = handleIncomingUser(callingPid, callingUid, userId, 13038 true, false, "broadcast", callerPackage); 13039 13040 // Make sure that the user who is receiving this broadcast is started. 13041 // If not, we will just skip it. 13042 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13043 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13044 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13045 Slog.w(TAG, "Skipping broadcast of " + intent 13046 + ": user " + userId + " is stopped"); 13047 return ActivityManager.BROADCAST_SUCCESS; 13048 } 13049 } 13050 13051 /* 13052 * Prevent non-system code (defined here to be non-persistent 13053 * processes) from sending protected broadcasts. 13054 */ 13055 int callingAppId = UserHandle.getAppId(callingUid); 13056 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13057 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13058 callingUid == 0) { 13059 // Always okay. 13060 } else if (callerApp == null || !callerApp.persistent) { 13061 try { 13062 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13063 intent.getAction())) { 13064 String msg = "Permission Denial: not allowed to send broadcast " 13065 + intent.getAction() + " from pid=" 13066 + callingPid + ", uid=" + callingUid; 13067 Slog.w(TAG, msg); 13068 throw new SecurityException(msg); 13069 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13070 // Special case for compatibility: we don't want apps to send this, 13071 // but historically it has not been protected and apps may be using it 13072 // to poke their own app widget. So, instead of making it protected, 13073 // just limit it to the caller. 13074 if (callerApp == null) { 13075 String msg = "Permission Denial: not allowed to send broadcast " 13076 + intent.getAction() + " from unknown caller."; 13077 Slog.w(TAG, msg); 13078 throw new SecurityException(msg); 13079 } else if (intent.getComponent() != null) { 13080 // They are good enough to send to an explicit component... verify 13081 // it is being sent to the calling app. 13082 if (!intent.getComponent().getPackageName().equals( 13083 callerApp.info.packageName)) { 13084 String msg = "Permission Denial: not allowed to send broadcast " 13085 + intent.getAction() + " to " 13086 + intent.getComponent().getPackageName() + " from " 13087 + callerApp.info.packageName; 13088 Slog.w(TAG, msg); 13089 throw new SecurityException(msg); 13090 } 13091 } else { 13092 // Limit broadcast to their own package. 13093 intent.setPackage(callerApp.info.packageName); 13094 } 13095 } 13096 } catch (RemoteException e) { 13097 Slog.w(TAG, "Remote exception", e); 13098 return ActivityManager.BROADCAST_SUCCESS; 13099 } 13100 } 13101 13102 // Handle special intents: if this broadcast is from the package 13103 // manager about a package being removed, we need to remove all of 13104 // its activities from the history stack. 13105 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13106 intent.getAction()); 13107 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13108 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13109 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13110 || uidRemoved) { 13111 if (checkComponentPermission( 13112 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13113 callingPid, callingUid, -1, true) 13114 == PackageManager.PERMISSION_GRANTED) { 13115 if (uidRemoved) { 13116 final Bundle intentExtras = intent.getExtras(); 13117 final int uid = intentExtras != null 13118 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13119 if (uid >= 0) { 13120 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13121 synchronized (bs) { 13122 bs.removeUidStatsLocked(uid); 13123 } 13124 mAppOpsService.uidRemoved(uid); 13125 } 13126 } else { 13127 // If resources are unavailable just force stop all 13128 // those packages and flush the attribute cache as well. 13129 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13130 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13131 if (list != null && (list.length > 0)) { 13132 for (String pkg : list) { 13133 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13134 "storage unmount"); 13135 } 13136 sendPackageBroadcastLocked( 13137 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13138 } 13139 } else { 13140 Uri data = intent.getData(); 13141 String ssp; 13142 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13143 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13144 intent.getAction()); 13145 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13146 forceStopPackageLocked(ssp, UserHandle.getAppId( 13147 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13148 false, userId, removed ? "pkg removed" : "pkg changed"); 13149 } 13150 if (removed) { 13151 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13152 new String[] {ssp}, userId); 13153 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13154 mAppOpsService.packageRemoved( 13155 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13156 13157 // Remove all permissions granted from/to this package 13158 removeUriPermissionsForPackageLocked(ssp, userId, true); 13159 } 13160 } 13161 } 13162 } 13163 } 13164 } else { 13165 String msg = "Permission Denial: " + intent.getAction() 13166 + " broadcast from " + callerPackage + " (pid=" + callingPid 13167 + ", uid=" + callingUid + ")" 13168 + " requires " 13169 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13170 Slog.w(TAG, msg); 13171 throw new SecurityException(msg); 13172 } 13173 13174 // Special case for adding a package: by default turn on compatibility 13175 // mode. 13176 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13177 Uri data = intent.getData(); 13178 String ssp; 13179 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13180 mCompatModePackages.handlePackageAddedLocked(ssp, 13181 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13182 } 13183 } 13184 13185 /* 13186 * If this is the time zone changed action, queue up a message that will reset the timezone 13187 * of all currently running processes. This message will get queued up before the broadcast 13188 * happens. 13189 */ 13190 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13191 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13192 } 13193 13194 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13195 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13196 } 13197 13198 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13199 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13200 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13201 } 13202 13203 // Add to the sticky list if requested. 13204 if (sticky) { 13205 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13206 callingPid, callingUid) 13207 != PackageManager.PERMISSION_GRANTED) { 13208 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13209 + callingPid + ", uid=" + callingUid 13210 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13211 Slog.w(TAG, msg); 13212 throw new SecurityException(msg); 13213 } 13214 if (requiredPermission != null) { 13215 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13216 + " and enforce permission " + requiredPermission); 13217 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13218 } 13219 if (intent.getComponent() != null) { 13220 throw new SecurityException( 13221 "Sticky broadcasts can't target a specific component"); 13222 } 13223 // We use userId directly here, since the "all" target is maintained 13224 // as a separate set of sticky broadcasts. 13225 if (userId != UserHandle.USER_ALL) { 13226 // But first, if this is not a broadcast to all users, then 13227 // make sure it doesn't conflict with an existing broadcast to 13228 // all users. 13229 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13230 UserHandle.USER_ALL); 13231 if (stickies != null) { 13232 ArrayList<Intent> list = stickies.get(intent.getAction()); 13233 if (list != null) { 13234 int N = list.size(); 13235 int i; 13236 for (i=0; i<N; i++) { 13237 if (intent.filterEquals(list.get(i))) { 13238 throw new IllegalArgumentException( 13239 "Sticky broadcast " + intent + " for user " 13240 + userId + " conflicts with existing global broadcast"); 13241 } 13242 } 13243 } 13244 } 13245 } 13246 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13247 if (stickies == null) { 13248 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13249 mStickyBroadcasts.put(userId, stickies); 13250 } 13251 ArrayList<Intent> list = stickies.get(intent.getAction()); 13252 if (list == null) { 13253 list = new ArrayList<Intent>(); 13254 stickies.put(intent.getAction(), list); 13255 } 13256 int N = list.size(); 13257 int i; 13258 for (i=0; i<N; i++) { 13259 if (intent.filterEquals(list.get(i))) { 13260 // This sticky already exists, replace it. 13261 list.set(i, new Intent(intent)); 13262 break; 13263 } 13264 } 13265 if (i >= N) { 13266 list.add(new Intent(intent)); 13267 } 13268 } 13269 13270 int[] users; 13271 if (userId == UserHandle.USER_ALL) { 13272 // Caller wants broadcast to go to all started users. 13273 users = mStartedUserArray; 13274 } else { 13275 // Caller wants broadcast to go to one specific user. 13276 users = new int[] {userId}; 13277 } 13278 13279 // Figure out who all will receive this broadcast. 13280 List receivers = null; 13281 List<BroadcastFilter> registeredReceivers = null; 13282 // Need to resolve the intent to interested receivers... 13283 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13284 == 0) { 13285 receivers = collectReceiverComponents(intent, resolvedType, users); 13286 } 13287 if (intent.getComponent() == null) { 13288 registeredReceivers = mReceiverResolver.queryIntent(intent, 13289 resolvedType, false, userId); 13290 } 13291 13292 final boolean replacePending = 13293 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13294 13295 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13296 + " replacePending=" + replacePending); 13297 13298 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13299 if (!ordered && NR > 0) { 13300 // If we are not serializing this broadcast, then send the 13301 // registered receivers separately so they don't wait for the 13302 // components to be launched. 13303 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13304 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13305 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13306 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13307 ordered, sticky, false, userId); 13308 if (DEBUG_BROADCAST) Slog.v( 13309 TAG, "Enqueueing parallel broadcast " + r); 13310 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13311 if (!replaced) { 13312 queue.enqueueParallelBroadcastLocked(r); 13313 queue.scheduleBroadcastsLocked(); 13314 } 13315 registeredReceivers = null; 13316 NR = 0; 13317 } 13318 13319 // Merge into one list. 13320 int ir = 0; 13321 if (receivers != null) { 13322 // A special case for PACKAGE_ADDED: do not allow the package 13323 // being added to see this broadcast. This prevents them from 13324 // using this as a back door to get run as soon as they are 13325 // installed. Maybe in the future we want to have a special install 13326 // broadcast or such for apps, but we'd like to deliberately make 13327 // this decision. 13328 String skipPackages[] = null; 13329 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13330 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13331 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13332 Uri data = intent.getData(); 13333 if (data != null) { 13334 String pkgName = data.getSchemeSpecificPart(); 13335 if (pkgName != null) { 13336 skipPackages = new String[] { pkgName }; 13337 } 13338 } 13339 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13340 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13341 } 13342 if (skipPackages != null && (skipPackages.length > 0)) { 13343 for (String skipPackage : skipPackages) { 13344 if (skipPackage != null) { 13345 int NT = receivers.size(); 13346 for (int it=0; it<NT; it++) { 13347 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13348 if (curt.activityInfo.packageName.equals(skipPackage)) { 13349 receivers.remove(it); 13350 it--; 13351 NT--; 13352 } 13353 } 13354 } 13355 } 13356 } 13357 13358 int NT = receivers != null ? receivers.size() : 0; 13359 int it = 0; 13360 ResolveInfo curt = null; 13361 BroadcastFilter curr = null; 13362 while (it < NT && ir < NR) { 13363 if (curt == null) { 13364 curt = (ResolveInfo)receivers.get(it); 13365 } 13366 if (curr == null) { 13367 curr = registeredReceivers.get(ir); 13368 } 13369 if (curr.getPriority() >= curt.priority) { 13370 // Insert this broadcast record into the final list. 13371 receivers.add(it, curr); 13372 ir++; 13373 curr = null; 13374 it++; 13375 NT++; 13376 } else { 13377 // Skip to the next ResolveInfo in the final list. 13378 it++; 13379 curt = null; 13380 } 13381 } 13382 } 13383 while (ir < NR) { 13384 if (receivers == null) { 13385 receivers = new ArrayList(); 13386 } 13387 receivers.add(registeredReceivers.get(ir)); 13388 ir++; 13389 } 13390 13391 if ((receivers != null && receivers.size() > 0) 13392 || resultTo != null) { 13393 BroadcastQueue queue = broadcastQueueForIntent(intent); 13394 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13395 callerPackage, callingPid, callingUid, resolvedType, 13396 requiredPermission, appOp, receivers, resultTo, resultCode, 13397 resultData, map, ordered, sticky, false, userId); 13398 if (DEBUG_BROADCAST) Slog.v( 13399 TAG, "Enqueueing ordered broadcast " + r 13400 + ": prev had " + queue.mOrderedBroadcasts.size()); 13401 if (DEBUG_BROADCAST) { 13402 int seq = r.intent.getIntExtra("seq", -1); 13403 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13404 } 13405 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13406 if (!replaced) { 13407 queue.enqueueOrderedBroadcastLocked(r); 13408 queue.scheduleBroadcastsLocked(); 13409 } 13410 } 13411 13412 return ActivityManager.BROADCAST_SUCCESS; 13413 } 13414 13415 final Intent verifyBroadcastLocked(Intent intent) { 13416 // Refuse possible leaked file descriptors 13417 if (intent != null && intent.hasFileDescriptors() == true) { 13418 throw new IllegalArgumentException("File descriptors passed in Intent"); 13419 } 13420 13421 int flags = intent.getFlags(); 13422 13423 if (!mProcessesReady) { 13424 // if the caller really truly claims to know what they're doing, go 13425 // ahead and allow the broadcast without launching any receivers 13426 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13427 intent = new Intent(intent); 13428 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13429 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13430 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13431 + " before boot completion"); 13432 throw new IllegalStateException("Cannot broadcast before boot completed"); 13433 } 13434 } 13435 13436 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13437 throw new IllegalArgumentException( 13438 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13439 } 13440 13441 return intent; 13442 } 13443 13444 public final int broadcastIntent(IApplicationThread caller, 13445 Intent intent, String resolvedType, IIntentReceiver resultTo, 13446 int resultCode, String resultData, Bundle map, 13447 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13448 enforceNotIsolatedCaller("broadcastIntent"); 13449 synchronized(this) { 13450 intent = verifyBroadcastLocked(intent); 13451 13452 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13453 final int callingPid = Binder.getCallingPid(); 13454 final int callingUid = Binder.getCallingUid(); 13455 final long origId = Binder.clearCallingIdentity(); 13456 int res = broadcastIntentLocked(callerApp, 13457 callerApp != null ? callerApp.info.packageName : null, 13458 intent, resolvedType, resultTo, 13459 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13460 callingPid, callingUid, userId); 13461 Binder.restoreCallingIdentity(origId); 13462 return res; 13463 } 13464 } 13465 13466 int broadcastIntentInPackage(String packageName, int uid, 13467 Intent intent, String resolvedType, IIntentReceiver resultTo, 13468 int resultCode, String resultData, Bundle map, 13469 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13470 synchronized(this) { 13471 intent = verifyBroadcastLocked(intent); 13472 13473 final long origId = Binder.clearCallingIdentity(); 13474 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13475 resultTo, resultCode, resultData, map, requiredPermission, 13476 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13477 Binder.restoreCallingIdentity(origId); 13478 return res; 13479 } 13480 } 13481 13482 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13483 // Refuse possible leaked file descriptors 13484 if (intent != null && intent.hasFileDescriptors() == true) { 13485 throw new IllegalArgumentException("File descriptors passed in Intent"); 13486 } 13487 13488 userId = handleIncomingUser(Binder.getCallingPid(), 13489 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13490 13491 synchronized(this) { 13492 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13493 != PackageManager.PERMISSION_GRANTED) { 13494 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13495 + Binder.getCallingPid() 13496 + ", uid=" + Binder.getCallingUid() 13497 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13498 Slog.w(TAG, msg); 13499 throw new SecurityException(msg); 13500 } 13501 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13502 if (stickies != null) { 13503 ArrayList<Intent> list = stickies.get(intent.getAction()); 13504 if (list != null) { 13505 int N = list.size(); 13506 int i; 13507 for (i=0; i<N; i++) { 13508 if (intent.filterEquals(list.get(i))) { 13509 list.remove(i); 13510 break; 13511 } 13512 } 13513 if (list.size() <= 0) { 13514 stickies.remove(intent.getAction()); 13515 } 13516 } 13517 if (stickies.size() <= 0) { 13518 mStickyBroadcasts.remove(userId); 13519 } 13520 } 13521 } 13522 } 13523 13524 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13525 String resultData, Bundle resultExtras, boolean resultAbort) { 13526 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13527 if (r == null) { 13528 Slog.w(TAG, "finishReceiver called but not found on queue"); 13529 return false; 13530 } 13531 13532 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13533 } 13534 13535 void backgroundServicesFinishedLocked(int userId) { 13536 for (BroadcastQueue queue : mBroadcastQueues) { 13537 queue.backgroundServicesFinishedLocked(userId); 13538 } 13539 } 13540 13541 public void finishReceiver(IBinder who, int resultCode, String resultData, 13542 Bundle resultExtras, boolean resultAbort) { 13543 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13544 13545 // Refuse possible leaked file descriptors 13546 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13547 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13548 } 13549 13550 final long origId = Binder.clearCallingIdentity(); 13551 try { 13552 boolean doNext = false; 13553 BroadcastRecord r; 13554 13555 synchronized(this) { 13556 r = broadcastRecordForReceiverLocked(who); 13557 if (r != null) { 13558 doNext = r.queue.finishReceiverLocked(r, resultCode, 13559 resultData, resultExtras, resultAbort, true); 13560 } 13561 } 13562 13563 if (doNext) { 13564 r.queue.processNextBroadcast(false); 13565 } 13566 trimApplications(); 13567 } finally { 13568 Binder.restoreCallingIdentity(origId); 13569 } 13570 } 13571 13572 // ========================================================= 13573 // INSTRUMENTATION 13574 // ========================================================= 13575 13576 public boolean startInstrumentation(ComponentName className, 13577 String profileFile, int flags, Bundle arguments, 13578 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13579 int userId) { 13580 enforceNotIsolatedCaller("startInstrumentation"); 13581 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13582 userId, false, true, "startInstrumentation", null); 13583 // Refuse possible leaked file descriptors 13584 if (arguments != null && arguments.hasFileDescriptors()) { 13585 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13586 } 13587 13588 synchronized(this) { 13589 InstrumentationInfo ii = null; 13590 ApplicationInfo ai = null; 13591 try { 13592 ii = mContext.getPackageManager().getInstrumentationInfo( 13593 className, STOCK_PM_FLAGS); 13594 ai = AppGlobals.getPackageManager().getApplicationInfo( 13595 ii.targetPackage, STOCK_PM_FLAGS, userId); 13596 } catch (PackageManager.NameNotFoundException e) { 13597 } catch (RemoteException e) { 13598 } 13599 if (ii == null) { 13600 reportStartInstrumentationFailure(watcher, className, 13601 "Unable to find instrumentation info for: " + className); 13602 return false; 13603 } 13604 if (ai == null) { 13605 reportStartInstrumentationFailure(watcher, className, 13606 "Unable to find instrumentation target package: " + ii.targetPackage); 13607 return false; 13608 } 13609 13610 int match = mContext.getPackageManager().checkSignatures( 13611 ii.targetPackage, ii.packageName); 13612 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13613 String msg = "Permission Denial: starting instrumentation " 13614 + className + " from pid=" 13615 + Binder.getCallingPid() 13616 + ", uid=" + Binder.getCallingPid() 13617 + " not allowed because package " + ii.packageName 13618 + " does not have a signature matching the target " 13619 + ii.targetPackage; 13620 reportStartInstrumentationFailure(watcher, className, msg); 13621 throw new SecurityException(msg); 13622 } 13623 13624 final long origId = Binder.clearCallingIdentity(); 13625 // Instrumentation can kill and relaunch even persistent processes 13626 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13627 "start instr"); 13628 ProcessRecord app = addAppLocked(ai, false); 13629 app.instrumentationClass = className; 13630 app.instrumentationInfo = ai; 13631 app.instrumentationProfileFile = profileFile; 13632 app.instrumentationArguments = arguments; 13633 app.instrumentationWatcher = watcher; 13634 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13635 app.instrumentationResultClass = className; 13636 Binder.restoreCallingIdentity(origId); 13637 } 13638 13639 return true; 13640 } 13641 13642 /** 13643 * Report errors that occur while attempting to start Instrumentation. Always writes the 13644 * error to the logs, but if somebody is watching, send the report there too. This enables 13645 * the "am" command to report errors with more information. 13646 * 13647 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13648 * @param cn The component name of the instrumentation. 13649 * @param report The error report. 13650 */ 13651 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13652 ComponentName cn, String report) { 13653 Slog.w(TAG, report); 13654 try { 13655 if (watcher != null) { 13656 Bundle results = new Bundle(); 13657 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13658 results.putString("Error", report); 13659 watcher.instrumentationStatus(cn, -1, results); 13660 } 13661 } catch (RemoteException e) { 13662 Slog.w(TAG, e); 13663 } 13664 } 13665 13666 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13667 if (app.instrumentationWatcher != null) { 13668 try { 13669 // NOTE: IInstrumentationWatcher *must* be oneway here 13670 app.instrumentationWatcher.instrumentationFinished( 13671 app.instrumentationClass, 13672 resultCode, 13673 results); 13674 } catch (RemoteException e) { 13675 } 13676 } 13677 if (app.instrumentationUiAutomationConnection != null) { 13678 try { 13679 app.instrumentationUiAutomationConnection.shutdown(); 13680 } catch (RemoteException re) { 13681 /* ignore */ 13682 } 13683 // Only a UiAutomation can set this flag and now that 13684 // it is finished we make sure it is reset to its default. 13685 mUserIsMonkey = false; 13686 } 13687 app.instrumentationWatcher = null; 13688 app.instrumentationUiAutomationConnection = null; 13689 app.instrumentationClass = null; 13690 app.instrumentationInfo = null; 13691 app.instrumentationProfileFile = null; 13692 app.instrumentationArguments = null; 13693 13694 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13695 "finished inst"); 13696 } 13697 13698 public void finishInstrumentation(IApplicationThread target, 13699 int resultCode, Bundle results) { 13700 int userId = UserHandle.getCallingUserId(); 13701 // Refuse possible leaked file descriptors 13702 if (results != null && results.hasFileDescriptors()) { 13703 throw new IllegalArgumentException("File descriptors passed in Intent"); 13704 } 13705 13706 synchronized(this) { 13707 ProcessRecord app = getRecordForAppLocked(target); 13708 if (app == null) { 13709 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13710 return; 13711 } 13712 final long origId = Binder.clearCallingIdentity(); 13713 finishInstrumentationLocked(app, resultCode, results); 13714 Binder.restoreCallingIdentity(origId); 13715 } 13716 } 13717 13718 // ========================================================= 13719 // CONFIGURATION 13720 // ========================================================= 13721 13722 public ConfigurationInfo getDeviceConfigurationInfo() { 13723 ConfigurationInfo config = new ConfigurationInfo(); 13724 synchronized (this) { 13725 config.reqTouchScreen = mConfiguration.touchscreen; 13726 config.reqKeyboardType = mConfiguration.keyboard; 13727 config.reqNavigation = mConfiguration.navigation; 13728 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13729 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13730 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13731 } 13732 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13733 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13734 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13735 } 13736 config.reqGlEsVersion = GL_ES_VERSION; 13737 } 13738 return config; 13739 } 13740 13741 ActivityStack getFocusedStack() { 13742 return mStackSupervisor.getFocusedStack(); 13743 } 13744 13745 public Configuration getConfiguration() { 13746 Configuration ci; 13747 synchronized(this) { 13748 ci = new Configuration(mConfiguration); 13749 } 13750 return ci; 13751 } 13752 13753 public void updatePersistentConfiguration(Configuration values) { 13754 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13755 "updateConfiguration()"); 13756 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 13757 "updateConfiguration()"); 13758 if (values == null) { 13759 throw new NullPointerException("Configuration must not be null"); 13760 } 13761 13762 synchronized(this) { 13763 final long origId = Binder.clearCallingIdentity(); 13764 updateConfigurationLocked(values, null, true, false); 13765 Binder.restoreCallingIdentity(origId); 13766 } 13767 } 13768 13769 public void updateConfiguration(Configuration values) { 13770 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13771 "updateConfiguration()"); 13772 13773 synchronized(this) { 13774 if (values == null && mWindowManager != null) { 13775 // sentinel: fetch the current configuration from the window manager 13776 values = mWindowManager.computeNewConfiguration(); 13777 } 13778 13779 if (mWindowManager != null) { 13780 mProcessList.applyDisplaySize(mWindowManager); 13781 } 13782 13783 final long origId = Binder.clearCallingIdentity(); 13784 if (values != null) { 13785 Settings.System.clearConfiguration(values); 13786 } 13787 updateConfigurationLocked(values, null, false, false); 13788 Binder.restoreCallingIdentity(origId); 13789 } 13790 } 13791 13792 /** 13793 * Do either or both things: (1) change the current configuration, and (2) 13794 * make sure the given activity is running with the (now) current 13795 * configuration. Returns true if the activity has been left running, or 13796 * false if <var>starting</var> is being destroyed to match the new 13797 * configuration. 13798 * @param persistent TODO 13799 */ 13800 boolean updateConfigurationLocked(Configuration values, 13801 ActivityRecord starting, boolean persistent, boolean initLocale) { 13802 // do nothing if we are headless 13803 if (mHeadless) return true; 13804 13805 int changes = 0; 13806 13807 if (values != null) { 13808 Configuration newConfig = new Configuration(mConfiguration); 13809 changes = newConfig.updateFrom(values); 13810 if (changes != 0) { 13811 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13812 Slog.i(TAG, "Updating configuration to: " + values); 13813 } 13814 13815 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13816 13817 if (values.locale != null && !initLocale) { 13818 saveLocaleLocked(values.locale, 13819 !values.locale.equals(mConfiguration.locale), 13820 values.userSetLocale); 13821 } 13822 13823 mConfigurationSeq++; 13824 if (mConfigurationSeq <= 0) { 13825 mConfigurationSeq = 1; 13826 } 13827 newConfig.seq = mConfigurationSeq; 13828 mConfiguration = newConfig; 13829 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 13830 13831 final Configuration configCopy = new Configuration(mConfiguration); 13832 13833 // TODO: If our config changes, should we auto dismiss any currently 13834 // showing dialogs? 13835 mShowDialogs = shouldShowDialogs(newConfig); 13836 13837 AttributeCache ac = AttributeCache.instance(); 13838 if (ac != null) { 13839 ac.updateConfiguration(configCopy); 13840 } 13841 13842 // Make sure all resources in our process are updated 13843 // right now, so that anyone who is going to retrieve 13844 // resource values after we return will be sure to get 13845 // the new ones. This is especially important during 13846 // boot, where the first config change needs to guarantee 13847 // all resources have that config before following boot 13848 // code is executed. 13849 mSystemThread.applyConfigurationToResources(configCopy); 13850 13851 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 13852 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13853 msg.obj = new Configuration(configCopy); 13854 mHandler.sendMessage(msg); 13855 } 13856 13857 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13858 ProcessRecord app = mLruProcesses.get(i); 13859 try { 13860 if (app.thread != null) { 13861 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13862 + app.processName + " new config " + mConfiguration); 13863 app.thread.scheduleConfigurationChanged(configCopy); 13864 } 13865 } catch (Exception e) { 13866 } 13867 } 13868 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13869 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13870 | Intent.FLAG_RECEIVER_REPLACE_PENDING 13871 | Intent.FLAG_RECEIVER_FOREGROUND); 13872 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13873 null, AppOpsManager.OP_NONE, false, false, MY_PID, 13874 Process.SYSTEM_UID, UserHandle.USER_ALL); 13875 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13876 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 13877 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 13878 broadcastIntentLocked(null, null, intent, 13879 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 13880 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 13881 } 13882 } 13883 } 13884 13885 boolean kept = true; 13886 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 13887 if (changes != 0 && starting == null) { 13888 // If the configuration changed, and the caller is not already 13889 // in the process of starting an activity, then find the top 13890 // activity to check if its configuration needs to change. 13891 starting = mainStack.topRunningActivityLocked(null); 13892 } 13893 13894 if (starting != null) { 13895 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 13896 // And we need to make sure at this point that all other activities 13897 // are made visible with the correct configuration. 13898 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 13899 } 13900 13901 if (values != null && mWindowManager != null) { 13902 mWindowManager.setNewConfiguration(mConfiguration); 13903 } 13904 13905 return kept; 13906 } 13907 13908 /** 13909 * Decide based on the configuration whether we should shouw the ANR, 13910 * crash, etc dialogs. The idea is that if there is no affordnace to 13911 * press the on-screen buttons, we shouldn't show the dialog. 13912 * 13913 * A thought: SystemUI might also want to get told about this, the Power 13914 * dialog / global actions also might want different behaviors. 13915 */ 13916 private static final boolean shouldShowDialogs(Configuration config) { 13917 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 13918 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 13919 } 13920 13921 /** 13922 * Save the locale. You must be inside a synchronized (this) block. 13923 */ 13924 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13925 if(isDiff) { 13926 SystemProperties.set("user.language", l.getLanguage()); 13927 SystemProperties.set("user.region", l.getCountry()); 13928 } 13929 13930 if(isPersist) { 13931 SystemProperties.set("persist.sys.language", l.getLanguage()); 13932 SystemProperties.set("persist.sys.country", l.getCountry()); 13933 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13934 } 13935 } 13936 13937 @Override 13938 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 13939 ActivityRecord srec = ActivityRecord.forToken(token); 13940 return srec != null && srec.task.affinity != null && 13941 srec.task.affinity.equals(destAffinity); 13942 } 13943 13944 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 13945 Intent resultData) { 13946 13947 synchronized (this) { 13948 final ActivityStack stack = ActivityRecord.getStackLocked(token); 13949 if (stack != null) { 13950 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 13951 } 13952 return false; 13953 } 13954 } 13955 13956 public int getLaunchedFromUid(IBinder activityToken) { 13957 ActivityRecord srec = ActivityRecord.forToken(activityToken); 13958 if (srec == null) { 13959 return -1; 13960 } 13961 return srec.launchedFromUid; 13962 } 13963 13964 public String getLaunchedFromPackage(IBinder activityToken) { 13965 ActivityRecord srec = ActivityRecord.forToken(activityToken); 13966 if (srec == null) { 13967 return null; 13968 } 13969 return srec.launchedFromPackage; 13970 } 13971 13972 // ========================================================= 13973 // LIFETIME MANAGEMENT 13974 // ========================================================= 13975 13976 // Returns which broadcast queue the app is the current [or imminent] receiver 13977 // on, or 'null' if the app is not an active broadcast recipient. 13978 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 13979 BroadcastRecord r = app.curReceiver; 13980 if (r != null) { 13981 return r.queue; 13982 } 13983 13984 // It's not the current receiver, but it might be starting up to become one 13985 synchronized (this) { 13986 for (BroadcastQueue queue : mBroadcastQueues) { 13987 r = queue.mPendingBroadcast; 13988 if (r != null && r.curApp == app) { 13989 // found it; report which queue it's in 13990 return queue; 13991 } 13992 } 13993 } 13994 13995 return null; 13996 } 13997 13998 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 13999 boolean doingAll, long now) { 14000 if (mAdjSeq == app.adjSeq) { 14001 // This adjustment has already been computed. 14002 return app.curRawAdj; 14003 } 14004 14005 if (app.thread == null) { 14006 app.adjSeq = mAdjSeq; 14007 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14008 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14009 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14010 } 14011 14012 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14013 app.adjSource = null; 14014 app.adjTarget = null; 14015 app.empty = false; 14016 app.cached = false; 14017 app.hasClientActivities = false; 14018 14019 final int activitiesSize = app.activities.size(); 14020 14021 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14022 // The max adjustment doesn't allow this app to be anything 14023 // below foreground, so it is not worth doing work for it. 14024 app.adjType = "fixed"; 14025 app.adjSeq = mAdjSeq; 14026 app.curRawAdj = app.maxAdj; 14027 app.hasActivities = false; 14028 app.foregroundActivities = false; 14029 app.keeping = true; 14030 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14031 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14032 // System process can do UI, and when they do we want to have 14033 // them trim their memory after the user leaves the UI. To 14034 // facilitate this, here we need to determine whether or not it 14035 // is currently showing UI. 14036 app.systemNoUi = true; 14037 if (app == TOP_APP) { 14038 app.systemNoUi = false; 14039 app.hasActivities = true; 14040 } else if (activitiesSize > 0) { 14041 for (int j = 0; j < activitiesSize; j++) { 14042 final ActivityRecord r = app.activities.get(j); 14043 if (r.visible) { 14044 app.systemNoUi = false; 14045 } 14046 if (r.app == app) { 14047 app.hasActivities = true; 14048 } 14049 } 14050 } 14051 if (!app.systemNoUi) { 14052 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14053 } 14054 return (app.curAdj=app.maxAdj); 14055 } 14056 14057 app.keeping = false; 14058 app.systemNoUi = false; 14059 app.hasActivities = false; 14060 14061 // Determine the importance of the process, starting with most 14062 // important to least, and assign an appropriate OOM adjustment. 14063 int adj; 14064 int schedGroup; 14065 int procState; 14066 boolean foregroundActivities = false; 14067 boolean interesting = false; 14068 BroadcastQueue queue; 14069 if (app == TOP_APP) { 14070 // The last app on the list is the foreground app. 14071 adj = ProcessList.FOREGROUND_APP_ADJ; 14072 schedGroup = Process.THREAD_GROUP_DEFAULT; 14073 app.adjType = "top-activity"; 14074 foregroundActivities = true; 14075 interesting = true; 14076 app.hasActivities = true; 14077 procState = ActivityManager.PROCESS_STATE_TOP; 14078 } else if (app.instrumentationClass != null) { 14079 // Don't want to kill running instrumentation. 14080 adj = ProcessList.FOREGROUND_APP_ADJ; 14081 schedGroup = Process.THREAD_GROUP_DEFAULT; 14082 app.adjType = "instrumentation"; 14083 interesting = true; 14084 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14085 } else if ((queue = isReceivingBroadcast(app)) != null) { 14086 // An app that is currently receiving a broadcast also 14087 // counts as being in the foreground for OOM killer purposes. 14088 // It's placed in a sched group based on the nature of the 14089 // broadcast as reflected by which queue it's active in. 14090 adj = ProcessList.FOREGROUND_APP_ADJ; 14091 schedGroup = (queue == mFgBroadcastQueue) 14092 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14093 app.adjType = "broadcast"; 14094 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14095 } else if (app.executingServices.size() > 0) { 14096 // An app that is currently executing a service callback also 14097 // counts as being in the foreground. 14098 adj = ProcessList.FOREGROUND_APP_ADJ; 14099 schedGroup = app.execServicesFg ? 14100 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14101 app.adjType = "exec-service"; 14102 procState = ActivityManager.PROCESS_STATE_SERVICE; 14103 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14104 } else { 14105 // As far as we know the process is empty. We may change our mind later. 14106 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14107 // At this point we don't actually know the adjustment. Use the cached adj 14108 // value that the caller wants us to. 14109 adj = cachedAdj; 14110 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14111 app.cached = true; 14112 app.empty = true; 14113 app.adjType = "cch-empty"; 14114 } 14115 14116 // Examine all activities if not already foreground. 14117 if (!foregroundActivities && activitiesSize > 0) { 14118 for (int j = 0; j < activitiesSize; j++) { 14119 final ActivityRecord r = app.activities.get(j); 14120 if (r.app != app) { 14121 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14122 + app + "?!?"); 14123 continue; 14124 } 14125 app.hasActivities = true; 14126 if (r.visible) { 14127 // App has a visible activity; only upgrade adjustment. 14128 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14129 adj = ProcessList.VISIBLE_APP_ADJ; 14130 app.adjType = "visible"; 14131 } 14132 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14133 procState = ActivityManager.PROCESS_STATE_TOP; 14134 } 14135 schedGroup = Process.THREAD_GROUP_DEFAULT; 14136 app.cached = false; 14137 app.empty = false; 14138 foregroundActivities = true; 14139 break; 14140 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14141 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14142 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14143 app.adjType = "pausing"; 14144 } 14145 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14146 procState = ActivityManager.PROCESS_STATE_TOP; 14147 } 14148 schedGroup = Process.THREAD_GROUP_DEFAULT; 14149 app.cached = false; 14150 app.empty = false; 14151 foregroundActivities = true; 14152 } else if (r.state == ActivityState.STOPPING) { 14153 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14154 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14155 app.adjType = "stopping"; 14156 } 14157 // For the process state, we will at this point consider the 14158 // process to be cached. It will be cached either as an activity 14159 // or empty depending on whether the activity is finishing. We do 14160 // this so that we can treat the process as cached for purposes of 14161 // memory trimming (determing current memory level, trim command to 14162 // send to process) since there can be an arbitrary number of stopping 14163 // processes and they should soon all go into the cached state. 14164 if (!r.finishing) { 14165 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14166 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14167 } 14168 } 14169 app.cached = false; 14170 app.empty = false; 14171 foregroundActivities = true; 14172 } else { 14173 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14174 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14175 app.adjType = "cch-act"; 14176 } 14177 } 14178 } 14179 } 14180 14181 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14182 if (app.foregroundServices) { 14183 // The user is aware of this app, so make it visible. 14184 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14185 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14186 app.cached = false; 14187 app.adjType = "fg-service"; 14188 schedGroup = Process.THREAD_GROUP_DEFAULT; 14189 } else if (app.forcingToForeground != null) { 14190 // The user is aware of this app, so make it visible. 14191 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14192 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14193 app.cached = false; 14194 app.adjType = "force-fg"; 14195 app.adjSource = app.forcingToForeground; 14196 schedGroup = Process.THREAD_GROUP_DEFAULT; 14197 } 14198 } 14199 14200 if (app.foregroundServices) { 14201 interesting = true; 14202 } 14203 14204 if (app == mHeavyWeightProcess) { 14205 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14206 // We don't want to kill the current heavy-weight process. 14207 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14208 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14209 app.cached = false; 14210 app.adjType = "heavy"; 14211 } 14212 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14213 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14214 } 14215 } 14216 14217 if (app == mHomeProcess) { 14218 if (adj > ProcessList.HOME_APP_ADJ) { 14219 // This process is hosting what we currently consider to be the 14220 // home app, so we don't want to let it go into the background. 14221 adj = ProcessList.HOME_APP_ADJ; 14222 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14223 app.cached = false; 14224 app.adjType = "home"; 14225 } 14226 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14227 procState = ActivityManager.PROCESS_STATE_HOME; 14228 } 14229 } 14230 14231 if (app == mPreviousProcess && app.activities.size() > 0) { 14232 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14233 // This was the previous process that showed UI to the user. 14234 // We want to try to keep it around more aggressively, to give 14235 // a good experience around switching between two apps. 14236 adj = ProcessList.PREVIOUS_APP_ADJ; 14237 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14238 app.cached = false; 14239 app.adjType = "previous"; 14240 } 14241 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14242 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14243 } 14244 } 14245 14246 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14247 + " reason=" + app.adjType); 14248 14249 // By default, we use the computed adjustment. It may be changed if 14250 // there are applications dependent on our services or providers, but 14251 // this gives us a baseline and makes sure we don't get into an 14252 // infinite recursion. 14253 app.adjSeq = mAdjSeq; 14254 app.curRawAdj = adj; 14255 app.hasStartedServices = false; 14256 14257 if (mBackupTarget != null && app == mBackupTarget.app) { 14258 // If possible we want to avoid killing apps while they're being backed up 14259 if (adj > ProcessList.BACKUP_APP_ADJ) { 14260 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14261 adj = ProcessList.BACKUP_APP_ADJ; 14262 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14263 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14264 } 14265 app.adjType = "backup"; 14266 app.cached = false; 14267 } 14268 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14269 procState = ActivityManager.PROCESS_STATE_BACKUP; 14270 } 14271 } 14272 14273 boolean mayBeTop = false; 14274 14275 for (int is = app.services.size()-1; 14276 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14277 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14278 || procState > ActivityManager.PROCESS_STATE_TOP); 14279 is--) { 14280 ServiceRecord s = app.services.valueAt(is); 14281 if (s.startRequested) { 14282 app.hasStartedServices = true; 14283 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14284 procState = ActivityManager.PROCESS_STATE_SERVICE; 14285 } 14286 if (app.hasShownUi && app != mHomeProcess) { 14287 // If this process has shown some UI, let it immediately 14288 // go to the LRU list because it may be pretty heavy with 14289 // UI stuff. We'll tag it with a label just to help 14290 // debug and understand what is going on. 14291 if (adj > ProcessList.SERVICE_ADJ) { 14292 app.adjType = "cch-started-ui-services"; 14293 } 14294 } else { 14295 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14296 // This service has seen some activity within 14297 // recent memory, so we will keep its process ahead 14298 // of the background processes. 14299 if (adj > ProcessList.SERVICE_ADJ) { 14300 adj = ProcessList.SERVICE_ADJ; 14301 app.adjType = "started-services"; 14302 app.cached = false; 14303 } 14304 } 14305 // If we have let the service slide into the background 14306 // state, still have some text describing what it is doing 14307 // even though the service no longer has an impact. 14308 if (adj > ProcessList.SERVICE_ADJ) { 14309 app.adjType = "cch-started-services"; 14310 } 14311 } 14312 // Don't kill this process because it is doing work; it 14313 // has said it is doing work. 14314 app.keeping = true; 14315 } 14316 for (int conni = s.connections.size()-1; 14317 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14318 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14319 || procState > ActivityManager.PROCESS_STATE_TOP); 14320 conni--) { 14321 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14322 for (int i = 0; 14323 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14324 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14325 || procState > ActivityManager.PROCESS_STATE_TOP); 14326 i++) { 14327 // XXX should compute this based on the max of 14328 // all connected clients. 14329 ConnectionRecord cr = clist.get(i); 14330 if (cr.binding.client == app) { 14331 // Binding to ourself is not interesting. 14332 continue; 14333 } 14334 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14335 ProcessRecord client = cr.binding.client; 14336 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14337 TOP_APP, doingAll, now); 14338 int clientProcState = client.curProcState; 14339 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14340 // If the other app is cached for any reason, for purposes here 14341 // we are going to consider it empty. The specific cached state 14342 // doesn't propagate except under certain conditions. 14343 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14344 } 14345 String adjType = null; 14346 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14347 // Not doing bind OOM management, so treat 14348 // this guy more like a started service. 14349 if (app.hasShownUi && app != mHomeProcess) { 14350 // If this process has shown some UI, let it immediately 14351 // go to the LRU list because it may be pretty heavy with 14352 // UI stuff. We'll tag it with a label just to help 14353 // debug and understand what is going on. 14354 if (adj > clientAdj) { 14355 adjType = "cch-bound-ui-services"; 14356 } 14357 app.cached = false; 14358 clientAdj = adj; 14359 clientProcState = procState; 14360 } else { 14361 if (now >= (s.lastActivity 14362 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14363 // This service has not seen activity within 14364 // recent memory, so allow it to drop to the 14365 // LRU list if there is no other reason to keep 14366 // it around. We'll also tag it with a label just 14367 // to help debug and undertand what is going on. 14368 if (adj > clientAdj) { 14369 adjType = "cch-bound-services"; 14370 } 14371 clientAdj = adj; 14372 } 14373 } 14374 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 14375 if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) { 14376 // If this connection is keeping the service 14377 // created, then we want to try to better follow 14378 // its memory management semantics for activities. 14379 // That is, if it is sitting in the background 14380 // LRU list as a cached process (with activities), 14381 // we don't want the service it is connected to 14382 // to go into the empty LRU and quickly get killed, 14383 // because all we'll do is just end up restarting 14384 // the service. 14385 if (client.hasActivities) { 14386 if (procState > 14387 ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT) { 14388 procState = 14389 ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14390 app.adjType = "cch-client-act"; 14391 } 14392 app.hasClientActivities = true; 14393 } 14394 } 14395 } 14396 if (adj > clientAdj) { 14397 // If this process has recently shown UI, and 14398 // the process that is binding to it is less 14399 // important than being visible, then we don't 14400 // care about the binding as much as we care 14401 // about letting this process get into the LRU 14402 // list to be killed and restarted if needed for 14403 // memory. 14404 if (app.hasShownUi && app != mHomeProcess 14405 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14406 adjType = "cch-bound-ui-services"; 14407 } else { 14408 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14409 |Context.BIND_IMPORTANT)) != 0) { 14410 adj = clientAdj; 14411 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14412 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14413 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14414 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14415 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14416 adj = clientAdj; 14417 } else { 14418 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14419 adj = ProcessList.VISIBLE_APP_ADJ; 14420 } 14421 } 14422 if (!client.cached) { 14423 app.cached = false; 14424 } 14425 if (client.keeping) { 14426 app.keeping = true; 14427 } 14428 adjType = "service"; 14429 } 14430 } 14431 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14432 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14433 schedGroup = Process.THREAD_GROUP_DEFAULT; 14434 } 14435 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14436 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14437 // Special handling of clients who are in the top state. 14438 // We *may* want to consider this process to be in the 14439 // top state as well, but only if there is not another 14440 // reason for it to be running. Being on the top is a 14441 // special state, meaning you are specifically running 14442 // for the current top app. If the process is already 14443 // running in the background for some other reason, it 14444 // is more important to continue considering it to be 14445 // in the background state. 14446 mayBeTop = true; 14447 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14448 } else { 14449 // Special handling for above-top states (persistent 14450 // processes). These should not bring the current process 14451 // into the top state, since they are not on top. Instead 14452 // give them the best state after that. 14453 clientProcState = 14454 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14455 } 14456 } 14457 } else { 14458 if (clientProcState < 14459 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14460 clientProcState = 14461 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14462 } 14463 } 14464 if (procState > clientProcState) { 14465 procState = clientProcState; 14466 } 14467 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14468 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14469 app.pendingUiClean = true; 14470 } 14471 if (adjType != null) { 14472 app.adjType = adjType; 14473 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14474 .REASON_SERVICE_IN_USE; 14475 app.adjSource = cr.binding.client; 14476 app.adjSourceOom = clientAdj; 14477 app.adjTarget = s.name; 14478 } 14479 } 14480 final ActivityRecord a = cr.activity; 14481 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14482 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14483 (a.visible || a.state == ActivityState.RESUMED 14484 || a.state == ActivityState.PAUSING)) { 14485 adj = ProcessList.FOREGROUND_APP_ADJ; 14486 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14487 schedGroup = Process.THREAD_GROUP_DEFAULT; 14488 } 14489 app.cached = false; 14490 app.adjType = "service"; 14491 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14492 .REASON_SERVICE_IN_USE; 14493 app.adjSource = a; 14494 app.adjSourceOom = adj; 14495 app.adjTarget = s.name; 14496 } 14497 } 14498 } 14499 } 14500 } 14501 14502 for (int provi = app.pubProviders.size()-1; 14503 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14504 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14505 || procState > ActivityManager.PROCESS_STATE_TOP); 14506 provi--) { 14507 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14508 for (int i = cpr.connections.size()-1; 14509 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14510 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14511 || procState > ActivityManager.PROCESS_STATE_TOP); 14512 i--) { 14513 ContentProviderConnection conn = cpr.connections.get(i); 14514 ProcessRecord client = conn.client; 14515 if (client == app) { 14516 // Being our own client is not interesting. 14517 continue; 14518 } 14519 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14520 int clientProcState = client.curProcState; 14521 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14522 // If the other app is cached for any reason, for purposes here 14523 // we are going to consider it empty. 14524 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14525 } 14526 if (adj > clientAdj) { 14527 if (app.hasShownUi && app != mHomeProcess 14528 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14529 app.adjType = "cch-ui-provider"; 14530 } else { 14531 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14532 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14533 app.adjType = "provider"; 14534 } 14535 app.cached &= client.cached; 14536 app.keeping |= client.keeping; 14537 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14538 .REASON_PROVIDER_IN_USE; 14539 app.adjSource = client; 14540 app.adjSourceOom = clientAdj; 14541 app.adjTarget = cpr.name; 14542 } 14543 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14544 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14545 // Special handling of clients who are in the top state. 14546 // We *may* want to consider this process to be in the 14547 // top state as well, but only if there is not another 14548 // reason for it to be running. Being on the top is a 14549 // special state, meaning you are specifically running 14550 // for the current top app. If the process is already 14551 // running in the background for some other reason, it 14552 // is more important to continue considering it to be 14553 // in the background state. 14554 mayBeTop = true; 14555 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14556 } else { 14557 // Special handling for above-top states (persistent 14558 // processes). These should not bring the current process 14559 // into the top state, since they are not on top. Instead 14560 // give them the best state after that. 14561 clientProcState = 14562 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14563 } 14564 } 14565 if (procState > clientProcState) { 14566 procState = clientProcState; 14567 } 14568 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14569 schedGroup = Process.THREAD_GROUP_DEFAULT; 14570 } 14571 } 14572 // If the provider has external (non-framework) process 14573 // dependencies, ensure that its adjustment is at least 14574 // FOREGROUND_APP_ADJ. 14575 if (cpr.hasExternalProcessHandles()) { 14576 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14577 adj = ProcessList.FOREGROUND_APP_ADJ; 14578 schedGroup = Process.THREAD_GROUP_DEFAULT; 14579 app.cached = false; 14580 app.keeping = true; 14581 app.adjType = "provider"; 14582 app.adjTarget = cpr.name; 14583 } 14584 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14585 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14586 } 14587 } 14588 } 14589 14590 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14591 // A client of one of our services or providers is in the top state. We 14592 // *may* want to be in the top state, but not if we are already running in 14593 // the background for some other reason. For the decision here, we are going 14594 // to pick out a few specific states that we want to remain in when a client 14595 // is top (states that tend to be longer-term) and otherwise allow it to go 14596 // to the top state. 14597 switch (procState) { 14598 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14599 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14600 case ActivityManager.PROCESS_STATE_SERVICE: 14601 // These all are longer-term states, so pull them up to the top 14602 // of the background states, but not all the way to the top state. 14603 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14604 break; 14605 default: 14606 // Otherwise, top is a better choice, so take it. 14607 procState = ActivityManager.PROCESS_STATE_TOP; 14608 break; 14609 } 14610 } 14611 14612 if (adj == ProcessList.SERVICE_ADJ) { 14613 if (doingAll) { 14614 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14615 mNewNumServiceProcs++; 14616 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14617 if (!app.serviceb) { 14618 // This service isn't far enough down on the LRU list to 14619 // normally be a B service, but if we are low on RAM and it 14620 // is large we want to force it down since we would prefer to 14621 // keep launcher over it. 14622 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14623 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14624 app.serviceHighRam = true; 14625 app.serviceb = true; 14626 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14627 } else { 14628 mNewNumAServiceProcs++; 14629 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14630 } 14631 } else { 14632 app.serviceHighRam = false; 14633 } 14634 } 14635 if (app.serviceb) { 14636 adj = ProcessList.SERVICE_B_ADJ; 14637 } 14638 } 14639 14640 app.curRawAdj = adj; 14641 14642 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14643 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14644 if (adj > app.maxAdj) { 14645 adj = app.maxAdj; 14646 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14647 schedGroup = Process.THREAD_GROUP_DEFAULT; 14648 } 14649 } 14650 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14651 app.keeping = true; 14652 } 14653 14654 // Do final modification to adj. Everything we do between here and applying 14655 // the final setAdj must be done in this function, because we will also use 14656 // it when computing the final cached adj later. Note that we don't need to 14657 // worry about this for max adj above, since max adj will always be used to 14658 // keep it out of the cached vaues. 14659 adj = app.modifyRawOomAdj(adj); 14660 14661 app.curProcState = procState; 14662 14663 int importance = app.memImportance; 14664 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14665 app.curAdj = adj; 14666 app.curSchedGroup = schedGroup; 14667 if (!interesting) { 14668 // For this reporting, if there is not something explicitly 14669 // interesting in this process then we will push it to the 14670 // background importance. 14671 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14672 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14673 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14674 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14675 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14676 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14677 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14678 } else if (adj >= ProcessList.SERVICE_ADJ) { 14679 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14680 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14681 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14682 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14683 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14684 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14685 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14686 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14687 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14688 } else { 14689 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14690 } 14691 } 14692 14693 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14694 if (foregroundActivities != app.foregroundActivities) { 14695 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14696 } 14697 if (changes != 0) { 14698 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14699 app.memImportance = importance; 14700 app.foregroundActivities = foregroundActivities; 14701 int i = mPendingProcessChanges.size()-1; 14702 ProcessChangeItem item = null; 14703 while (i >= 0) { 14704 item = mPendingProcessChanges.get(i); 14705 if (item.pid == app.pid) { 14706 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14707 break; 14708 } 14709 i--; 14710 } 14711 if (i < 0) { 14712 // No existing item in pending changes; need a new one. 14713 final int NA = mAvailProcessChanges.size(); 14714 if (NA > 0) { 14715 item = mAvailProcessChanges.remove(NA-1); 14716 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14717 } else { 14718 item = new ProcessChangeItem(); 14719 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14720 } 14721 item.changes = 0; 14722 item.pid = app.pid; 14723 item.uid = app.info.uid; 14724 if (mPendingProcessChanges.size() == 0) { 14725 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14726 "*** Enqueueing dispatch processes changed!"); 14727 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14728 } 14729 mPendingProcessChanges.add(item); 14730 } 14731 item.changes |= changes; 14732 item.importance = importance; 14733 item.foregroundActivities = foregroundActivities; 14734 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14735 + Integer.toHexString(System.identityHashCode(item)) 14736 + " " + app.toShortString() + ": changes=" + item.changes 14737 + " importance=" + item.importance 14738 + " foreground=" + item.foregroundActivities 14739 + " type=" + app.adjType + " source=" + app.adjSource 14740 + " target=" + app.adjTarget); 14741 } 14742 14743 return app.curRawAdj; 14744 } 14745 14746 /** 14747 * Schedule PSS collection of a process. 14748 */ 14749 void requestPssLocked(ProcessRecord proc, int procState) { 14750 if (mPendingPssProcesses.contains(proc)) { 14751 return; 14752 } 14753 if (mPendingPssProcesses.size() == 0) { 14754 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14755 } 14756 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14757 proc.pssProcState = procState; 14758 mPendingPssProcesses.add(proc); 14759 } 14760 14761 /** 14762 * Schedule PSS collection of all processes. 14763 */ 14764 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14765 if (!always) { 14766 if (now < (mLastFullPssTime + 14767 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14768 return; 14769 } 14770 } 14771 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14772 mLastFullPssTime = now; 14773 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14774 mPendingPssProcesses.clear(); 14775 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14776 ProcessRecord app = mLruProcesses.get(i); 14777 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14778 app.pssProcState = app.setProcState; 14779 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14780 mSleeping, now); 14781 mPendingPssProcesses.add(app); 14782 } 14783 } 14784 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14785 } 14786 14787 /** 14788 * Ask a given process to GC right now. 14789 */ 14790 final void performAppGcLocked(ProcessRecord app) { 14791 try { 14792 app.lastRequestedGc = SystemClock.uptimeMillis(); 14793 if (app.thread != null) { 14794 if (app.reportLowMemory) { 14795 app.reportLowMemory = false; 14796 app.thread.scheduleLowMemory(); 14797 } else { 14798 app.thread.processInBackground(); 14799 } 14800 } 14801 } catch (Exception e) { 14802 // whatever. 14803 } 14804 } 14805 14806 /** 14807 * Returns true if things are idle enough to perform GCs. 14808 */ 14809 private final boolean canGcNowLocked() { 14810 boolean processingBroadcasts = false; 14811 for (BroadcastQueue q : mBroadcastQueues) { 14812 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 14813 processingBroadcasts = true; 14814 } 14815 } 14816 return !processingBroadcasts 14817 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 14818 } 14819 14820 /** 14821 * Perform GCs on all processes that are waiting for it, but only 14822 * if things are idle. 14823 */ 14824 final void performAppGcsLocked() { 14825 final int N = mProcessesToGc.size(); 14826 if (N <= 0) { 14827 return; 14828 } 14829 if (canGcNowLocked()) { 14830 while (mProcessesToGc.size() > 0) { 14831 ProcessRecord proc = mProcessesToGc.remove(0); 14832 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 14833 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 14834 <= SystemClock.uptimeMillis()) { 14835 // To avoid spamming the system, we will GC processes one 14836 // at a time, waiting a few seconds between each. 14837 performAppGcLocked(proc); 14838 scheduleAppGcsLocked(); 14839 return; 14840 } else { 14841 // It hasn't been long enough since we last GCed this 14842 // process... put it in the list to wait for its time. 14843 addProcessToGcListLocked(proc); 14844 break; 14845 } 14846 } 14847 } 14848 14849 scheduleAppGcsLocked(); 14850 } 14851 } 14852 14853 /** 14854 * If all looks good, perform GCs on all processes waiting for them. 14855 */ 14856 final void performAppGcsIfAppropriateLocked() { 14857 if (canGcNowLocked()) { 14858 performAppGcsLocked(); 14859 return; 14860 } 14861 // Still not idle, wait some more. 14862 scheduleAppGcsLocked(); 14863 } 14864 14865 /** 14866 * Schedule the execution of all pending app GCs. 14867 */ 14868 final void scheduleAppGcsLocked() { 14869 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 14870 14871 if (mProcessesToGc.size() > 0) { 14872 // Schedule a GC for the time to the next process. 14873 ProcessRecord proc = mProcessesToGc.get(0); 14874 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 14875 14876 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 14877 long now = SystemClock.uptimeMillis(); 14878 if (when < (now+GC_TIMEOUT)) { 14879 when = now + GC_TIMEOUT; 14880 } 14881 mHandler.sendMessageAtTime(msg, when); 14882 } 14883 } 14884 14885 /** 14886 * Add a process to the array of processes waiting to be GCed. Keeps the 14887 * list in sorted order by the last GC time. The process can't already be 14888 * on the list. 14889 */ 14890 final void addProcessToGcListLocked(ProcessRecord proc) { 14891 boolean added = false; 14892 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 14893 if (mProcessesToGc.get(i).lastRequestedGc < 14894 proc.lastRequestedGc) { 14895 added = true; 14896 mProcessesToGc.add(i+1, proc); 14897 break; 14898 } 14899 } 14900 if (!added) { 14901 mProcessesToGc.add(0, proc); 14902 } 14903 } 14904 14905 /** 14906 * Set up to ask a process to GC itself. This will either do it 14907 * immediately, or put it on the list of processes to gc the next 14908 * time things are idle. 14909 */ 14910 final void scheduleAppGcLocked(ProcessRecord app) { 14911 long now = SystemClock.uptimeMillis(); 14912 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 14913 return; 14914 } 14915 if (!mProcessesToGc.contains(app)) { 14916 addProcessToGcListLocked(app); 14917 scheduleAppGcsLocked(); 14918 } 14919 } 14920 14921 final void checkExcessivePowerUsageLocked(boolean doKills) { 14922 updateCpuStatsNow(); 14923 14924 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14925 boolean doWakeKills = doKills; 14926 boolean doCpuKills = doKills; 14927 if (mLastPowerCheckRealtime == 0) { 14928 doWakeKills = false; 14929 } 14930 if (mLastPowerCheckUptime == 0) { 14931 doCpuKills = false; 14932 } 14933 if (stats.isScreenOn()) { 14934 doWakeKills = false; 14935 } 14936 final long curRealtime = SystemClock.elapsedRealtime(); 14937 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 14938 final long curUptime = SystemClock.uptimeMillis(); 14939 final long uptimeSince = curUptime - mLastPowerCheckUptime; 14940 mLastPowerCheckRealtime = curRealtime; 14941 mLastPowerCheckUptime = curUptime; 14942 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 14943 doWakeKills = false; 14944 } 14945 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 14946 doCpuKills = false; 14947 } 14948 int i = mLruProcesses.size(); 14949 while (i > 0) { 14950 i--; 14951 ProcessRecord app = mLruProcesses.get(i); 14952 if (!app.keeping) { 14953 long wtime; 14954 synchronized (stats) { 14955 wtime = stats.getProcessWakeTime(app.info.uid, 14956 app.pid, curRealtime); 14957 } 14958 long wtimeUsed = wtime - app.lastWakeTime; 14959 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 14960 if (DEBUG_POWER) { 14961 StringBuilder sb = new StringBuilder(128); 14962 sb.append("Wake for "); 14963 app.toShortString(sb); 14964 sb.append(": over "); 14965 TimeUtils.formatDuration(realtimeSince, sb); 14966 sb.append(" used "); 14967 TimeUtils.formatDuration(wtimeUsed, sb); 14968 sb.append(" ("); 14969 sb.append((wtimeUsed*100)/realtimeSince); 14970 sb.append("%)"); 14971 Slog.i(TAG, sb.toString()); 14972 sb.setLength(0); 14973 sb.append("CPU for "); 14974 app.toShortString(sb); 14975 sb.append(": over "); 14976 TimeUtils.formatDuration(uptimeSince, sb); 14977 sb.append(" used "); 14978 TimeUtils.formatDuration(cputimeUsed, sb); 14979 sb.append(" ("); 14980 sb.append((cputimeUsed*100)/uptimeSince); 14981 sb.append("%)"); 14982 Slog.i(TAG, sb.toString()); 14983 } 14984 // If a process has held a wake lock for more 14985 // than 50% of the time during this period, 14986 // that sounds bad. Kill! 14987 if (doWakeKills && realtimeSince > 0 14988 && ((wtimeUsed*100)/realtimeSince) >= 50) { 14989 synchronized (stats) { 14990 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 14991 realtimeSince, wtimeUsed); 14992 } 14993 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 14994 + " during " + realtimeSince); 14995 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 14996 } else if (doCpuKills && uptimeSince > 0 14997 && ((cputimeUsed*100)/uptimeSince) >= 50) { 14998 synchronized (stats) { 14999 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15000 uptimeSince, cputimeUsed); 15001 } 15002 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15003 + " during " + uptimeSince); 15004 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15005 } else { 15006 app.lastWakeTime = wtime; 15007 app.lastCpuTime = app.curCpuTime; 15008 } 15009 } 15010 } 15011 } 15012 15013 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15014 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15015 boolean success = true; 15016 15017 if (app.curRawAdj != app.setRawAdj) { 15018 if (wasKeeping && !app.keeping) { 15019 // This app is no longer something we want to keep. Note 15020 // its current wake lock time to later know to kill it if 15021 // it is not behaving well. 15022 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15023 synchronized (stats) { 15024 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15025 app.pid, SystemClock.elapsedRealtime()); 15026 } 15027 app.lastCpuTime = app.curCpuTime; 15028 } 15029 15030 app.setRawAdj = app.curRawAdj; 15031 } 15032 15033 if (app.curAdj != app.setAdj) { 15034 if (Process.setOomAdj(app.pid, app.curAdj)) { 15035 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15036 TAG, "Set " + app.pid + " " + app.processName + 15037 " adj " + app.curAdj + ": " + app.adjType); 15038 app.setAdj = app.curAdj; 15039 } else { 15040 success = false; 15041 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 15042 } 15043 } 15044 if (app.setSchedGroup != app.curSchedGroup) { 15045 app.setSchedGroup = app.curSchedGroup; 15046 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15047 "Setting process group of " + app.processName 15048 + " to " + app.curSchedGroup); 15049 if (app.waitingToKill != null && 15050 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15051 killUnneededProcessLocked(app, app.waitingToKill); 15052 success = false; 15053 } else { 15054 if (true) { 15055 long oldId = Binder.clearCallingIdentity(); 15056 try { 15057 Process.setProcessGroup(app.pid, app.curSchedGroup); 15058 } catch (Exception e) { 15059 Slog.w(TAG, "Failed setting process group of " + app.pid 15060 + " to " + app.curSchedGroup); 15061 e.printStackTrace(); 15062 } finally { 15063 Binder.restoreCallingIdentity(oldId); 15064 } 15065 } else { 15066 if (app.thread != null) { 15067 try { 15068 app.thread.setSchedulingGroup(app.curSchedGroup); 15069 } catch (RemoteException e) { 15070 } 15071 } 15072 } 15073 Process.setSwappiness(app.pid, 15074 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15075 } 15076 } 15077 if (app.repProcState != app.curProcState) { 15078 app.repProcState = app.curProcState; 15079 if (!reportingProcessState && app.thread != null) { 15080 try { 15081 if (false) { 15082 //RuntimeException h = new RuntimeException("here"); 15083 Slog.i(TAG, "Sending new process state " + app.repProcState 15084 + " to " + app /*, h*/); 15085 } 15086 app.thread.setProcessState(app.repProcState); 15087 } catch (RemoteException e) { 15088 } 15089 } 15090 } 15091 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15092 app.setProcState)) { 15093 app.lastStateTime = now; 15094 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15095 mSleeping, now); 15096 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15097 + ProcessList.makeProcStateString(app.setProcState) + " to " 15098 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15099 + (app.nextPssTime-now) + ": " + app); 15100 } else { 15101 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15102 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15103 requestPssLocked(app, app.setProcState); 15104 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15105 mSleeping, now); 15106 } else if (false && DEBUG_PSS) { 15107 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15108 } 15109 } 15110 if (app.setProcState != app.curProcState) { 15111 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15112 "Proc state change of " + app.processName 15113 + " to " + app.curProcState); 15114 app.setProcState = app.curProcState; 15115 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15116 app.notCachedSinceIdle = false; 15117 } 15118 if (!doingAll) { 15119 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15120 } else { 15121 app.procStateChanged = true; 15122 } 15123 } 15124 return success; 15125 } 15126 15127 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15128 if (proc.thread != null && proc.baseProcessTracker != null) { 15129 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15130 } 15131 } 15132 15133 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15134 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15135 if (app.thread == null) { 15136 return false; 15137 } 15138 15139 final boolean wasKeeping = app.keeping; 15140 15141 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15142 15143 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15144 reportingProcessState, now); 15145 } 15146 15147 private final ActivityRecord resumedAppLocked() { 15148 return mStackSupervisor.resumedAppLocked(); 15149 } 15150 15151 final boolean updateOomAdjLocked(ProcessRecord app) { 15152 return updateOomAdjLocked(app, false); 15153 } 15154 15155 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15156 final ActivityRecord TOP_ACT = resumedAppLocked(); 15157 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15158 final boolean wasCached = app.cached; 15159 15160 mAdjSeq++; 15161 15162 // This is the desired cached adjusment we want to tell it to use. 15163 // If our app is currently cached, we know it, and that is it. Otherwise, 15164 // we don't know it yet, and it needs to now be cached we will then 15165 // need to do a complete oom adj. 15166 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15167 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15168 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15169 SystemClock.uptimeMillis()); 15170 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15171 // Changed to/from cached state, so apps after it in the LRU 15172 // list may also be changed. 15173 updateOomAdjLocked(); 15174 } 15175 return success; 15176 } 15177 15178 final void updateOomAdjLocked() { 15179 final ActivityRecord TOP_ACT = resumedAppLocked(); 15180 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15181 final long now = SystemClock.uptimeMillis(); 15182 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15183 final int N = mLruProcesses.size(); 15184 15185 if (false) { 15186 RuntimeException e = new RuntimeException(); 15187 e.fillInStackTrace(); 15188 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15189 } 15190 15191 mAdjSeq++; 15192 mNewNumServiceProcs = 0; 15193 mNewNumAServiceProcs = 0; 15194 15195 final int emptyProcessLimit; 15196 final int cachedProcessLimit; 15197 if (mProcessLimit <= 0) { 15198 emptyProcessLimit = cachedProcessLimit = 0; 15199 } else if (mProcessLimit == 1) { 15200 emptyProcessLimit = 1; 15201 cachedProcessLimit = 0; 15202 } else { 15203 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15204 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15205 } 15206 15207 // Let's determine how many processes we have running vs. 15208 // how many slots we have for background processes; we may want 15209 // to put multiple processes in a slot of there are enough of 15210 // them. 15211 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15212 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15213 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15214 if (numEmptyProcs > cachedProcessLimit) { 15215 // If there are more empty processes than our limit on cached 15216 // processes, then use the cached process limit for the factor. 15217 // This ensures that the really old empty processes get pushed 15218 // down to the bottom, so if we are running low on memory we will 15219 // have a better chance at keeping around more cached processes 15220 // instead of a gazillion empty processes. 15221 numEmptyProcs = cachedProcessLimit; 15222 } 15223 int emptyFactor = numEmptyProcs/numSlots; 15224 if (emptyFactor < 1) emptyFactor = 1; 15225 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15226 if (cachedFactor < 1) cachedFactor = 1; 15227 int stepCached = 0; 15228 int stepEmpty = 0; 15229 int numCached = 0; 15230 int numEmpty = 0; 15231 int numTrimming = 0; 15232 15233 mNumNonCachedProcs = 0; 15234 mNumCachedHiddenProcs = 0; 15235 15236 // First update the OOM adjustment for each of the 15237 // application processes based on their current state. 15238 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15239 int nextCachedAdj = curCachedAdj+1; 15240 int curClientCachedAdj = curCachedAdj+1; 15241 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15242 int nextEmptyAdj = curEmptyAdj+2; 15243 for (int i=N-1; i>=0; i--) { 15244 ProcessRecord app = mLruProcesses.get(i); 15245 if (!app.killedByAm && app.thread != null) { 15246 app.procStateChanged = false; 15247 final boolean wasKeeping = app.keeping; 15248 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15249 15250 // If we haven't yet assigned the final cached adj 15251 // to the process, do that now. 15252 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15253 switch (app.curProcState) { 15254 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15255 // This process is a cached process holding activities... 15256 // assign it the next cached value for that type, and then 15257 // step that cached level. 15258 app.curRawAdj = curCachedAdj; 15259 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15260 if (curCachedAdj != nextCachedAdj) { 15261 stepCached++; 15262 if (stepCached >= cachedFactor) { 15263 stepCached = 0; 15264 curCachedAdj = nextCachedAdj; 15265 nextCachedAdj += 2; 15266 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15267 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15268 } 15269 if (curClientCachedAdj <= curCachedAdj) { 15270 curClientCachedAdj = curCachedAdj + 1; 15271 if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15272 curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15273 } 15274 } 15275 } 15276 } 15277 break; 15278 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15279 // Special case for cached client processes... just step 15280 // down from after regular cached processes. 15281 app.curRawAdj = curClientCachedAdj; 15282 app.curAdj = app.modifyRawOomAdj(curClientCachedAdj); 15283 curClientCachedAdj++; 15284 if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15285 curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15286 } 15287 break; 15288 default: 15289 // For everything else, assign next empty cached process 15290 // level and bump that up. Note that this means that 15291 // long-running services that have dropped down to the 15292 // cached level will be treated as empty (since their process 15293 // state is still as a service), which is what we want. 15294 app.curRawAdj = curEmptyAdj; 15295 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15296 if (curEmptyAdj != nextEmptyAdj) { 15297 stepEmpty++; 15298 if (stepEmpty >= emptyFactor) { 15299 stepEmpty = 0; 15300 curEmptyAdj = nextEmptyAdj; 15301 nextEmptyAdj += 2; 15302 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15303 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15304 } 15305 } 15306 } 15307 break; 15308 } 15309 } 15310 15311 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15312 15313 // Count the number of process types. 15314 switch (app.curProcState) { 15315 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15316 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15317 mNumCachedHiddenProcs++; 15318 numCached++; 15319 if (numCached > cachedProcessLimit) { 15320 killUnneededProcessLocked(app, "cached #" + numCached); 15321 } 15322 break; 15323 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15324 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15325 && app.lastActivityTime < oldTime) { 15326 killUnneededProcessLocked(app, "empty for " 15327 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15328 / 1000) + "s"); 15329 } else { 15330 numEmpty++; 15331 if (numEmpty > emptyProcessLimit) { 15332 killUnneededProcessLocked(app, "empty #" + numEmpty); 15333 } 15334 } 15335 break; 15336 default: 15337 mNumNonCachedProcs++; 15338 break; 15339 } 15340 15341 if (app.isolated && app.services.size() <= 0) { 15342 // If this is an isolated process, and there are no 15343 // services running in it, then the process is no longer 15344 // needed. We agressively kill these because we can by 15345 // definition not re-use the same process again, and it is 15346 // good to avoid having whatever code was running in them 15347 // left sitting around after no longer needed. 15348 killUnneededProcessLocked(app, "isolated not needed"); 15349 } 15350 15351 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15352 && !app.killedByAm) { 15353 numTrimming++; 15354 } 15355 } 15356 } 15357 15358 mNumServiceProcs = mNewNumServiceProcs; 15359 15360 // Now determine the memory trimming level of background processes. 15361 // Unfortunately we need to start at the back of the list to do this 15362 // properly. We only do this if the number of background apps we 15363 // are managing to keep around is less than half the maximum we desire; 15364 // if we are keeping a good number around, we'll let them use whatever 15365 // memory they want. 15366 final int numCachedAndEmpty = numCached + numEmpty; 15367 int memFactor; 15368 if (numCached <= ProcessList.TRIM_CACHED_APPS 15369 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15370 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15371 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15372 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15373 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15374 } else { 15375 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15376 } 15377 } else { 15378 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15379 } 15380 // We always allow the memory level to go up (better). We only allow it to go 15381 // down if we are in a state where that is allowed, *and* the total number of processes 15382 // has gone down since last time. 15383 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15384 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15385 + " last=" + mLastNumProcesses); 15386 if (memFactor > mLastMemoryLevel) { 15387 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15388 memFactor = mLastMemoryLevel; 15389 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15390 } 15391 } 15392 mLastMemoryLevel = memFactor; 15393 mLastNumProcesses = mLruProcesses.size(); 15394 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15395 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15396 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15397 if (mLowRamStartTime == 0) { 15398 mLowRamStartTime = now; 15399 } 15400 int step = 0; 15401 int fgTrimLevel; 15402 switch (memFactor) { 15403 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15404 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15405 break; 15406 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15407 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15408 break; 15409 default: 15410 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15411 break; 15412 } 15413 int factor = numTrimming/3; 15414 int minFactor = 2; 15415 if (mHomeProcess != null) minFactor++; 15416 if (mPreviousProcess != null) minFactor++; 15417 if (factor < minFactor) factor = minFactor; 15418 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15419 for (int i=N-1; i>=0; i--) { 15420 ProcessRecord app = mLruProcesses.get(i); 15421 if (allChanged || app.procStateChanged) { 15422 setProcessTrackerState(app, trackerMemFactor, now); 15423 app.procStateChanged = false; 15424 } 15425 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15426 && !app.killedByAm) { 15427 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15428 try { 15429 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15430 "Trimming memory of " + app.processName 15431 + " to " + curLevel); 15432 app.thread.scheduleTrimMemory(curLevel); 15433 } catch (RemoteException e) { 15434 } 15435 if (false) { 15436 // For now we won't do this; our memory trimming seems 15437 // to be good enough at this point that destroying 15438 // activities causes more harm than good. 15439 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15440 && app != mHomeProcess && app != mPreviousProcess) { 15441 // Need to do this on its own message because the stack may not 15442 // be in a consistent state at this point. 15443 // For these apps we will also finish their activities 15444 // to help them free memory. 15445 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15446 } 15447 } 15448 } 15449 app.trimMemoryLevel = curLevel; 15450 step++; 15451 if (step >= factor) { 15452 step = 0; 15453 switch (curLevel) { 15454 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15455 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15456 break; 15457 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15458 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15459 break; 15460 } 15461 } 15462 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15463 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15464 && app.thread != null) { 15465 try { 15466 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15467 "Trimming memory of heavy-weight " + app.processName 15468 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15469 app.thread.scheduleTrimMemory( 15470 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15471 } catch (RemoteException e) { 15472 } 15473 } 15474 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15475 } else { 15476 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15477 || app.systemNoUi) && app.pendingUiClean) { 15478 // If this application is now in the background and it 15479 // had done UI, then give it the special trim level to 15480 // have it free UI resources. 15481 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15482 if (app.trimMemoryLevel < level && app.thread != null) { 15483 try { 15484 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15485 "Trimming memory of bg-ui " + app.processName 15486 + " to " + level); 15487 app.thread.scheduleTrimMemory(level); 15488 } catch (RemoteException e) { 15489 } 15490 } 15491 app.pendingUiClean = false; 15492 } 15493 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15494 try { 15495 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15496 "Trimming memory of fg " + app.processName 15497 + " to " + fgTrimLevel); 15498 app.thread.scheduleTrimMemory(fgTrimLevel); 15499 } catch (RemoteException e) { 15500 } 15501 } 15502 app.trimMemoryLevel = fgTrimLevel; 15503 } 15504 } 15505 } else { 15506 if (mLowRamStartTime != 0) { 15507 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15508 mLowRamStartTime = 0; 15509 } 15510 for (int i=N-1; i>=0; i--) { 15511 ProcessRecord app = mLruProcesses.get(i); 15512 if (allChanged || app.procStateChanged) { 15513 setProcessTrackerState(app, trackerMemFactor, now); 15514 app.procStateChanged = false; 15515 } 15516 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15517 || app.systemNoUi) && app.pendingUiClean) { 15518 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15519 && app.thread != null) { 15520 try { 15521 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15522 "Trimming memory of ui hidden " + app.processName 15523 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15524 app.thread.scheduleTrimMemory( 15525 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15526 } catch (RemoteException e) { 15527 } 15528 } 15529 app.pendingUiClean = false; 15530 } 15531 app.trimMemoryLevel = 0; 15532 } 15533 } 15534 15535 if (mAlwaysFinishActivities) { 15536 // Need to do this on its own message because the stack may not 15537 // be in a consistent state at this point. 15538 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15539 } 15540 15541 if (allChanged) { 15542 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15543 } 15544 15545 if (mProcessStats.shouldWriteNowLocked(now)) { 15546 mHandler.post(new Runnable() { 15547 @Override public void run() { 15548 synchronized (ActivityManagerService.this) { 15549 mProcessStats.writeStateAsyncLocked(); 15550 } 15551 } 15552 }); 15553 } 15554 15555 if (DEBUG_OOM_ADJ) { 15556 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15557 } 15558 } 15559 15560 final void trimApplications() { 15561 synchronized (this) { 15562 int i; 15563 15564 // First remove any unused application processes whose package 15565 // has been removed. 15566 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15567 final ProcessRecord app = mRemovedProcesses.get(i); 15568 if (app.activities.size() == 0 15569 && app.curReceiver == null && app.services.size() == 0) { 15570 Slog.i( 15571 TAG, "Exiting empty application process " 15572 + app.processName + " (" 15573 + (app.thread != null ? app.thread.asBinder() : null) 15574 + ")\n"); 15575 if (app.pid > 0 && app.pid != MY_PID) { 15576 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15577 app.processName, app.setAdj, "empty"); 15578 app.killedByAm = true; 15579 Process.killProcessQuiet(app.pid); 15580 } else { 15581 try { 15582 app.thread.scheduleExit(); 15583 } catch (Exception e) { 15584 // Ignore exceptions. 15585 } 15586 } 15587 cleanUpApplicationRecordLocked(app, false, true, -1); 15588 mRemovedProcesses.remove(i); 15589 15590 if (app.persistent) { 15591 if (app.persistent) { 15592 addAppLocked(app.info, false); 15593 } 15594 } 15595 } 15596 } 15597 15598 // Now update the oom adj for all processes. 15599 updateOomAdjLocked(); 15600 } 15601 } 15602 15603 /** This method sends the specified signal to each of the persistent apps */ 15604 public void signalPersistentProcesses(int sig) throws RemoteException { 15605 if (sig != Process.SIGNAL_USR1) { 15606 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15607 } 15608 15609 synchronized (this) { 15610 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15611 != PackageManager.PERMISSION_GRANTED) { 15612 throw new SecurityException("Requires permission " 15613 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15614 } 15615 15616 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15617 ProcessRecord r = mLruProcesses.get(i); 15618 if (r.thread != null && r.persistent) { 15619 Process.sendSignal(r.pid, sig); 15620 } 15621 } 15622 } 15623 } 15624 15625 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15626 if (proc == null || proc == mProfileProc) { 15627 proc = mProfileProc; 15628 path = mProfileFile; 15629 profileType = mProfileType; 15630 clearProfilerLocked(); 15631 } 15632 if (proc == null) { 15633 return; 15634 } 15635 try { 15636 proc.thread.profilerControl(false, path, null, profileType); 15637 } catch (RemoteException e) { 15638 throw new IllegalStateException("Process disappeared"); 15639 } 15640 } 15641 15642 private void clearProfilerLocked() { 15643 if (mProfileFd != null) { 15644 try { 15645 mProfileFd.close(); 15646 } catch (IOException e) { 15647 } 15648 } 15649 mProfileApp = null; 15650 mProfileProc = null; 15651 mProfileFile = null; 15652 mProfileType = 0; 15653 mAutoStopProfiler = false; 15654 } 15655 15656 public boolean profileControl(String process, int userId, boolean start, 15657 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15658 15659 try { 15660 synchronized (this) { 15661 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15662 // its own permission. 15663 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15664 != PackageManager.PERMISSION_GRANTED) { 15665 throw new SecurityException("Requires permission " 15666 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15667 } 15668 15669 if (start && fd == null) { 15670 throw new IllegalArgumentException("null fd"); 15671 } 15672 15673 ProcessRecord proc = null; 15674 if (process != null) { 15675 proc = findProcessLocked(process, userId, "profileControl"); 15676 } 15677 15678 if (start && (proc == null || proc.thread == null)) { 15679 throw new IllegalArgumentException("Unknown process: " + process); 15680 } 15681 15682 if (start) { 15683 stopProfilerLocked(null, null, 0); 15684 setProfileApp(proc.info, proc.processName, path, fd, false); 15685 mProfileProc = proc; 15686 mProfileType = profileType; 15687 try { 15688 fd = fd.dup(); 15689 } catch (IOException e) { 15690 fd = null; 15691 } 15692 proc.thread.profilerControl(start, path, fd, profileType); 15693 fd = null; 15694 mProfileFd = null; 15695 } else { 15696 stopProfilerLocked(proc, path, profileType); 15697 if (fd != null) { 15698 try { 15699 fd.close(); 15700 } catch (IOException e) { 15701 } 15702 } 15703 } 15704 15705 return true; 15706 } 15707 } catch (RemoteException e) { 15708 throw new IllegalStateException("Process disappeared"); 15709 } finally { 15710 if (fd != null) { 15711 try { 15712 fd.close(); 15713 } catch (IOException e) { 15714 } 15715 } 15716 } 15717 } 15718 15719 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15720 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15721 userId, true, true, callName, null); 15722 ProcessRecord proc = null; 15723 try { 15724 int pid = Integer.parseInt(process); 15725 synchronized (mPidsSelfLocked) { 15726 proc = mPidsSelfLocked.get(pid); 15727 } 15728 } catch (NumberFormatException e) { 15729 } 15730 15731 if (proc == null) { 15732 ArrayMap<String, SparseArray<ProcessRecord>> all 15733 = mProcessNames.getMap(); 15734 SparseArray<ProcessRecord> procs = all.get(process); 15735 if (procs != null && procs.size() > 0) { 15736 proc = procs.valueAt(0); 15737 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15738 for (int i=1; i<procs.size(); i++) { 15739 ProcessRecord thisProc = procs.valueAt(i); 15740 if (thisProc.userId == userId) { 15741 proc = thisProc; 15742 break; 15743 } 15744 } 15745 } 15746 } 15747 } 15748 15749 return proc; 15750 } 15751 15752 public boolean dumpHeap(String process, int userId, boolean managed, 15753 String path, ParcelFileDescriptor fd) throws RemoteException { 15754 15755 try { 15756 synchronized (this) { 15757 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15758 // its own permission (same as profileControl). 15759 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15760 != PackageManager.PERMISSION_GRANTED) { 15761 throw new SecurityException("Requires permission " 15762 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15763 } 15764 15765 if (fd == null) { 15766 throw new IllegalArgumentException("null fd"); 15767 } 15768 15769 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15770 if (proc == null || proc.thread == null) { 15771 throw new IllegalArgumentException("Unknown process: " + process); 15772 } 15773 15774 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15775 if (!isDebuggable) { 15776 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15777 throw new SecurityException("Process not debuggable: " + proc); 15778 } 15779 } 15780 15781 proc.thread.dumpHeap(managed, path, fd); 15782 fd = null; 15783 return true; 15784 } 15785 } catch (RemoteException e) { 15786 throw new IllegalStateException("Process disappeared"); 15787 } finally { 15788 if (fd != null) { 15789 try { 15790 fd.close(); 15791 } catch (IOException e) { 15792 } 15793 } 15794 } 15795 } 15796 15797 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 15798 public void monitor() { 15799 synchronized (this) { } 15800 } 15801 15802 void onCoreSettingsChange(Bundle settings) { 15803 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 15804 ProcessRecord processRecord = mLruProcesses.get(i); 15805 try { 15806 if (processRecord.thread != null) { 15807 processRecord.thread.setCoreSettings(settings); 15808 } 15809 } catch (RemoteException re) { 15810 /* ignore */ 15811 } 15812 } 15813 } 15814 15815 // Multi-user methods 15816 15817 @Override 15818 public boolean switchUser(final int userId) { 15819 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 15820 != PackageManager.PERMISSION_GRANTED) { 15821 String msg = "Permission Denial: switchUser() from pid=" 15822 + Binder.getCallingPid() 15823 + ", uid=" + Binder.getCallingUid() 15824 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 15825 Slog.w(TAG, msg); 15826 throw new SecurityException(msg); 15827 } 15828 15829 final long ident = Binder.clearCallingIdentity(); 15830 try { 15831 synchronized (this) { 15832 final int oldUserId = mCurrentUserId; 15833 if (oldUserId == userId) { 15834 return true; 15835 } 15836 15837 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 15838 if (userInfo == null) { 15839 Slog.w(TAG, "No user info for user #" + userId); 15840 return false; 15841 } 15842 15843 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 15844 R.anim.screen_user_enter); 15845 15846 boolean needStart = false; 15847 15848 // If the user we are switching to is not currently started, then 15849 // we need to start it now. 15850 if (mStartedUsers.get(userId) == null) { 15851 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 15852 updateStartedUserArrayLocked(); 15853 needStart = true; 15854 } 15855 15856 mCurrentUserId = userId; 15857 final Integer userIdInt = Integer.valueOf(userId); 15858 mUserLru.remove(userIdInt); 15859 mUserLru.add(userIdInt); 15860 15861 mWindowManager.setCurrentUser(userId); 15862 15863 // Once the internal notion of the active user has switched, we lock the device 15864 // with the option to show the user switcher on the keyguard. 15865 mWindowManager.lockNow(null); 15866 15867 final UserStartedState uss = mStartedUsers.get(userId); 15868 15869 // Make sure user is in the started state. If it is currently 15870 // stopping, we need to knock that off. 15871 if (uss.mState == UserStartedState.STATE_STOPPING) { 15872 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 15873 // so we can just fairly silently bring the user back from 15874 // the almost-dead. 15875 uss.mState = UserStartedState.STATE_RUNNING; 15876 updateStartedUserArrayLocked(); 15877 needStart = true; 15878 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 15879 // This means ACTION_SHUTDOWN has been sent, so we will 15880 // need to treat this as a new boot of the user. 15881 uss.mState = UserStartedState.STATE_BOOTING; 15882 updateStartedUserArrayLocked(); 15883 needStart = true; 15884 } 15885 15886 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 15887 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 15888 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 15889 oldUserId, userId, uss)); 15890 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 15891 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 15892 if (needStart) { 15893 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 15894 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15895 | Intent.FLAG_RECEIVER_FOREGROUND); 15896 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 15897 broadcastIntentLocked(null, null, intent, 15898 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15899 false, false, MY_PID, Process.SYSTEM_UID, userId); 15900 } 15901 15902 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 15903 if (userId != 0) { 15904 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 15905 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15906 broadcastIntentLocked(null, null, intent, null, 15907 new IIntentReceiver.Stub() { 15908 public void performReceive(Intent intent, int resultCode, 15909 String data, Bundle extras, boolean ordered, 15910 boolean sticky, int sendingUser) { 15911 userInitialized(uss, userId); 15912 } 15913 }, 0, null, null, null, AppOpsManager.OP_NONE, 15914 true, false, MY_PID, Process.SYSTEM_UID, 15915 userId); 15916 uss.initializing = true; 15917 } else { 15918 getUserManagerLocked().makeInitialized(userInfo.id); 15919 } 15920 } 15921 15922 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 15923 if (homeInFront) { 15924 startHomeActivityLocked(userId); 15925 } else { 15926 mStackSupervisor.resumeTopActivitiesLocked(); 15927 } 15928 15929 EventLogTags.writeAmSwitchUser(userId); 15930 getUserManagerLocked().userForeground(userId); 15931 sendUserSwitchBroadcastsLocked(oldUserId, userId); 15932 if (needStart) { 15933 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 15934 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15935 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 15936 broadcastIntentLocked(null, null, intent, 15937 null, new IIntentReceiver.Stub() { 15938 @Override 15939 public void performReceive(Intent intent, int resultCode, String data, 15940 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 15941 throws RemoteException { 15942 } 15943 }, 0, null, null, 15944 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 15945 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15946 } 15947 } 15948 } finally { 15949 Binder.restoreCallingIdentity(ident); 15950 } 15951 15952 return true; 15953 } 15954 15955 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 15956 long ident = Binder.clearCallingIdentity(); 15957 try { 15958 Intent intent; 15959 if (oldUserId >= 0) { 15960 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 15961 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15962 | Intent.FLAG_RECEIVER_FOREGROUND); 15963 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 15964 broadcastIntentLocked(null, null, intent, 15965 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15966 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 15967 } 15968 if (newUserId >= 0) { 15969 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 15970 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15971 | Intent.FLAG_RECEIVER_FOREGROUND); 15972 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 15973 broadcastIntentLocked(null, null, intent, 15974 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15975 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 15976 intent = new Intent(Intent.ACTION_USER_SWITCHED); 15977 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15978 | Intent.FLAG_RECEIVER_FOREGROUND); 15979 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 15980 broadcastIntentLocked(null, null, intent, 15981 null, null, 0, null, null, 15982 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 15983 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15984 } 15985 } finally { 15986 Binder.restoreCallingIdentity(ident); 15987 } 15988 } 15989 15990 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 15991 final int newUserId) { 15992 final int N = mUserSwitchObservers.beginBroadcast(); 15993 if (N > 0) { 15994 final IRemoteCallback callback = new IRemoteCallback.Stub() { 15995 int mCount = 0; 15996 @Override 15997 public void sendResult(Bundle data) throws RemoteException { 15998 synchronized (ActivityManagerService.this) { 15999 if (mCurUserSwitchCallback == this) { 16000 mCount++; 16001 if (mCount == N) { 16002 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16003 } 16004 } 16005 } 16006 } 16007 }; 16008 synchronized (this) { 16009 uss.switching = true; 16010 mCurUserSwitchCallback = callback; 16011 } 16012 for (int i=0; i<N; i++) { 16013 try { 16014 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16015 newUserId, callback); 16016 } catch (RemoteException e) { 16017 } 16018 } 16019 } else { 16020 synchronized (this) { 16021 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16022 } 16023 } 16024 mUserSwitchObservers.finishBroadcast(); 16025 } 16026 16027 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16028 synchronized (this) { 16029 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16030 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16031 } 16032 } 16033 16034 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16035 mCurUserSwitchCallback = null; 16036 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16037 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16038 oldUserId, newUserId, uss)); 16039 } 16040 16041 void userInitialized(UserStartedState uss, int newUserId) { 16042 completeSwitchAndInitalize(uss, newUserId, true, false); 16043 } 16044 16045 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16046 completeSwitchAndInitalize(uss, newUserId, false, true); 16047 } 16048 16049 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16050 boolean clearInitializing, boolean clearSwitching) { 16051 boolean unfrozen = false; 16052 synchronized (this) { 16053 if (clearInitializing) { 16054 uss.initializing = false; 16055 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16056 } 16057 if (clearSwitching) { 16058 uss.switching = false; 16059 } 16060 if (!uss.switching && !uss.initializing) { 16061 mWindowManager.stopFreezingScreen(); 16062 unfrozen = true; 16063 } 16064 } 16065 if (unfrozen) { 16066 final int N = mUserSwitchObservers.beginBroadcast(); 16067 for (int i=0; i<N; i++) { 16068 try { 16069 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16070 } catch (RemoteException e) { 16071 } 16072 } 16073 mUserSwitchObservers.finishBroadcast(); 16074 } 16075 } 16076 16077 void finishUserSwitch(UserStartedState uss) { 16078 synchronized (this) { 16079 if (uss.mState == UserStartedState.STATE_BOOTING 16080 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16081 uss.mState = UserStartedState.STATE_RUNNING; 16082 final int userId = uss.mHandle.getIdentifier(); 16083 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16084 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16085 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16086 broadcastIntentLocked(null, null, intent, 16087 null, null, 0, null, null, 16088 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16089 true, false, MY_PID, Process.SYSTEM_UID, userId); 16090 } 16091 int num = mUserLru.size(); 16092 int i = 0; 16093 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16094 Integer oldUserId = mUserLru.get(i); 16095 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16096 if (oldUss == null) { 16097 // Shouldn't happen, but be sane if it does. 16098 mUserLru.remove(i); 16099 num--; 16100 continue; 16101 } 16102 if (oldUss.mState == UserStartedState.STATE_STOPPING 16103 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16104 // This user is already stopping, doesn't count. 16105 num--; 16106 i++; 16107 continue; 16108 } 16109 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16110 // Owner and current can't be stopped, but count as running. 16111 i++; 16112 continue; 16113 } 16114 // This is a user to be stopped. 16115 stopUserLocked(oldUserId, null); 16116 num--; 16117 i++; 16118 } 16119 } 16120 } 16121 16122 @Override 16123 public int stopUser(final int userId, final IStopUserCallback callback) { 16124 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16125 != PackageManager.PERMISSION_GRANTED) { 16126 String msg = "Permission Denial: switchUser() from pid=" 16127 + Binder.getCallingPid() 16128 + ", uid=" + Binder.getCallingUid() 16129 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16130 Slog.w(TAG, msg); 16131 throw new SecurityException(msg); 16132 } 16133 if (userId <= 0) { 16134 throw new IllegalArgumentException("Can't stop primary user " + userId); 16135 } 16136 synchronized (this) { 16137 return stopUserLocked(userId, callback); 16138 } 16139 } 16140 16141 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16142 if (mCurrentUserId == userId) { 16143 return ActivityManager.USER_OP_IS_CURRENT; 16144 } 16145 16146 final UserStartedState uss = mStartedUsers.get(userId); 16147 if (uss == null) { 16148 // User is not started, nothing to do... but we do need to 16149 // callback if requested. 16150 if (callback != null) { 16151 mHandler.post(new Runnable() { 16152 @Override 16153 public void run() { 16154 try { 16155 callback.userStopped(userId); 16156 } catch (RemoteException e) { 16157 } 16158 } 16159 }); 16160 } 16161 return ActivityManager.USER_OP_SUCCESS; 16162 } 16163 16164 if (callback != null) { 16165 uss.mStopCallbacks.add(callback); 16166 } 16167 16168 if (uss.mState != UserStartedState.STATE_STOPPING 16169 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16170 uss.mState = UserStartedState.STATE_STOPPING; 16171 updateStartedUserArrayLocked(); 16172 16173 long ident = Binder.clearCallingIdentity(); 16174 try { 16175 // We are going to broadcast ACTION_USER_STOPPING and then 16176 // once that is done send a final ACTION_SHUTDOWN and then 16177 // stop the user. 16178 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16179 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16180 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16181 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16182 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16183 // This is the result receiver for the final shutdown broadcast. 16184 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16185 @Override 16186 public void performReceive(Intent intent, int resultCode, String data, 16187 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16188 finishUserStop(uss); 16189 } 16190 }; 16191 // This is the result receiver for the initial stopping broadcast. 16192 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16193 @Override 16194 public void performReceive(Intent intent, int resultCode, String data, 16195 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16196 // On to the next. 16197 synchronized (ActivityManagerService.this) { 16198 if (uss.mState != UserStartedState.STATE_STOPPING) { 16199 // Whoops, we are being started back up. Abort, abort! 16200 return; 16201 } 16202 uss.mState = UserStartedState.STATE_SHUTDOWN; 16203 } 16204 broadcastIntentLocked(null, null, shutdownIntent, 16205 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16206 true, false, MY_PID, Process.SYSTEM_UID, userId); 16207 } 16208 }; 16209 // Kick things off. 16210 broadcastIntentLocked(null, null, stoppingIntent, 16211 null, stoppingReceiver, 0, null, null, 16212 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16213 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16214 } finally { 16215 Binder.restoreCallingIdentity(ident); 16216 } 16217 } 16218 16219 return ActivityManager.USER_OP_SUCCESS; 16220 } 16221 16222 void finishUserStop(UserStartedState uss) { 16223 final int userId = uss.mHandle.getIdentifier(); 16224 boolean stopped; 16225 ArrayList<IStopUserCallback> callbacks; 16226 synchronized (this) { 16227 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16228 if (mStartedUsers.get(userId) != uss) { 16229 stopped = false; 16230 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16231 stopped = false; 16232 } else { 16233 stopped = true; 16234 // User can no longer run. 16235 mStartedUsers.remove(userId); 16236 mUserLru.remove(Integer.valueOf(userId)); 16237 updateStartedUserArrayLocked(); 16238 16239 // Clean up all state and processes associated with the user. 16240 // Kill all the processes for the user. 16241 forceStopUserLocked(userId, "finish user"); 16242 } 16243 } 16244 16245 for (int i=0; i<callbacks.size(); i++) { 16246 try { 16247 if (stopped) callbacks.get(i).userStopped(userId); 16248 else callbacks.get(i).userStopAborted(userId); 16249 } catch (RemoteException e) { 16250 } 16251 } 16252 16253 mStackSupervisor.removeUserLocked(userId); 16254 } 16255 16256 @Override 16257 public UserInfo getCurrentUser() { 16258 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16259 != PackageManager.PERMISSION_GRANTED) && ( 16260 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16261 != PackageManager.PERMISSION_GRANTED)) { 16262 String msg = "Permission Denial: getCurrentUser() from pid=" 16263 + Binder.getCallingPid() 16264 + ", uid=" + Binder.getCallingUid() 16265 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16266 Slog.w(TAG, msg); 16267 throw new SecurityException(msg); 16268 } 16269 synchronized (this) { 16270 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16271 } 16272 } 16273 16274 int getCurrentUserIdLocked() { 16275 return mCurrentUserId; 16276 } 16277 16278 @Override 16279 public boolean isUserRunning(int userId, boolean orStopped) { 16280 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16281 != PackageManager.PERMISSION_GRANTED) { 16282 String msg = "Permission Denial: isUserRunning() from pid=" 16283 + Binder.getCallingPid() 16284 + ", uid=" + Binder.getCallingUid() 16285 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16286 Slog.w(TAG, msg); 16287 throw new SecurityException(msg); 16288 } 16289 synchronized (this) { 16290 return isUserRunningLocked(userId, orStopped); 16291 } 16292 } 16293 16294 boolean isUserRunningLocked(int userId, boolean orStopped) { 16295 UserStartedState state = mStartedUsers.get(userId); 16296 if (state == null) { 16297 return false; 16298 } 16299 if (orStopped) { 16300 return true; 16301 } 16302 return state.mState != UserStartedState.STATE_STOPPING 16303 && state.mState != UserStartedState.STATE_SHUTDOWN; 16304 } 16305 16306 @Override 16307 public int[] getRunningUserIds() { 16308 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16309 != PackageManager.PERMISSION_GRANTED) { 16310 String msg = "Permission Denial: isUserRunning() from pid=" 16311 + Binder.getCallingPid() 16312 + ", uid=" + Binder.getCallingUid() 16313 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16314 Slog.w(TAG, msg); 16315 throw new SecurityException(msg); 16316 } 16317 synchronized (this) { 16318 return mStartedUserArray; 16319 } 16320 } 16321 16322 private void updateStartedUserArrayLocked() { 16323 int num = 0; 16324 for (int i=0; i<mStartedUsers.size(); i++) { 16325 UserStartedState uss = mStartedUsers.valueAt(i); 16326 // This list does not include stopping users. 16327 if (uss.mState != UserStartedState.STATE_STOPPING 16328 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16329 num++; 16330 } 16331 } 16332 mStartedUserArray = new int[num]; 16333 num = 0; 16334 for (int i=0; i<mStartedUsers.size(); i++) { 16335 UserStartedState uss = mStartedUsers.valueAt(i); 16336 if (uss.mState != UserStartedState.STATE_STOPPING 16337 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16338 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16339 num++; 16340 } 16341 } 16342 } 16343 16344 @Override 16345 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16346 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16347 != PackageManager.PERMISSION_GRANTED) { 16348 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16349 + Binder.getCallingPid() 16350 + ", uid=" + Binder.getCallingUid() 16351 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16352 Slog.w(TAG, msg); 16353 throw new SecurityException(msg); 16354 } 16355 16356 mUserSwitchObservers.register(observer); 16357 } 16358 16359 @Override 16360 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16361 mUserSwitchObservers.unregister(observer); 16362 } 16363 16364 private boolean userExists(int userId) { 16365 if (userId == 0) { 16366 return true; 16367 } 16368 UserManagerService ums = getUserManagerLocked(); 16369 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16370 } 16371 16372 int[] getUsersLocked() { 16373 UserManagerService ums = getUserManagerLocked(); 16374 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16375 } 16376 16377 UserManagerService getUserManagerLocked() { 16378 if (mUserManager == null) { 16379 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16380 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16381 } 16382 return mUserManager; 16383 } 16384 16385 private void checkValidCaller(int uid, int userId) { 16386 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return; 16387 16388 throw new SecurityException("Caller uid=" + uid 16389 + " is not privileged to communicate with user=" + userId); 16390 } 16391 16392 private int applyUserId(int uid, int userId) { 16393 return UserHandle.getUid(userId, uid); 16394 } 16395 16396 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16397 if (info == null) return null; 16398 ApplicationInfo newInfo = new ApplicationInfo(info); 16399 newInfo.uid = applyUserId(info.uid, userId); 16400 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16401 + info.packageName; 16402 return newInfo; 16403 } 16404 16405 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16406 if (aInfo == null 16407 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16408 return aInfo; 16409 } 16410 16411 ActivityInfo info = new ActivityInfo(aInfo); 16412 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16413 return info; 16414 } 16415 } 16416