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 com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26 import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30 import android.app.AppOpsManager; 31 import android.appwidget.AppWidgetManager; 32 import android.util.ArrayMap; 33 import com.android.internal.R; 34 import com.android.internal.annotations.GuardedBy; 35 import com.android.internal.app.IAppOpsService; 36 import com.android.internal.app.ProcessStats; 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_LRU = localLOGV || false; 221 static final boolean DEBUG_PAUSE = localLOGV || false; 222 static final boolean DEBUG_POWER = localLOGV || false; 223 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 224 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 225 static final boolean DEBUG_PROCESSES = localLOGV || false; 226 static final boolean DEBUG_PROVIDER = localLOGV || false; 227 static final boolean DEBUG_RESULTS = localLOGV || false; 228 static final boolean DEBUG_SERVICE = localLOGV || false; 229 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 230 static final boolean DEBUG_STACK = localLOGV || false; 231 static final boolean DEBUG_SWITCH = localLOGV || false; 232 static final boolean DEBUG_TASKS = localLOGV || false; 233 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 234 static final boolean DEBUG_TRANSITION = localLOGV || false; 235 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 236 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 237 static final boolean DEBUG_VISBILITY = localLOGV || false; 238 static final boolean DEBUG_PSS = localLOGV || false; 239 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 240 static final boolean VALIDATE_TOKENS = false; 241 static final boolean SHOW_ACTIVITY_START_TIME = true; 242 243 // Control over CPU and battery monitoring. 244 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 245 static final boolean MONITOR_CPU_USAGE = true; 246 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 247 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 248 static final boolean MONITOR_THREAD_CPU_USAGE = false; 249 250 // The flags that are set for all calls we make to the package manager. 251 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 252 253 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 254 255 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 256 257 // Maximum number of recent tasks that we can remember. 258 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 259 260 // Amount of time after a call to stopAppSwitches() during which we will 261 // prevent further untrusted switches from happening. 262 static final long APP_SWITCH_DELAY_TIME = 5*1000; 263 264 // How long we wait for a launched process to attach to the activity manager 265 // before we decide it's never going to come up for real. 266 static final int PROC_START_TIMEOUT = 10*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real, when the process was 270 // started with a wrapper for instrumentation (such as Valgrind) because it 271 // could take much longer than usual. 272 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 273 274 // How long to wait after going idle before forcing apps to GC. 275 static final int GC_TIMEOUT = 5*1000; 276 277 // The minimum amount of time between successive GC requests for a process. 278 static final int GC_MIN_INTERVAL = 60*1000; 279 280 // The minimum amount of time between successive PSS requests for a process. 281 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 282 283 // The minimum amount of time between successive PSS requests for a process 284 // when the request is due to the memory state being lowered. 285 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 286 287 // The rate at which we check for apps using excessive power -- 15 mins. 288 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 289 290 // The minimum sample duration we will allow before deciding we have 291 // enough data on wake locks to start killing things. 292 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on CPU usage to start killing things. 296 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // How long we allow a receiver to run before giving up on it. 299 static final int BROADCAST_FG_TIMEOUT = 10*1000; 300 static final int BROADCAST_BG_TIMEOUT = 60*1000; 301 302 // How long we wait until we timeout on key dispatching. 303 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 304 305 // How long we wait until we timeout on key dispatching during instrumentation. 306 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 307 308 // Amount of time we wait for observers to handle a user switch before 309 // giving up on them and unfreezing the screen. 310 static final int USER_SWITCH_TIMEOUT = 2*1000; 311 312 // Maximum number of users we allow to be running at a time. 313 static final int MAX_RUNNING_USERS = 3; 314 315 // How long to wait in getAssistContextExtras for the activity and foreground services 316 // to respond with the result. 317 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 318 319 // Maximum number of persisted Uri grants a package is allowed 320 static final int MAX_PERSISTED_URI_GRANTS = 128; 321 322 static final int MY_PID = Process.myPid(); 323 324 static final String[] EMPTY_STRING_ARRAY = new String[0]; 325 326 // How many bytes to write into the dropbox log before truncating 327 static final int DROPBOX_MAX_SIZE = 256 * 1024; 328 329 /** Run all ActivityStacks through this */ 330 ActivityStackSupervisor mStackSupervisor; 331 332 public IntentFirewall mIntentFirewall; 333 334 private final boolean mHeadless; 335 336 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 337 // default actuion automatically. Important for devices without direct input 338 // devices. 339 private boolean mShowDialogs = true; 340 341 /** 342 * Description of a request to start a new activity, which has been held 343 * due to app switches being disabled. 344 */ 345 static class PendingActivityLaunch { 346 final ActivityRecord r; 347 final ActivityRecord sourceRecord; 348 final int startFlags; 349 final ActivityStack stack; 350 351 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 352 int _startFlags, ActivityStack _stack) { 353 r = _r; 354 sourceRecord = _sourceRecord; 355 startFlags = _startFlags; 356 stack = _stack; 357 } 358 } 359 360 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 361 = new ArrayList<PendingActivityLaunch>(); 362 363 BroadcastQueue mFgBroadcastQueue; 364 BroadcastQueue mBgBroadcastQueue; 365 // Convenient for easy iteration over the queues. Foreground is first 366 // so that dispatch of foreground broadcasts gets precedence. 367 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 368 369 BroadcastQueue broadcastQueueForIntent(Intent intent) { 370 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 371 if (DEBUG_BACKGROUND_BROADCAST) { 372 Slog.i(TAG, "Broadcast intent " + intent + " on " 373 + (isFg ? "foreground" : "background") 374 + " queue"); 375 } 376 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 377 } 378 379 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 380 for (BroadcastQueue queue : mBroadcastQueues) { 381 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 382 if (r != null) { 383 return r; 384 } 385 } 386 return null; 387 } 388 389 /** 390 * Activity we have told the window manager to have key focus. 391 */ 392 ActivityRecord mFocusedActivity = null; 393 394 /** 395 * List of intents that were used to start the most recent tasks. 396 */ 397 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 398 399 public class PendingAssistExtras extends Binder implements Runnable { 400 public final ActivityRecord activity; 401 public boolean haveResult = false; 402 public Bundle result = null; 403 public PendingAssistExtras(ActivityRecord _activity) { 404 activity = _activity; 405 } 406 @Override 407 public void run() { 408 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 409 synchronized (this) { 410 haveResult = true; 411 notifyAll(); 412 } 413 } 414 } 415 416 final ArrayList<PendingAssistExtras> mPendingAssistExtras 417 = new ArrayList<PendingAssistExtras>(); 418 419 /** 420 * Process management. 421 */ 422 final ProcessList mProcessList = new ProcessList(); 423 424 /** 425 * All of the applications we currently have running organized by name. 426 * The keys are strings of the application package name (as 427 * returned by the package manager), and the keys are ApplicationRecord 428 * objects. 429 */ 430 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 431 432 /** 433 * Tracking long-term execution of processes to look for abuse and other 434 * bad app behavior. 435 */ 436 final ProcessStatsService mProcessStats; 437 438 /** 439 * The currently running isolated processes. 440 */ 441 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 442 443 /** 444 * Counter for assigning isolated process uids, to avoid frequently reusing the 445 * same ones. 446 */ 447 int mNextIsolatedProcessUid = 0; 448 449 /** 450 * The currently running heavy-weight process, if any. 451 */ 452 ProcessRecord mHeavyWeightProcess = null; 453 454 /** 455 * The last time that various processes have crashed. 456 */ 457 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 458 459 /** 460 * Information about a process that is currently marked as bad. 461 */ 462 static final class BadProcessInfo { 463 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 464 this.time = time; 465 this.shortMsg = shortMsg; 466 this.longMsg = longMsg; 467 this.stack = stack; 468 } 469 470 final long time; 471 final String shortMsg; 472 final String longMsg; 473 final String stack; 474 } 475 476 /** 477 * Set of applications that we consider to be bad, and will reject 478 * incoming broadcasts from (which the user has no control over). 479 * Processes are added to this set when they have crashed twice within 480 * a minimum amount of time; they are removed from it when they are 481 * later restarted (hopefully due to some user action). The value is the 482 * time it was added to the list. 483 */ 484 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 485 486 /** 487 * All of the processes we currently have running organized by pid. 488 * The keys are the pid running the application. 489 * 490 * <p>NOTE: This object is protected by its own lock, NOT the global 491 * activity manager lock! 492 */ 493 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 494 495 /** 496 * All of the processes that have been forced to be foreground. The key 497 * is the pid of the caller who requested it (we hold a death 498 * link on it). 499 */ 500 abstract class ForegroundToken implements IBinder.DeathRecipient { 501 int pid; 502 IBinder token; 503 } 504 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 505 506 /** 507 * List of records for processes that someone had tried to start before the 508 * system was ready. We don't start them at that point, but ensure they 509 * are started by the time booting is complete. 510 */ 511 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 512 513 /** 514 * List of persistent applications that are in the process 515 * of being started. 516 */ 517 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 518 519 /** 520 * Processes that are being forcibly torn down. 521 */ 522 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 523 524 /** 525 * List of running applications, sorted by recent usage. 526 * The first entry in the list is the least recently used. 527 */ 528 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 529 530 /** 531 * Where in mLruProcesses that the processes hosting activities start. 532 */ 533 int mLruProcessActivityStart = 0; 534 535 /** 536 * Where in mLruProcesses that the processes hosting services start. 537 * This is after (lower index) than mLruProcessesActivityStart. 538 */ 539 int mLruProcessServiceStart = 0; 540 541 /** 542 * List of processes that should gc as soon as things are idle. 543 */ 544 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 545 546 /** 547 * Processes we want to collect PSS data from. 548 */ 549 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Last time we requested PSS data of all processes. 553 */ 554 long mLastFullPssTime = SystemClock.uptimeMillis(); 555 556 /** 557 * This is the process holding what we currently consider to be 558 * the "home" activity. 559 */ 560 ProcessRecord mHomeProcess; 561 562 /** 563 * This is the process holding the activity the user last visited that 564 * is in a different process from the one they are currently in. 565 */ 566 ProcessRecord mPreviousProcess; 567 568 /** 569 * The time at which the previous process was last visible. 570 */ 571 long mPreviousProcessVisibleTime; 572 573 /** 574 * Which uses have been started, so are allowed to run code. 575 */ 576 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 577 578 /** 579 * LRU list of history of current users. Most recently current is at the end. 580 */ 581 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 582 583 /** 584 * Constant array of the users that are currently started. 585 */ 586 int[] mStartedUserArray = new int[] { 0 }; 587 588 /** 589 * Registered observers of the user switching mechanics. 590 */ 591 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 592 = new RemoteCallbackList<IUserSwitchObserver>(); 593 594 /** 595 * Currently active user switch. 596 */ 597 Object mCurUserSwitchCallback; 598 599 /** 600 * Packages that the user has asked to have run in screen size 601 * compatibility mode instead of filling the screen. 602 */ 603 final CompatModePackages mCompatModePackages; 604 605 /** 606 * Set of IntentSenderRecord objects that are currently active. 607 */ 608 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 609 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 610 611 /** 612 * Fingerprints (hashCode()) of stack traces that we've 613 * already logged DropBox entries for. Guarded by itself. If 614 * something (rogue user app) forces this over 615 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 616 */ 617 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 618 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 619 620 /** 621 * Strict Mode background batched logging state. 622 * 623 * The string buffer is guarded by itself, and its lock is also 624 * used to determine if another batched write is already 625 * in-flight. 626 */ 627 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 628 629 /** 630 * Keeps track of all IIntentReceivers that have been registered for 631 * broadcasts. Hash keys are the receiver IBinder, hash value is 632 * a ReceiverList. 633 */ 634 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 635 new HashMap<IBinder, ReceiverList>(); 636 637 /** 638 * Resolver for broadcast intents to registered receivers. 639 * Holds BroadcastFilter (subclass of IntentFilter). 640 */ 641 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 642 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 643 @Override 644 protected boolean allowFilterResult( 645 BroadcastFilter filter, List<BroadcastFilter> dest) { 646 IBinder target = filter.receiverList.receiver.asBinder(); 647 for (int i=dest.size()-1; i>=0; i--) { 648 if (dest.get(i).receiverList.receiver.asBinder() == target) { 649 return false; 650 } 651 } 652 return true; 653 } 654 655 @Override 656 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 657 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 658 || userId == filter.owningUserId) { 659 return super.newResult(filter, match, userId); 660 } 661 return null; 662 } 663 664 @Override 665 protected BroadcastFilter[] newArray(int size) { 666 return new BroadcastFilter[size]; 667 } 668 669 @Override 670 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 671 return packageName.equals(filter.packageName); 672 } 673 }; 674 675 /** 676 * State of all active sticky broadcasts per user. Keys are the action of the 677 * sticky Intent, values are an ArrayList of all broadcasted intents with 678 * that action (which should usually be one). The SparseArray is keyed 679 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 680 * for stickies that are sent to all users. 681 */ 682 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 683 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 684 685 final ActiveServices mServices; 686 687 /** 688 * Backup/restore process management 689 */ 690 String mBackupAppName = null; 691 BackupRecord mBackupTarget = null; 692 693 /** 694 * List of PendingThumbnailsRecord objects of clients who are still 695 * waiting to receive all of the thumbnails for a task. 696 */ 697 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 698 new ArrayList<PendingThumbnailsRecord>(); 699 700 final ProviderMap mProviderMap; 701 702 /** 703 * List of content providers who have clients waiting for them. The 704 * application is currently being launched and the provider will be 705 * removed from this list once it is published. 706 */ 707 final ArrayList<ContentProviderRecord> mLaunchingProviders 708 = new ArrayList<ContentProviderRecord>(); 709 710 /** 711 * File storing persisted {@link #mGrantedUriPermissions}. 712 */ 713 private final AtomicFile mGrantFile; 714 715 /** XML constants used in {@link #mGrantFile} */ 716 private static final String TAG_URI_GRANTS = "uri-grants"; 717 private static final String TAG_URI_GRANT = "uri-grant"; 718 private static final String ATTR_USER_HANDLE = "userHandle"; 719 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 720 private static final String ATTR_TARGET_PKG = "targetPkg"; 721 private static final String ATTR_URI = "uri"; 722 private static final String ATTR_MODE_FLAGS = "modeFlags"; 723 private static final String ATTR_CREATED_TIME = "createdTime"; 724 725 /** 726 * Global set of specific {@link Uri} permissions that have been granted. 727 * This optimized lookup structure maps from {@link UriPermission#targetUid} 728 * to {@link UriPermission#uri} to {@link UriPermission}. 729 */ 730 @GuardedBy("this") 731 private final SparseArray<ArrayMap<Uri, UriPermission>> 732 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 733 734 CoreSettingsObserver mCoreSettingsObserver; 735 736 /** 737 * Thread-local storage used to carry caller permissions over through 738 * indirect content-provider access. 739 */ 740 private class Identity { 741 public int pid; 742 public int uid; 743 744 Identity(int _pid, int _uid) { 745 pid = _pid; 746 uid = _uid; 747 } 748 } 749 750 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 751 752 /** 753 * All information we have collected about the runtime performance of 754 * any user id that can impact battery performance. 755 */ 756 final BatteryStatsService mBatteryStatsService; 757 758 /** 759 * Information about component usage 760 */ 761 final UsageStatsService mUsageStatsService; 762 763 /** 764 * Information about and control over application operations 765 */ 766 final AppOpsService mAppOpsService; 767 768 /** 769 * Current configuration information. HistoryRecord objects are given 770 * a reference to this object to indicate which configuration they are 771 * currently running in, so this object must be kept immutable. 772 */ 773 Configuration mConfiguration = new Configuration(); 774 775 /** 776 * Current sequencing integer of the configuration, for skipping old 777 * configurations. 778 */ 779 int mConfigurationSeq = 0; 780 781 /** 782 * Hardware-reported OpenGLES version. 783 */ 784 final int GL_ES_VERSION; 785 786 /** 787 * List of initialization arguments to pass to all processes when binding applications to them. 788 * For example, references to the commonly used services. 789 */ 790 HashMap<String, IBinder> mAppBindArgs; 791 792 /** 793 * Temporary to avoid allocations. Protected by main lock. 794 */ 795 final StringBuilder mStringBuilder = new StringBuilder(256); 796 797 /** 798 * Used to control how we initialize the service. 799 */ 800 boolean mStartRunning = false; 801 ComponentName mTopComponent; 802 String mTopAction; 803 String mTopData; 804 boolean mProcessesReady = false; 805 boolean mSystemReady = false; 806 boolean mBooting = false; 807 boolean mWaitingUpdate = false; 808 boolean mDidUpdate = false; 809 boolean mOnBattery = false; 810 boolean mLaunchWarningShown = false; 811 812 Context mContext; 813 814 int mFactoryTest; 815 816 boolean mCheckedForSetup; 817 818 /** 819 * The time at which we will allow normal application switches again, 820 * after a call to {@link #stopAppSwitches()}. 821 */ 822 long mAppSwitchesAllowedTime; 823 824 /** 825 * This is set to true after the first switch after mAppSwitchesAllowedTime 826 * is set; any switches after that will clear the time. 827 */ 828 boolean mDidAppSwitch; 829 830 /** 831 * Last time (in realtime) at which we checked for power usage. 832 */ 833 long mLastPowerCheckRealtime; 834 835 /** 836 * Last time (in uptime) at which we checked for power usage. 837 */ 838 long mLastPowerCheckUptime; 839 840 /** 841 * Set while we are wanting to sleep, to prevent any 842 * activities from being started/resumed. 843 */ 844 boolean mSleeping = false; 845 846 /** 847 * State of external calls telling us if the device is asleep. 848 */ 849 boolean mWentToSleep = false; 850 851 /** 852 * State of external call telling us if the lock screen is shown. 853 */ 854 boolean mLockScreenShown = false; 855 856 /** 857 * Set if we are shutting down the system, similar to sleeping. 858 */ 859 boolean mShuttingDown = false; 860 861 /** 862 * Current sequence id for oom_adj computation traversal. 863 */ 864 int mAdjSeq = 0; 865 866 /** 867 * Current sequence id for process LRU updating. 868 */ 869 int mLruSeq = 0; 870 871 /** 872 * Keep track of the non-cached/empty process we last found, to help 873 * determine how to distribute cached/empty processes next time. 874 */ 875 int mNumNonCachedProcs = 0; 876 877 /** 878 * Keep track of the number of cached hidden procs, to balance oom adj 879 * distribution between those and empty procs. 880 */ 881 int mNumCachedHiddenProcs = 0; 882 883 /** 884 * Keep track of the number of service processes we last found, to 885 * determine on the next iteration which should be B services. 886 */ 887 int mNumServiceProcs = 0; 888 int mNewNumAServiceProcs = 0; 889 int mNewNumServiceProcs = 0; 890 891 /** 892 * Allow the current computed overall memory level of the system to go down? 893 * This is set to false when we are killing processes for reasons other than 894 * memory management, so that the now smaller process list will not be taken as 895 * an indication that memory is tighter. 896 */ 897 boolean mAllowLowerMemLevel = false; 898 899 /** 900 * The last computed memory level, for holding when we are in a state that 901 * processes are going away for other reasons. 902 */ 903 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 904 905 /** 906 * The last total number of process we have, to determine if changes actually look 907 * like a shrinking number of process due to lower RAM. 908 */ 909 int mLastNumProcesses; 910 911 /** 912 * The uptime of the last time we performed idle maintenance. 913 */ 914 long mLastIdleTime = SystemClock.uptimeMillis(); 915 916 /** 917 * Total time spent with RAM that has been added in the past since the last idle time. 918 */ 919 long mLowRamTimeSinceLastIdle = 0; 920 921 /** 922 * If RAM is currently low, when that horrible situatin started. 923 */ 924 long mLowRamStartTime = 0; 925 926 /** 927 * This is set if we had to do a delayed dexopt of an app before launching 928 * it, to increasing the ANR timeouts in that case. 929 */ 930 boolean mDidDexOpt; 931 932 String mDebugApp = null; 933 boolean mWaitForDebugger = false; 934 boolean mDebugTransient = false; 935 String mOrigDebugApp = null; 936 boolean mOrigWaitForDebugger = false; 937 boolean mAlwaysFinishActivities = false; 938 IActivityController mController = null; 939 String mProfileApp = null; 940 ProcessRecord mProfileProc = null; 941 String mProfileFile; 942 ParcelFileDescriptor mProfileFd; 943 int mProfileType = 0; 944 boolean mAutoStopProfiler = false; 945 String mOpenGlTraceApp = null; 946 947 static class ProcessChangeItem { 948 static final int CHANGE_ACTIVITIES = 1<<0; 949 static final int CHANGE_IMPORTANCE= 1<<1; 950 int changes; 951 int uid; 952 int pid; 953 int importance; 954 boolean foregroundActivities; 955 } 956 957 final RemoteCallbackList<IProcessObserver> mProcessObservers 958 = new RemoteCallbackList<IProcessObserver>(); 959 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 960 961 final ArrayList<ProcessChangeItem> mPendingProcessChanges 962 = new ArrayList<ProcessChangeItem>(); 963 final ArrayList<ProcessChangeItem> mAvailProcessChanges 964 = new ArrayList<ProcessChangeItem>(); 965 966 /** 967 * Runtime CPU use collection thread. This object's lock is used to 968 * protect all related state. 969 */ 970 final Thread mProcessCpuThread; 971 972 /** 973 * Used to collect process stats when showing not responding dialog. 974 * Protected by mProcessCpuThread. 975 */ 976 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 977 MONITOR_THREAD_CPU_USAGE); 978 final AtomicLong mLastCpuTime = new AtomicLong(0); 979 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 980 981 long mLastWriteTime = 0; 982 983 /** 984 * Used to retain an update lock when the foreground activity is in 985 * immersive mode. 986 */ 987 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 988 989 /** 990 * Set to true after the system has finished booting. 991 */ 992 boolean mBooted = false; 993 994 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 995 int mProcessLimitOverride = -1; 996 997 WindowManagerService mWindowManager; 998 999 static ActivityManagerService mSelf; 1000 static ActivityThread mSystemThread; 1001 1002 int mCurrentUserId = 0; 1003 private UserManagerService mUserManager; 1004 1005 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1006 final ProcessRecord mApp; 1007 final int mPid; 1008 final IApplicationThread mAppThread; 1009 1010 AppDeathRecipient(ProcessRecord app, int pid, 1011 IApplicationThread thread) { 1012 if (localLOGV) Slog.v( 1013 TAG, "New death recipient " + this 1014 + " for thread " + thread.asBinder()); 1015 mApp = app; 1016 mPid = pid; 1017 mAppThread = thread; 1018 } 1019 1020 @Override 1021 public void binderDied() { 1022 if (localLOGV) Slog.v( 1023 TAG, "Death received in " + this 1024 + " for thread " + mAppThread.asBinder()); 1025 synchronized(ActivityManagerService.this) { 1026 appDiedLocked(mApp, mPid, mAppThread); 1027 } 1028 } 1029 } 1030 1031 static final int SHOW_ERROR_MSG = 1; 1032 static final int SHOW_NOT_RESPONDING_MSG = 2; 1033 static final int SHOW_FACTORY_ERROR_MSG = 3; 1034 static final int UPDATE_CONFIGURATION_MSG = 4; 1035 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1036 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1037 static final int SERVICE_TIMEOUT_MSG = 12; 1038 static final int UPDATE_TIME_ZONE = 13; 1039 static final int SHOW_UID_ERROR_MSG = 14; 1040 static final int IM_FEELING_LUCKY_MSG = 15; 1041 static final int PROC_START_TIMEOUT_MSG = 20; 1042 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1043 static final int KILL_APPLICATION_MSG = 22; 1044 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1045 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1046 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1047 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1048 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1049 static final int CLEAR_DNS_CACHE_MSG = 28; 1050 static final int UPDATE_HTTP_PROXY_MSG = 29; 1051 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1052 static final int DISPATCH_PROCESSES_CHANGED = 31; 1053 static final int DISPATCH_PROCESS_DIED = 32; 1054 static final int REPORT_MEM_USAGE_MSG = 33; 1055 static final int REPORT_USER_SWITCH_MSG = 34; 1056 static final int CONTINUE_USER_SWITCH_MSG = 35; 1057 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1058 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1059 static final int PERSIST_URI_GRANTS_MSG = 38; 1060 static final int REQUEST_ALL_PSS_MSG = 39; 1061 1062 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1063 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1064 static final int FIRST_COMPAT_MODE_MSG = 300; 1065 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1066 1067 AlertDialog mUidAlert; 1068 CompatModeDialog mCompatModeDialog; 1069 long mLastMemUsageReportTime = 0; 1070 1071 /** 1072 * Flag whether the current user is a "monkey", i.e. whether 1073 * the UI is driven by a UI automation tool. 1074 */ 1075 private boolean mUserIsMonkey; 1076 1077 final Handler mHandler = new Handler() { 1078 //public Handler() { 1079 // if (localLOGV) Slog.v(TAG, "Handler started!"); 1080 //} 1081 1082 @Override 1083 public void handleMessage(Message msg) { 1084 switch (msg.what) { 1085 case SHOW_ERROR_MSG: { 1086 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1087 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1088 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1089 synchronized (ActivityManagerService.this) { 1090 ProcessRecord proc = (ProcessRecord)data.get("app"); 1091 AppErrorResult res = (AppErrorResult) data.get("result"); 1092 if (proc != null && proc.crashDialog != null) { 1093 Slog.e(TAG, "App already has crash dialog: " + proc); 1094 if (res != null) { 1095 res.set(0); 1096 } 1097 return; 1098 } 1099 if (!showBackground && UserHandle.getAppId(proc.uid) 1100 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1101 && proc.pid != MY_PID) { 1102 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1103 if (res != null) { 1104 res.set(0); 1105 } 1106 return; 1107 } 1108 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1109 Dialog d = new AppErrorDialog(mContext, 1110 ActivityManagerService.this, res, proc); 1111 d.show(); 1112 proc.crashDialog = d; 1113 } else { 1114 // The device is asleep, so just pretend that the user 1115 // saw a crash dialog and hit "force quit". 1116 if (res != null) { 1117 res.set(0); 1118 } 1119 } 1120 } 1121 1122 ensureBootCompleted(); 1123 } break; 1124 case SHOW_NOT_RESPONDING_MSG: { 1125 synchronized (ActivityManagerService.this) { 1126 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1127 ProcessRecord proc = (ProcessRecord)data.get("app"); 1128 if (proc != null && proc.anrDialog != null) { 1129 Slog.e(TAG, "App already has anr dialog: " + proc); 1130 return; 1131 } 1132 1133 Intent intent = new Intent("android.intent.action.ANR"); 1134 if (!mProcessesReady) { 1135 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1136 | Intent.FLAG_RECEIVER_FOREGROUND); 1137 } 1138 broadcastIntentLocked(null, null, intent, 1139 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1140 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1141 1142 if (mShowDialogs) { 1143 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1144 mContext, proc, (ActivityRecord)data.get("activity"), 1145 msg.arg1 != 0); 1146 d.show(); 1147 proc.anrDialog = d; 1148 } else { 1149 // Just kill the app if there is no dialog to be shown. 1150 killAppAtUsersRequest(proc, null); 1151 } 1152 } 1153 1154 ensureBootCompleted(); 1155 } break; 1156 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1157 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1158 synchronized (ActivityManagerService.this) { 1159 ProcessRecord proc = (ProcessRecord) data.get("app"); 1160 if (proc == null) { 1161 Slog.e(TAG, "App not found when showing strict mode dialog."); 1162 break; 1163 } 1164 if (proc.crashDialog != null) { 1165 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1166 return; 1167 } 1168 AppErrorResult res = (AppErrorResult) data.get("result"); 1169 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1170 Dialog d = new StrictModeViolationDialog(mContext, 1171 ActivityManagerService.this, res, proc); 1172 d.show(); 1173 proc.crashDialog = d; 1174 } else { 1175 // The device is asleep, so just pretend that the user 1176 // saw a crash dialog and hit "force quit". 1177 res.set(0); 1178 } 1179 } 1180 ensureBootCompleted(); 1181 } break; 1182 case SHOW_FACTORY_ERROR_MSG: { 1183 Dialog d = new FactoryErrorDialog( 1184 mContext, msg.getData().getCharSequence("msg")); 1185 d.show(); 1186 ensureBootCompleted(); 1187 } break; 1188 case UPDATE_CONFIGURATION_MSG: { 1189 final ContentResolver resolver = mContext.getContentResolver(); 1190 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1191 } break; 1192 case GC_BACKGROUND_PROCESSES_MSG: { 1193 synchronized (ActivityManagerService.this) { 1194 performAppGcsIfAppropriateLocked(); 1195 } 1196 } break; 1197 case WAIT_FOR_DEBUGGER_MSG: { 1198 synchronized (ActivityManagerService.this) { 1199 ProcessRecord app = (ProcessRecord)msg.obj; 1200 if (msg.arg1 != 0) { 1201 if (!app.waitedForDebugger) { 1202 Dialog d = new AppWaitingForDebuggerDialog( 1203 ActivityManagerService.this, 1204 mContext, app); 1205 app.waitDialog = d; 1206 app.waitedForDebugger = true; 1207 d.show(); 1208 } 1209 } else { 1210 if (app.waitDialog != null) { 1211 app.waitDialog.dismiss(); 1212 app.waitDialog = null; 1213 } 1214 } 1215 } 1216 } break; 1217 case SERVICE_TIMEOUT_MSG: { 1218 if (mDidDexOpt) { 1219 mDidDexOpt = false; 1220 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1221 nmsg.obj = msg.obj; 1222 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1223 return; 1224 } 1225 mServices.serviceTimeout((ProcessRecord)msg.obj); 1226 } break; 1227 case UPDATE_TIME_ZONE: { 1228 synchronized (ActivityManagerService.this) { 1229 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1230 ProcessRecord r = mLruProcesses.get(i); 1231 if (r.thread != null) { 1232 try { 1233 r.thread.updateTimeZone(); 1234 } catch (RemoteException ex) { 1235 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1236 } 1237 } 1238 } 1239 } 1240 } break; 1241 case CLEAR_DNS_CACHE_MSG: { 1242 synchronized (ActivityManagerService.this) { 1243 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1244 ProcessRecord r = mLruProcesses.get(i); 1245 if (r.thread != null) { 1246 try { 1247 r.thread.clearDnsCache(); 1248 } catch (RemoteException ex) { 1249 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1250 } 1251 } 1252 } 1253 } 1254 } break; 1255 case UPDATE_HTTP_PROXY_MSG: { 1256 ProxyProperties proxy = (ProxyProperties)msg.obj; 1257 String host = ""; 1258 String port = ""; 1259 String exclList = ""; 1260 String pacFileUrl = null; 1261 if (proxy != null) { 1262 host = proxy.getHost(); 1263 port = Integer.toString(proxy.getPort()); 1264 exclList = proxy.getExclusionList(); 1265 pacFileUrl = proxy.getPacFileUrl(); 1266 } 1267 synchronized (ActivityManagerService.this) { 1268 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1269 ProcessRecord r = mLruProcesses.get(i); 1270 if (r.thread != null) { 1271 try { 1272 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1273 } catch (RemoteException ex) { 1274 Slog.w(TAG, "Failed to update http proxy for: " + 1275 r.info.processName); 1276 } 1277 } 1278 } 1279 } 1280 } break; 1281 case SHOW_UID_ERROR_MSG: { 1282 String title = "System UIDs Inconsistent"; 1283 String text = "UIDs on the system are inconsistent, you need to wipe your" 1284 + " data partition or your device will be unstable."; 1285 Log.e(TAG, title + ": " + text); 1286 if (mShowDialogs) { 1287 // XXX This is a temporary dialog, no need to localize. 1288 AlertDialog d = new BaseErrorDialog(mContext); 1289 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1290 d.setCancelable(false); 1291 d.setTitle(title); 1292 d.setMessage(text); 1293 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1294 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1295 mUidAlert = d; 1296 d.show(); 1297 } 1298 } break; 1299 case IM_FEELING_LUCKY_MSG: { 1300 if (mUidAlert != null) { 1301 mUidAlert.dismiss(); 1302 mUidAlert = null; 1303 } 1304 } break; 1305 case PROC_START_TIMEOUT_MSG: { 1306 if (mDidDexOpt) { 1307 mDidDexOpt = false; 1308 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1309 nmsg.obj = msg.obj; 1310 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1311 return; 1312 } 1313 ProcessRecord app = (ProcessRecord)msg.obj; 1314 synchronized (ActivityManagerService.this) { 1315 processStartTimedOutLocked(app); 1316 } 1317 } break; 1318 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1319 synchronized (ActivityManagerService.this) { 1320 doPendingActivityLaunchesLocked(true); 1321 } 1322 } break; 1323 case KILL_APPLICATION_MSG: { 1324 synchronized (ActivityManagerService.this) { 1325 int appid = msg.arg1; 1326 boolean restart = (msg.arg2 == 1); 1327 Bundle bundle = (Bundle)msg.obj; 1328 String pkg = bundle.getString("pkg"); 1329 String reason = bundle.getString("reason"); 1330 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1331 false, UserHandle.USER_ALL, reason); 1332 } 1333 } break; 1334 case FINALIZE_PENDING_INTENT_MSG: { 1335 ((PendingIntentRecord)msg.obj).completeFinalize(); 1336 } break; 1337 case POST_HEAVY_NOTIFICATION_MSG: { 1338 INotificationManager inm = NotificationManager.getService(); 1339 if (inm == null) { 1340 return; 1341 } 1342 1343 ActivityRecord root = (ActivityRecord)msg.obj; 1344 ProcessRecord process = root.app; 1345 if (process == null) { 1346 return; 1347 } 1348 1349 try { 1350 Context context = mContext.createPackageContext(process.info.packageName, 0); 1351 String text = mContext.getString(R.string.heavy_weight_notification, 1352 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1353 Notification notification = new Notification(); 1354 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1355 notification.when = 0; 1356 notification.flags = Notification.FLAG_ONGOING_EVENT; 1357 notification.tickerText = text; 1358 notification.defaults = 0; // please be quiet 1359 notification.sound = null; 1360 notification.vibrate = null; 1361 notification.setLatestEventInfo(context, text, 1362 mContext.getText(R.string.heavy_weight_notification_detail), 1363 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1364 PendingIntent.FLAG_CANCEL_CURRENT, null, 1365 new UserHandle(root.userId))); 1366 1367 try { 1368 int[] outId = new int[1]; 1369 inm.enqueueNotificationWithTag("android", "android", null, 1370 R.string.heavy_weight_notification, 1371 notification, outId, root.userId); 1372 } catch (RuntimeException e) { 1373 Slog.w(ActivityManagerService.TAG, 1374 "Error showing notification for heavy-weight app", e); 1375 } catch (RemoteException e) { 1376 } 1377 } catch (NameNotFoundException e) { 1378 Slog.w(TAG, "Unable to create context for heavy notification", e); 1379 } 1380 } break; 1381 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1382 INotificationManager inm = NotificationManager.getService(); 1383 if (inm == null) { 1384 return; 1385 } 1386 try { 1387 inm.cancelNotificationWithTag("android", null, 1388 R.string.heavy_weight_notification, msg.arg1); 1389 } catch (RuntimeException e) { 1390 Slog.w(ActivityManagerService.TAG, 1391 "Error canceling notification for service", e); 1392 } catch (RemoteException e) { 1393 } 1394 } break; 1395 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1396 synchronized (ActivityManagerService.this) { 1397 checkExcessivePowerUsageLocked(true); 1398 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1399 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1400 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1401 } 1402 } break; 1403 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1404 synchronized (ActivityManagerService.this) { 1405 ActivityRecord ar = (ActivityRecord)msg.obj; 1406 if (mCompatModeDialog != null) { 1407 if (mCompatModeDialog.mAppInfo.packageName.equals( 1408 ar.info.applicationInfo.packageName)) { 1409 return; 1410 } 1411 mCompatModeDialog.dismiss(); 1412 mCompatModeDialog = null; 1413 } 1414 if (ar != null && false) { 1415 if (mCompatModePackages.getPackageAskCompatModeLocked( 1416 ar.packageName)) { 1417 int mode = mCompatModePackages.computeCompatModeLocked( 1418 ar.info.applicationInfo); 1419 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1420 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1421 mCompatModeDialog = new CompatModeDialog( 1422 ActivityManagerService.this, mContext, 1423 ar.info.applicationInfo); 1424 mCompatModeDialog.show(); 1425 } 1426 } 1427 } 1428 } 1429 break; 1430 } 1431 case DISPATCH_PROCESSES_CHANGED: { 1432 dispatchProcessesChanged(); 1433 break; 1434 } 1435 case DISPATCH_PROCESS_DIED: { 1436 final int pid = msg.arg1; 1437 final int uid = msg.arg2; 1438 dispatchProcessDied(pid, uid); 1439 break; 1440 } 1441 case REPORT_MEM_USAGE_MSG: { 1442 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1443 Thread thread = new Thread() { 1444 @Override public void run() { 1445 final SparseArray<ProcessMemInfo> infoMap 1446 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1447 for (int i=0, N=memInfos.size(); i<N; i++) { 1448 ProcessMemInfo mi = memInfos.get(i); 1449 infoMap.put(mi.pid, mi); 1450 } 1451 updateCpuStatsNow(); 1452 synchronized (mProcessCpuThread) { 1453 final int N = mProcessCpuTracker.countStats(); 1454 for (int i=0; i<N; i++) { 1455 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1456 if (st.vsize > 0) { 1457 long pss = Debug.getPss(st.pid, null); 1458 if (pss > 0) { 1459 if (infoMap.indexOfKey(st.pid) < 0) { 1460 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1461 ProcessList.NATIVE_ADJ, -1, "native", null); 1462 mi.pss = pss; 1463 memInfos.add(mi); 1464 } 1465 } 1466 } 1467 } 1468 } 1469 1470 long totalPss = 0; 1471 for (int i=0, N=memInfos.size(); i<N; i++) { 1472 ProcessMemInfo mi = memInfos.get(i); 1473 if (mi.pss == 0) { 1474 mi.pss = Debug.getPss(mi.pid, null); 1475 } 1476 totalPss += mi.pss; 1477 } 1478 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1479 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1480 if (lhs.oomAdj != rhs.oomAdj) { 1481 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1482 } 1483 if (lhs.pss != rhs.pss) { 1484 return lhs.pss < rhs.pss ? 1 : -1; 1485 } 1486 return 0; 1487 } 1488 }); 1489 1490 StringBuilder tag = new StringBuilder(128); 1491 StringBuilder stack = new StringBuilder(128); 1492 tag.append("Low on memory -- "); 1493 appendMemBucket(tag, totalPss, "total", false); 1494 appendMemBucket(stack, totalPss, "total", true); 1495 1496 StringBuilder logBuilder = new StringBuilder(1024); 1497 logBuilder.append("Low on memory:\n"); 1498 1499 boolean firstLine = true; 1500 int lastOomAdj = Integer.MIN_VALUE; 1501 for (int i=0, N=memInfos.size(); i<N; i++) { 1502 ProcessMemInfo mi = memInfos.get(i); 1503 1504 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1505 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1506 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1507 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1508 if (lastOomAdj != mi.oomAdj) { 1509 lastOomAdj = mi.oomAdj; 1510 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1511 tag.append(" / "); 1512 } 1513 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1514 if (firstLine) { 1515 stack.append(":"); 1516 firstLine = false; 1517 } 1518 stack.append("\n\t at "); 1519 } else { 1520 stack.append("$"); 1521 } 1522 } else { 1523 tag.append(" "); 1524 stack.append("$"); 1525 } 1526 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1527 appendMemBucket(tag, mi.pss, mi.name, false); 1528 } 1529 appendMemBucket(stack, mi.pss, mi.name, true); 1530 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1531 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1532 stack.append("("); 1533 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1534 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1535 stack.append(DUMP_MEM_OOM_LABEL[k]); 1536 stack.append(":"); 1537 stack.append(DUMP_MEM_OOM_ADJ[k]); 1538 } 1539 } 1540 stack.append(")"); 1541 } 1542 } 1543 1544 logBuilder.append(" "); 1545 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1546 logBuilder.append(' '); 1547 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1548 logBuilder.append(' '); 1549 ProcessList.appendRamKb(logBuilder, mi.pss); 1550 logBuilder.append(" kB: "); 1551 logBuilder.append(mi.name); 1552 logBuilder.append(" ("); 1553 logBuilder.append(mi.pid); 1554 logBuilder.append(") "); 1555 logBuilder.append(mi.adjType); 1556 logBuilder.append('\n'); 1557 if (mi.adjReason != null) { 1558 logBuilder.append(" "); 1559 logBuilder.append(mi.adjReason); 1560 logBuilder.append('\n'); 1561 } 1562 } 1563 1564 logBuilder.append(" "); 1565 ProcessList.appendRamKb(logBuilder, totalPss); 1566 logBuilder.append(" kB: TOTAL\n"); 1567 1568 long[] infos = new long[Debug.MEMINFO_COUNT]; 1569 Debug.getMemInfo(infos); 1570 logBuilder.append(" MemInfo: "); 1571 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1572 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1573 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1574 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1575 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1576 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1577 logBuilder.append(" ZRAM: "); 1578 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1579 logBuilder.append(" kB RAM, "); 1580 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1581 logBuilder.append(" kB swap total, "); 1582 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1583 logBuilder.append(" kB swap free\n"); 1584 } 1585 Slog.i(TAG, logBuilder.toString()); 1586 1587 StringBuilder dropBuilder = new StringBuilder(1024); 1588 /* 1589 StringWriter oomSw = new StringWriter(); 1590 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1591 StringWriter catSw = new StringWriter(); 1592 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1593 String[] emptyArgs = new String[] { }; 1594 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1595 oomPw.flush(); 1596 String oomString = oomSw.toString(); 1597 */ 1598 dropBuilder.append(stack); 1599 dropBuilder.append('\n'); 1600 dropBuilder.append('\n'); 1601 dropBuilder.append(logBuilder); 1602 dropBuilder.append('\n'); 1603 /* 1604 dropBuilder.append(oomString); 1605 dropBuilder.append('\n'); 1606 */ 1607 StringWriter catSw = new StringWriter(); 1608 synchronized (ActivityManagerService.this) { 1609 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1610 String[] emptyArgs = new String[] { }; 1611 catPw.println(); 1612 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1613 catPw.println(); 1614 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1615 false, false, null); 1616 catPw.println(); 1617 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1618 catPw.flush(); 1619 } 1620 dropBuilder.append(catSw.toString()); 1621 addErrorToDropBox("lowmem", null, "system_server", null, 1622 null, tag.toString(), dropBuilder.toString(), null, null); 1623 //Slog.i(TAG, "Sent to dropbox:"); 1624 //Slog.i(TAG, dropBuilder.toString()); 1625 synchronized (ActivityManagerService.this) { 1626 long now = SystemClock.uptimeMillis(); 1627 if (mLastMemUsageReportTime < now) { 1628 mLastMemUsageReportTime = now; 1629 } 1630 } 1631 } 1632 }; 1633 thread.start(); 1634 break; 1635 } 1636 case REPORT_USER_SWITCH_MSG: { 1637 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1638 break; 1639 } 1640 case CONTINUE_USER_SWITCH_MSG: { 1641 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1642 break; 1643 } 1644 case USER_SWITCH_TIMEOUT_MSG: { 1645 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1646 break; 1647 } 1648 case IMMERSIVE_MODE_LOCK_MSG: { 1649 final boolean nextState = (msg.arg1 != 0); 1650 if (mUpdateLock.isHeld() != nextState) { 1651 if (DEBUG_IMMERSIVE) { 1652 final ActivityRecord r = (ActivityRecord) msg.obj; 1653 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1654 } 1655 if (nextState) { 1656 mUpdateLock.acquire(); 1657 } else { 1658 mUpdateLock.release(); 1659 } 1660 } 1661 break; 1662 } 1663 case PERSIST_URI_GRANTS_MSG: { 1664 writeGrantedUriPermissions(); 1665 break; 1666 } 1667 case REQUEST_ALL_PSS_MSG: { 1668 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1669 break; 1670 } 1671 } 1672 } 1673 }; 1674 1675 static final int COLLECT_PSS_BG_MSG = 1; 1676 1677 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1678 @Override 1679 public void handleMessage(Message msg) { 1680 switch (msg.what) { 1681 case COLLECT_PSS_BG_MSG: { 1682 int i=0, num=0; 1683 long start = SystemClock.uptimeMillis(); 1684 long[] tmp = new long[1]; 1685 do { 1686 ProcessRecord proc; 1687 int procState; 1688 int pid; 1689 synchronized (ActivityManagerService.this) { 1690 if (i >= mPendingPssProcesses.size()) { 1691 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1692 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1693 mPendingPssProcesses.clear(); 1694 return; 1695 } 1696 proc = mPendingPssProcesses.get(i); 1697 procState = proc.pssProcState; 1698 if (proc.thread != null && procState == proc.setProcState) { 1699 pid = proc.pid; 1700 } else { 1701 proc = null; 1702 pid = 0; 1703 } 1704 i++; 1705 } 1706 if (proc != null) { 1707 long pss = Debug.getPss(pid, tmp); 1708 synchronized (ActivityManagerService.this) { 1709 if (proc.thread != null && proc.setProcState == procState 1710 && proc.pid == pid) { 1711 num++; 1712 proc.lastPssTime = SystemClock.uptimeMillis(); 1713 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1714 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1715 + ": " + pss + " lastPss=" + proc.lastPss 1716 + " state=" + ProcessList.makeProcStateString(procState)); 1717 if (proc.initialIdlePss == 0) { 1718 proc.initialIdlePss = pss; 1719 } 1720 proc.lastPss = pss; 1721 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1722 proc.lastCachedPss = pss; 1723 } 1724 } 1725 } 1726 } 1727 } while (true); 1728 } 1729 } 1730 } 1731 }; 1732 1733 public static void setSystemProcess() { 1734 try { 1735 ActivityManagerService m = mSelf; 1736 1737 ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true); 1738 ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats); 1739 ServiceManager.addService("meminfo", new MemBinder(m)); 1740 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1741 ServiceManager.addService("dbinfo", new DbBinder(m)); 1742 if (MONITOR_CPU_USAGE) { 1743 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1744 } 1745 ServiceManager.addService("permission", new PermissionController(m)); 1746 1747 ApplicationInfo info = 1748 mSelf.mContext.getPackageManager().getApplicationInfo( 1749 "android", STOCK_PM_FLAGS); 1750 mSystemThread.installSystemApplicationInfo(info); 1751 1752 synchronized (mSelf) { 1753 ProcessRecord app = mSelf.newProcessRecordLocked(info, 1754 info.processName, false); 1755 app.persistent = true; 1756 app.pid = MY_PID; 1757 app.maxAdj = ProcessList.SYSTEM_ADJ; 1758 app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats); 1759 mSelf.mProcessNames.put(app.processName, app.uid, app); 1760 synchronized (mSelf.mPidsSelfLocked) { 1761 mSelf.mPidsSelfLocked.put(app.pid, app); 1762 } 1763 mSelf.updateLruProcessLocked(app, false, null); 1764 mSelf.updateOomAdjLocked(); 1765 } 1766 } catch (PackageManager.NameNotFoundException e) { 1767 throw new RuntimeException( 1768 "Unable to find android system package", e); 1769 } 1770 } 1771 1772 public void setWindowManager(WindowManagerService wm) { 1773 mWindowManager = wm; 1774 mStackSupervisor.setWindowManager(wm); 1775 wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f); 1776 } 1777 1778 public void startObservingNativeCrashes() { 1779 final NativeCrashListener ncl = new NativeCrashListener(); 1780 ncl.start(); 1781 } 1782 1783 public static final Context main(int factoryTest) { 1784 AThread thr = new AThread(); 1785 thr.start(); 1786 1787 synchronized (thr) { 1788 while (thr.mService == null) { 1789 try { 1790 thr.wait(); 1791 } catch (InterruptedException e) { 1792 } 1793 } 1794 } 1795 1796 ActivityManagerService m = thr.mService; 1797 mSelf = m; 1798 ActivityThread at = ActivityThread.systemMain(); 1799 mSystemThread = at; 1800 Context context = at.getSystemContext(); 1801 context.setTheme(android.R.style.Theme_Holo); 1802 m.mContext = context; 1803 m.mFactoryTest = factoryTest; 1804 m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface()); 1805 1806 m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper); 1807 1808 m.mBatteryStatsService.publish(context); 1809 m.mUsageStatsService.publish(context); 1810 m.mAppOpsService.publish(context); 1811 1812 synchronized (thr) { 1813 thr.mReady = true; 1814 thr.notifyAll(); 1815 } 1816 1817 m.startRunning(null, null, null, null); 1818 1819 return context; 1820 } 1821 1822 public static ActivityManagerService self() { 1823 return mSelf; 1824 } 1825 1826 public IAppOpsService getAppOpsService() { 1827 return mAppOpsService; 1828 } 1829 1830 static class AThread extends Thread { 1831 ActivityManagerService mService; 1832 Looper mLooper; 1833 boolean mReady = false; 1834 1835 public AThread() { 1836 super("ActivityManager"); 1837 } 1838 1839 @Override 1840 public void run() { 1841 Looper.prepare(); 1842 1843 android.os.Process.setThreadPriority( 1844 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1845 android.os.Process.setCanSelfBackground(false); 1846 1847 ActivityManagerService m = new ActivityManagerService(); 1848 1849 synchronized (this) { 1850 mService = m; 1851 mLooper = Looper.myLooper(); 1852 Watchdog.getInstance().addThread(new Handler(mLooper), getName()); 1853 notifyAll(); 1854 } 1855 1856 synchronized (this) { 1857 while (!mReady) { 1858 try { 1859 wait(); 1860 } catch (InterruptedException e) { 1861 } 1862 } 1863 } 1864 1865 // For debug builds, log event loop stalls to dropbox for analysis. 1866 if (StrictMode.conditionallyEnableDebugLogging()) { 1867 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1868 } 1869 1870 Looper.loop(); 1871 } 1872 } 1873 1874 static class MemBinder extends Binder { 1875 ActivityManagerService mActivityManagerService; 1876 MemBinder(ActivityManagerService activityManagerService) { 1877 mActivityManagerService = activityManagerService; 1878 } 1879 1880 @Override 1881 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1882 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1883 != PackageManager.PERMISSION_GRANTED) { 1884 pw.println("Permission Denial: can't dump meminfo from from pid=" 1885 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1886 + " without permission " + android.Manifest.permission.DUMP); 1887 return; 1888 } 1889 1890 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1891 } 1892 } 1893 1894 static class GraphicsBinder extends Binder { 1895 ActivityManagerService mActivityManagerService; 1896 GraphicsBinder(ActivityManagerService activityManagerService) { 1897 mActivityManagerService = activityManagerService; 1898 } 1899 1900 @Override 1901 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1902 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1903 != PackageManager.PERMISSION_GRANTED) { 1904 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1905 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1906 + " without permission " + android.Manifest.permission.DUMP); 1907 return; 1908 } 1909 1910 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1911 } 1912 } 1913 1914 static class DbBinder extends Binder { 1915 ActivityManagerService mActivityManagerService; 1916 DbBinder(ActivityManagerService activityManagerService) { 1917 mActivityManagerService = activityManagerService; 1918 } 1919 1920 @Override 1921 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1922 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1923 != PackageManager.PERMISSION_GRANTED) { 1924 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1925 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1926 + " without permission " + android.Manifest.permission.DUMP); 1927 return; 1928 } 1929 1930 mActivityManagerService.dumpDbInfo(fd, pw, args); 1931 } 1932 } 1933 1934 static class CpuBinder extends Binder { 1935 ActivityManagerService mActivityManagerService; 1936 CpuBinder(ActivityManagerService activityManagerService) { 1937 mActivityManagerService = activityManagerService; 1938 } 1939 1940 @Override 1941 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1942 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1943 != PackageManager.PERMISSION_GRANTED) { 1944 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1945 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1946 + " without permission " + android.Manifest.permission.DUMP); 1947 return; 1948 } 1949 1950 synchronized (mActivityManagerService.mProcessCpuThread) { 1951 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1952 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1953 SystemClock.uptimeMillis())); 1954 } 1955 } 1956 } 1957 1958 private ActivityManagerService() { 1959 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1960 1961 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false); 1962 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true); 1963 mBroadcastQueues[0] = mFgBroadcastQueue; 1964 mBroadcastQueues[1] = mBgBroadcastQueue; 1965 1966 mServices = new ActiveServices(this); 1967 mProviderMap = new ProviderMap(this); 1968 1969 File dataDir = Environment.getDataDirectory(); 1970 File systemDir = new File(dataDir, "system"); 1971 systemDir.mkdirs(); 1972 mBatteryStatsService = new BatteryStatsService(new File( 1973 systemDir, "batterystats.bin").toString()); 1974 mBatteryStatsService.getActiveStatistics().readLocked(); 1975 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1976 mOnBattery = DEBUG_POWER ? true 1977 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1978 mBatteryStatsService.getActiveStatistics().setCallback(this); 1979 1980 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1981 1982 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1983 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml")); 1984 1985 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1986 1987 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1988 1989 // User 0 is the first and only user that runs at boot. 1990 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1991 mUserLru.add(Integer.valueOf(0)); 1992 updateStartedUserArrayLocked(); 1993 1994 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1995 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1996 1997 mConfiguration.setToDefaults(); 1998 mConfiguration.setLocale(Locale.getDefault()); 1999 2000 mConfigurationSeq = mConfiguration.seq = 1; 2001 mProcessCpuTracker.init(); 2002 2003 mCompatModePackages = new CompatModePackages(this, systemDir); 2004 2005 // Add ourself to the Watchdog monitors. 2006 Watchdog.getInstance().addMonitor(this); 2007 2008 mProcessCpuThread = new Thread("CpuTracker") { 2009 @Override 2010 public void run() { 2011 while (true) { 2012 try { 2013 try { 2014 synchronized(this) { 2015 final long now = SystemClock.uptimeMillis(); 2016 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2017 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2018 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2019 // + ", write delay=" + nextWriteDelay); 2020 if (nextWriteDelay < nextCpuDelay) { 2021 nextCpuDelay = nextWriteDelay; 2022 } 2023 if (nextCpuDelay > 0) { 2024 mProcessCpuMutexFree.set(true); 2025 this.wait(nextCpuDelay); 2026 } 2027 } 2028 } catch (InterruptedException e) { 2029 } 2030 updateCpuStatsNow(); 2031 } catch (Exception e) { 2032 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2033 } 2034 } 2035 } 2036 }; 2037 mProcessCpuThread.start(); 2038 } 2039 2040 @Override 2041 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2042 throws RemoteException { 2043 if (code == SYSPROPS_TRANSACTION) { 2044 // We need to tell all apps about the system property change. 2045 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2046 synchronized(this) { 2047 final int NP = mProcessNames.getMap().size(); 2048 for (int ip=0; ip<NP; ip++) { 2049 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2050 final int NA = apps.size(); 2051 for (int ia=0; ia<NA; ia++) { 2052 ProcessRecord app = apps.valueAt(ia); 2053 if (app.thread != null) { 2054 procs.add(app.thread.asBinder()); 2055 } 2056 } 2057 } 2058 } 2059 2060 int N = procs.size(); 2061 for (int i=0; i<N; i++) { 2062 Parcel data2 = Parcel.obtain(); 2063 try { 2064 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2065 } catch (RemoteException e) { 2066 } 2067 data2.recycle(); 2068 } 2069 } 2070 try { 2071 return super.onTransact(code, data, reply, flags); 2072 } catch (RuntimeException e) { 2073 // The activity manager only throws security exceptions, so let's 2074 // log all others. 2075 if (!(e instanceof SecurityException)) { 2076 Slog.wtf(TAG, "Activity Manager Crash", e); 2077 } 2078 throw e; 2079 } 2080 } 2081 2082 void updateCpuStats() { 2083 final long now = SystemClock.uptimeMillis(); 2084 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2085 return; 2086 } 2087 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2088 synchronized (mProcessCpuThread) { 2089 mProcessCpuThread.notify(); 2090 } 2091 } 2092 } 2093 2094 void updateCpuStatsNow() { 2095 synchronized (mProcessCpuThread) { 2096 mProcessCpuMutexFree.set(false); 2097 final long now = SystemClock.uptimeMillis(); 2098 boolean haveNewCpuStats = false; 2099 2100 if (MONITOR_CPU_USAGE && 2101 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2102 mLastCpuTime.set(now); 2103 haveNewCpuStats = true; 2104 mProcessCpuTracker.update(); 2105 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2106 //Slog.i(TAG, "Total CPU usage: " 2107 // + mProcessCpu.getTotalCpuPercent() + "%"); 2108 2109 // Slog the cpu usage if the property is set. 2110 if ("true".equals(SystemProperties.get("events.cpu"))) { 2111 int user = mProcessCpuTracker.getLastUserTime(); 2112 int system = mProcessCpuTracker.getLastSystemTime(); 2113 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2114 int irq = mProcessCpuTracker.getLastIrqTime(); 2115 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2116 int idle = mProcessCpuTracker.getLastIdleTime(); 2117 2118 int total = user + system + iowait + irq + softIrq + idle; 2119 if (total == 0) total = 1; 2120 2121 EventLog.writeEvent(EventLogTags.CPU, 2122 ((user+system+iowait+irq+softIrq) * 100) / total, 2123 (user * 100) / total, 2124 (system * 100) / total, 2125 (iowait * 100) / total, 2126 (irq * 100) / total, 2127 (softIrq * 100) / total); 2128 } 2129 } 2130 2131 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2132 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2133 synchronized(bstats) { 2134 synchronized(mPidsSelfLocked) { 2135 if (haveNewCpuStats) { 2136 if (mOnBattery) { 2137 int perc = bstats.startAddingCpuLocked(); 2138 int totalUTime = 0; 2139 int totalSTime = 0; 2140 final int N = mProcessCpuTracker.countStats(); 2141 for (int i=0; i<N; i++) { 2142 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2143 if (!st.working) { 2144 continue; 2145 } 2146 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2147 int otherUTime = (st.rel_utime*perc)/100; 2148 int otherSTime = (st.rel_stime*perc)/100; 2149 totalUTime += otherUTime; 2150 totalSTime += otherSTime; 2151 if (pr != null) { 2152 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2153 st.name, st.pid); 2154 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2155 st.rel_stime-otherSTime); 2156 ps.addSpeedStepTimes(cpuSpeedTimes); 2157 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2158 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2159 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2160 if (ps == null) { 2161 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2162 "(Unknown)"); 2163 } 2164 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2165 st.rel_stime-otherSTime); 2166 ps.addSpeedStepTimes(cpuSpeedTimes); 2167 } else { 2168 BatteryStatsImpl.Uid.Proc ps = 2169 bstats.getProcessStatsLocked(st.name, st.pid); 2170 if (ps != null) { 2171 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2172 st.rel_stime-otherSTime); 2173 ps.addSpeedStepTimes(cpuSpeedTimes); 2174 } 2175 } 2176 } 2177 bstats.finishAddingCpuLocked(perc, totalUTime, 2178 totalSTime, cpuSpeedTimes); 2179 } 2180 } 2181 } 2182 2183 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2184 mLastWriteTime = now; 2185 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2186 } 2187 } 2188 } 2189 } 2190 2191 @Override 2192 public void batteryNeedsCpuUpdate() { 2193 updateCpuStatsNow(); 2194 } 2195 2196 @Override 2197 public void batteryPowerChanged(boolean onBattery) { 2198 // When plugging in, update the CPU stats first before changing 2199 // the plug state. 2200 updateCpuStatsNow(); 2201 synchronized (this) { 2202 synchronized(mPidsSelfLocked) { 2203 mOnBattery = DEBUG_POWER ? true : onBattery; 2204 } 2205 } 2206 } 2207 2208 /** 2209 * Initialize the application bind args. These are passed to each 2210 * process when the bindApplication() IPC is sent to the process. They're 2211 * lazily setup to make sure the services are running when they're asked for. 2212 */ 2213 private HashMap<String, IBinder> getCommonServicesLocked() { 2214 if (mAppBindArgs == null) { 2215 mAppBindArgs = new HashMap<String, IBinder>(); 2216 2217 // Setup the application init args 2218 mAppBindArgs.put("package", ServiceManager.getService("package")); 2219 mAppBindArgs.put("window", ServiceManager.getService("window")); 2220 mAppBindArgs.put(Context.ALARM_SERVICE, 2221 ServiceManager.getService(Context.ALARM_SERVICE)); 2222 } 2223 return mAppBindArgs; 2224 } 2225 2226 final void setFocusedActivityLocked(ActivityRecord r) { 2227 if (mFocusedActivity != r) { 2228 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2229 mFocusedActivity = r; 2230 mStackSupervisor.setFocusedStack(r); 2231 if (r != null) { 2232 mWindowManager.setFocusedApp(r.appToken, true); 2233 } 2234 applyUpdateLockStateLocked(r); 2235 } 2236 } 2237 2238 @Override 2239 public void setFocusedStack(int stackId) { 2240 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2241 synchronized (ActivityManagerService.this) { 2242 ActivityStack stack = mStackSupervisor.getStack(stackId); 2243 if (stack != null) { 2244 ActivityRecord r = stack.topRunningActivityLocked(null); 2245 if (r != null) { 2246 setFocusedActivityLocked(r); 2247 } 2248 } 2249 } 2250 } 2251 2252 @Override 2253 public void notifyActivityDrawn(IBinder token) { 2254 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2255 synchronized (this) { 2256 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2257 if (r != null) { 2258 r.task.stack.notifyActivityDrawnLocked(r); 2259 } 2260 } 2261 } 2262 2263 final void applyUpdateLockStateLocked(ActivityRecord r) { 2264 // Modifications to the UpdateLock state are done on our handler, outside 2265 // the activity manager's locks. The new state is determined based on the 2266 // state *now* of the relevant activity record. The object is passed to 2267 // the handler solely for logging detail, not to be consulted/modified. 2268 final boolean nextState = r != null && r.immersive; 2269 mHandler.sendMessage( 2270 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2271 } 2272 2273 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2274 Message msg = Message.obtain(); 2275 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2276 msg.obj = r.task.askedCompatMode ? null : r; 2277 mHandler.sendMessage(msg); 2278 } 2279 2280 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2281 String what, Object obj, ProcessRecord srcApp) { 2282 app.lastActivityTime = now; 2283 2284 if (app.activities.size() > 0) { 2285 // Don't want to touch dependent processes that are hosting activities. 2286 return index; 2287 } 2288 2289 int lrui = mLruProcesses.lastIndexOf(app); 2290 if (lrui < 0) { 2291 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2292 + what + " " + obj + " from " + srcApp); 2293 return index; 2294 } 2295 2296 if (lrui >= index) { 2297 // Don't want to cause this to move dependent processes *back* in the 2298 // list as if they were less frequently used. 2299 return index; 2300 } 2301 2302 if (lrui >= mLruProcessActivityStart) { 2303 // Don't want to touch dependent processes that are hosting activities. 2304 return index; 2305 } 2306 2307 mLruProcesses.remove(lrui); 2308 if (index > 0) { 2309 index--; 2310 } 2311 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2312 + " in LRU list: " + app); 2313 mLruProcesses.add(index, app); 2314 return index; 2315 } 2316 2317 final void removeLruProcessLocked(ProcessRecord app) { 2318 int lrui = mLruProcesses.lastIndexOf(app); 2319 if (lrui >= 0) { 2320 if (lrui <= mLruProcessActivityStart) { 2321 mLruProcessActivityStart--; 2322 } 2323 if (lrui <= mLruProcessServiceStart) { 2324 mLruProcessServiceStart--; 2325 } 2326 mLruProcesses.remove(lrui); 2327 } 2328 } 2329 2330 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2331 ProcessRecord client) { 2332 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2333 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2334 if (!activityChange && hasActivity) { 2335 // The process has activties, so we are only going to allow activity-based 2336 // adjustments move it. It should be kept in the front of the list with other 2337 // processes that have activities, and we don't want those to change their 2338 // order except due to activity operations. 2339 return; 2340 } 2341 2342 mLruSeq++; 2343 final long now = SystemClock.uptimeMillis(); 2344 app.lastActivityTime = now; 2345 2346 // First a quick reject: if the app is already at the position we will 2347 // put it, then there is nothing to do. 2348 if (hasActivity) { 2349 final int N = mLruProcesses.size(); 2350 if (N > 0 && mLruProcesses.get(N-1) == app) { 2351 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2352 return; 2353 } 2354 } else { 2355 if (mLruProcessServiceStart > 0 2356 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2357 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2358 return; 2359 } 2360 } 2361 2362 int lrui = mLruProcesses.lastIndexOf(app); 2363 2364 if (app.persistent && lrui >= 0) { 2365 // We don't care about the position of persistent processes, as long as 2366 // they are in the list. 2367 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2368 return; 2369 } 2370 2371 /* In progress: compute new position first, so we can avoid doing work 2372 if the process is not actually going to move. Not yet working. 2373 int addIndex; 2374 int nextIndex; 2375 boolean inActivity = false, inService = false; 2376 if (hasActivity) { 2377 // Process has activities, put it at the very tipsy-top. 2378 addIndex = mLruProcesses.size(); 2379 nextIndex = mLruProcessServiceStart; 2380 inActivity = true; 2381 } else if (hasService) { 2382 // Process has services, put it at the top of the service list. 2383 addIndex = mLruProcessActivityStart; 2384 nextIndex = mLruProcessServiceStart; 2385 inActivity = true; 2386 inService = true; 2387 } else { 2388 // Process not otherwise of interest, it goes to the top of the non-service area. 2389 addIndex = mLruProcessServiceStart; 2390 if (client != null) { 2391 int clientIndex = mLruProcesses.lastIndexOf(client); 2392 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2393 + app); 2394 if (clientIndex >= 0 && addIndex > clientIndex) { 2395 addIndex = clientIndex; 2396 } 2397 } 2398 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2399 } 2400 2401 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2402 + mLruProcessActivityStart + "): " + app); 2403 */ 2404 2405 if (lrui >= 0) { 2406 if (lrui < mLruProcessActivityStart) { 2407 mLruProcessActivityStart--; 2408 } 2409 if (lrui < mLruProcessServiceStart) { 2410 mLruProcessServiceStart--; 2411 } 2412 /* 2413 if (addIndex > lrui) { 2414 addIndex--; 2415 } 2416 if (nextIndex > lrui) { 2417 nextIndex--; 2418 } 2419 */ 2420 mLruProcesses.remove(lrui); 2421 } 2422 2423 /* 2424 mLruProcesses.add(addIndex, app); 2425 if (inActivity) { 2426 mLruProcessActivityStart++; 2427 } 2428 if (inService) { 2429 mLruProcessActivityStart++; 2430 } 2431 */ 2432 2433 int nextIndex; 2434 if (hasActivity) { 2435 final int N = mLruProcesses.size(); 2436 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2437 // Process doesn't have activities, but has clients with 2438 // activities... move it up, but one below the top (the top 2439 // should always have a real activity). 2440 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2441 mLruProcesses.add(N-1, app); 2442 // To keep it from spamming the LRU list (by making a bunch of clients), 2443 // we will push down any other entries owned by the app. 2444 final int uid = app.info.uid; 2445 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2446 ProcessRecord subProc = mLruProcesses.get(i); 2447 if (subProc.info.uid == uid) { 2448 // We want to push this one down the list. If the process after 2449 // it is for the same uid, however, don't do so, because we don't 2450 // want them internally to be re-ordered. 2451 if (mLruProcesses.get(i-1).info.uid != uid) { 2452 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2453 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2454 ProcessRecord tmp = mLruProcesses.get(i); 2455 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2456 mLruProcesses.set(i-1, tmp); 2457 i--; 2458 } 2459 } else { 2460 // A gap, we can stop here. 2461 break; 2462 } 2463 } 2464 } else { 2465 // Process has activities, put it at the very tipsy-top. 2466 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2467 mLruProcesses.add(app); 2468 } 2469 nextIndex = mLruProcessServiceStart; 2470 } else if (hasService) { 2471 // Process has services, put it at the top of the service list. 2472 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2473 mLruProcesses.add(mLruProcessActivityStart, app); 2474 nextIndex = mLruProcessServiceStart; 2475 mLruProcessActivityStart++; 2476 } else { 2477 // Process not otherwise of interest, it goes to the top of the non-service area. 2478 int index = mLruProcessServiceStart; 2479 if (client != null) { 2480 // If there is a client, don't allow the process to be moved up higher 2481 // in the list than that client. 2482 int clientIndex = mLruProcesses.lastIndexOf(client); 2483 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2484 + " when updating " + app); 2485 if (clientIndex <= lrui) { 2486 // Don't allow the client index restriction to push it down farther in the 2487 // list than it already is. 2488 clientIndex = lrui; 2489 } 2490 if (clientIndex >= 0 && index > clientIndex) { 2491 index = clientIndex; 2492 } 2493 } 2494 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2495 mLruProcesses.add(index, app); 2496 nextIndex = index-1; 2497 mLruProcessActivityStart++; 2498 mLruProcessServiceStart++; 2499 } 2500 2501 // If the app is currently using a content provider or service, 2502 // bump those processes as well. 2503 for (int j=app.connections.size()-1; j>=0; j--) { 2504 ConnectionRecord cr = app.connections.valueAt(j); 2505 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2506 && cr.binding.service.app != null 2507 && cr.binding.service.app.lruSeq != mLruSeq 2508 && !cr.binding.service.app.persistent) { 2509 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2510 "service connection", cr, app); 2511 } 2512 } 2513 for (int j=app.conProviders.size()-1; j>=0; j--) { 2514 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2515 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2516 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2517 "provider reference", cpr, app); 2518 } 2519 } 2520 } 2521 2522 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2523 if (uid == Process.SYSTEM_UID) { 2524 // The system gets to run in any process. If there are multiple 2525 // processes with the same uid, just pick the first (this 2526 // should never happen). 2527 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2528 if (procs == null) return null; 2529 final int N = procs.size(); 2530 for (int i = 0; i < N; i++) { 2531 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2532 } 2533 } 2534 ProcessRecord proc = mProcessNames.get(processName, uid); 2535 if (false && proc != null && !keepIfLarge 2536 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2537 && proc.lastCachedPss >= 4000) { 2538 // Turn this condition on to cause killing to happen regularly, for testing. 2539 if (proc.baseProcessTracker != null) { 2540 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2541 } 2542 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2543 + "k from cached"); 2544 } else if (proc != null && !keepIfLarge 2545 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2546 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2547 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2548 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2549 if (proc.baseProcessTracker != null) { 2550 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2551 } 2552 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2553 + "k from cached"); 2554 } 2555 } 2556 return proc; 2557 } 2558 2559 void ensurePackageDexOpt(String packageName) { 2560 IPackageManager pm = AppGlobals.getPackageManager(); 2561 try { 2562 if (pm.performDexOpt(packageName)) { 2563 mDidDexOpt = true; 2564 } 2565 } catch (RemoteException e) { 2566 } 2567 } 2568 2569 boolean isNextTransitionForward() { 2570 int transit = mWindowManager.getPendingAppTransition(); 2571 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2572 || transit == AppTransition.TRANSIT_TASK_OPEN 2573 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2574 } 2575 2576 final ProcessRecord startProcessLocked(String processName, 2577 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2578 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2579 boolean isolated, boolean keepIfLarge) { 2580 ProcessRecord app; 2581 if (!isolated) { 2582 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2583 } else { 2584 // If this is an isolated process, it can't re-use an existing process. 2585 app = null; 2586 } 2587 // We don't have to do anything more if: 2588 // (1) There is an existing application record; and 2589 // (2) The caller doesn't think it is dead, OR there is no thread 2590 // object attached to it so we know it couldn't have crashed; and 2591 // (3) There is a pid assigned to it, so it is either starting or 2592 // already running. 2593 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2594 + " app=" + app + " knownToBeDead=" + knownToBeDead 2595 + " thread=" + (app != null ? app.thread : null) 2596 + " pid=" + (app != null ? app.pid : -1)); 2597 if (app != null && app.pid > 0) { 2598 if (!knownToBeDead || app.thread == null) { 2599 // We already have the app running, or are waiting for it to 2600 // come up (we have a pid but not yet its thread), so keep it. 2601 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2602 // If this is a new package in the process, add the package to the list 2603 app.addPackage(info.packageName, mProcessStats); 2604 return app; 2605 } 2606 2607 // An application record is attached to a previous process, 2608 // clean it up now. 2609 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2610 handleAppDiedLocked(app, true, true); 2611 } 2612 2613 String hostingNameStr = hostingName != null 2614 ? hostingName.flattenToShortString() : null; 2615 2616 if (!isolated) { 2617 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2618 // If we are in the background, then check to see if this process 2619 // is bad. If so, we will just silently fail. 2620 if (mBadProcesses.get(info.processName, info.uid) != null) { 2621 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2622 + "/" + info.processName); 2623 return null; 2624 } 2625 } else { 2626 // When the user is explicitly starting a process, then clear its 2627 // crash count so that we won't make it bad until they see at 2628 // least one crash dialog again, and make the process good again 2629 // if it had been bad. 2630 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2631 + "/" + info.processName); 2632 mProcessCrashTimes.remove(info.processName, info.uid); 2633 if (mBadProcesses.get(info.processName, info.uid) != null) { 2634 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2635 UserHandle.getUserId(info.uid), info.uid, 2636 info.processName); 2637 mBadProcesses.remove(info.processName, info.uid); 2638 if (app != null) { 2639 app.bad = false; 2640 } 2641 } 2642 } 2643 } 2644 2645 if (app == null) { 2646 app = newProcessRecordLocked(info, processName, isolated); 2647 if (app == null) { 2648 Slog.w(TAG, "Failed making new process record for " 2649 + processName + "/" + info.uid + " isolated=" + isolated); 2650 return null; 2651 } 2652 mProcessNames.put(processName, app.uid, app); 2653 if (isolated) { 2654 mIsolatedProcesses.put(app.uid, app); 2655 } 2656 } else { 2657 // If this is a new package in the process, add the package to the list 2658 app.addPackage(info.packageName, mProcessStats); 2659 } 2660 2661 // If the system is not ready yet, then hold off on starting this 2662 // process until it is. 2663 if (!mProcessesReady 2664 && !isAllowedWhileBooting(info) 2665 && !allowWhileBooting) { 2666 if (!mProcessesOnHold.contains(app)) { 2667 mProcessesOnHold.add(app); 2668 } 2669 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2670 return app; 2671 } 2672 2673 startProcessLocked(app, hostingType, hostingNameStr); 2674 return (app.pid != 0) ? app : null; 2675 } 2676 2677 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2678 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2679 } 2680 2681 private final void startProcessLocked(ProcessRecord app, 2682 String hostingType, String hostingNameStr) { 2683 if (app.pid > 0 && app.pid != MY_PID) { 2684 synchronized (mPidsSelfLocked) { 2685 mPidsSelfLocked.remove(app.pid); 2686 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2687 } 2688 app.setPid(0); 2689 } 2690 2691 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2692 "startProcessLocked removing on hold: " + app); 2693 mProcessesOnHold.remove(app); 2694 2695 updateCpuStats(); 2696 2697 try { 2698 int uid = app.uid; 2699 2700 int[] gids = null; 2701 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2702 if (!app.isolated) { 2703 int[] permGids = null; 2704 try { 2705 final PackageManager pm = mContext.getPackageManager(); 2706 permGids = pm.getPackageGids(app.info.packageName); 2707 2708 if (Environment.isExternalStorageEmulated()) { 2709 if (pm.checkPermission( 2710 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2711 app.info.packageName) == PERMISSION_GRANTED) { 2712 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2713 } else { 2714 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2715 } 2716 } 2717 } catch (PackageManager.NameNotFoundException e) { 2718 Slog.w(TAG, "Unable to retrieve gids", e); 2719 } 2720 2721 /* 2722 * Add shared application GID so applications can share some 2723 * resources like shared libraries 2724 */ 2725 if (permGids == null) { 2726 gids = new int[1]; 2727 } else { 2728 gids = new int[permGids.length + 1]; 2729 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2730 } 2731 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2732 } 2733 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2734 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2735 && mTopComponent != null 2736 && app.processName.equals(mTopComponent.getPackageName())) { 2737 uid = 0; 2738 } 2739 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2740 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2741 uid = 0; 2742 } 2743 } 2744 int debugFlags = 0; 2745 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2746 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2747 // Also turn on CheckJNI for debuggable apps. It's quite 2748 // awkward to turn on otherwise. 2749 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2750 } 2751 // Run the app in safe mode if its manifest requests so or the 2752 // system is booted in safe mode. 2753 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2754 Zygote.systemInSafeMode == true) { 2755 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2756 } 2757 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2758 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2759 } 2760 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2761 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2762 } 2763 if ("1".equals(SystemProperties.get("debug.assert"))) { 2764 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2765 } 2766 2767 // Start the process. It will either succeed and return a result containing 2768 // the PID of the new process, or else throw a RuntimeException. 2769 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2770 app.processName, uid, uid, gids, debugFlags, mountExternal, 2771 app.info.targetSdkVersion, app.info.seinfo, null); 2772 2773 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2774 synchronized (bs) { 2775 if (bs.isOnBattery()) { 2776 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2777 } 2778 } 2779 2780 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2781 UserHandle.getUserId(uid), startResult.pid, uid, 2782 app.processName, hostingType, 2783 hostingNameStr != null ? hostingNameStr : ""); 2784 2785 if (app.persistent) { 2786 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2787 } 2788 2789 StringBuilder buf = mStringBuilder; 2790 buf.setLength(0); 2791 buf.append("Start proc "); 2792 buf.append(app.processName); 2793 buf.append(" for "); 2794 buf.append(hostingType); 2795 if (hostingNameStr != null) { 2796 buf.append(" "); 2797 buf.append(hostingNameStr); 2798 } 2799 buf.append(": pid="); 2800 buf.append(startResult.pid); 2801 buf.append(" uid="); 2802 buf.append(uid); 2803 buf.append(" gids={"); 2804 if (gids != null) { 2805 for (int gi=0; gi<gids.length; gi++) { 2806 if (gi != 0) buf.append(", "); 2807 buf.append(gids[gi]); 2808 2809 } 2810 } 2811 buf.append("}"); 2812 Slog.i(TAG, buf.toString()); 2813 app.setPid(startResult.pid); 2814 app.usingWrapper = startResult.usingWrapper; 2815 app.removed = false; 2816 synchronized (mPidsSelfLocked) { 2817 this.mPidsSelfLocked.put(startResult.pid, app); 2818 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2819 msg.obj = app; 2820 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2821 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2822 } 2823 } catch (RuntimeException e) { 2824 // XXX do better error recovery. 2825 app.setPid(0); 2826 Slog.e(TAG, "Failure starting process " + app.processName, e); 2827 } 2828 } 2829 2830 void updateUsageStats(ActivityRecord component, boolean resumed) { 2831 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2832 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2833 if (resumed) { 2834 mUsageStatsService.noteResumeComponent(component.realActivity); 2835 synchronized (stats) { 2836 stats.noteActivityResumedLocked(component.app.uid); 2837 } 2838 } else { 2839 mUsageStatsService.notePauseComponent(component.realActivity); 2840 synchronized (stats) { 2841 stats.noteActivityPausedLocked(component.app.uid); 2842 } 2843 } 2844 } 2845 2846 Intent getHomeIntent() { 2847 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2848 intent.setComponent(mTopComponent); 2849 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2850 intent.addCategory(Intent.CATEGORY_HOME); 2851 } 2852 return intent; 2853 } 2854 2855 boolean startHomeActivityLocked(int userId) { 2856 if (mHeadless) { 2857 // Added because none of the other calls to ensureBootCompleted seem to fire 2858 // when running headless. 2859 ensureBootCompleted(); 2860 return false; 2861 } 2862 2863 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2864 && mTopAction == null) { 2865 // We are running in factory test mode, but unable to find 2866 // the factory test app, so just sit around displaying the 2867 // error message and don't try to start anything. 2868 return false; 2869 } 2870 Intent intent = getHomeIntent(); 2871 ActivityInfo aInfo = 2872 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2873 if (aInfo != null) { 2874 intent.setComponent(new ComponentName( 2875 aInfo.applicationInfo.packageName, aInfo.name)); 2876 // Don't do this if the home app is currently being 2877 // instrumented. 2878 aInfo = new ActivityInfo(aInfo); 2879 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2880 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2881 aInfo.applicationInfo.uid, true); 2882 if (app == null || app.instrumentationClass == null) { 2883 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2884 mStackSupervisor.startHomeActivity(intent, aInfo); 2885 } 2886 } 2887 2888 return true; 2889 } 2890 2891 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2892 ActivityInfo ai = null; 2893 ComponentName comp = intent.getComponent(); 2894 try { 2895 if (comp != null) { 2896 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2897 } else { 2898 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2899 intent, 2900 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2901 flags, userId); 2902 2903 if (info != null) { 2904 ai = info.activityInfo; 2905 } 2906 } 2907 } catch (RemoteException e) { 2908 // ignore 2909 } 2910 2911 return ai; 2912 } 2913 2914 /** 2915 * Starts the "new version setup screen" if appropriate. 2916 */ 2917 void startSetupActivityLocked() { 2918 // Only do this once per boot. 2919 if (mCheckedForSetup) { 2920 return; 2921 } 2922 2923 // We will show this screen if the current one is a different 2924 // version than the last one shown, and we are not running in 2925 // low-level factory test mode. 2926 final ContentResolver resolver = mContext.getContentResolver(); 2927 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2928 Settings.Global.getInt(resolver, 2929 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2930 mCheckedForSetup = true; 2931 2932 // See if we should be showing the platform update setup UI. 2933 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2934 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2935 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2936 2937 // We don't allow third party apps to replace this. 2938 ResolveInfo ri = null; 2939 for (int i=0; ris != null && i<ris.size(); i++) { 2940 if ((ris.get(i).activityInfo.applicationInfo.flags 2941 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2942 ri = ris.get(i); 2943 break; 2944 } 2945 } 2946 2947 if (ri != null) { 2948 String vers = ri.activityInfo.metaData != null 2949 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2950 : null; 2951 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2952 vers = ri.activityInfo.applicationInfo.metaData.getString( 2953 Intent.METADATA_SETUP_VERSION); 2954 } 2955 String lastVers = Settings.Secure.getString( 2956 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2957 if (vers != null && !vers.equals(lastVers)) { 2958 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2959 intent.setComponent(new ComponentName( 2960 ri.activityInfo.packageName, ri.activityInfo.name)); 2961 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2962 null, null, 0, 0, 0, null, 0, null, false, null); 2963 } 2964 } 2965 } 2966 } 2967 2968 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2969 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2970 } 2971 2972 void enforceNotIsolatedCaller(String caller) { 2973 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2974 throw new SecurityException("Isolated process not allowed to call " + caller); 2975 } 2976 } 2977 2978 @Override 2979 public int getFrontActivityScreenCompatMode() { 2980 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2981 synchronized (this) { 2982 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2983 } 2984 } 2985 2986 @Override 2987 public void setFrontActivityScreenCompatMode(int mode) { 2988 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2989 "setFrontActivityScreenCompatMode"); 2990 synchronized (this) { 2991 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2992 } 2993 } 2994 2995 @Override 2996 public int getPackageScreenCompatMode(String packageName) { 2997 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2998 synchronized (this) { 2999 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3000 } 3001 } 3002 3003 @Override 3004 public void setPackageScreenCompatMode(String packageName, int mode) { 3005 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3006 "setPackageScreenCompatMode"); 3007 synchronized (this) { 3008 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3009 } 3010 } 3011 3012 @Override 3013 public boolean getPackageAskScreenCompat(String packageName) { 3014 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3015 synchronized (this) { 3016 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3017 } 3018 } 3019 3020 @Override 3021 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3022 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3023 "setPackageAskScreenCompat"); 3024 synchronized (this) { 3025 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3026 } 3027 } 3028 3029 private void dispatchProcessesChanged() { 3030 int N; 3031 synchronized (this) { 3032 N = mPendingProcessChanges.size(); 3033 if (mActiveProcessChanges.length < N) { 3034 mActiveProcessChanges = new ProcessChangeItem[N]; 3035 } 3036 mPendingProcessChanges.toArray(mActiveProcessChanges); 3037 mAvailProcessChanges.addAll(mPendingProcessChanges); 3038 mPendingProcessChanges.clear(); 3039 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3040 } 3041 3042 int i = mProcessObservers.beginBroadcast(); 3043 while (i > 0) { 3044 i--; 3045 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3046 if (observer != null) { 3047 try { 3048 for (int j=0; j<N; j++) { 3049 ProcessChangeItem item = mActiveProcessChanges[j]; 3050 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3051 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3052 + item.pid + " uid=" + item.uid + ": " 3053 + item.foregroundActivities); 3054 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3055 item.foregroundActivities); 3056 } 3057 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3058 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3059 + item.pid + " uid=" + item.uid + ": " + item.importance); 3060 observer.onImportanceChanged(item.pid, item.uid, 3061 item.importance); 3062 } 3063 } 3064 } catch (RemoteException e) { 3065 } 3066 } 3067 } 3068 mProcessObservers.finishBroadcast(); 3069 } 3070 3071 private void dispatchProcessDied(int pid, int uid) { 3072 int i = mProcessObservers.beginBroadcast(); 3073 while (i > 0) { 3074 i--; 3075 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3076 if (observer != null) { 3077 try { 3078 observer.onProcessDied(pid, uid); 3079 } catch (RemoteException e) { 3080 } 3081 } 3082 } 3083 mProcessObservers.finishBroadcast(); 3084 } 3085 3086 final void doPendingActivityLaunchesLocked(boolean doResume) { 3087 final int N = mPendingActivityLaunches.size(); 3088 if (N <= 0) { 3089 return; 3090 } 3091 for (int i=0; i<N; i++) { 3092 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3093 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3094 doResume && i == (N-1), null); 3095 } 3096 mPendingActivityLaunches.clear(); 3097 } 3098 3099 @Override 3100 public final int startActivity(IApplicationThread caller, String callingPackage, 3101 Intent intent, String resolvedType, IBinder resultTo, 3102 String resultWho, int requestCode, int startFlags, 3103 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3104 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3105 resultWho, requestCode, 3106 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3107 } 3108 3109 @Override 3110 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3111 Intent intent, String resolvedType, IBinder resultTo, 3112 String resultWho, int requestCode, int startFlags, 3113 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3114 enforceNotIsolatedCaller("startActivity"); 3115 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3116 false, true, "startActivity", null); 3117 // TODO: Switch to user app stacks here. 3118 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3119 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3120 null, null, options, userId); 3121 } 3122 3123 @Override 3124 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3125 Intent intent, String resolvedType, IBinder resultTo, 3126 String resultWho, int requestCode, int startFlags, String profileFile, 3127 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3128 enforceNotIsolatedCaller("startActivityAndWait"); 3129 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3130 false, true, "startActivityAndWait", null); 3131 WaitResult res = new WaitResult(); 3132 // TODO: Switch to user app stacks here. 3133 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3134 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3135 res, null, options, UserHandle.getCallingUserId()); 3136 return res; 3137 } 3138 3139 @Override 3140 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3141 Intent intent, String resolvedType, IBinder resultTo, 3142 String resultWho, int requestCode, int startFlags, Configuration config, 3143 Bundle options, int userId) { 3144 enforceNotIsolatedCaller("startActivityWithConfig"); 3145 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3146 false, true, "startActivityWithConfig", null); 3147 // TODO: Switch to user app stacks here. 3148 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3149 resolvedType, resultTo, resultWho, requestCode, startFlags, 3150 null, null, null, config, options, userId); 3151 return ret; 3152 } 3153 3154 @Override 3155 public int startActivityIntentSender(IApplicationThread caller, 3156 IntentSender intent, Intent fillInIntent, String resolvedType, 3157 IBinder resultTo, String resultWho, int requestCode, 3158 int flagsMask, int flagsValues, Bundle options) { 3159 enforceNotIsolatedCaller("startActivityIntentSender"); 3160 // Refuse possible leaked file descriptors 3161 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3162 throw new IllegalArgumentException("File descriptors passed in Intent"); 3163 } 3164 3165 IIntentSender sender = intent.getTarget(); 3166 if (!(sender instanceof PendingIntentRecord)) { 3167 throw new IllegalArgumentException("Bad PendingIntent object"); 3168 } 3169 3170 PendingIntentRecord pir = (PendingIntentRecord)sender; 3171 3172 synchronized (this) { 3173 // If this is coming from the currently resumed activity, it is 3174 // effectively saying that app switches are allowed at this point. 3175 final ActivityStack stack = getFocusedStack(); 3176 if (stack.mResumedActivity != null && 3177 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3178 mAppSwitchesAllowedTime = 0; 3179 } 3180 } 3181 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3182 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 3183 return ret; 3184 } 3185 3186 @Override 3187 public boolean startNextMatchingActivity(IBinder callingActivity, 3188 Intent intent, Bundle options) { 3189 // Refuse possible leaked file descriptors 3190 if (intent != null && intent.hasFileDescriptors() == true) { 3191 throw new IllegalArgumentException("File descriptors passed in Intent"); 3192 } 3193 3194 synchronized (this) { 3195 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3196 if (r == null) { 3197 ActivityOptions.abort(options); 3198 return false; 3199 } 3200 if (r.app == null || r.app.thread == null) { 3201 // The caller is not running... d'oh! 3202 ActivityOptions.abort(options); 3203 return false; 3204 } 3205 intent = new Intent(intent); 3206 // The caller is not allowed to change the data. 3207 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3208 // And we are resetting to find the next component... 3209 intent.setComponent(null); 3210 3211 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3212 3213 ActivityInfo aInfo = null; 3214 try { 3215 List<ResolveInfo> resolves = 3216 AppGlobals.getPackageManager().queryIntentActivities( 3217 intent, r.resolvedType, 3218 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3219 UserHandle.getCallingUserId()); 3220 3221 // Look for the original activity in the list... 3222 final int N = resolves != null ? resolves.size() : 0; 3223 for (int i=0; i<N; i++) { 3224 ResolveInfo rInfo = resolves.get(i); 3225 if (rInfo.activityInfo.packageName.equals(r.packageName) 3226 && rInfo.activityInfo.name.equals(r.info.name)) { 3227 // We found the current one... the next matching is 3228 // after it. 3229 i++; 3230 if (i<N) { 3231 aInfo = resolves.get(i).activityInfo; 3232 } 3233 if (debug) { 3234 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3235 + "/" + r.info.name); 3236 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3237 + "/" + aInfo.name); 3238 } 3239 break; 3240 } 3241 } 3242 } catch (RemoteException e) { 3243 } 3244 3245 if (aInfo == null) { 3246 // Nobody who is next! 3247 ActivityOptions.abort(options); 3248 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3249 return false; 3250 } 3251 3252 intent.setComponent(new ComponentName( 3253 aInfo.applicationInfo.packageName, aInfo.name)); 3254 intent.setFlags(intent.getFlags()&~( 3255 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3256 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3257 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3258 Intent.FLAG_ACTIVITY_NEW_TASK)); 3259 3260 // Okay now we need to start the new activity, replacing the 3261 // currently running activity. This is a little tricky because 3262 // we want to start the new one as if the current one is finished, 3263 // but not finish the current one first so that there is no flicker. 3264 // And thus... 3265 final boolean wasFinishing = r.finishing; 3266 r.finishing = true; 3267 3268 // Propagate reply information over to the new activity. 3269 final ActivityRecord resultTo = r.resultTo; 3270 final String resultWho = r.resultWho; 3271 final int requestCode = r.requestCode; 3272 r.resultTo = null; 3273 if (resultTo != null) { 3274 resultTo.removeResultsLocked(r, resultWho, requestCode); 3275 } 3276 3277 final long origId = Binder.clearCallingIdentity(); 3278 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3279 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3280 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3281 options, false, null); 3282 Binder.restoreCallingIdentity(origId); 3283 3284 r.finishing = wasFinishing; 3285 if (res != ActivityManager.START_SUCCESS) { 3286 return false; 3287 } 3288 return true; 3289 } 3290 } 3291 3292 final int startActivityInPackage(int uid, String callingPackage, 3293 Intent intent, String resolvedType, IBinder resultTo, 3294 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 3295 3296 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3297 false, true, "startActivityInPackage", null); 3298 3299 // TODO: Switch to user app stacks here. 3300 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3301 resultTo, resultWho, requestCode, startFlags, 3302 null, null, null, null, options, userId); 3303 return ret; 3304 } 3305 3306 @Override 3307 public final int startActivities(IApplicationThread caller, String callingPackage, 3308 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3309 int userId) { 3310 enforceNotIsolatedCaller("startActivities"); 3311 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3312 false, true, "startActivity", null); 3313 // TODO: Switch to user app stacks here. 3314 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3315 resolvedTypes, resultTo, options, userId); 3316 return ret; 3317 } 3318 3319 final int startActivitiesInPackage(int uid, String callingPackage, 3320 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3321 Bundle options, int userId) { 3322 3323 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3324 false, true, "startActivityInPackage", null); 3325 // TODO: Switch to user app stacks here. 3326 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3327 resultTo, options, userId); 3328 return ret; 3329 } 3330 3331 final void addRecentTaskLocked(TaskRecord task) { 3332 int N = mRecentTasks.size(); 3333 // Quick case: check if the top-most recent task is the same. 3334 if (N > 0 && mRecentTasks.get(0) == task) { 3335 return; 3336 } 3337 // Remove any existing entries that are the same kind of task. 3338 for (int i=0; i<N; i++) { 3339 TaskRecord tr = mRecentTasks.get(i); 3340 if (task.userId == tr.userId 3341 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3342 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3343 tr.disposeThumbnail(); 3344 mRecentTasks.remove(i); 3345 i--; 3346 N--; 3347 if (task.intent == null) { 3348 // If the new recent task we are adding is not fully 3349 // specified, then replace it with the existing recent task. 3350 task = tr; 3351 } 3352 } 3353 } 3354 if (N >= MAX_RECENT_TASKS) { 3355 mRecentTasks.remove(N-1).disposeThumbnail(); 3356 } 3357 mRecentTasks.add(0, task); 3358 } 3359 3360 @Override 3361 public void reportActivityFullyDrawn(IBinder token) { 3362 synchronized (this) { 3363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3364 if (r == null) { 3365 return; 3366 } 3367 r.reportFullyDrawnLocked(); 3368 } 3369 } 3370 3371 @Override 3372 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3373 synchronized (this) { 3374 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3375 if (r == null) { 3376 return; 3377 } 3378 final long origId = Binder.clearCallingIdentity(); 3379 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3380 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3381 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3382 if (config != null) { 3383 r.frozenBeforeDestroy = true; 3384 if (!updateConfigurationLocked(config, r, false, false)) { 3385 mStackSupervisor.resumeTopActivitiesLocked(); 3386 } 3387 } 3388 Binder.restoreCallingIdentity(origId); 3389 } 3390 } 3391 3392 @Override 3393 public int getRequestedOrientation(IBinder token) { 3394 synchronized (this) { 3395 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3396 if (r == null) { 3397 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3398 } 3399 return mWindowManager.getAppOrientation(r.appToken); 3400 } 3401 } 3402 3403 /** 3404 * This is the internal entry point for handling Activity.finish(). 3405 * 3406 * @param token The Binder token referencing the Activity we want to finish. 3407 * @param resultCode Result code, if any, from this Activity. 3408 * @param resultData Result data (Intent), if any, from this Activity. 3409 * 3410 * @return Returns true if the activity successfully finished, or false if it is still running. 3411 */ 3412 @Override 3413 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3414 // Refuse possible leaked file descriptors 3415 if (resultData != null && resultData.hasFileDescriptors() == true) { 3416 throw new IllegalArgumentException("File descriptors passed in Intent"); 3417 } 3418 3419 synchronized(this) { 3420 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3421 if (r == null) { 3422 return true; 3423 } 3424 if (mController != null) { 3425 // Find the first activity that is not finishing. 3426 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3427 if (next != null) { 3428 // ask watcher if this is allowed 3429 boolean resumeOK = true; 3430 try { 3431 resumeOK = mController.activityResuming(next.packageName); 3432 } catch (RemoteException e) { 3433 mController = null; 3434 Watchdog.getInstance().setActivityController(null); 3435 } 3436 3437 if (!resumeOK) { 3438 return false; 3439 } 3440 } 3441 } 3442 final long origId = Binder.clearCallingIdentity(); 3443 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3444 resultData, "app-request", true); 3445 Binder.restoreCallingIdentity(origId); 3446 return res; 3447 } 3448 } 3449 3450 @Override 3451 public final void finishHeavyWeightApp() { 3452 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3453 != PackageManager.PERMISSION_GRANTED) { 3454 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3455 + Binder.getCallingPid() 3456 + ", uid=" + Binder.getCallingUid() 3457 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3458 Slog.w(TAG, msg); 3459 throw new SecurityException(msg); 3460 } 3461 3462 synchronized(this) { 3463 if (mHeavyWeightProcess == null) { 3464 return; 3465 } 3466 3467 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3468 mHeavyWeightProcess.activities); 3469 for (int i=0; i<activities.size(); i++) { 3470 ActivityRecord r = activities.get(i); 3471 if (!r.finishing) { 3472 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3473 null, "finish-heavy", true); 3474 } 3475 } 3476 3477 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3478 mHeavyWeightProcess.userId, 0)); 3479 mHeavyWeightProcess = null; 3480 } 3481 } 3482 3483 @Override 3484 public void crashApplication(int uid, int initialPid, String packageName, 3485 String message) { 3486 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3487 != PackageManager.PERMISSION_GRANTED) { 3488 String msg = "Permission Denial: crashApplication() from pid=" 3489 + Binder.getCallingPid() 3490 + ", uid=" + Binder.getCallingUid() 3491 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3492 Slog.w(TAG, msg); 3493 throw new SecurityException(msg); 3494 } 3495 3496 synchronized(this) { 3497 ProcessRecord proc = null; 3498 3499 // Figure out which process to kill. We don't trust that initialPid 3500 // still has any relation to current pids, so must scan through the 3501 // list. 3502 synchronized (mPidsSelfLocked) { 3503 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3504 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3505 if (p.uid != uid) { 3506 continue; 3507 } 3508 if (p.pid == initialPid) { 3509 proc = p; 3510 break; 3511 } 3512 if (p.pkgList.containsKey(packageName)) { 3513 proc = p; 3514 } 3515 } 3516 } 3517 3518 if (proc == null) { 3519 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3520 + " initialPid=" + initialPid 3521 + " packageName=" + packageName); 3522 return; 3523 } 3524 3525 if (proc.thread != null) { 3526 if (proc.pid == Process.myPid()) { 3527 Log.w(TAG, "crashApplication: trying to crash self!"); 3528 return; 3529 } 3530 long ident = Binder.clearCallingIdentity(); 3531 try { 3532 proc.thread.scheduleCrash(message); 3533 } catch (RemoteException e) { 3534 } 3535 Binder.restoreCallingIdentity(ident); 3536 } 3537 } 3538 } 3539 3540 @Override 3541 public final void finishSubActivity(IBinder token, String resultWho, 3542 int requestCode) { 3543 synchronized(this) { 3544 final long origId = Binder.clearCallingIdentity(); 3545 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3546 if (r != null) { 3547 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3548 } 3549 Binder.restoreCallingIdentity(origId); 3550 } 3551 } 3552 3553 @Override 3554 public boolean finishActivityAffinity(IBinder token) { 3555 synchronized(this) { 3556 final long origId = Binder.clearCallingIdentity(); 3557 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3558 boolean res = false; 3559 if (r != null) { 3560 res = r.task.stack.finishActivityAffinityLocked(r); 3561 } 3562 Binder.restoreCallingIdentity(origId); 3563 return res; 3564 } 3565 } 3566 3567 @Override 3568 public boolean willActivityBeVisible(IBinder token) { 3569 synchronized(this) { 3570 ActivityStack stack = ActivityRecord.getStackLocked(token); 3571 if (stack != null) { 3572 return stack.willActivityBeVisibleLocked(token); 3573 } 3574 return false; 3575 } 3576 } 3577 3578 @Override 3579 public void overridePendingTransition(IBinder token, String packageName, 3580 int enterAnim, int exitAnim) { 3581 synchronized(this) { 3582 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3583 if (self == null) { 3584 return; 3585 } 3586 3587 final long origId = Binder.clearCallingIdentity(); 3588 3589 if (self.state == ActivityState.RESUMED 3590 || self.state == ActivityState.PAUSING) { 3591 mWindowManager.overridePendingAppTransition(packageName, 3592 enterAnim, exitAnim, null); 3593 } 3594 3595 Binder.restoreCallingIdentity(origId); 3596 } 3597 } 3598 3599 /** 3600 * Main function for removing an existing process from the activity manager 3601 * as a result of that process going away. Clears out all connections 3602 * to the process. 3603 */ 3604 private final void handleAppDiedLocked(ProcessRecord app, 3605 boolean restarting, boolean allowRestart) { 3606 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3607 if (!restarting) { 3608 removeLruProcessLocked(app); 3609 } 3610 3611 if (mProfileProc == app) { 3612 clearProfilerLocked(); 3613 } 3614 3615 // Remove this application's activities from active lists. 3616 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3617 3618 app.activities.clear(); 3619 3620 if (app.instrumentationClass != null) { 3621 Slog.w(TAG, "Crash of app " + app.processName 3622 + " running instrumentation " + app.instrumentationClass); 3623 Bundle info = new Bundle(); 3624 info.putString("shortMsg", "Process crashed."); 3625 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3626 } 3627 3628 if (!restarting) { 3629 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3630 // If there was nothing to resume, and we are not already 3631 // restarting this process, but there is a visible activity that 3632 // is hosted by the process... then make sure all visible 3633 // activities are running, taking care of restarting this 3634 // process. 3635 if (hasVisibleActivities) { 3636 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3637 } 3638 } 3639 } 3640 } 3641 3642 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3643 IBinder threadBinder = thread.asBinder(); 3644 // Find the application record. 3645 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3646 ProcessRecord rec = mLruProcesses.get(i); 3647 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3648 return i; 3649 } 3650 } 3651 return -1; 3652 } 3653 3654 final ProcessRecord getRecordForAppLocked( 3655 IApplicationThread thread) { 3656 if (thread == null) { 3657 return null; 3658 } 3659 3660 int appIndex = getLRURecordIndexForAppLocked(thread); 3661 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3662 } 3663 3664 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3665 // If there are no longer any background processes running, 3666 // and the app that died was not running instrumentation, 3667 // then tell everyone we are now low on memory. 3668 boolean haveBg = false; 3669 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3670 ProcessRecord rec = mLruProcesses.get(i); 3671 if (rec.thread != null 3672 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3673 haveBg = true; 3674 break; 3675 } 3676 } 3677 3678 if (!haveBg) { 3679 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3680 if (doReport) { 3681 long now = SystemClock.uptimeMillis(); 3682 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3683 doReport = false; 3684 } else { 3685 mLastMemUsageReportTime = now; 3686 } 3687 } 3688 final ArrayList<ProcessMemInfo> memInfos 3689 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3690 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3691 long now = SystemClock.uptimeMillis(); 3692 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3693 ProcessRecord rec = mLruProcesses.get(i); 3694 if (rec == dyingProc || rec.thread == null) { 3695 continue; 3696 } 3697 if (doReport) { 3698 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3699 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3700 } 3701 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3702 // The low memory report is overriding any current 3703 // state for a GC request. Make sure to do 3704 // heavy/important/visible/foreground processes first. 3705 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3706 rec.lastRequestedGc = 0; 3707 } else { 3708 rec.lastRequestedGc = rec.lastLowMemory; 3709 } 3710 rec.reportLowMemory = true; 3711 rec.lastLowMemory = now; 3712 mProcessesToGc.remove(rec); 3713 addProcessToGcListLocked(rec); 3714 } 3715 } 3716 if (doReport) { 3717 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3718 mHandler.sendMessage(msg); 3719 } 3720 scheduleAppGcsLocked(); 3721 } 3722 } 3723 3724 final void appDiedLocked(ProcessRecord app, int pid, 3725 IApplicationThread thread) { 3726 3727 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3728 synchronized (stats) { 3729 stats.noteProcessDiedLocked(app.info.uid, pid); 3730 } 3731 3732 // Clean up already done if the process has been re-started. 3733 if (app.pid == pid && app.thread != null && 3734 app.thread.asBinder() == thread.asBinder()) { 3735 boolean doLowMem = app.instrumentationClass == null; 3736 boolean doOomAdj = doLowMem; 3737 if (!app.killedByAm) { 3738 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3739 + ") has died."); 3740 mAllowLowerMemLevel = true; 3741 } else { 3742 // Note that we always want to do oom adj to update our state with the 3743 // new number of procs. 3744 mAllowLowerMemLevel = false; 3745 doLowMem = false; 3746 } 3747 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3748 if (DEBUG_CLEANUP) Slog.v( 3749 TAG, "Dying app: " + app + ", pid: " + pid 3750 + ", thread: " + thread.asBinder()); 3751 handleAppDiedLocked(app, false, true); 3752 3753 if (doOomAdj) { 3754 updateOomAdjLocked(); 3755 } 3756 if (doLowMem) { 3757 doLowMemReportIfNeededLocked(app); 3758 } 3759 } else if (app.pid != pid) { 3760 // A new process has already been started. 3761 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3762 + ") has died and restarted (pid " + app.pid + ")."); 3763 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3764 } else if (DEBUG_PROCESSES) { 3765 Slog.d(TAG, "Received spurious death notification for thread " 3766 + thread.asBinder()); 3767 } 3768 } 3769 3770 /** 3771 * If a stack trace dump file is configured, dump process stack traces. 3772 * @param clearTraces causes the dump file to be erased prior to the new 3773 * traces being written, if true; when false, the new traces will be 3774 * appended to any existing file content. 3775 * @param firstPids of dalvik VM processes to dump stack traces for first 3776 * @param lastPids of dalvik VM processes to dump stack traces for last 3777 * @param nativeProcs optional list of native process names to dump stack crawls 3778 * @return file containing stack traces, or null if no dump file is configured 3779 */ 3780 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3781 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3782 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3783 if (tracesPath == null || tracesPath.length() == 0) { 3784 return null; 3785 } 3786 3787 File tracesFile = new File(tracesPath); 3788 try { 3789 File tracesDir = tracesFile.getParentFile(); 3790 if (!tracesDir.exists()) { 3791 tracesFile.mkdirs(); 3792 if (!SELinux.restorecon(tracesDir)) { 3793 return null; 3794 } 3795 } 3796 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3797 3798 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3799 tracesFile.createNewFile(); 3800 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3801 } catch (IOException e) { 3802 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3803 return null; 3804 } 3805 3806 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3807 return tracesFile; 3808 } 3809 3810 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3811 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3812 // Use a FileObserver to detect when traces finish writing. 3813 // The order of traces is considered important to maintain for legibility. 3814 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3815 @Override 3816 public synchronized void onEvent(int event, String path) { notify(); } 3817 }; 3818 3819 try { 3820 observer.startWatching(); 3821 3822 // First collect all of the stacks of the most important pids. 3823 if (firstPids != null) { 3824 try { 3825 int num = firstPids.size(); 3826 for (int i = 0; i < num; i++) { 3827 synchronized (observer) { 3828 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3829 observer.wait(200); // Wait for write-close, give up after 200msec 3830 } 3831 } 3832 } catch (InterruptedException e) { 3833 Log.wtf(TAG, e); 3834 } 3835 } 3836 3837 // Next collect the stacks of the native pids 3838 if (nativeProcs != null) { 3839 int[] pids = Process.getPidsForCommands(nativeProcs); 3840 if (pids != null) { 3841 for (int pid : pids) { 3842 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3843 } 3844 } 3845 } 3846 3847 // Lastly, measure CPU usage. 3848 if (processCpuTracker != null) { 3849 processCpuTracker.init(); 3850 System.gc(); 3851 processCpuTracker.update(); 3852 try { 3853 synchronized (processCpuTracker) { 3854 processCpuTracker.wait(500); // measure over 1/2 second. 3855 } 3856 } catch (InterruptedException e) { 3857 } 3858 processCpuTracker.update(); 3859 3860 // We'll take the stack crawls of just the top apps using CPU. 3861 final int N = processCpuTracker.countWorkingStats(); 3862 int numProcs = 0; 3863 for (int i=0; i<N && numProcs<5; i++) { 3864 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3865 if (lastPids.indexOfKey(stats.pid) >= 0) { 3866 numProcs++; 3867 try { 3868 synchronized (observer) { 3869 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3870 observer.wait(200); // Wait for write-close, give up after 200msec 3871 } 3872 } catch (InterruptedException e) { 3873 Log.wtf(TAG, e); 3874 } 3875 3876 } 3877 } 3878 } 3879 } finally { 3880 observer.stopWatching(); 3881 } 3882 } 3883 3884 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3885 if (true || IS_USER_BUILD) { 3886 return; 3887 } 3888 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3889 if (tracesPath == null || tracesPath.length() == 0) { 3890 return; 3891 } 3892 3893 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3894 StrictMode.allowThreadDiskWrites(); 3895 try { 3896 final File tracesFile = new File(tracesPath); 3897 final File tracesDir = tracesFile.getParentFile(); 3898 final File tracesTmp = new File(tracesDir, "__tmp__"); 3899 try { 3900 if (!tracesDir.exists()) { 3901 tracesFile.mkdirs(); 3902 if (!SELinux.restorecon(tracesDir.getPath())) { 3903 return; 3904 } 3905 } 3906 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3907 3908 if (tracesFile.exists()) { 3909 tracesTmp.delete(); 3910 tracesFile.renameTo(tracesTmp); 3911 } 3912 StringBuilder sb = new StringBuilder(); 3913 Time tobj = new Time(); 3914 tobj.set(System.currentTimeMillis()); 3915 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3916 sb.append(": "); 3917 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3918 sb.append(" since "); 3919 sb.append(msg); 3920 FileOutputStream fos = new FileOutputStream(tracesFile); 3921 fos.write(sb.toString().getBytes()); 3922 if (app == null) { 3923 fos.write("\n*** No application process!".getBytes()); 3924 } 3925 fos.close(); 3926 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3927 } catch (IOException e) { 3928 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3929 return; 3930 } 3931 3932 if (app != null) { 3933 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3934 firstPids.add(app.pid); 3935 dumpStackTraces(tracesPath, firstPids, null, null, null); 3936 } 3937 3938 File lastTracesFile = null; 3939 File curTracesFile = null; 3940 for (int i=9; i>=0; i--) { 3941 String name = String.format(Locale.US, "slow%02d.txt", i); 3942 curTracesFile = new File(tracesDir, name); 3943 if (curTracesFile.exists()) { 3944 if (lastTracesFile != null) { 3945 curTracesFile.renameTo(lastTracesFile); 3946 } else { 3947 curTracesFile.delete(); 3948 } 3949 } 3950 lastTracesFile = curTracesFile; 3951 } 3952 tracesFile.renameTo(curTracesFile); 3953 if (tracesTmp.exists()) { 3954 tracesTmp.renameTo(tracesFile); 3955 } 3956 } finally { 3957 StrictMode.setThreadPolicy(oldPolicy); 3958 } 3959 } 3960 3961 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3962 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3963 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3964 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3965 3966 if (mController != null) { 3967 try { 3968 // 0 == continue, -1 = kill process immediately 3969 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3970 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3971 } catch (RemoteException e) { 3972 mController = null; 3973 Watchdog.getInstance().setActivityController(null); 3974 } 3975 } 3976 3977 long anrTime = SystemClock.uptimeMillis(); 3978 if (MONITOR_CPU_USAGE) { 3979 updateCpuStatsNow(); 3980 } 3981 3982 synchronized (this) { 3983 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3984 if (mShuttingDown) { 3985 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3986 return; 3987 } else if (app.notResponding) { 3988 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3989 return; 3990 } else if (app.crashing) { 3991 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3992 return; 3993 } 3994 3995 // In case we come through here for the same app before completing 3996 // this one, mark as anring now so we will bail out. 3997 app.notResponding = true; 3998 3999 // Log the ANR to the event log. 4000 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4001 app.processName, app.info.flags, annotation); 4002 4003 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4004 firstPids.add(app.pid); 4005 4006 int parentPid = app.pid; 4007 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4008 if (parentPid != app.pid) firstPids.add(parentPid); 4009 4010 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4011 4012 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4013 ProcessRecord r = mLruProcesses.get(i); 4014 if (r != null && r.thread != null) { 4015 int pid = r.pid; 4016 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4017 if (r.persistent) { 4018 firstPids.add(pid); 4019 } else { 4020 lastPids.put(pid, Boolean.TRUE); 4021 } 4022 } 4023 } 4024 } 4025 } 4026 4027 // Log the ANR to the main log. 4028 StringBuilder info = new StringBuilder(); 4029 info.setLength(0); 4030 info.append("ANR in ").append(app.processName); 4031 if (activity != null && activity.shortComponentName != null) { 4032 info.append(" (").append(activity.shortComponentName).append(")"); 4033 } 4034 info.append("\n"); 4035 info.append("PID: ").append(app.pid).append("\n"); 4036 if (annotation != null) { 4037 info.append("Reason: ").append(annotation).append("\n"); 4038 } 4039 if (parent != null && parent != activity) { 4040 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4041 } 4042 4043 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4044 4045 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4046 NATIVE_STACKS_OF_INTEREST); 4047 4048 String cpuInfo = null; 4049 if (MONITOR_CPU_USAGE) { 4050 updateCpuStatsNow(); 4051 synchronized (mProcessCpuThread) { 4052 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4053 } 4054 info.append(processCpuTracker.printCurrentLoad()); 4055 info.append(cpuInfo); 4056 } 4057 4058 info.append(processCpuTracker.printCurrentState(anrTime)); 4059 4060 Slog.e(TAG, info.toString()); 4061 if (tracesFile == null) { 4062 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4063 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4064 } 4065 4066 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4067 cpuInfo, tracesFile, null); 4068 4069 if (mController != null) { 4070 try { 4071 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4072 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4073 if (res != 0) { 4074 if (res < 0 && app.pid != MY_PID) { 4075 Process.killProcess(app.pid); 4076 } else { 4077 synchronized (this) { 4078 mServices.scheduleServiceTimeoutLocked(app); 4079 } 4080 } 4081 return; 4082 } 4083 } catch (RemoteException e) { 4084 mController = null; 4085 Watchdog.getInstance().setActivityController(null); 4086 } 4087 } 4088 4089 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4090 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4091 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4092 4093 synchronized (this) { 4094 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4095 killUnneededProcessLocked(app, "background ANR"); 4096 return; 4097 } 4098 4099 // Set the app's notResponding state, and look up the errorReportReceiver 4100 makeAppNotRespondingLocked(app, 4101 activity != null ? activity.shortComponentName : null, 4102 annotation != null ? "ANR " + annotation : "ANR", 4103 info.toString()); 4104 4105 // Bring up the infamous App Not Responding dialog 4106 Message msg = Message.obtain(); 4107 HashMap<String, Object> map = new HashMap<String, Object>(); 4108 msg.what = SHOW_NOT_RESPONDING_MSG; 4109 msg.obj = map; 4110 msg.arg1 = aboveSystem ? 1 : 0; 4111 map.put("app", app); 4112 if (activity != null) { 4113 map.put("activity", activity); 4114 } 4115 4116 mHandler.sendMessage(msg); 4117 } 4118 } 4119 4120 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4121 if (!mLaunchWarningShown) { 4122 mLaunchWarningShown = true; 4123 mHandler.post(new Runnable() { 4124 @Override 4125 public void run() { 4126 synchronized (ActivityManagerService.this) { 4127 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4128 d.show(); 4129 mHandler.postDelayed(new Runnable() { 4130 @Override 4131 public void run() { 4132 synchronized (ActivityManagerService.this) { 4133 d.dismiss(); 4134 mLaunchWarningShown = false; 4135 } 4136 } 4137 }, 4000); 4138 } 4139 } 4140 }); 4141 } 4142 } 4143 4144 @Override 4145 public boolean clearApplicationUserData(final String packageName, 4146 final IPackageDataObserver observer, int userId) { 4147 enforceNotIsolatedCaller("clearApplicationUserData"); 4148 int uid = Binder.getCallingUid(); 4149 int pid = Binder.getCallingPid(); 4150 userId = handleIncomingUser(pid, uid, 4151 userId, false, true, "clearApplicationUserData", null); 4152 long callingId = Binder.clearCallingIdentity(); 4153 try { 4154 IPackageManager pm = AppGlobals.getPackageManager(); 4155 int pkgUid = -1; 4156 synchronized(this) { 4157 try { 4158 pkgUid = pm.getPackageUid(packageName, userId); 4159 } catch (RemoteException e) { 4160 } 4161 if (pkgUid == -1) { 4162 Slog.w(TAG, "Invalid packageName: " + packageName); 4163 if (observer != null) { 4164 try { 4165 observer.onRemoveCompleted(packageName, false); 4166 } catch (RemoteException e) { 4167 Slog.i(TAG, "Observer no longer exists."); 4168 } 4169 } 4170 return false; 4171 } 4172 if (uid == pkgUid || checkComponentPermission( 4173 android.Manifest.permission.CLEAR_APP_USER_DATA, 4174 pid, uid, -1, true) 4175 == PackageManager.PERMISSION_GRANTED) { 4176 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4177 } else { 4178 throw new SecurityException(pid+" does not have permission:"+ 4179 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 4180 "for process:"+packageName); 4181 } 4182 } 4183 4184 try { 4185 // Clear application user data 4186 pm.clearApplicationUserData(packageName, observer, userId); 4187 4188 // Remove all permissions granted from/to this package 4189 removeUriPermissionsForPackageLocked(packageName, userId, true); 4190 4191 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4192 Uri.fromParts("package", packageName, null)); 4193 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4194 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4195 null, null, 0, null, null, null, false, false, userId); 4196 } catch (RemoteException e) { 4197 } 4198 } finally { 4199 Binder.restoreCallingIdentity(callingId); 4200 } 4201 return true; 4202 } 4203 4204 @Override 4205 public void killBackgroundProcesses(final String packageName, int userId) { 4206 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4207 != PackageManager.PERMISSION_GRANTED && 4208 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4209 != PackageManager.PERMISSION_GRANTED) { 4210 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4211 + Binder.getCallingPid() 4212 + ", uid=" + Binder.getCallingUid() 4213 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4214 Slog.w(TAG, msg); 4215 throw new SecurityException(msg); 4216 } 4217 4218 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4219 userId, true, true, "killBackgroundProcesses", null); 4220 long callingId = Binder.clearCallingIdentity(); 4221 try { 4222 IPackageManager pm = AppGlobals.getPackageManager(); 4223 synchronized(this) { 4224 int appId = -1; 4225 try { 4226 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4227 } catch (RemoteException e) { 4228 } 4229 if (appId == -1) { 4230 Slog.w(TAG, "Invalid packageName: " + packageName); 4231 return; 4232 } 4233 killPackageProcessesLocked(packageName, appId, userId, 4234 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4235 } 4236 } finally { 4237 Binder.restoreCallingIdentity(callingId); 4238 } 4239 } 4240 4241 @Override 4242 public void killAllBackgroundProcesses() { 4243 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4244 != PackageManager.PERMISSION_GRANTED) { 4245 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4246 + Binder.getCallingPid() 4247 + ", uid=" + Binder.getCallingUid() 4248 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4249 Slog.w(TAG, msg); 4250 throw new SecurityException(msg); 4251 } 4252 4253 long callingId = Binder.clearCallingIdentity(); 4254 try { 4255 synchronized(this) { 4256 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4257 final int NP = mProcessNames.getMap().size(); 4258 for (int ip=0; ip<NP; ip++) { 4259 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4260 final int NA = apps.size(); 4261 for (int ia=0; ia<NA; ia++) { 4262 ProcessRecord app = apps.valueAt(ia); 4263 if (app.persistent) { 4264 // we don't kill persistent processes 4265 continue; 4266 } 4267 if (app.removed) { 4268 procs.add(app); 4269 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4270 app.removed = true; 4271 procs.add(app); 4272 } 4273 } 4274 } 4275 4276 int N = procs.size(); 4277 for (int i=0; i<N; i++) { 4278 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4279 } 4280 mAllowLowerMemLevel = true; 4281 updateOomAdjLocked(); 4282 doLowMemReportIfNeededLocked(null); 4283 } 4284 } finally { 4285 Binder.restoreCallingIdentity(callingId); 4286 } 4287 } 4288 4289 @Override 4290 public void forceStopPackage(final String packageName, int userId) { 4291 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4292 != PackageManager.PERMISSION_GRANTED) { 4293 String msg = "Permission Denial: forceStopPackage() from pid=" 4294 + Binder.getCallingPid() 4295 + ", uid=" + Binder.getCallingUid() 4296 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4297 Slog.w(TAG, msg); 4298 throw new SecurityException(msg); 4299 } 4300 final int callingPid = Binder.getCallingPid(); 4301 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4302 userId, true, true, "forceStopPackage", null); 4303 long callingId = Binder.clearCallingIdentity(); 4304 try { 4305 IPackageManager pm = AppGlobals.getPackageManager(); 4306 synchronized(this) { 4307 int[] users = userId == UserHandle.USER_ALL 4308 ? getUsersLocked() : new int[] { userId }; 4309 for (int user : users) { 4310 int pkgUid = -1; 4311 try { 4312 pkgUid = pm.getPackageUid(packageName, user); 4313 } catch (RemoteException e) { 4314 } 4315 if (pkgUid == -1) { 4316 Slog.w(TAG, "Invalid packageName: " + packageName); 4317 continue; 4318 } 4319 try { 4320 pm.setPackageStoppedState(packageName, true, user); 4321 } catch (RemoteException e) { 4322 } catch (IllegalArgumentException e) { 4323 Slog.w(TAG, "Failed trying to unstop package " 4324 + packageName + ": " + e); 4325 } 4326 if (isUserRunningLocked(user, false)) { 4327 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4328 } 4329 } 4330 } 4331 } finally { 4332 Binder.restoreCallingIdentity(callingId); 4333 } 4334 } 4335 4336 /* 4337 * The pkg name and app id have to be specified. 4338 */ 4339 @Override 4340 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4341 if (pkg == null) { 4342 return; 4343 } 4344 // Make sure the uid is valid. 4345 if (appid < 0) { 4346 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4347 return; 4348 } 4349 int callerUid = Binder.getCallingUid(); 4350 // Only the system server can kill an application 4351 if (callerUid == Process.SYSTEM_UID) { 4352 // Post an aysnc message to kill the application 4353 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4354 msg.arg1 = appid; 4355 msg.arg2 = 0; 4356 Bundle bundle = new Bundle(); 4357 bundle.putString("pkg", pkg); 4358 bundle.putString("reason", reason); 4359 msg.obj = bundle; 4360 mHandler.sendMessage(msg); 4361 } else { 4362 throw new SecurityException(callerUid + " cannot kill pkg: " + 4363 pkg); 4364 } 4365 } 4366 4367 @Override 4368 public void closeSystemDialogs(String reason) { 4369 enforceNotIsolatedCaller("closeSystemDialogs"); 4370 4371 final int pid = Binder.getCallingPid(); 4372 final int uid = Binder.getCallingUid(); 4373 final long origId = Binder.clearCallingIdentity(); 4374 try { 4375 synchronized (this) { 4376 // Only allow this from foreground processes, so that background 4377 // applications can't abuse it to prevent system UI from being shown. 4378 if (uid >= Process.FIRST_APPLICATION_UID) { 4379 ProcessRecord proc; 4380 synchronized (mPidsSelfLocked) { 4381 proc = mPidsSelfLocked.get(pid); 4382 } 4383 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4384 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4385 + " from background process " + proc); 4386 return; 4387 } 4388 } 4389 closeSystemDialogsLocked(reason); 4390 } 4391 } finally { 4392 Binder.restoreCallingIdentity(origId); 4393 } 4394 } 4395 4396 void closeSystemDialogsLocked(String reason) { 4397 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4398 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4399 | Intent.FLAG_RECEIVER_FOREGROUND); 4400 if (reason != null) { 4401 intent.putExtra("reason", reason); 4402 } 4403 mWindowManager.closeSystemDialogs(reason); 4404 4405 mStackSupervisor.closeSystemDialogsLocked(); 4406 4407 broadcastIntentLocked(null, null, intent, null, 4408 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4409 Process.SYSTEM_UID, UserHandle.USER_ALL); 4410 } 4411 4412 @Override 4413 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4414 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4415 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4416 for (int i=pids.length-1; i>=0; i--) { 4417 ProcessRecord proc; 4418 int oomAdj; 4419 synchronized (this) { 4420 synchronized (mPidsSelfLocked) { 4421 proc = mPidsSelfLocked.get(pids[i]); 4422 oomAdj = proc != null ? proc.setAdj : 0; 4423 } 4424 } 4425 infos[i] = new Debug.MemoryInfo(); 4426 Debug.getMemoryInfo(pids[i], infos[i]); 4427 if (proc != null) { 4428 synchronized (this) { 4429 if (proc.thread != null && proc.setAdj == oomAdj) { 4430 // Record this for posterity if the process has been stable. 4431 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4432 infos[i].getTotalUss(), false, proc.pkgList); 4433 } 4434 } 4435 } 4436 } 4437 return infos; 4438 } 4439 4440 @Override 4441 public long[] getProcessPss(int[] pids) { 4442 enforceNotIsolatedCaller("getProcessPss"); 4443 long[] pss = new long[pids.length]; 4444 for (int i=pids.length-1; i>=0; i--) { 4445 ProcessRecord proc; 4446 int oomAdj; 4447 synchronized (this) { 4448 synchronized (mPidsSelfLocked) { 4449 proc = mPidsSelfLocked.get(pids[i]); 4450 oomAdj = proc != null ? proc.setAdj : 0; 4451 } 4452 } 4453 long[] tmpUss = new long[1]; 4454 pss[i] = Debug.getPss(pids[i], tmpUss); 4455 if (proc != null) { 4456 synchronized (this) { 4457 if (proc.thread != null && proc.setAdj == oomAdj) { 4458 // Record this for posterity if the process has been stable. 4459 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4460 } 4461 } 4462 } 4463 } 4464 return pss; 4465 } 4466 4467 @Override 4468 public void killApplicationProcess(String processName, int uid) { 4469 if (processName == null) { 4470 return; 4471 } 4472 4473 int callerUid = Binder.getCallingUid(); 4474 // Only the system server can kill an application 4475 if (callerUid == Process.SYSTEM_UID) { 4476 synchronized (this) { 4477 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4478 if (app != null && app.thread != null) { 4479 try { 4480 app.thread.scheduleSuicide(); 4481 } catch (RemoteException e) { 4482 // If the other end already died, then our work here is done. 4483 } 4484 } else { 4485 Slog.w(TAG, "Process/uid not found attempting kill of " 4486 + processName + " / " + uid); 4487 } 4488 } 4489 } else { 4490 throw new SecurityException(callerUid + " cannot kill app process: " + 4491 processName); 4492 } 4493 } 4494 4495 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4496 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4497 false, true, false, false, UserHandle.getUserId(uid), reason); 4498 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4499 Uri.fromParts("package", packageName, null)); 4500 if (!mProcessesReady) { 4501 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4502 | Intent.FLAG_RECEIVER_FOREGROUND); 4503 } 4504 intent.putExtra(Intent.EXTRA_UID, uid); 4505 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4506 broadcastIntentLocked(null, null, intent, 4507 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4508 false, false, 4509 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4510 } 4511 4512 private void forceStopUserLocked(int userId, String reason) { 4513 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4514 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4515 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4516 | Intent.FLAG_RECEIVER_FOREGROUND); 4517 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4518 broadcastIntentLocked(null, null, intent, 4519 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4520 false, false, 4521 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4522 } 4523 4524 private final boolean killPackageProcessesLocked(String packageName, int appId, 4525 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4526 boolean doit, boolean evenPersistent, String reason) { 4527 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4528 4529 // Remove all processes this package may have touched: all with the 4530 // same UID (except for the system or root user), and all whose name 4531 // matches the package name. 4532 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4533 final int NP = mProcessNames.getMap().size(); 4534 for (int ip=0; ip<NP; ip++) { 4535 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4536 final int NA = apps.size(); 4537 for (int ia=0; ia<NA; ia++) { 4538 ProcessRecord app = apps.valueAt(ia); 4539 if (app.persistent && !evenPersistent) { 4540 // we don't kill persistent processes 4541 continue; 4542 } 4543 if (app.removed) { 4544 if (doit) { 4545 procs.add(app); 4546 } 4547 continue; 4548 } 4549 4550 // Skip process if it doesn't meet our oom adj requirement. 4551 if (app.setAdj < minOomAdj) { 4552 continue; 4553 } 4554 4555 // If no package is specified, we call all processes under the 4556 // give user id. 4557 if (packageName == null) { 4558 if (app.userId != userId) { 4559 continue; 4560 } 4561 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4562 continue; 4563 } 4564 // Package has been specified, we want to hit all processes 4565 // that match it. We need to qualify this by the processes 4566 // that are running under the specified app and user ID. 4567 } else { 4568 if (UserHandle.getAppId(app.uid) != appId) { 4569 continue; 4570 } 4571 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4572 continue; 4573 } 4574 if (!app.pkgList.containsKey(packageName)) { 4575 continue; 4576 } 4577 } 4578 4579 // Process has passed all conditions, kill it! 4580 if (!doit) { 4581 return true; 4582 } 4583 app.removed = true; 4584 procs.add(app); 4585 } 4586 } 4587 4588 int N = procs.size(); 4589 for (int i=0; i<N; i++) { 4590 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4591 } 4592 updateOomAdjLocked(); 4593 return N > 0; 4594 } 4595 4596 private final boolean forceStopPackageLocked(String name, int appId, 4597 boolean callerWillRestart, boolean purgeCache, boolean doit, 4598 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4599 int i; 4600 int N; 4601 4602 if (userId == UserHandle.USER_ALL && name == null) { 4603 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4604 } 4605 4606 if (appId < 0 && name != null) { 4607 try { 4608 appId = UserHandle.getAppId( 4609 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4610 } catch (RemoteException e) { 4611 } 4612 } 4613 4614 if (doit) { 4615 if (name != null) { 4616 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4617 + " user=" + userId + ": " + reason); 4618 } else { 4619 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4620 } 4621 4622 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4623 for (int ip=pmap.size()-1; ip>=0; ip--) { 4624 SparseArray<Long> ba = pmap.valueAt(ip); 4625 for (i=ba.size()-1; i>=0; i--) { 4626 boolean remove = false; 4627 final int entUid = ba.keyAt(i); 4628 if (name != null) { 4629 if (userId == UserHandle.USER_ALL) { 4630 if (UserHandle.getAppId(entUid) == appId) { 4631 remove = true; 4632 } 4633 } else { 4634 if (entUid == UserHandle.getUid(userId, appId)) { 4635 remove = true; 4636 } 4637 } 4638 } else if (UserHandle.getUserId(entUid) == userId) { 4639 remove = true; 4640 } 4641 if (remove) { 4642 ba.removeAt(i); 4643 } 4644 } 4645 if (ba.size() == 0) { 4646 pmap.removeAt(ip); 4647 } 4648 } 4649 } 4650 4651 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4652 -100, callerWillRestart, true, doit, evenPersistent, 4653 name == null ? ("stop user " + userId) : ("stop " + name)); 4654 4655 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4656 if (!doit) { 4657 return true; 4658 } 4659 didSomething = true; 4660 } 4661 4662 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4663 if (!doit) { 4664 return true; 4665 } 4666 didSomething = true; 4667 } 4668 4669 if (name == null) { 4670 // Remove all sticky broadcasts from this user. 4671 mStickyBroadcasts.remove(userId); 4672 } 4673 4674 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4675 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4676 userId, providers)) { 4677 if (!doit) { 4678 return true; 4679 } 4680 didSomething = true; 4681 } 4682 N = providers.size(); 4683 for (i=0; i<N; i++) { 4684 removeDyingProviderLocked(null, providers.get(i), true); 4685 } 4686 4687 // Remove transient permissions granted from/to this package/user 4688 removeUriPermissionsForPackageLocked(name, userId, false); 4689 4690 if (name == null || uninstalling) { 4691 // Remove pending intents. For now we only do this when force 4692 // stopping users, because we have some problems when doing this 4693 // for packages -- app widgets are not currently cleaned up for 4694 // such packages, so they can be left with bad pending intents. 4695 if (mIntentSenderRecords.size() > 0) { 4696 Iterator<WeakReference<PendingIntentRecord>> it 4697 = mIntentSenderRecords.values().iterator(); 4698 while (it.hasNext()) { 4699 WeakReference<PendingIntentRecord> wpir = it.next(); 4700 if (wpir == null) { 4701 it.remove(); 4702 continue; 4703 } 4704 PendingIntentRecord pir = wpir.get(); 4705 if (pir == null) { 4706 it.remove(); 4707 continue; 4708 } 4709 if (name == null) { 4710 // Stopping user, remove all objects for the user. 4711 if (pir.key.userId != userId) { 4712 // Not the same user, skip it. 4713 continue; 4714 } 4715 } else { 4716 if (UserHandle.getAppId(pir.uid) != appId) { 4717 // Different app id, skip it. 4718 continue; 4719 } 4720 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4721 // Different user, skip it. 4722 continue; 4723 } 4724 if (!pir.key.packageName.equals(name)) { 4725 // Different package, skip it. 4726 continue; 4727 } 4728 } 4729 if (!doit) { 4730 return true; 4731 } 4732 didSomething = true; 4733 it.remove(); 4734 pir.canceled = true; 4735 if (pir.key.activity != null) { 4736 pir.key.activity.pendingResults.remove(pir.ref); 4737 } 4738 } 4739 } 4740 } 4741 4742 if (doit) { 4743 if (purgeCache && name != null) { 4744 AttributeCache ac = AttributeCache.instance(); 4745 if (ac != null) { 4746 ac.removePackage(name); 4747 } 4748 } 4749 if (mBooted) { 4750 mStackSupervisor.resumeTopActivitiesLocked(); 4751 mStackSupervisor.scheduleIdleLocked(); 4752 } 4753 } 4754 4755 return didSomething; 4756 } 4757 4758 private final boolean removeProcessLocked(ProcessRecord app, 4759 boolean callerWillRestart, boolean allowRestart, String reason) { 4760 final String name = app.processName; 4761 final int uid = app.uid; 4762 if (DEBUG_PROCESSES) Slog.d( 4763 TAG, "Force removing proc " + app.toShortString() + " (" + name 4764 + "/" + uid + ")"); 4765 4766 mProcessNames.remove(name, uid); 4767 mIsolatedProcesses.remove(app.uid); 4768 if (mHeavyWeightProcess == app) { 4769 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4770 mHeavyWeightProcess.userId, 0)); 4771 mHeavyWeightProcess = null; 4772 } 4773 boolean needRestart = false; 4774 if (app.pid > 0 && app.pid != MY_PID) { 4775 int pid = app.pid; 4776 synchronized (mPidsSelfLocked) { 4777 mPidsSelfLocked.remove(pid); 4778 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4779 } 4780 killUnneededProcessLocked(app, reason); 4781 handleAppDiedLocked(app, true, allowRestart); 4782 removeLruProcessLocked(app); 4783 4784 if (app.persistent && !app.isolated) { 4785 if (!callerWillRestart) { 4786 addAppLocked(app.info, false); 4787 } else { 4788 needRestart = true; 4789 } 4790 } 4791 } else { 4792 mRemovedProcesses.add(app); 4793 } 4794 4795 return needRestart; 4796 } 4797 4798 private final void processStartTimedOutLocked(ProcessRecord app) { 4799 final int pid = app.pid; 4800 boolean gone = false; 4801 synchronized (mPidsSelfLocked) { 4802 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4803 if (knownApp != null && knownApp.thread == null) { 4804 mPidsSelfLocked.remove(pid); 4805 gone = true; 4806 } 4807 } 4808 4809 if (gone) { 4810 Slog.w(TAG, "Process " + app + " failed to attach"); 4811 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4812 pid, app.uid, app.processName); 4813 mProcessNames.remove(app.processName, app.uid); 4814 mIsolatedProcesses.remove(app.uid); 4815 if (mHeavyWeightProcess == app) { 4816 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4817 mHeavyWeightProcess.userId, 0)); 4818 mHeavyWeightProcess = null; 4819 } 4820 // Take care of any launching providers waiting for this process. 4821 checkAppInLaunchingProvidersLocked(app, true); 4822 // Take care of any services that are waiting for the process. 4823 mServices.processStartTimedOutLocked(app); 4824 killUnneededProcessLocked(app, "start timeout"); 4825 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4826 Slog.w(TAG, "Unattached app died before backup, skipping"); 4827 try { 4828 IBackupManager bm = IBackupManager.Stub.asInterface( 4829 ServiceManager.getService(Context.BACKUP_SERVICE)); 4830 bm.agentDisconnected(app.info.packageName); 4831 } catch (RemoteException e) { 4832 // Can't happen; the backup manager is local 4833 } 4834 } 4835 if (isPendingBroadcastProcessLocked(pid)) { 4836 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4837 skipPendingBroadcastLocked(pid); 4838 } 4839 } else { 4840 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4841 } 4842 } 4843 4844 private final boolean attachApplicationLocked(IApplicationThread thread, 4845 int pid) { 4846 4847 // Find the application record that is being attached... either via 4848 // the pid if we are running in multiple processes, or just pull the 4849 // next app record if we are emulating process with anonymous threads. 4850 ProcessRecord app; 4851 if (pid != MY_PID && pid >= 0) { 4852 synchronized (mPidsSelfLocked) { 4853 app = mPidsSelfLocked.get(pid); 4854 } 4855 } else { 4856 app = null; 4857 } 4858 4859 if (app == null) { 4860 Slog.w(TAG, "No pending application record for pid " + pid 4861 + " (IApplicationThread " + thread + "); dropping process"); 4862 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4863 if (pid > 0 && pid != MY_PID) { 4864 Process.killProcessQuiet(pid); 4865 } else { 4866 try { 4867 thread.scheduleExit(); 4868 } catch (Exception e) { 4869 // Ignore exceptions. 4870 } 4871 } 4872 return false; 4873 } 4874 4875 // If this application record is still attached to a previous 4876 // process, clean it up now. 4877 if (app.thread != null) { 4878 handleAppDiedLocked(app, true, true); 4879 } 4880 4881 // Tell the process all about itself. 4882 4883 if (localLOGV) Slog.v( 4884 TAG, "Binding process pid " + pid + " to record " + app); 4885 4886 final String processName = app.processName; 4887 try { 4888 AppDeathRecipient adr = new AppDeathRecipient( 4889 app, pid, thread); 4890 thread.asBinder().linkToDeath(adr, 0); 4891 app.deathRecipient = adr; 4892 } catch (RemoteException e) { 4893 app.resetPackageList(mProcessStats); 4894 startProcessLocked(app, "link fail", processName); 4895 return false; 4896 } 4897 4898 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4899 4900 app.makeActive(thread, mProcessStats); 4901 app.curAdj = app.setAdj = -100; 4902 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4903 app.forcingToForeground = null; 4904 app.foregroundServices = false; 4905 app.hasShownUi = false; 4906 app.debugging = false; 4907 app.cached = false; 4908 4909 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4910 4911 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4912 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4913 4914 if (!normalMode) { 4915 Slog.i(TAG, "Launching preboot mode app: " + app); 4916 } 4917 4918 if (localLOGV) Slog.v( 4919 TAG, "New app record " + app 4920 + " thread=" + thread.asBinder() + " pid=" + pid); 4921 try { 4922 int testMode = IApplicationThread.DEBUG_OFF; 4923 if (mDebugApp != null && mDebugApp.equals(processName)) { 4924 testMode = mWaitForDebugger 4925 ? IApplicationThread.DEBUG_WAIT 4926 : IApplicationThread.DEBUG_ON; 4927 app.debugging = true; 4928 if (mDebugTransient) { 4929 mDebugApp = mOrigDebugApp; 4930 mWaitForDebugger = mOrigWaitForDebugger; 4931 } 4932 } 4933 String profileFile = app.instrumentationProfileFile; 4934 ParcelFileDescriptor profileFd = null; 4935 boolean profileAutoStop = false; 4936 if (mProfileApp != null && mProfileApp.equals(processName)) { 4937 mProfileProc = app; 4938 profileFile = mProfileFile; 4939 profileFd = mProfileFd; 4940 profileAutoStop = mAutoStopProfiler; 4941 } 4942 boolean enableOpenGlTrace = false; 4943 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4944 enableOpenGlTrace = true; 4945 mOpenGlTraceApp = null; 4946 } 4947 4948 // If the app is being launched for restore or full backup, set it up specially 4949 boolean isRestrictedBackupMode = false; 4950 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4951 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4952 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4953 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4954 } 4955 4956 ensurePackageDexOpt(app.instrumentationInfo != null 4957 ? app.instrumentationInfo.packageName 4958 : app.info.packageName); 4959 if (app.instrumentationClass != null) { 4960 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4961 } 4962 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4963 + processName + " with config " + mConfiguration); 4964 ApplicationInfo appInfo = app.instrumentationInfo != null 4965 ? app.instrumentationInfo : app.info; 4966 app.compat = compatibilityInfoForPackageLocked(appInfo); 4967 if (profileFd != null) { 4968 profileFd = profileFd.dup(); 4969 } 4970 thread.bindApplication(processName, appInfo, providers, 4971 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4972 app.instrumentationArguments, app.instrumentationWatcher, 4973 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4974 isRestrictedBackupMode || !normalMode, app.persistent, 4975 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4976 mCoreSettingsObserver.getCoreSettingsLocked()); 4977 updateLruProcessLocked(app, false, null); 4978 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4979 } catch (Exception e) { 4980 // todo: Yikes! What should we do? For now we will try to 4981 // start another process, but that could easily get us in 4982 // an infinite loop of restarting processes... 4983 Slog.w(TAG, "Exception thrown during bind!", e); 4984 4985 app.resetPackageList(mProcessStats); 4986 app.unlinkDeathRecipient(); 4987 startProcessLocked(app, "bind fail", processName); 4988 return false; 4989 } 4990 4991 // Remove this record from the list of starting applications. 4992 mPersistentStartingProcesses.remove(app); 4993 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4994 "Attach application locked removing on hold: " + app); 4995 mProcessesOnHold.remove(app); 4996 4997 boolean badApp = false; 4998 boolean didSomething = false; 4999 5000 // See if the top visible activity is waiting to run in this process... 5001 if (normalMode) { 5002 try { 5003 if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) { 5004 didSomething = true; 5005 } 5006 } catch (Exception e) { 5007 badApp = true; 5008 } 5009 } 5010 5011 // Find any services that should be running in this process... 5012 if (!badApp) { 5013 try { 5014 didSomething |= mServices.attachApplicationLocked(app, processName); 5015 } catch (Exception e) { 5016 badApp = true; 5017 } 5018 } 5019 5020 // Check if a next-broadcast receiver is in this process... 5021 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5022 try { 5023 didSomething |= sendPendingBroadcastsLocked(app); 5024 } catch (Exception e) { 5025 // If the app died trying to launch the receiver we declare it 'bad' 5026 badApp = true; 5027 } 5028 } 5029 5030 // Check whether the next backup agent is in this process... 5031 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5032 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5033 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5034 try { 5035 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5036 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5037 mBackupTarget.backupMode); 5038 } catch (Exception e) { 5039 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5040 e.printStackTrace(); 5041 } 5042 } 5043 5044 if (badApp) { 5045 // todo: Also need to kill application to deal with all 5046 // kinds of exceptions. 5047 handleAppDiedLocked(app, false, true); 5048 return false; 5049 } 5050 5051 if (!didSomething) { 5052 updateOomAdjLocked(); 5053 } 5054 5055 return true; 5056 } 5057 5058 @Override 5059 public final void attachApplication(IApplicationThread thread) { 5060 synchronized (this) { 5061 int callingPid = Binder.getCallingPid(); 5062 final long origId = Binder.clearCallingIdentity(); 5063 attachApplicationLocked(thread, callingPid); 5064 Binder.restoreCallingIdentity(origId); 5065 } 5066 } 5067 5068 @Override 5069 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5070 final long origId = Binder.clearCallingIdentity(); 5071 synchronized (this) { 5072 ActivityStack stack = ActivityRecord.getStackLocked(token); 5073 if (stack != null) { 5074 ActivityRecord r = 5075 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5076 if (stopProfiling) { 5077 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5078 try { 5079 mProfileFd.close(); 5080 } catch (IOException e) { 5081 } 5082 clearProfilerLocked(); 5083 } 5084 } 5085 } 5086 } 5087 Binder.restoreCallingIdentity(origId); 5088 } 5089 5090 void enableScreenAfterBoot() { 5091 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5092 SystemClock.uptimeMillis()); 5093 mWindowManager.enableScreenAfterBoot(); 5094 5095 synchronized (this) { 5096 updateEventDispatchingLocked(); 5097 } 5098 } 5099 5100 @Override 5101 public void showBootMessage(final CharSequence msg, final boolean always) { 5102 enforceNotIsolatedCaller("showBootMessage"); 5103 mWindowManager.showBootMessage(msg, always); 5104 } 5105 5106 @Override 5107 public void dismissKeyguardOnNextActivity() { 5108 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5109 final long token = Binder.clearCallingIdentity(); 5110 try { 5111 synchronized (this) { 5112 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5113 if (mLockScreenShown) { 5114 mLockScreenShown = false; 5115 comeOutOfSleepIfNeededLocked(); 5116 } 5117 mStackSupervisor.setDismissKeyguard(true); 5118 } 5119 } finally { 5120 Binder.restoreCallingIdentity(token); 5121 } 5122 } 5123 5124 final void finishBooting() { 5125 IntentFilter pkgFilter = new IntentFilter(); 5126 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5127 pkgFilter.addDataScheme("package"); 5128 mContext.registerReceiver(new BroadcastReceiver() { 5129 @Override 5130 public void onReceive(Context context, Intent intent) { 5131 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5132 if (pkgs != null) { 5133 for (String pkg : pkgs) { 5134 synchronized (ActivityManagerService.this) { 5135 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5136 "finished booting")) { 5137 setResultCode(Activity.RESULT_OK); 5138 return; 5139 } 5140 } 5141 } 5142 } 5143 } 5144 }, pkgFilter); 5145 5146 synchronized (this) { 5147 // Ensure that any processes we had put on hold are now started 5148 // up. 5149 final int NP = mProcessesOnHold.size(); 5150 if (NP > 0) { 5151 ArrayList<ProcessRecord> procs = 5152 new ArrayList<ProcessRecord>(mProcessesOnHold); 5153 for (int ip=0; ip<NP; ip++) { 5154 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5155 + procs.get(ip)); 5156 startProcessLocked(procs.get(ip), "on-hold", null); 5157 } 5158 } 5159 5160 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5161 // Start looking for apps that are abusing wake locks. 5162 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5163 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5164 // Tell anyone interested that we are done booting! 5165 SystemProperties.set("sys.boot_completed", "1"); 5166 SystemProperties.set("dev.bootcomplete", "1"); 5167 for (int i=0; i<mStartedUsers.size(); i++) { 5168 UserStartedState uss = mStartedUsers.valueAt(i); 5169 if (uss.mState == UserStartedState.STATE_BOOTING) { 5170 uss.mState = UserStartedState.STATE_RUNNING; 5171 final int userId = mStartedUsers.keyAt(i); 5172 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5173 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5174 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5175 broadcastIntentLocked(null, null, intent, null, 5176 new IIntentReceiver.Stub() { 5177 @Override 5178 public void performReceive(Intent intent, int resultCode, 5179 String data, Bundle extras, boolean ordered, 5180 boolean sticky, int sendingUser) { 5181 synchronized (ActivityManagerService.this) { 5182 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5183 true, false); 5184 } 5185 } 5186 }, 5187 0, null, null, 5188 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5189 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5190 userId); 5191 } 5192 } 5193 } 5194 } 5195 } 5196 5197 final void ensureBootCompleted() { 5198 boolean booting; 5199 boolean enableScreen; 5200 synchronized (this) { 5201 booting = mBooting; 5202 mBooting = false; 5203 enableScreen = !mBooted; 5204 mBooted = true; 5205 } 5206 5207 if (booting) { 5208 finishBooting(); 5209 } 5210 5211 if (enableScreen) { 5212 enableScreenAfterBoot(); 5213 } 5214 } 5215 5216 @Override 5217 public final void activityResumed(IBinder token) { 5218 final long origId = Binder.clearCallingIdentity(); 5219 synchronized(this) { 5220 ActivityStack stack = ActivityRecord.getStackLocked(token); 5221 if (stack != null) { 5222 ActivityRecord.activityResumedLocked(token); 5223 } 5224 } 5225 Binder.restoreCallingIdentity(origId); 5226 } 5227 5228 @Override 5229 public final void activityPaused(IBinder token) { 5230 final long origId = Binder.clearCallingIdentity(); 5231 synchronized(this) { 5232 ActivityStack stack = ActivityRecord.getStackLocked(token); 5233 if (stack != null) { 5234 stack.activityPausedLocked(token, false); 5235 } 5236 } 5237 Binder.restoreCallingIdentity(origId); 5238 } 5239 5240 @Override 5241 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5242 CharSequence description) { 5243 if (localLOGV) Slog.v( 5244 TAG, "Activity stopped: token=" + token); 5245 5246 // Refuse possible leaked file descriptors 5247 if (icicle != null && icicle.hasFileDescriptors()) { 5248 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5249 } 5250 5251 ActivityRecord r = null; 5252 5253 final long origId = Binder.clearCallingIdentity(); 5254 5255 synchronized (this) { 5256 r = ActivityRecord.isInStackLocked(token); 5257 if (r != null) { 5258 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5259 } 5260 } 5261 5262 if (r != null) { 5263 sendPendingThumbnail(r, null, null, null, false); 5264 } 5265 5266 trimApplications(); 5267 5268 Binder.restoreCallingIdentity(origId); 5269 } 5270 5271 @Override 5272 public final void activityDestroyed(IBinder token) { 5273 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5274 synchronized (this) { 5275 ActivityStack stack = ActivityRecord.getStackLocked(token); 5276 if (stack != null) { 5277 stack.activityDestroyedLocked(token); 5278 } 5279 } 5280 } 5281 5282 @Override 5283 public String getCallingPackage(IBinder token) { 5284 synchronized (this) { 5285 ActivityRecord r = getCallingRecordLocked(token); 5286 return r != null ? r.info.packageName : null; 5287 } 5288 } 5289 5290 @Override 5291 public ComponentName getCallingActivity(IBinder token) { 5292 synchronized (this) { 5293 ActivityRecord r = getCallingRecordLocked(token); 5294 return r != null ? r.intent.getComponent() : null; 5295 } 5296 } 5297 5298 private ActivityRecord getCallingRecordLocked(IBinder token) { 5299 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5300 if (r == null) { 5301 return null; 5302 } 5303 return r.resultTo; 5304 } 5305 5306 @Override 5307 public ComponentName getActivityClassForToken(IBinder token) { 5308 synchronized(this) { 5309 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5310 if (r == null) { 5311 return null; 5312 } 5313 return r.intent.getComponent(); 5314 } 5315 } 5316 5317 @Override 5318 public String getPackageForToken(IBinder token) { 5319 synchronized(this) { 5320 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5321 if (r == null) { 5322 return null; 5323 } 5324 return r.packageName; 5325 } 5326 } 5327 5328 @Override 5329 public IIntentSender getIntentSender(int type, 5330 String packageName, IBinder token, String resultWho, 5331 int requestCode, Intent[] intents, String[] resolvedTypes, 5332 int flags, Bundle options, int userId) { 5333 enforceNotIsolatedCaller("getIntentSender"); 5334 // Refuse possible leaked file descriptors 5335 if (intents != null) { 5336 if (intents.length < 1) { 5337 throw new IllegalArgumentException("Intents array length must be >= 1"); 5338 } 5339 for (int i=0; i<intents.length; i++) { 5340 Intent intent = intents[i]; 5341 if (intent != null) { 5342 if (intent.hasFileDescriptors()) { 5343 throw new IllegalArgumentException("File descriptors passed in Intent"); 5344 } 5345 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5346 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5347 throw new IllegalArgumentException( 5348 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5349 } 5350 intents[i] = new Intent(intent); 5351 } 5352 } 5353 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5354 throw new IllegalArgumentException( 5355 "Intent array length does not match resolvedTypes length"); 5356 } 5357 } 5358 if (options != null) { 5359 if (options.hasFileDescriptors()) { 5360 throw new IllegalArgumentException("File descriptors passed in options"); 5361 } 5362 } 5363 5364 synchronized(this) { 5365 int callingUid = Binder.getCallingUid(); 5366 int origUserId = userId; 5367 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5368 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5369 "getIntentSender", null); 5370 if (origUserId == UserHandle.USER_CURRENT) { 5371 // We don't want to evaluate this until the pending intent is 5372 // actually executed. However, we do want to always do the 5373 // security checking for it above. 5374 userId = UserHandle.USER_CURRENT; 5375 } 5376 try { 5377 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5378 int uid = AppGlobals.getPackageManager() 5379 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5380 if (!UserHandle.isSameApp(callingUid, uid)) { 5381 String msg = "Permission Denial: getIntentSender() from pid=" 5382 + Binder.getCallingPid() 5383 + ", uid=" + Binder.getCallingUid() 5384 + ", (need uid=" + uid + ")" 5385 + " is not allowed to send as package " + packageName; 5386 Slog.w(TAG, msg); 5387 throw new SecurityException(msg); 5388 } 5389 } 5390 5391 return getIntentSenderLocked(type, packageName, callingUid, userId, 5392 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5393 5394 } catch (RemoteException e) { 5395 throw new SecurityException(e); 5396 } 5397 } 5398 } 5399 5400 IIntentSender getIntentSenderLocked(int type, String packageName, 5401 int callingUid, int userId, IBinder token, String resultWho, 5402 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5403 Bundle options) { 5404 if (DEBUG_MU) 5405 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5406 ActivityRecord activity = null; 5407 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5408 activity = ActivityRecord.isInStackLocked(token); 5409 if (activity == null) { 5410 return null; 5411 } 5412 if (activity.finishing) { 5413 return null; 5414 } 5415 } 5416 5417 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5418 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5419 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5420 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5421 |PendingIntent.FLAG_UPDATE_CURRENT); 5422 5423 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5424 type, packageName, activity, resultWho, 5425 requestCode, intents, resolvedTypes, flags, options, userId); 5426 WeakReference<PendingIntentRecord> ref; 5427 ref = mIntentSenderRecords.get(key); 5428 PendingIntentRecord rec = ref != null ? ref.get() : null; 5429 if (rec != null) { 5430 if (!cancelCurrent) { 5431 if (updateCurrent) { 5432 if (rec.key.requestIntent != null) { 5433 rec.key.requestIntent.replaceExtras(intents != null ? 5434 intents[intents.length - 1] : null); 5435 } 5436 if (intents != null) { 5437 intents[intents.length-1] = rec.key.requestIntent; 5438 rec.key.allIntents = intents; 5439 rec.key.allResolvedTypes = resolvedTypes; 5440 } else { 5441 rec.key.allIntents = null; 5442 rec.key.allResolvedTypes = null; 5443 } 5444 } 5445 return rec; 5446 } 5447 rec.canceled = true; 5448 mIntentSenderRecords.remove(key); 5449 } 5450 if (noCreate) { 5451 return rec; 5452 } 5453 rec = new PendingIntentRecord(this, key, callingUid); 5454 mIntentSenderRecords.put(key, rec.ref); 5455 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5456 if (activity.pendingResults == null) { 5457 activity.pendingResults 5458 = new HashSet<WeakReference<PendingIntentRecord>>(); 5459 } 5460 activity.pendingResults.add(rec.ref); 5461 } 5462 return rec; 5463 } 5464 5465 @Override 5466 public void cancelIntentSender(IIntentSender sender) { 5467 if (!(sender instanceof PendingIntentRecord)) { 5468 return; 5469 } 5470 synchronized(this) { 5471 PendingIntentRecord rec = (PendingIntentRecord)sender; 5472 try { 5473 int uid = AppGlobals.getPackageManager() 5474 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5475 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5476 String msg = "Permission Denial: cancelIntentSender() from pid=" 5477 + Binder.getCallingPid() 5478 + ", uid=" + Binder.getCallingUid() 5479 + " is not allowed to cancel packges " 5480 + rec.key.packageName; 5481 Slog.w(TAG, msg); 5482 throw new SecurityException(msg); 5483 } 5484 } catch (RemoteException e) { 5485 throw new SecurityException(e); 5486 } 5487 cancelIntentSenderLocked(rec, true); 5488 } 5489 } 5490 5491 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5492 rec.canceled = true; 5493 mIntentSenderRecords.remove(rec.key); 5494 if (cleanActivity && rec.key.activity != null) { 5495 rec.key.activity.pendingResults.remove(rec.ref); 5496 } 5497 } 5498 5499 @Override 5500 public String getPackageForIntentSender(IIntentSender pendingResult) { 5501 if (!(pendingResult instanceof PendingIntentRecord)) { 5502 return null; 5503 } 5504 try { 5505 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5506 return res.key.packageName; 5507 } catch (ClassCastException e) { 5508 } 5509 return null; 5510 } 5511 5512 @Override 5513 public int getUidForIntentSender(IIntentSender sender) { 5514 if (sender instanceof PendingIntentRecord) { 5515 try { 5516 PendingIntentRecord res = (PendingIntentRecord)sender; 5517 return res.uid; 5518 } catch (ClassCastException e) { 5519 } 5520 } 5521 return -1; 5522 } 5523 5524 @Override 5525 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5526 if (!(pendingResult instanceof PendingIntentRecord)) { 5527 return false; 5528 } 5529 try { 5530 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5531 if (res.key.allIntents == null) { 5532 return false; 5533 } 5534 for (int i=0; i<res.key.allIntents.length; i++) { 5535 Intent intent = res.key.allIntents[i]; 5536 if (intent.getPackage() != null && intent.getComponent() != null) { 5537 return false; 5538 } 5539 } 5540 return true; 5541 } catch (ClassCastException e) { 5542 } 5543 return false; 5544 } 5545 5546 @Override 5547 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5548 if (!(pendingResult instanceof PendingIntentRecord)) { 5549 return false; 5550 } 5551 try { 5552 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5553 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5554 return true; 5555 } 5556 return false; 5557 } catch (ClassCastException e) { 5558 } 5559 return false; 5560 } 5561 5562 @Override 5563 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5564 if (!(pendingResult instanceof PendingIntentRecord)) { 5565 return null; 5566 } 5567 try { 5568 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5569 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5570 } catch (ClassCastException e) { 5571 } 5572 return null; 5573 } 5574 5575 @Override 5576 public void setProcessLimit(int max) { 5577 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5578 "setProcessLimit()"); 5579 synchronized (this) { 5580 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5581 mProcessLimitOverride = max; 5582 } 5583 trimApplications(); 5584 } 5585 5586 @Override 5587 public int getProcessLimit() { 5588 synchronized (this) { 5589 return mProcessLimitOverride; 5590 } 5591 } 5592 5593 void foregroundTokenDied(ForegroundToken token) { 5594 synchronized (ActivityManagerService.this) { 5595 synchronized (mPidsSelfLocked) { 5596 ForegroundToken cur 5597 = mForegroundProcesses.get(token.pid); 5598 if (cur != token) { 5599 return; 5600 } 5601 mForegroundProcesses.remove(token.pid); 5602 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5603 if (pr == null) { 5604 return; 5605 } 5606 pr.forcingToForeground = null; 5607 pr.foregroundServices = false; 5608 } 5609 updateOomAdjLocked(); 5610 } 5611 } 5612 5613 @Override 5614 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5615 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5616 "setProcessForeground()"); 5617 synchronized(this) { 5618 boolean changed = false; 5619 5620 synchronized (mPidsSelfLocked) { 5621 ProcessRecord pr = mPidsSelfLocked.get(pid); 5622 if (pr == null && isForeground) { 5623 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5624 return; 5625 } 5626 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5627 if (oldToken != null) { 5628 oldToken.token.unlinkToDeath(oldToken, 0); 5629 mForegroundProcesses.remove(pid); 5630 if (pr != null) { 5631 pr.forcingToForeground = null; 5632 } 5633 changed = true; 5634 } 5635 if (isForeground && token != null) { 5636 ForegroundToken newToken = new ForegroundToken() { 5637 @Override 5638 public void binderDied() { 5639 foregroundTokenDied(this); 5640 } 5641 }; 5642 newToken.pid = pid; 5643 newToken.token = token; 5644 try { 5645 token.linkToDeath(newToken, 0); 5646 mForegroundProcesses.put(pid, newToken); 5647 pr.forcingToForeground = token; 5648 changed = true; 5649 } catch (RemoteException e) { 5650 // If the process died while doing this, we will later 5651 // do the cleanup with the process death link. 5652 } 5653 } 5654 } 5655 5656 if (changed) { 5657 updateOomAdjLocked(); 5658 } 5659 } 5660 } 5661 5662 // ========================================================= 5663 // PERMISSIONS 5664 // ========================================================= 5665 5666 static class PermissionController extends IPermissionController.Stub { 5667 ActivityManagerService mActivityManagerService; 5668 PermissionController(ActivityManagerService activityManagerService) { 5669 mActivityManagerService = activityManagerService; 5670 } 5671 5672 @Override 5673 public boolean checkPermission(String permission, int pid, int uid) { 5674 return mActivityManagerService.checkPermission(permission, pid, 5675 uid) == PackageManager.PERMISSION_GRANTED; 5676 } 5677 } 5678 5679 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5680 @Override 5681 public int checkComponentPermission(String permission, int pid, int uid, 5682 int owningUid, boolean exported) { 5683 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5684 owningUid, exported); 5685 } 5686 5687 @Override 5688 public Object getAMSLock() { 5689 return ActivityManagerService.this; 5690 } 5691 } 5692 5693 /** 5694 * This can be called with or without the global lock held. 5695 */ 5696 int checkComponentPermission(String permission, int pid, int uid, 5697 int owningUid, boolean exported) { 5698 // We might be performing an operation on behalf of an indirect binder 5699 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5700 // client identity accordingly before proceeding. 5701 Identity tlsIdentity = sCallerIdentity.get(); 5702 if (tlsIdentity != null) { 5703 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5704 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5705 uid = tlsIdentity.uid; 5706 pid = tlsIdentity.pid; 5707 } 5708 5709 if (pid == MY_PID) { 5710 return PackageManager.PERMISSION_GRANTED; 5711 } 5712 5713 return ActivityManager.checkComponentPermission(permission, uid, 5714 owningUid, exported); 5715 } 5716 5717 /** 5718 * As the only public entry point for permissions checking, this method 5719 * can enforce the semantic that requesting a check on a null global 5720 * permission is automatically denied. (Internally a null permission 5721 * string is used when calling {@link #checkComponentPermission} in cases 5722 * when only uid-based security is needed.) 5723 * 5724 * This can be called with or without the global lock held. 5725 */ 5726 @Override 5727 public int checkPermission(String permission, int pid, int uid) { 5728 if (permission == null) { 5729 return PackageManager.PERMISSION_DENIED; 5730 } 5731 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5732 } 5733 5734 /** 5735 * Binder IPC calls go through the public entry point. 5736 * This can be called with or without the global lock held. 5737 */ 5738 int checkCallingPermission(String permission) { 5739 return checkPermission(permission, 5740 Binder.getCallingPid(), 5741 UserHandle.getAppId(Binder.getCallingUid())); 5742 } 5743 5744 /** 5745 * This can be called with or without the global lock held. 5746 */ 5747 void enforceCallingPermission(String permission, String func) { 5748 if (checkCallingPermission(permission) 5749 == PackageManager.PERMISSION_GRANTED) { 5750 return; 5751 } 5752 5753 String msg = "Permission Denial: " + func + " from pid=" 5754 + Binder.getCallingPid() 5755 + ", uid=" + Binder.getCallingUid() 5756 + " requires " + permission; 5757 Slog.w(TAG, msg); 5758 throw new SecurityException(msg); 5759 } 5760 5761 /** 5762 * Determine if UID is holding permissions required to access {@link Uri} in 5763 * the given {@link ProviderInfo}. Final permission checking is always done 5764 * in {@link ContentProvider}. 5765 */ 5766 private final boolean checkHoldingPermissionsLocked( 5767 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5768 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5769 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5770 5771 if (pi.applicationInfo.uid == uid) { 5772 return true; 5773 } else if (!pi.exported) { 5774 return false; 5775 } 5776 5777 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5778 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5779 try { 5780 // check if target holds top-level <provider> permissions 5781 if (!readMet && pi.readPermission != null 5782 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5783 readMet = true; 5784 } 5785 if (!writeMet && pi.writePermission != null 5786 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5787 writeMet = true; 5788 } 5789 5790 // track if unprotected read/write is allowed; any denied 5791 // <path-permission> below removes this ability 5792 boolean allowDefaultRead = pi.readPermission == null; 5793 boolean allowDefaultWrite = pi.writePermission == null; 5794 5795 // check if target holds any <path-permission> that match uri 5796 final PathPermission[] pps = pi.pathPermissions; 5797 if (pps != null) { 5798 final String path = uri.getPath(); 5799 int i = pps.length; 5800 while (i > 0 && (!readMet || !writeMet)) { 5801 i--; 5802 PathPermission pp = pps[i]; 5803 if (pp.match(path)) { 5804 if (!readMet) { 5805 final String pprperm = pp.getReadPermission(); 5806 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5807 + pprperm + " for " + pp.getPath() 5808 + ": match=" + pp.match(path) 5809 + " check=" + pm.checkUidPermission(pprperm, uid)); 5810 if (pprperm != null) { 5811 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5812 readMet = true; 5813 } else { 5814 allowDefaultRead = false; 5815 } 5816 } 5817 } 5818 if (!writeMet) { 5819 final String ppwperm = pp.getWritePermission(); 5820 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5821 + ppwperm + " for " + pp.getPath() 5822 + ": match=" + pp.match(path) 5823 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5824 if (ppwperm != null) { 5825 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5826 writeMet = true; 5827 } else { 5828 allowDefaultWrite = false; 5829 } 5830 } 5831 } 5832 } 5833 } 5834 } 5835 5836 // grant unprotected <provider> read/write, if not blocked by 5837 // <path-permission> above 5838 if (allowDefaultRead) readMet = true; 5839 if (allowDefaultWrite) writeMet = true; 5840 5841 } catch (RemoteException e) { 5842 return false; 5843 } 5844 5845 return readMet && writeMet; 5846 } 5847 5848 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5849 ProviderInfo pi = null; 5850 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5851 if (cpr != null) { 5852 pi = cpr.info; 5853 } else { 5854 try { 5855 pi = AppGlobals.getPackageManager().resolveContentProvider( 5856 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5857 } catch (RemoteException ex) { 5858 } 5859 } 5860 return pi; 5861 } 5862 5863 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5864 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5865 if (targetUris != null) { 5866 return targetUris.get(uri); 5867 } else { 5868 return null; 5869 } 5870 } 5871 5872 private UriPermission findOrCreateUriPermissionLocked( 5873 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5874 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5875 if (targetUris == null) { 5876 targetUris = Maps.newArrayMap(); 5877 mGrantedUriPermissions.put(targetUid, targetUris); 5878 } 5879 5880 UriPermission perm = targetUris.get(uri); 5881 if (perm == null) { 5882 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5883 targetUris.put(uri, perm); 5884 } 5885 5886 return perm; 5887 } 5888 5889 private final boolean checkUriPermissionLocked( 5890 Uri uri, int uid, int modeFlags, int minStrength) { 5891 // Root gets to do everything. 5892 if (uid == 0) { 5893 return true; 5894 } 5895 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5896 if (perms == null) return false; 5897 UriPermission perm = perms.get(uri); 5898 if (perm == null) return false; 5899 return perm.getStrength(modeFlags) >= minStrength; 5900 } 5901 5902 @Override 5903 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5904 enforceNotIsolatedCaller("checkUriPermission"); 5905 5906 // Another redirected-binder-call permissions check as in 5907 // {@link checkComponentPermission}. 5908 Identity tlsIdentity = sCallerIdentity.get(); 5909 if (tlsIdentity != null) { 5910 uid = tlsIdentity.uid; 5911 pid = tlsIdentity.pid; 5912 } 5913 5914 // Our own process gets to do everything. 5915 if (pid == MY_PID) { 5916 return PackageManager.PERMISSION_GRANTED; 5917 } 5918 synchronized(this) { 5919 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5920 ? PackageManager.PERMISSION_GRANTED 5921 : PackageManager.PERMISSION_DENIED; 5922 } 5923 } 5924 5925 /** 5926 * Check if the targetPkg can be granted permission to access uri by 5927 * the callingUid using the given modeFlags. Throws a security exception 5928 * if callingUid is not allowed to do this. Returns the uid of the target 5929 * if the URI permission grant should be performed; returns -1 if it is not 5930 * needed (for example targetPkg already has permission to access the URI). 5931 * If you already know the uid of the target, you can supply it in 5932 * lastTargetUid else set that to -1. 5933 */ 5934 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5935 Uri uri, int modeFlags, int lastTargetUid) { 5936 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5937 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5938 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5939 if (modeFlags == 0) { 5940 return -1; 5941 } 5942 5943 if (targetPkg != null) { 5944 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5945 "Checking grant " + targetPkg + " permission to " + uri); 5946 } 5947 5948 final IPackageManager pm = AppGlobals.getPackageManager(); 5949 5950 // If this is not a content: uri, we can't do anything with it. 5951 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5952 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5953 "Can't grant URI permission for non-content URI: " + uri); 5954 return -1; 5955 } 5956 5957 final String authority = uri.getAuthority(); 5958 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5959 if (pi == null) { 5960 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5961 return -1; 5962 } 5963 5964 int targetUid = lastTargetUid; 5965 if (targetUid < 0 && targetPkg != null) { 5966 try { 5967 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5968 if (targetUid < 0) { 5969 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5970 "Can't grant URI permission no uid for: " + targetPkg); 5971 return -1; 5972 } 5973 } catch (RemoteException ex) { 5974 return -1; 5975 } 5976 } 5977 5978 if (targetUid >= 0) { 5979 // First... does the target actually need this permission? 5980 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5981 // No need to grant the target this permission. 5982 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5983 "Target " + targetPkg + " already has full permission to " + uri); 5984 return -1; 5985 } 5986 } else { 5987 // First... there is no target package, so can anyone access it? 5988 boolean allowed = pi.exported; 5989 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5990 if (pi.readPermission != null) { 5991 allowed = false; 5992 } 5993 } 5994 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5995 if (pi.writePermission != null) { 5996 allowed = false; 5997 } 5998 } 5999 if (allowed) { 6000 return -1; 6001 } 6002 } 6003 6004 // Second... is the provider allowing granting of URI permissions? 6005 if (!pi.grantUriPermissions) { 6006 throw new SecurityException("Provider " + pi.packageName 6007 + "/" + pi.name 6008 + " does not allow granting of Uri permissions (uri " 6009 + uri + ")"); 6010 } 6011 if (pi.uriPermissionPatterns != null) { 6012 final int N = pi.uriPermissionPatterns.length; 6013 boolean allowed = false; 6014 for (int i=0; i<N; i++) { 6015 if (pi.uriPermissionPatterns[i] != null 6016 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6017 allowed = true; 6018 break; 6019 } 6020 } 6021 if (!allowed) { 6022 throw new SecurityException("Provider " + pi.packageName 6023 + "/" + pi.name 6024 + " does not allow granting of permission to path of Uri " 6025 + uri); 6026 } 6027 } 6028 6029 // Third... does the caller itself have permission to access 6030 // this uri? 6031 if (callingUid != Process.myUid()) { 6032 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6033 // Require they hold a strong enough Uri permission 6034 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6035 : UriPermission.STRENGTH_OWNED; 6036 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6037 throw new SecurityException("Uid " + callingUid 6038 + " does not have permission to uri " + uri); 6039 } 6040 } 6041 } 6042 6043 return targetUid; 6044 } 6045 6046 @Override 6047 public int checkGrantUriPermission(int callingUid, String targetPkg, 6048 Uri uri, int modeFlags) { 6049 enforceNotIsolatedCaller("checkGrantUriPermission"); 6050 synchronized(this) { 6051 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6052 } 6053 } 6054 6055 void grantUriPermissionUncheckedLocked( 6056 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6057 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6058 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6059 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6060 if (modeFlags == 0) { 6061 return; 6062 } 6063 6064 // So here we are: the caller has the assumed permission 6065 // to the uri, and the target doesn't. Let's now give this to 6066 // the target. 6067 6068 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6069 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6070 6071 final String authority = uri.getAuthority(); 6072 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6073 if (pi == null) { 6074 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6075 return; 6076 } 6077 6078 final UriPermission perm = findOrCreateUriPermissionLocked( 6079 pi.packageName, targetPkg, targetUid, uri); 6080 perm.grantModes(modeFlags, persistable, owner); 6081 } 6082 6083 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6084 int modeFlags, UriPermissionOwner owner) { 6085 if (targetPkg == null) { 6086 throw new NullPointerException("targetPkg"); 6087 } 6088 6089 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6090 if (targetUid < 0) { 6091 return; 6092 } 6093 6094 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6095 } 6096 6097 static class NeededUriGrants extends ArrayList<Uri> { 6098 final String targetPkg; 6099 final int targetUid; 6100 final int flags; 6101 6102 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6103 this.targetPkg = targetPkg; 6104 this.targetUid = targetUid; 6105 this.flags = flags; 6106 } 6107 } 6108 6109 /** 6110 * Like checkGrantUriPermissionLocked, but takes an Intent. 6111 */ 6112 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6113 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6114 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6115 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6116 + " clip=" + (intent != null ? intent.getClipData() : null) 6117 + " from " + intent + "; flags=0x" 6118 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6119 6120 if (targetPkg == null) { 6121 throw new NullPointerException("targetPkg"); 6122 } 6123 6124 if (intent == null) { 6125 return null; 6126 } 6127 Uri data = intent.getData(); 6128 ClipData clip = intent.getClipData(); 6129 if (data == null && clip == null) { 6130 return null; 6131 } 6132 6133 if (data != null) { 6134 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6135 mode, needed != null ? needed.targetUid : -1); 6136 if (targetUid > 0) { 6137 if (needed == null) { 6138 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6139 } 6140 needed.add(data); 6141 } 6142 } 6143 if (clip != null) { 6144 for (int i=0; i<clip.getItemCount(); i++) { 6145 Uri uri = clip.getItemAt(i).getUri(); 6146 if (uri != null) { 6147 int targetUid = -1; 6148 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6149 mode, needed != null ? needed.targetUid : -1); 6150 if (targetUid > 0) { 6151 if (needed == null) { 6152 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6153 } 6154 needed.add(uri); 6155 } 6156 } else { 6157 Intent clipIntent = clip.getItemAt(i).getIntent(); 6158 if (clipIntent != null) { 6159 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6160 callingUid, targetPkg, clipIntent, mode, needed); 6161 if (newNeeded != null) { 6162 needed = newNeeded; 6163 } 6164 } 6165 } 6166 } 6167 } 6168 6169 return needed; 6170 } 6171 6172 /** 6173 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6174 */ 6175 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6176 UriPermissionOwner owner) { 6177 if (needed != null) { 6178 for (int i=0; i<needed.size(); i++) { 6179 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6180 needed.get(i), needed.flags, owner); 6181 } 6182 } 6183 } 6184 6185 void grantUriPermissionFromIntentLocked(int callingUid, 6186 String targetPkg, Intent intent, UriPermissionOwner owner) { 6187 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6188 intent, intent != null ? intent.getFlags() : 0, null); 6189 if (needed == null) { 6190 return; 6191 } 6192 6193 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6194 } 6195 6196 @Override 6197 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6198 Uri uri, int modeFlags) { 6199 enforceNotIsolatedCaller("grantUriPermission"); 6200 synchronized(this) { 6201 final ProcessRecord r = getRecordForAppLocked(caller); 6202 if (r == null) { 6203 throw new SecurityException("Unable to find app for caller " 6204 + caller 6205 + " when granting permission to uri " + uri); 6206 } 6207 if (targetPkg == null) { 6208 throw new IllegalArgumentException("null target"); 6209 } 6210 if (uri == null) { 6211 throw new IllegalArgumentException("null uri"); 6212 } 6213 6214 // Persistable only supported through Intents 6215 Preconditions.checkFlagsArgument(modeFlags, 6216 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6217 6218 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6219 null); 6220 } 6221 } 6222 6223 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6224 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6225 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6226 ArrayMap<Uri, UriPermission> perms 6227 = mGrantedUriPermissions.get(perm.targetUid); 6228 if (perms != null) { 6229 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6230 "Removing " + perm.targetUid + " permission to " + perm.uri); 6231 perms.remove(perm.uri); 6232 if (perms.size() == 0) { 6233 mGrantedUriPermissions.remove(perm.targetUid); 6234 } 6235 } 6236 } 6237 } 6238 6239 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6240 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6241 6242 final IPackageManager pm = AppGlobals.getPackageManager(); 6243 final String authority = uri.getAuthority(); 6244 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6245 if (pi == null) { 6246 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6247 return; 6248 } 6249 6250 // Does the caller have this permission on the URI? 6251 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6252 // Right now, if you are not the original owner of the permission, 6253 // you are not allowed to revoke it. 6254 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6255 throw new SecurityException("Uid " + callingUid 6256 + " does not have permission to uri " + uri); 6257 //} 6258 } 6259 6260 boolean persistChanged = false; 6261 6262 // Go through all of the permissions and remove any that match. 6263 final List<String> SEGMENTS = uri.getPathSegments(); 6264 if (SEGMENTS != null) { 6265 final int NS = SEGMENTS.size(); 6266 int N = mGrantedUriPermissions.size(); 6267 for (int i=0; i<N; i++) { 6268 ArrayMap<Uri, UriPermission> perms 6269 = mGrantedUriPermissions.valueAt(i); 6270 Iterator<UriPermission> it = perms.values().iterator(); 6271 toploop: 6272 while (it.hasNext()) { 6273 UriPermission perm = it.next(); 6274 Uri targetUri = perm.uri; 6275 if (!authority.equals(targetUri.getAuthority())) { 6276 continue; 6277 } 6278 List<String> targetSegments = targetUri.getPathSegments(); 6279 if (targetSegments == null) { 6280 continue; 6281 } 6282 if (targetSegments.size() < NS) { 6283 continue; 6284 } 6285 for (int j=0; j<NS; j++) { 6286 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6287 continue toploop; 6288 } 6289 } 6290 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6291 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6292 persistChanged |= perm.clearModes(modeFlags, true); 6293 if (perm.modeFlags == 0) { 6294 it.remove(); 6295 } 6296 } 6297 if (perms.size() == 0) { 6298 mGrantedUriPermissions.remove( 6299 mGrantedUriPermissions.keyAt(i)); 6300 N--; 6301 i--; 6302 } 6303 } 6304 } 6305 6306 if (persistChanged) { 6307 schedulePersistUriGrants(); 6308 } 6309 } 6310 6311 @Override 6312 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6313 int modeFlags) { 6314 enforceNotIsolatedCaller("revokeUriPermission"); 6315 synchronized(this) { 6316 final ProcessRecord r = getRecordForAppLocked(caller); 6317 if (r == null) { 6318 throw new SecurityException("Unable to find app for caller " 6319 + caller 6320 + " when revoking permission to uri " + uri); 6321 } 6322 if (uri == null) { 6323 Slog.w(TAG, "revokeUriPermission: null uri"); 6324 return; 6325 } 6326 6327 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6328 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6329 if (modeFlags == 0) { 6330 return; 6331 } 6332 6333 final IPackageManager pm = AppGlobals.getPackageManager(); 6334 final String authority = uri.getAuthority(); 6335 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6336 if (pi == null) { 6337 Slog.w(TAG, "No content provider found for permission revoke: " 6338 + uri.toSafeString()); 6339 return; 6340 } 6341 6342 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6343 } 6344 } 6345 6346 /** 6347 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6348 * given package. 6349 * 6350 * @param packageName Package name to match, or {@code null} to apply to all 6351 * packages. 6352 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6353 * to all users. 6354 * @param persistable If persistable grants should be removed. 6355 */ 6356 private void removeUriPermissionsForPackageLocked( 6357 String packageName, int userHandle, boolean persistable) { 6358 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6359 throw new IllegalArgumentException("Must narrow by either package or user"); 6360 } 6361 6362 boolean persistChanged = false; 6363 6364 final int size = mGrantedUriPermissions.size(); 6365 for (int i = 0; i < size; i++) { 6366 // Only inspect grants matching user 6367 if (userHandle == UserHandle.USER_ALL 6368 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6369 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6370 .values().iterator(); 6371 while (it.hasNext()) { 6372 final UriPermission perm = it.next(); 6373 6374 // Only inspect grants matching package 6375 if (packageName == null || perm.sourcePkg.equals(packageName) 6376 || perm.targetPkg.equals(packageName)) { 6377 persistChanged |= perm.clearModes(~0, persistable); 6378 6379 // Only remove when no modes remain; any persisted grants 6380 // will keep this alive. 6381 if (perm.modeFlags == 0) { 6382 it.remove(); 6383 } 6384 } 6385 } 6386 } 6387 } 6388 6389 if (persistChanged) { 6390 schedulePersistUriGrants(); 6391 } 6392 } 6393 6394 @Override 6395 public IBinder newUriPermissionOwner(String name) { 6396 enforceNotIsolatedCaller("newUriPermissionOwner"); 6397 synchronized(this) { 6398 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6399 return owner.getExternalTokenLocked(); 6400 } 6401 } 6402 6403 @Override 6404 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6405 Uri uri, int modeFlags) { 6406 synchronized(this) { 6407 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6408 if (owner == null) { 6409 throw new IllegalArgumentException("Unknown owner: " + token); 6410 } 6411 if (fromUid != Binder.getCallingUid()) { 6412 if (Binder.getCallingUid() != Process.myUid()) { 6413 // Only system code can grant URI permissions on behalf 6414 // of other users. 6415 throw new SecurityException("nice try"); 6416 } 6417 } 6418 if (targetPkg == null) { 6419 throw new IllegalArgumentException("null target"); 6420 } 6421 if (uri == null) { 6422 throw new IllegalArgumentException("null uri"); 6423 } 6424 6425 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6426 } 6427 } 6428 6429 @Override 6430 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6431 synchronized(this) { 6432 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6433 if (owner == null) { 6434 throw new IllegalArgumentException("Unknown owner: " + token); 6435 } 6436 6437 if (uri == null) { 6438 owner.removeUriPermissionsLocked(mode); 6439 } else { 6440 owner.removeUriPermissionLocked(uri, mode); 6441 } 6442 } 6443 } 6444 6445 private void schedulePersistUriGrants() { 6446 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6447 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6448 10 * DateUtils.SECOND_IN_MILLIS); 6449 } 6450 } 6451 6452 private void writeGrantedUriPermissions() { 6453 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6454 6455 // Snapshot permissions so we can persist without lock 6456 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6457 synchronized (this) { 6458 final int size = mGrantedUriPermissions.size(); 6459 for (int i = 0 ; i < size; i++) { 6460 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6461 if (perm.persistedModeFlags != 0) { 6462 persist.add(perm.snapshot()); 6463 } 6464 } 6465 } 6466 } 6467 6468 FileOutputStream fos = null; 6469 try { 6470 fos = mGrantFile.startWrite(); 6471 6472 XmlSerializer out = new FastXmlSerializer(); 6473 out.setOutput(fos, "utf-8"); 6474 out.startDocument(null, true); 6475 out.startTag(null, TAG_URI_GRANTS); 6476 for (UriPermission.Snapshot perm : persist) { 6477 out.startTag(null, TAG_URI_GRANT); 6478 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6479 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6480 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6481 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6482 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6483 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6484 out.endTag(null, TAG_URI_GRANT); 6485 } 6486 out.endTag(null, TAG_URI_GRANTS); 6487 out.endDocument(); 6488 6489 mGrantFile.finishWrite(fos); 6490 } catch (IOException e) { 6491 if (fos != null) { 6492 mGrantFile.failWrite(fos); 6493 } 6494 } 6495 } 6496 6497 private void readGrantedUriPermissionsLocked() { 6498 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6499 6500 final long now = System.currentTimeMillis(); 6501 6502 FileInputStream fis = null; 6503 try { 6504 fis = mGrantFile.openRead(); 6505 final XmlPullParser in = Xml.newPullParser(); 6506 in.setInput(fis, null); 6507 6508 int type; 6509 while ((type = in.next()) != END_DOCUMENT) { 6510 final String tag = in.getName(); 6511 if (type == START_TAG) { 6512 if (TAG_URI_GRANT.equals(tag)) { 6513 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6514 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6515 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6516 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6517 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6518 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6519 6520 // Sanity check that provider still belongs to source package 6521 final ProviderInfo pi = getProviderInfoLocked( 6522 uri.getAuthority(), userHandle); 6523 if (pi != null && sourcePkg.equals(pi.packageName)) { 6524 int targetUid = -1; 6525 try { 6526 targetUid = AppGlobals.getPackageManager() 6527 .getPackageUid(targetPkg, userHandle); 6528 } catch (RemoteException e) { 6529 } 6530 if (targetUid != -1) { 6531 final UriPermission perm = findOrCreateUriPermissionLocked( 6532 sourcePkg, targetPkg, targetUid, uri); 6533 perm.initPersistedModes(modeFlags, createdTime); 6534 } 6535 } else { 6536 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6537 + " but instead found " + pi); 6538 } 6539 } 6540 } 6541 } 6542 } catch (FileNotFoundException e) { 6543 // Missing grants is okay 6544 } catch (IOException e) { 6545 Log.wtf(TAG, "Failed reading Uri grants", e); 6546 } catch (XmlPullParserException e) { 6547 Log.wtf(TAG, "Failed reading Uri grants", e); 6548 } finally { 6549 IoUtils.closeQuietly(fis); 6550 } 6551 } 6552 6553 @Override 6554 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6555 enforceNotIsolatedCaller("takePersistableUriPermission"); 6556 6557 Preconditions.checkFlagsArgument(modeFlags, 6558 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6559 6560 synchronized (this) { 6561 final int callingUid = Binder.getCallingUid(); 6562 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6563 if (perm == null) { 6564 throw new SecurityException("No permission grant found for UID " + callingUid 6565 + " and Uri " + uri.toSafeString()); 6566 } 6567 6568 boolean persistChanged = perm.takePersistableModes(modeFlags); 6569 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6570 6571 if (persistChanged) { 6572 schedulePersistUriGrants(); 6573 } 6574 } 6575 } 6576 6577 @Override 6578 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6579 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6580 6581 Preconditions.checkFlagsArgument(modeFlags, 6582 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6583 6584 synchronized (this) { 6585 final int callingUid = Binder.getCallingUid(); 6586 6587 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6588 if (perm == null) { 6589 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6590 + uri.toSafeString()); 6591 return; 6592 } 6593 6594 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6595 removeUriPermissionIfNeededLocked(perm); 6596 if (persistChanged) { 6597 schedulePersistUriGrants(); 6598 } 6599 } 6600 } 6601 6602 /** 6603 * Prune any older {@link UriPermission} for the given UID until outstanding 6604 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6605 * 6606 * @return if any mutations occured that require persisting. 6607 */ 6608 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6609 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6610 if (perms == null) return false; 6611 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6612 6613 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6614 for (UriPermission perm : perms.values()) { 6615 if (perm.persistedModeFlags != 0) { 6616 persisted.add(perm); 6617 } 6618 } 6619 6620 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6621 if (trimCount <= 0) return false; 6622 6623 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6624 for (int i = 0; i < trimCount; i++) { 6625 final UriPermission perm = persisted.get(i); 6626 6627 if (DEBUG_URI_PERMISSION) { 6628 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6629 } 6630 6631 perm.releasePersistableModes(~0); 6632 removeUriPermissionIfNeededLocked(perm); 6633 } 6634 6635 return true; 6636 } 6637 6638 @Override 6639 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6640 String packageName, boolean incoming) { 6641 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6642 Preconditions.checkNotNull(packageName, "packageName"); 6643 6644 final int callingUid = Binder.getCallingUid(); 6645 final IPackageManager pm = AppGlobals.getPackageManager(); 6646 try { 6647 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6648 if (packageUid != callingUid) { 6649 throw new SecurityException( 6650 "Package " + packageName + " does not belong to calling UID " + callingUid); 6651 } 6652 } catch (RemoteException e) { 6653 throw new SecurityException("Failed to verify package name ownership"); 6654 } 6655 6656 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6657 synchronized (this) { 6658 if (incoming) { 6659 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6660 if (perms == null) { 6661 Slog.w(TAG, "No permission grants found for " + packageName); 6662 } else { 6663 final int size = perms.size(); 6664 for (int i = 0; i < size; i++) { 6665 final UriPermission perm = perms.valueAt(i); 6666 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6667 result.add(perm.buildPersistedPublicApiObject()); 6668 } 6669 } 6670 } 6671 } else { 6672 final int size = mGrantedUriPermissions.size(); 6673 for (int i = 0; i < size; i++) { 6674 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6675 final int permsSize = perms.size(); 6676 for (int j = 0; j < permsSize; j++) { 6677 final UriPermission perm = perms.valueAt(j); 6678 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6679 result.add(perm.buildPersistedPublicApiObject()); 6680 } 6681 } 6682 } 6683 } 6684 } 6685 return new ParceledListSlice<android.content.UriPermission>(result); 6686 } 6687 6688 @Override 6689 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6690 synchronized (this) { 6691 ProcessRecord app = 6692 who != null ? getRecordForAppLocked(who) : null; 6693 if (app == null) return; 6694 6695 Message msg = Message.obtain(); 6696 msg.what = WAIT_FOR_DEBUGGER_MSG; 6697 msg.obj = app; 6698 msg.arg1 = waiting ? 1 : 0; 6699 mHandler.sendMessage(msg); 6700 } 6701 } 6702 6703 @Override 6704 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6705 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6706 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6707 outInfo.availMem = Process.getFreeMemory(); 6708 outInfo.totalMem = Process.getTotalMemory(); 6709 outInfo.threshold = homeAppMem; 6710 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6711 outInfo.hiddenAppThreshold = cachedAppMem; 6712 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6713 ProcessList.SERVICE_ADJ); 6714 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6715 ProcessList.VISIBLE_APP_ADJ); 6716 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6717 ProcessList.FOREGROUND_APP_ADJ); 6718 } 6719 6720 // ========================================================= 6721 // TASK MANAGEMENT 6722 // ========================================================= 6723 6724 @Override 6725 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6726 IThumbnailReceiver receiver) { 6727 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6728 6729 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6730 ActivityRecord topRecord = null; 6731 6732 synchronized(this) { 6733 if (localLOGV) Slog.v( 6734 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6735 + ", receiver=" + receiver); 6736 6737 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6738 != PackageManager.PERMISSION_GRANTED) { 6739 if (receiver != null) { 6740 // If the caller wants to wait for pending thumbnails, 6741 // it ain't gonna get them. 6742 try { 6743 receiver.finished(); 6744 } catch (RemoteException ex) { 6745 } 6746 } 6747 String msg = "Permission Denial: getTasks() from pid=" 6748 + Binder.getCallingPid() 6749 + ", uid=" + Binder.getCallingUid() 6750 + " requires " + android.Manifest.permission.GET_TASKS; 6751 Slog.w(TAG, msg); 6752 throw new SecurityException(msg); 6753 } 6754 6755 // TODO: Improve with MRU list from all ActivityStacks. 6756 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6757 6758 if (!pending.pendingRecords.isEmpty()) { 6759 mPendingThumbnails.add(pending); 6760 } 6761 } 6762 6763 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6764 6765 if (topRecord != null) { 6766 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6767 try { 6768 IApplicationThread topThumbnail = topRecord.app.thread; 6769 topThumbnail.requestThumbnail(topRecord.appToken); 6770 } catch (Exception e) { 6771 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6772 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6773 } 6774 } 6775 6776 if (pending == null && receiver != null) { 6777 // In this case all thumbnails were available and the client 6778 // is being asked to be told when the remaining ones come in... 6779 // which is unusually, since the top-most currently running 6780 // activity should never have a canned thumbnail! Oh well. 6781 try { 6782 receiver.finished(); 6783 } catch (RemoteException ex) { 6784 } 6785 } 6786 6787 return list; 6788 } 6789 6790 TaskRecord getMostRecentTask() { 6791 return mRecentTasks.get(0); 6792 } 6793 6794 @Override 6795 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6796 int flags, int userId) { 6797 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6798 false, true, "getRecentTasks", null); 6799 6800 synchronized (this) { 6801 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6802 "getRecentTasks()"); 6803 final boolean detailed = checkCallingPermission( 6804 android.Manifest.permission.GET_DETAILED_TASKS) 6805 == PackageManager.PERMISSION_GRANTED; 6806 6807 IPackageManager pm = AppGlobals.getPackageManager(); 6808 6809 final int N = mRecentTasks.size(); 6810 ArrayList<ActivityManager.RecentTaskInfo> res 6811 = new ArrayList<ActivityManager.RecentTaskInfo>( 6812 maxNum < N ? maxNum : N); 6813 for (int i=0; i<N && maxNum > 0; i++) { 6814 TaskRecord tr = mRecentTasks.get(i); 6815 // Only add calling user's recent tasks 6816 if (tr.userId != userId) continue; 6817 // Return the entry if desired by the caller. We always return 6818 // the first entry, because callers always expect this to be the 6819 // foreground app. We may filter others if the caller has 6820 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6821 // we should exclude the entry. 6822 6823 if (i == 0 6824 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6825 || (tr.intent == null) 6826 || ((tr.intent.getFlags() 6827 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6828 ActivityManager.RecentTaskInfo rti 6829 = new ActivityManager.RecentTaskInfo(); 6830 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6831 rti.persistentId = tr.taskId; 6832 rti.baseIntent = new Intent( 6833 tr.intent != null ? tr.intent : tr.affinityIntent); 6834 if (!detailed) { 6835 rti.baseIntent.replaceExtras((Bundle)null); 6836 } 6837 rti.origActivity = tr.origActivity; 6838 rti.description = tr.lastDescription; 6839 rti.stackId = tr.stack.mStackId; 6840 6841 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6842 // Check whether this activity is currently available. 6843 try { 6844 if (rti.origActivity != null) { 6845 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6846 == null) { 6847 continue; 6848 } 6849 } else if (rti.baseIntent != null) { 6850 if (pm.queryIntentActivities(rti.baseIntent, 6851 null, 0, userId) == null) { 6852 continue; 6853 } 6854 } 6855 } catch (RemoteException e) { 6856 // Will never happen. 6857 } 6858 } 6859 6860 res.add(rti); 6861 maxNum--; 6862 } 6863 } 6864 return res; 6865 } 6866 } 6867 6868 private TaskRecord recentTaskForIdLocked(int id) { 6869 final int N = mRecentTasks.size(); 6870 for (int i=0; i<N; i++) { 6871 TaskRecord tr = mRecentTasks.get(i); 6872 if (tr.taskId == id) { 6873 return tr; 6874 } 6875 } 6876 return null; 6877 } 6878 6879 @Override 6880 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6881 synchronized (this) { 6882 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6883 "getTaskThumbnails()"); 6884 TaskRecord tr = recentTaskForIdLocked(id); 6885 if (tr != null) { 6886 return tr.getTaskThumbnailsLocked(); 6887 } 6888 } 6889 return null; 6890 } 6891 6892 @Override 6893 public Bitmap getTaskTopThumbnail(int id) { 6894 synchronized (this) { 6895 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6896 "getTaskTopThumbnail()"); 6897 TaskRecord tr = recentTaskForIdLocked(id); 6898 if (tr != null) { 6899 return tr.getTaskTopThumbnailLocked(); 6900 } 6901 } 6902 return null; 6903 } 6904 6905 @Override 6906 public boolean removeSubTask(int taskId, int subTaskIndex) { 6907 synchronized (this) { 6908 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6909 "removeSubTask()"); 6910 long ident = Binder.clearCallingIdentity(); 6911 try { 6912 TaskRecord tr = recentTaskForIdLocked(taskId); 6913 if (tr != null) { 6914 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6915 } 6916 return false; 6917 } finally { 6918 Binder.restoreCallingIdentity(ident); 6919 } 6920 } 6921 } 6922 6923 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6924 if (!pr.killedByAm) { 6925 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6926 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6927 pr.processName, pr.setAdj, reason); 6928 pr.killedByAm = true; 6929 Process.killProcessQuiet(pr.pid); 6930 } 6931 } 6932 6933 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6934 tr.disposeThumbnail(); 6935 mRecentTasks.remove(tr); 6936 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6937 Intent baseIntent = new Intent( 6938 tr.intent != null ? tr.intent : tr.affinityIntent); 6939 ComponentName component = baseIntent.getComponent(); 6940 if (component == null) { 6941 Slog.w(TAG, "Now component for base intent of task: " + tr); 6942 return; 6943 } 6944 6945 // Find any running services associated with this app. 6946 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6947 6948 if (killProcesses) { 6949 // Find any running processes associated with this app. 6950 final String pkg = component.getPackageName(); 6951 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6952 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6953 for (int i=0; i<pmap.size(); i++) { 6954 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6955 for (int j=0; j<uids.size(); j++) { 6956 ProcessRecord proc = uids.valueAt(j); 6957 if (proc.userId != tr.userId) { 6958 continue; 6959 } 6960 if (!proc.pkgList.containsKey(pkg)) { 6961 continue; 6962 } 6963 procs.add(proc); 6964 } 6965 } 6966 6967 // Kill the running processes. 6968 for (int i=0; i<procs.size(); i++) { 6969 ProcessRecord pr = procs.get(i); 6970 if (pr == mHomeProcess) { 6971 // Don't kill the home process along with tasks from the same package. 6972 continue; 6973 } 6974 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6975 killUnneededProcessLocked(pr, "remove task"); 6976 } else { 6977 pr.waitingToKill = "remove task"; 6978 } 6979 } 6980 } 6981 } 6982 6983 @Override 6984 public boolean removeTask(int taskId, int flags) { 6985 synchronized (this) { 6986 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6987 "removeTask()"); 6988 long ident = Binder.clearCallingIdentity(); 6989 try { 6990 TaskRecord tr = recentTaskForIdLocked(taskId); 6991 if (tr != null) { 6992 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6993 if (r != null) { 6994 cleanUpRemovedTaskLocked(tr, flags); 6995 return true; 6996 } 6997 if (tr.mActivities.size() == 0) { 6998 // Caller is just removing a recent task that is 6999 // not actively running. That is easy! 7000 cleanUpRemovedTaskLocked(tr, flags); 7001 return true; 7002 } 7003 Slog.w(TAG, "removeTask: task " + taskId 7004 + " does not have activities to remove, " 7005 + " but numActivities=" + tr.numActivities 7006 + ": " + tr); 7007 } 7008 } finally { 7009 Binder.restoreCallingIdentity(ident); 7010 } 7011 } 7012 return false; 7013 } 7014 7015 /** 7016 * TODO: Add mController hook 7017 */ 7018 @Override 7019 public void moveTaskToFront(int task, int flags, Bundle options) { 7020 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7021 "moveTaskToFront()"); 7022 7023 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7024 synchronized(this) { 7025 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7026 Binder.getCallingUid(), "Task to front")) { 7027 ActivityOptions.abort(options); 7028 return; 7029 } 7030 final long origId = Binder.clearCallingIdentity(); 7031 try { 7032 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7033 } finally { 7034 Binder.restoreCallingIdentity(origId); 7035 } 7036 ActivityOptions.abort(options); 7037 } 7038 } 7039 7040 @Override 7041 public void moveTaskToBack(int taskId) { 7042 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7043 "moveTaskToBack()"); 7044 7045 synchronized(this) { 7046 TaskRecord tr = recentTaskForIdLocked(taskId); 7047 if (tr != null) { 7048 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7049 ActivityStack stack = tr.stack; 7050 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7051 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7052 Binder.getCallingUid(), "Task to back")) { 7053 return; 7054 } 7055 } 7056 final long origId = Binder.clearCallingIdentity(); 7057 try { 7058 stack.moveTaskToBackLocked(taskId, null); 7059 } finally { 7060 Binder.restoreCallingIdentity(origId); 7061 } 7062 } 7063 } 7064 } 7065 7066 /** 7067 * Moves an activity, and all of the other activities within the same task, to the bottom 7068 * of the history stack. The activity's order within the task is unchanged. 7069 * 7070 * @param token A reference to the activity we wish to move 7071 * @param nonRoot If false then this only works if the activity is the root 7072 * of a task; if true it will work for any activity in a task. 7073 * @return Returns true if the move completed, false if not. 7074 */ 7075 @Override 7076 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7077 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7078 synchronized(this) { 7079 final long origId = Binder.clearCallingIdentity(); 7080 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7081 if (taskId >= 0) { 7082 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7083 } 7084 Binder.restoreCallingIdentity(origId); 7085 } 7086 return false; 7087 } 7088 7089 @Override 7090 public void moveTaskBackwards(int task) { 7091 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7092 "moveTaskBackwards()"); 7093 7094 synchronized(this) { 7095 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7096 Binder.getCallingUid(), "Task backwards")) { 7097 return; 7098 } 7099 final long origId = Binder.clearCallingIdentity(); 7100 moveTaskBackwardsLocked(task); 7101 Binder.restoreCallingIdentity(origId); 7102 } 7103 } 7104 7105 private final void moveTaskBackwardsLocked(int task) { 7106 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7107 } 7108 7109 @Override 7110 public int createStack(int taskId, int relativeStackBoxId, int position, float weight) { 7111 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7112 "createStack()"); 7113 if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId + " relStackBoxId=" + 7114 relativeStackBoxId + " position=" + position + " weight=" + weight); 7115 synchronized (this) { 7116 long ident = Binder.clearCallingIdentity(); 7117 try { 7118 int stackId = mStackSupervisor.createStack(); 7119 mWindowManager.createStack(stackId, relativeStackBoxId, position, weight); 7120 if (taskId > 0) { 7121 moveTaskToStack(taskId, stackId, true); 7122 } 7123 return stackId; 7124 } finally { 7125 Binder.restoreCallingIdentity(ident); 7126 } 7127 } 7128 } 7129 7130 @Override 7131 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7132 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7133 "moveTaskToStack()"); 7134 if (stackId == HOME_STACK_ID) { 7135 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7136 new RuntimeException("here").fillInStackTrace()); 7137 } 7138 synchronized (this) { 7139 long ident = Binder.clearCallingIdentity(); 7140 try { 7141 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7142 + stackId + " toTop=" + toTop); 7143 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7144 } finally { 7145 Binder.restoreCallingIdentity(ident); 7146 } 7147 } 7148 } 7149 7150 @Override 7151 public void resizeStackBox(int stackBoxId, float weight) { 7152 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7153 "resizeStackBox()"); 7154 long ident = Binder.clearCallingIdentity(); 7155 try { 7156 mWindowManager.resizeStackBox(stackBoxId, weight); 7157 } finally { 7158 Binder.restoreCallingIdentity(ident); 7159 } 7160 } 7161 7162 private ArrayList<StackInfo> getStacks() { 7163 synchronized (this) { 7164 ArrayList<ActivityManager.StackInfo> list = new ArrayList<ActivityManager.StackInfo>(); 7165 ArrayList<ActivityStack> stacks = mStackSupervisor.getStacks(); 7166 for (ActivityStack stack : stacks) { 7167 ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo(); 7168 int stackId = stack.mStackId; 7169 stackInfo.stackId = stackId; 7170 stackInfo.bounds = mWindowManager.getStackBounds(stackId); 7171 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 7172 final int numTasks = tasks.size(); 7173 int[] taskIds = new int[numTasks]; 7174 String[] taskNames = new String[numTasks]; 7175 for (int i = 0; i < numTasks; ++i) { 7176 final TaskRecord task = tasks.get(i); 7177 taskIds[i] = task.taskId; 7178 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 7179 : task.realActivity != null ? task.realActivity.flattenToString() 7180 : task.getTopActivity() != null ? task.getTopActivity().packageName 7181 : "unknown"; 7182 } 7183 stackInfo.taskIds = taskIds; 7184 stackInfo.taskNames = taskNames; 7185 list.add(stackInfo); 7186 } 7187 return list; 7188 } 7189 } 7190 7191 private void addStackInfoToStackBoxInfo(StackBoxInfo stackBoxInfo, List<StackInfo> stackInfos) { 7192 final int stackId = stackBoxInfo.stackId; 7193 if (stackId >= 0) { 7194 for (StackInfo stackInfo : stackInfos) { 7195 if (stackId == stackInfo.stackId) { 7196 stackBoxInfo.stack = stackInfo; 7197 stackInfos.remove(stackInfo); 7198 return; 7199 } 7200 } 7201 } else { 7202 addStackInfoToStackBoxInfo(stackBoxInfo.children[0], stackInfos); 7203 addStackInfoToStackBoxInfo(stackBoxInfo.children[1], stackInfos); 7204 } 7205 } 7206 7207 @Override 7208 public List<StackBoxInfo> getStackBoxes() { 7209 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7210 "getStackBoxes()"); 7211 long ident = Binder.clearCallingIdentity(); 7212 try { 7213 List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos(); 7214 synchronized (this) { 7215 List<StackInfo> stackInfos = getStacks(); 7216 for (StackBoxInfo stackBoxInfo : stackBoxInfos) { 7217 addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos); 7218 } 7219 } 7220 return stackBoxInfos; 7221 } finally { 7222 Binder.restoreCallingIdentity(ident); 7223 } 7224 } 7225 7226 @Override 7227 public StackBoxInfo getStackBoxInfo(int stackBoxId) { 7228 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7229 "getStackBoxInfo()"); 7230 long ident = Binder.clearCallingIdentity(); 7231 try { 7232 List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos(); 7233 StackBoxInfo info = null; 7234 synchronized (this) { 7235 List<StackInfo> stackInfos = getStacks(); 7236 for (StackBoxInfo stackBoxInfo : stackBoxInfos) { 7237 addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos); 7238 if (stackBoxInfo.stackBoxId == stackBoxId) { 7239 info = stackBoxInfo; 7240 } 7241 } 7242 } 7243 return info; 7244 } finally { 7245 Binder.restoreCallingIdentity(ident); 7246 } 7247 } 7248 7249 @Override 7250 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7251 synchronized(this) { 7252 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7253 } 7254 } 7255 7256 // ========================================================= 7257 // THUMBNAILS 7258 // ========================================================= 7259 7260 public void reportThumbnail(IBinder token, 7261 Bitmap thumbnail, CharSequence description) { 7262 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7263 final long origId = Binder.clearCallingIdentity(); 7264 sendPendingThumbnail(null, token, thumbnail, description, true); 7265 Binder.restoreCallingIdentity(origId); 7266 } 7267 7268 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7269 Bitmap thumbnail, CharSequence description, boolean always) { 7270 TaskRecord task; 7271 ArrayList<PendingThumbnailsRecord> receivers = null; 7272 7273 //System.out.println("Send pending thumbnail: " + r); 7274 7275 synchronized(this) { 7276 if (r == null) { 7277 r = ActivityRecord.isInStackLocked(token); 7278 if (r == null) { 7279 return; 7280 } 7281 } 7282 if (thumbnail == null && r.thumbHolder != null) { 7283 thumbnail = r.thumbHolder.lastThumbnail; 7284 description = r.thumbHolder.lastDescription; 7285 } 7286 if (thumbnail == null && !always) { 7287 // If there is no thumbnail, and this entry is not actually 7288 // going away, then abort for now and pick up the next 7289 // thumbnail we get. 7290 return; 7291 } 7292 task = r.task; 7293 7294 int N = mPendingThumbnails.size(); 7295 int i=0; 7296 while (i<N) { 7297 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7298 //System.out.println("Looking in " + pr.pendingRecords); 7299 if (pr.pendingRecords.remove(r)) { 7300 if (receivers == null) { 7301 receivers = new ArrayList<PendingThumbnailsRecord>(); 7302 } 7303 receivers.add(pr); 7304 if (pr.pendingRecords.size() == 0) { 7305 pr.finished = true; 7306 mPendingThumbnails.remove(i); 7307 N--; 7308 continue; 7309 } 7310 } 7311 i++; 7312 } 7313 } 7314 7315 if (receivers != null) { 7316 final int N = receivers.size(); 7317 for (int i=0; i<N; i++) { 7318 try { 7319 PendingThumbnailsRecord pr = receivers.get(i); 7320 pr.receiver.newThumbnail( 7321 task != null ? task.taskId : -1, thumbnail, description); 7322 if (pr.finished) { 7323 pr.receiver.finished(); 7324 } 7325 } catch (Exception e) { 7326 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7327 } 7328 } 7329 } 7330 } 7331 7332 // ========================================================= 7333 // CONTENT PROVIDERS 7334 // ========================================================= 7335 7336 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7337 List<ProviderInfo> providers = null; 7338 try { 7339 providers = AppGlobals.getPackageManager(). 7340 queryContentProviders(app.processName, app.uid, 7341 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7342 } catch (RemoteException ex) { 7343 } 7344 if (DEBUG_MU) 7345 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7346 int userId = app.userId; 7347 if (providers != null) { 7348 int N = providers.size(); 7349 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7350 for (int i=0; i<N; i++) { 7351 ProviderInfo cpi = 7352 (ProviderInfo)providers.get(i); 7353 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7354 cpi.name, cpi.flags); 7355 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7356 // This is a singleton provider, but a user besides the 7357 // default user is asking to initialize a process it runs 7358 // in... well, no, it doesn't actually run in this process, 7359 // it runs in the process of the default user. Get rid of it. 7360 providers.remove(i); 7361 N--; 7362 i--; 7363 continue; 7364 } 7365 7366 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7367 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7368 if (cpr == null) { 7369 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7370 mProviderMap.putProviderByClass(comp, cpr); 7371 } 7372 if (DEBUG_MU) 7373 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7374 app.pubProviders.put(cpi.name, cpr); 7375 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7376 // Don't add this if it is a platform component that is marked 7377 // to run in multiple processes, because this is actually 7378 // part of the framework so doesn't make sense to track as a 7379 // separate apk in the process. 7380 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7381 } 7382 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7383 } 7384 } 7385 return providers; 7386 } 7387 7388 /** 7389 * Check if {@link ProcessRecord} has a possible chance at accessing the 7390 * given {@link ProviderInfo}. Final permission checking is always done 7391 * in {@link ContentProvider}. 7392 */ 7393 private final String checkContentProviderPermissionLocked( 7394 ProviderInfo cpi, ProcessRecord r) { 7395 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7396 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7397 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7398 cpi.applicationInfo.uid, cpi.exported) 7399 == PackageManager.PERMISSION_GRANTED) { 7400 return null; 7401 } 7402 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7403 cpi.applicationInfo.uid, cpi.exported) 7404 == PackageManager.PERMISSION_GRANTED) { 7405 return null; 7406 } 7407 7408 PathPermission[] pps = cpi.pathPermissions; 7409 if (pps != null) { 7410 int i = pps.length; 7411 while (i > 0) { 7412 i--; 7413 PathPermission pp = pps[i]; 7414 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7415 cpi.applicationInfo.uid, cpi.exported) 7416 == PackageManager.PERMISSION_GRANTED) { 7417 return null; 7418 } 7419 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7420 cpi.applicationInfo.uid, cpi.exported) 7421 == PackageManager.PERMISSION_GRANTED) { 7422 return null; 7423 } 7424 } 7425 } 7426 7427 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7428 if (perms != null) { 7429 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7430 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7431 return null; 7432 } 7433 } 7434 } 7435 7436 String msg; 7437 if (!cpi.exported) { 7438 msg = "Permission Denial: opening provider " + cpi.name 7439 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7440 + ", uid=" + callingUid + ") that is not exported from uid " 7441 + cpi.applicationInfo.uid; 7442 } else { 7443 msg = "Permission Denial: opening provider " + cpi.name 7444 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7445 + ", uid=" + callingUid + ") requires " 7446 + cpi.readPermission + " or " + cpi.writePermission; 7447 } 7448 Slog.w(TAG, msg); 7449 return msg; 7450 } 7451 7452 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7453 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7454 if (r != null) { 7455 for (int i=0; i<r.conProviders.size(); i++) { 7456 ContentProviderConnection conn = r.conProviders.get(i); 7457 if (conn.provider == cpr) { 7458 if (DEBUG_PROVIDER) Slog.v(TAG, 7459 "Adding provider requested by " 7460 + r.processName + " from process " 7461 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7462 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7463 if (stable) { 7464 conn.stableCount++; 7465 conn.numStableIncs++; 7466 } else { 7467 conn.unstableCount++; 7468 conn.numUnstableIncs++; 7469 } 7470 return conn; 7471 } 7472 } 7473 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7474 if (stable) { 7475 conn.stableCount = 1; 7476 conn.numStableIncs = 1; 7477 } else { 7478 conn.unstableCount = 1; 7479 conn.numUnstableIncs = 1; 7480 } 7481 cpr.connections.add(conn); 7482 r.conProviders.add(conn); 7483 return conn; 7484 } 7485 cpr.addExternalProcessHandleLocked(externalProcessToken); 7486 return null; 7487 } 7488 7489 boolean decProviderCountLocked(ContentProviderConnection conn, 7490 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7491 if (conn != null) { 7492 cpr = conn.provider; 7493 if (DEBUG_PROVIDER) Slog.v(TAG, 7494 "Removing provider requested by " 7495 + conn.client.processName + " from process " 7496 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7497 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7498 if (stable) { 7499 conn.stableCount--; 7500 } else { 7501 conn.unstableCount--; 7502 } 7503 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7504 cpr.connections.remove(conn); 7505 conn.client.conProviders.remove(conn); 7506 return true; 7507 } 7508 return false; 7509 } 7510 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7511 return false; 7512 } 7513 7514 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7515 String name, IBinder token, boolean stable, int userId) { 7516 ContentProviderRecord cpr; 7517 ContentProviderConnection conn = null; 7518 ProviderInfo cpi = null; 7519 7520 synchronized(this) { 7521 ProcessRecord r = null; 7522 if (caller != null) { 7523 r = getRecordForAppLocked(caller); 7524 if (r == null) { 7525 throw new SecurityException( 7526 "Unable to find app for caller " + caller 7527 + " (pid=" + Binder.getCallingPid() 7528 + ") when getting content provider " + name); 7529 } 7530 } 7531 7532 // First check if this content provider has been published... 7533 cpr = mProviderMap.getProviderByName(name, userId); 7534 boolean providerRunning = cpr != null; 7535 if (providerRunning) { 7536 cpi = cpr.info; 7537 String msg; 7538 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7539 throw new SecurityException(msg); 7540 } 7541 7542 if (r != null && cpr.canRunHere(r)) { 7543 // This provider has been published or is in the process 7544 // of being published... but it is also allowed to run 7545 // in the caller's process, so don't make a connection 7546 // and just let the caller instantiate its own instance. 7547 ContentProviderHolder holder = cpr.newHolder(null); 7548 // don't give caller the provider object, it needs 7549 // to make its own. 7550 holder.provider = null; 7551 return holder; 7552 } 7553 7554 final long origId = Binder.clearCallingIdentity(); 7555 7556 // In this case the provider instance already exists, so we can 7557 // return it right away. 7558 conn = incProviderCountLocked(r, cpr, token, stable); 7559 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7560 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7561 // If this is a perceptible app accessing the provider, 7562 // make sure to count it as being accessed and thus 7563 // back up on the LRU list. This is good because 7564 // content providers are often expensive to start. 7565 updateLruProcessLocked(cpr.proc, false, null); 7566 } 7567 } 7568 7569 if (cpr.proc != null) { 7570 if (false) { 7571 if (cpr.name.flattenToShortString().equals( 7572 "com.android.providers.calendar/.CalendarProvider2")) { 7573 Slog.v(TAG, "****************** KILLING " 7574 + cpr.name.flattenToShortString()); 7575 Process.killProcess(cpr.proc.pid); 7576 } 7577 } 7578 boolean success = updateOomAdjLocked(cpr.proc); 7579 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7580 // NOTE: there is still a race here where a signal could be 7581 // pending on the process even though we managed to update its 7582 // adj level. Not sure what to do about this, but at least 7583 // the race is now smaller. 7584 if (!success) { 7585 // Uh oh... it looks like the provider's process 7586 // has been killed on us. We need to wait for a new 7587 // process to be started, and make sure its death 7588 // doesn't kill our process. 7589 Slog.i(TAG, 7590 "Existing provider " + cpr.name.flattenToShortString() 7591 + " is crashing; detaching " + r); 7592 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7593 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7594 if (!lastRef) { 7595 // This wasn't the last ref our process had on 7596 // the provider... we have now been killed, bail. 7597 return null; 7598 } 7599 providerRunning = false; 7600 conn = null; 7601 } 7602 } 7603 7604 Binder.restoreCallingIdentity(origId); 7605 } 7606 7607 boolean singleton; 7608 if (!providerRunning) { 7609 try { 7610 cpi = AppGlobals.getPackageManager(). 7611 resolveContentProvider(name, 7612 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7613 } catch (RemoteException ex) { 7614 } 7615 if (cpi == null) { 7616 return null; 7617 } 7618 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7619 cpi.name, cpi.flags); 7620 if (singleton) { 7621 userId = 0; 7622 } 7623 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7624 7625 String msg; 7626 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7627 throw new SecurityException(msg); 7628 } 7629 7630 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7631 && !cpi.processName.equals("system")) { 7632 // If this content provider does not run in the system 7633 // process, and the system is not yet ready to run other 7634 // processes, then fail fast instead of hanging. 7635 throw new IllegalArgumentException( 7636 "Attempt to launch content provider before system ready"); 7637 } 7638 7639 // Make sure that the user who owns this provider is started. If not, 7640 // we don't want to allow it to run. 7641 if (mStartedUsers.get(userId) == null) { 7642 Slog.w(TAG, "Unable to launch app " 7643 + cpi.applicationInfo.packageName + "/" 7644 + cpi.applicationInfo.uid + " for provider " 7645 + name + ": user " + userId + " is stopped"); 7646 return null; 7647 } 7648 7649 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7650 cpr = mProviderMap.getProviderByClass(comp, userId); 7651 final boolean firstClass = cpr == null; 7652 if (firstClass) { 7653 try { 7654 ApplicationInfo ai = 7655 AppGlobals.getPackageManager(). 7656 getApplicationInfo( 7657 cpi.applicationInfo.packageName, 7658 STOCK_PM_FLAGS, userId); 7659 if (ai == null) { 7660 Slog.w(TAG, "No package info for content provider " 7661 + cpi.name); 7662 return null; 7663 } 7664 ai = getAppInfoForUser(ai, userId); 7665 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7666 } catch (RemoteException ex) { 7667 // pm is in same process, this will never happen. 7668 } 7669 } 7670 7671 if (r != null && cpr.canRunHere(r)) { 7672 // If this is a multiprocess provider, then just return its 7673 // info and allow the caller to instantiate it. Only do 7674 // this if the provider is the same user as the caller's 7675 // process, or can run as root (so can be in any process). 7676 return cpr.newHolder(null); 7677 } 7678 7679 if (DEBUG_PROVIDER) { 7680 RuntimeException e = new RuntimeException("here"); 7681 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7682 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7683 } 7684 7685 // This is single process, and our app is now connecting to it. 7686 // See if we are already in the process of launching this 7687 // provider. 7688 final int N = mLaunchingProviders.size(); 7689 int i; 7690 for (i=0; i<N; i++) { 7691 if (mLaunchingProviders.get(i) == cpr) { 7692 break; 7693 } 7694 } 7695 7696 // If the provider is not already being launched, then get it 7697 // started. 7698 if (i >= N) { 7699 final long origId = Binder.clearCallingIdentity(); 7700 7701 try { 7702 // Content provider is now in use, its package can't be stopped. 7703 try { 7704 AppGlobals.getPackageManager().setPackageStoppedState( 7705 cpr.appInfo.packageName, false, userId); 7706 } catch (RemoteException e) { 7707 } catch (IllegalArgumentException e) { 7708 Slog.w(TAG, "Failed trying to unstop package " 7709 + cpr.appInfo.packageName + ": " + e); 7710 } 7711 7712 // Use existing process if already started 7713 ProcessRecord proc = getProcessRecordLocked( 7714 cpi.processName, cpr.appInfo.uid, false); 7715 if (proc != null && proc.thread != null) { 7716 if (DEBUG_PROVIDER) { 7717 Slog.d(TAG, "Installing in existing process " + proc); 7718 } 7719 proc.pubProviders.put(cpi.name, cpr); 7720 try { 7721 proc.thread.scheduleInstallProvider(cpi); 7722 } catch (RemoteException e) { 7723 } 7724 } else { 7725 proc = startProcessLocked(cpi.processName, 7726 cpr.appInfo, false, 0, "content provider", 7727 new ComponentName(cpi.applicationInfo.packageName, 7728 cpi.name), false, false, false); 7729 if (proc == null) { 7730 Slog.w(TAG, "Unable to launch app " 7731 + cpi.applicationInfo.packageName + "/" 7732 + cpi.applicationInfo.uid + " for provider " 7733 + name + ": process is bad"); 7734 return null; 7735 } 7736 } 7737 cpr.launchingApp = proc; 7738 mLaunchingProviders.add(cpr); 7739 } finally { 7740 Binder.restoreCallingIdentity(origId); 7741 } 7742 } 7743 7744 // Make sure the provider is published (the same provider class 7745 // may be published under multiple names). 7746 if (firstClass) { 7747 mProviderMap.putProviderByClass(comp, cpr); 7748 } 7749 7750 mProviderMap.putProviderByName(name, cpr); 7751 conn = incProviderCountLocked(r, cpr, token, stable); 7752 if (conn != null) { 7753 conn.waiting = true; 7754 } 7755 } 7756 } 7757 7758 // Wait for the provider to be published... 7759 synchronized (cpr) { 7760 while (cpr.provider == null) { 7761 if (cpr.launchingApp == null) { 7762 Slog.w(TAG, "Unable to launch app " 7763 + cpi.applicationInfo.packageName + "/" 7764 + cpi.applicationInfo.uid + " for provider " 7765 + name + ": launching app became null"); 7766 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7767 UserHandle.getUserId(cpi.applicationInfo.uid), 7768 cpi.applicationInfo.packageName, 7769 cpi.applicationInfo.uid, name); 7770 return null; 7771 } 7772 try { 7773 if (DEBUG_MU) { 7774 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7775 + cpr.launchingApp); 7776 } 7777 if (conn != null) { 7778 conn.waiting = true; 7779 } 7780 cpr.wait(); 7781 } catch (InterruptedException ex) { 7782 } finally { 7783 if (conn != null) { 7784 conn.waiting = false; 7785 } 7786 } 7787 } 7788 } 7789 return cpr != null ? cpr.newHolder(conn) : null; 7790 } 7791 7792 public final ContentProviderHolder getContentProvider( 7793 IApplicationThread caller, String name, int userId, boolean stable) { 7794 enforceNotIsolatedCaller("getContentProvider"); 7795 if (caller == null) { 7796 String msg = "null IApplicationThread when getting content provider " 7797 + name; 7798 Slog.w(TAG, msg); 7799 throw new SecurityException(msg); 7800 } 7801 7802 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7803 false, true, "getContentProvider", null); 7804 return getContentProviderImpl(caller, name, null, stable, userId); 7805 } 7806 7807 public ContentProviderHolder getContentProviderExternal( 7808 String name, int userId, IBinder token) { 7809 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7810 "Do not have permission in call getContentProviderExternal()"); 7811 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7812 false, true, "getContentProvider", null); 7813 return getContentProviderExternalUnchecked(name, token, userId); 7814 } 7815 7816 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7817 IBinder token, int userId) { 7818 return getContentProviderImpl(null, name, token, true, userId); 7819 } 7820 7821 /** 7822 * Drop a content provider from a ProcessRecord's bookkeeping 7823 */ 7824 public void removeContentProvider(IBinder connection, boolean stable) { 7825 enforceNotIsolatedCaller("removeContentProvider"); 7826 synchronized (this) { 7827 ContentProviderConnection conn; 7828 try { 7829 conn = (ContentProviderConnection)connection; 7830 } catch (ClassCastException e) { 7831 String msg ="removeContentProvider: " + connection 7832 + " not a ContentProviderConnection"; 7833 Slog.w(TAG, msg); 7834 throw new IllegalArgumentException(msg); 7835 } 7836 if (conn == null) { 7837 throw new NullPointerException("connection is null"); 7838 } 7839 if (decProviderCountLocked(conn, null, null, stable)) { 7840 updateOomAdjLocked(); 7841 } 7842 } 7843 } 7844 7845 public void removeContentProviderExternal(String name, IBinder token) { 7846 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7847 "Do not have permission in call removeContentProviderExternal()"); 7848 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7849 } 7850 7851 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7852 synchronized (this) { 7853 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7854 if(cpr == null) { 7855 //remove from mProvidersByClass 7856 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7857 return; 7858 } 7859 7860 //update content provider record entry info 7861 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7862 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7863 if (localCpr.hasExternalProcessHandles()) { 7864 if (localCpr.removeExternalProcessHandleLocked(token)) { 7865 updateOomAdjLocked(); 7866 } else { 7867 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7868 + " with no external reference for token: " 7869 + token + "."); 7870 } 7871 } else { 7872 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7873 + " with no external references."); 7874 } 7875 } 7876 } 7877 7878 public final void publishContentProviders(IApplicationThread caller, 7879 List<ContentProviderHolder> providers) { 7880 if (providers == null) { 7881 return; 7882 } 7883 7884 enforceNotIsolatedCaller("publishContentProviders"); 7885 synchronized (this) { 7886 final ProcessRecord r = getRecordForAppLocked(caller); 7887 if (DEBUG_MU) 7888 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7889 if (r == null) { 7890 throw new SecurityException( 7891 "Unable to find app for caller " + caller 7892 + " (pid=" + Binder.getCallingPid() 7893 + ") when publishing content providers"); 7894 } 7895 7896 final long origId = Binder.clearCallingIdentity(); 7897 7898 final int N = providers.size(); 7899 for (int i=0; i<N; i++) { 7900 ContentProviderHolder src = providers.get(i); 7901 if (src == null || src.info == null || src.provider == null) { 7902 continue; 7903 } 7904 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7905 if (DEBUG_MU) 7906 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7907 if (dst != null) { 7908 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7909 mProviderMap.putProviderByClass(comp, dst); 7910 String names[] = dst.info.authority.split(";"); 7911 for (int j = 0; j < names.length; j++) { 7912 mProviderMap.putProviderByName(names[j], dst); 7913 } 7914 7915 int NL = mLaunchingProviders.size(); 7916 int j; 7917 for (j=0; j<NL; j++) { 7918 if (mLaunchingProviders.get(j) == dst) { 7919 mLaunchingProviders.remove(j); 7920 j--; 7921 NL--; 7922 } 7923 } 7924 synchronized (dst) { 7925 dst.provider = src.provider; 7926 dst.proc = r; 7927 dst.notifyAll(); 7928 } 7929 updateOomAdjLocked(r); 7930 } 7931 } 7932 7933 Binder.restoreCallingIdentity(origId); 7934 } 7935 } 7936 7937 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7938 ContentProviderConnection conn; 7939 try { 7940 conn = (ContentProviderConnection)connection; 7941 } catch (ClassCastException e) { 7942 String msg ="refContentProvider: " + connection 7943 + " not a ContentProviderConnection"; 7944 Slog.w(TAG, msg); 7945 throw new IllegalArgumentException(msg); 7946 } 7947 if (conn == null) { 7948 throw new NullPointerException("connection is null"); 7949 } 7950 7951 synchronized (this) { 7952 if (stable > 0) { 7953 conn.numStableIncs += stable; 7954 } 7955 stable = conn.stableCount + stable; 7956 if (stable < 0) { 7957 throw new IllegalStateException("stableCount < 0: " + stable); 7958 } 7959 7960 if (unstable > 0) { 7961 conn.numUnstableIncs += unstable; 7962 } 7963 unstable = conn.unstableCount + unstable; 7964 if (unstable < 0) { 7965 throw new IllegalStateException("unstableCount < 0: " + unstable); 7966 } 7967 7968 if ((stable+unstable) <= 0) { 7969 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7970 + stable + " unstable=" + unstable); 7971 } 7972 conn.stableCount = stable; 7973 conn.unstableCount = unstable; 7974 return !conn.dead; 7975 } 7976 } 7977 7978 public void unstableProviderDied(IBinder connection) { 7979 ContentProviderConnection conn; 7980 try { 7981 conn = (ContentProviderConnection)connection; 7982 } catch (ClassCastException e) { 7983 String msg ="refContentProvider: " + connection 7984 + " not a ContentProviderConnection"; 7985 Slog.w(TAG, msg); 7986 throw new IllegalArgumentException(msg); 7987 } 7988 if (conn == null) { 7989 throw new NullPointerException("connection is null"); 7990 } 7991 7992 // Safely retrieve the content provider associated with the connection. 7993 IContentProvider provider; 7994 synchronized (this) { 7995 provider = conn.provider.provider; 7996 } 7997 7998 if (provider == null) { 7999 // Um, yeah, we're way ahead of you. 8000 return; 8001 } 8002 8003 // Make sure the caller is being honest with us. 8004 if (provider.asBinder().pingBinder()) { 8005 // Er, no, still looks good to us. 8006 synchronized (this) { 8007 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8008 + " says " + conn + " died, but we don't agree"); 8009 return; 8010 } 8011 } 8012 8013 // Well look at that! It's dead! 8014 synchronized (this) { 8015 if (conn.provider.provider != provider) { 8016 // But something changed... good enough. 8017 return; 8018 } 8019 8020 ProcessRecord proc = conn.provider.proc; 8021 if (proc == null || proc.thread == null) { 8022 // Seems like the process is already cleaned up. 8023 return; 8024 } 8025 8026 // As far as we're concerned, this is just like receiving a 8027 // death notification... just a bit prematurely. 8028 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8029 + ") early provider death"); 8030 final long ident = Binder.clearCallingIdentity(); 8031 try { 8032 appDiedLocked(proc, proc.pid, proc.thread); 8033 } finally { 8034 Binder.restoreCallingIdentity(ident); 8035 } 8036 } 8037 } 8038 8039 @Override 8040 public void appNotRespondingViaProvider(IBinder connection) { 8041 enforceCallingPermission( 8042 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8043 8044 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8045 if (conn == null) { 8046 Slog.w(TAG, "ContentProviderConnection is null"); 8047 return; 8048 } 8049 8050 final ProcessRecord host = conn.provider.proc; 8051 if (host == null) { 8052 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8053 return; 8054 } 8055 8056 final long token = Binder.clearCallingIdentity(); 8057 try { 8058 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8059 } finally { 8060 Binder.restoreCallingIdentity(token); 8061 } 8062 } 8063 8064 public static final void installSystemProviders() { 8065 List<ProviderInfo> providers; 8066 synchronized (mSelf) { 8067 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 8068 providers = mSelf.generateApplicationProvidersLocked(app); 8069 if (providers != null) { 8070 for (int i=providers.size()-1; i>=0; i--) { 8071 ProviderInfo pi = (ProviderInfo)providers.get(i); 8072 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8073 Slog.w(TAG, "Not installing system proc provider " + pi.name 8074 + ": not system .apk"); 8075 providers.remove(i); 8076 } 8077 } 8078 } 8079 } 8080 if (providers != null) { 8081 mSystemThread.installSystemProviders(providers); 8082 } 8083 8084 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 8085 8086 mSelf.mUsageStatsService.monitorPackages(); 8087 } 8088 8089 /** 8090 * Allows app to retrieve the MIME type of a URI without having permission 8091 * to access its content provider. 8092 * 8093 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8094 * 8095 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8096 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8097 */ 8098 public String getProviderMimeType(Uri uri, int userId) { 8099 enforceNotIsolatedCaller("getProviderMimeType"); 8100 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8101 userId, false, true, "getProviderMimeType", null); 8102 final String name = uri.getAuthority(); 8103 final long ident = Binder.clearCallingIdentity(); 8104 ContentProviderHolder holder = null; 8105 8106 try { 8107 holder = getContentProviderExternalUnchecked(name, null, userId); 8108 if (holder != null) { 8109 return holder.provider.getType(uri); 8110 } 8111 } catch (RemoteException e) { 8112 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8113 return null; 8114 } finally { 8115 if (holder != null) { 8116 removeContentProviderExternalUnchecked(name, null, userId); 8117 } 8118 Binder.restoreCallingIdentity(ident); 8119 } 8120 8121 return null; 8122 } 8123 8124 // ========================================================= 8125 // GLOBAL MANAGEMENT 8126 // ========================================================= 8127 8128 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8129 boolean isolated) { 8130 String proc = customProcess != null ? customProcess : info.processName; 8131 BatteryStatsImpl.Uid.Proc ps = null; 8132 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8133 int uid = info.uid; 8134 if (isolated) { 8135 int userId = UserHandle.getUserId(uid); 8136 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8137 while (true) { 8138 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8139 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8140 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8141 } 8142 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8143 mNextIsolatedProcessUid++; 8144 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8145 // No process for this uid, use it. 8146 break; 8147 } 8148 stepsLeft--; 8149 if (stepsLeft <= 0) { 8150 return null; 8151 } 8152 } 8153 } 8154 return new ProcessRecord(stats, info, proc, uid); 8155 } 8156 8157 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8158 ProcessRecord app; 8159 if (!isolated) { 8160 app = getProcessRecordLocked(info.processName, info.uid, true); 8161 } else { 8162 app = null; 8163 } 8164 8165 if (app == null) { 8166 app = newProcessRecordLocked(info, null, isolated); 8167 mProcessNames.put(info.processName, app.uid, app); 8168 if (isolated) { 8169 mIsolatedProcesses.put(app.uid, app); 8170 } 8171 updateLruProcessLocked(app, false, null); 8172 updateOomAdjLocked(); 8173 } 8174 8175 // This package really, really can not be stopped. 8176 try { 8177 AppGlobals.getPackageManager().setPackageStoppedState( 8178 info.packageName, false, UserHandle.getUserId(app.uid)); 8179 } catch (RemoteException e) { 8180 } catch (IllegalArgumentException e) { 8181 Slog.w(TAG, "Failed trying to unstop package " 8182 + info.packageName + ": " + e); 8183 } 8184 8185 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8186 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8187 app.persistent = true; 8188 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8189 } 8190 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8191 mPersistentStartingProcesses.add(app); 8192 startProcessLocked(app, "added application", app.processName); 8193 } 8194 8195 return app; 8196 } 8197 8198 public void unhandledBack() { 8199 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8200 "unhandledBack()"); 8201 8202 synchronized(this) { 8203 final long origId = Binder.clearCallingIdentity(); 8204 try { 8205 getFocusedStack().unhandledBackLocked(); 8206 } finally { 8207 Binder.restoreCallingIdentity(origId); 8208 } 8209 } 8210 } 8211 8212 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8213 enforceNotIsolatedCaller("openContentUri"); 8214 final int userId = UserHandle.getCallingUserId(); 8215 String name = uri.getAuthority(); 8216 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8217 ParcelFileDescriptor pfd = null; 8218 if (cph != null) { 8219 // We record the binder invoker's uid in thread-local storage before 8220 // going to the content provider to open the file. Later, in the code 8221 // that handles all permissions checks, we look for this uid and use 8222 // that rather than the Activity Manager's own uid. The effect is that 8223 // we do the check against the caller's permissions even though it looks 8224 // to the content provider like the Activity Manager itself is making 8225 // the request. 8226 sCallerIdentity.set(new Identity( 8227 Binder.getCallingPid(), Binder.getCallingUid())); 8228 try { 8229 pfd = cph.provider.openFile(null, uri, "r", null); 8230 } catch (FileNotFoundException e) { 8231 // do nothing; pfd will be returned null 8232 } finally { 8233 // Ensure that whatever happens, we clean up the identity state 8234 sCallerIdentity.remove(); 8235 } 8236 8237 // We've got the fd now, so we're done with the provider. 8238 removeContentProviderExternalUnchecked(name, null, userId); 8239 } else { 8240 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8241 } 8242 return pfd; 8243 } 8244 8245 // Actually is sleeping or shutting down or whatever else in the future 8246 // is an inactive state. 8247 public boolean isSleepingOrShuttingDown() { 8248 return mSleeping || mShuttingDown; 8249 } 8250 8251 public void goingToSleep() { 8252 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8253 != PackageManager.PERMISSION_GRANTED) { 8254 throw new SecurityException("Requires permission " 8255 + android.Manifest.permission.DEVICE_POWER); 8256 } 8257 8258 synchronized(this) { 8259 mWentToSleep = true; 8260 updateEventDispatchingLocked(); 8261 8262 if (!mSleeping) { 8263 mSleeping = true; 8264 mStackSupervisor.goingToSleepLocked(); 8265 8266 // Initialize the wake times of all processes. 8267 checkExcessivePowerUsageLocked(false); 8268 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8269 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8270 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8271 } 8272 } 8273 } 8274 8275 @Override 8276 public boolean shutdown(int timeout) { 8277 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8278 != PackageManager.PERMISSION_GRANTED) { 8279 throw new SecurityException("Requires permission " 8280 + android.Manifest.permission.SHUTDOWN); 8281 } 8282 8283 boolean timedout = false; 8284 8285 synchronized(this) { 8286 mShuttingDown = true; 8287 updateEventDispatchingLocked(); 8288 timedout = mStackSupervisor.shutdownLocked(timeout); 8289 } 8290 8291 mAppOpsService.shutdown(); 8292 mUsageStatsService.shutdown(); 8293 mBatteryStatsService.shutdown(); 8294 synchronized (this) { 8295 mProcessStats.shutdownLocked(); 8296 } 8297 8298 return timedout; 8299 } 8300 8301 public final void activitySlept(IBinder token) { 8302 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8303 8304 final long origId = Binder.clearCallingIdentity(); 8305 8306 synchronized (this) { 8307 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8308 if (r != null) { 8309 mStackSupervisor.activitySleptLocked(r); 8310 } 8311 } 8312 8313 Binder.restoreCallingIdentity(origId); 8314 } 8315 8316 void logLockScreen(String msg) { 8317 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8318 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8319 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8320 mStackSupervisor.mDismissKeyguardOnNextActivity); 8321 } 8322 8323 private void comeOutOfSleepIfNeededLocked() { 8324 if (!mWentToSleep && !mLockScreenShown) { 8325 if (mSleeping) { 8326 mSleeping = false; 8327 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8328 } 8329 } 8330 } 8331 8332 public void wakingUp() { 8333 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8334 != PackageManager.PERMISSION_GRANTED) { 8335 throw new SecurityException("Requires permission " 8336 + android.Manifest.permission.DEVICE_POWER); 8337 } 8338 8339 synchronized(this) { 8340 mWentToSleep = false; 8341 updateEventDispatchingLocked(); 8342 comeOutOfSleepIfNeededLocked(); 8343 } 8344 } 8345 8346 private void updateEventDispatchingLocked() { 8347 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8348 } 8349 8350 public void setLockScreenShown(boolean shown) { 8351 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8352 != PackageManager.PERMISSION_GRANTED) { 8353 throw new SecurityException("Requires permission " 8354 + android.Manifest.permission.DEVICE_POWER); 8355 } 8356 8357 synchronized(this) { 8358 long ident = Binder.clearCallingIdentity(); 8359 try { 8360 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8361 mLockScreenShown = shown; 8362 comeOutOfSleepIfNeededLocked(); 8363 } finally { 8364 Binder.restoreCallingIdentity(ident); 8365 } 8366 } 8367 } 8368 8369 public void stopAppSwitches() { 8370 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8371 != PackageManager.PERMISSION_GRANTED) { 8372 throw new SecurityException("Requires permission " 8373 + android.Manifest.permission.STOP_APP_SWITCHES); 8374 } 8375 8376 synchronized(this) { 8377 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8378 + APP_SWITCH_DELAY_TIME; 8379 mDidAppSwitch = false; 8380 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8381 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8382 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8383 } 8384 } 8385 8386 public void resumeAppSwitches() { 8387 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8388 != PackageManager.PERMISSION_GRANTED) { 8389 throw new SecurityException("Requires permission " 8390 + android.Manifest.permission.STOP_APP_SWITCHES); 8391 } 8392 8393 synchronized(this) { 8394 // Note that we don't execute any pending app switches... we will 8395 // let those wait until either the timeout, or the next start 8396 // activity request. 8397 mAppSwitchesAllowedTime = 0; 8398 } 8399 } 8400 8401 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8402 String name) { 8403 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8404 return true; 8405 } 8406 8407 final int perm = checkComponentPermission( 8408 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8409 callingUid, -1, true); 8410 if (perm == PackageManager.PERMISSION_GRANTED) { 8411 return true; 8412 } 8413 8414 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8415 return false; 8416 } 8417 8418 public void setDebugApp(String packageName, boolean waitForDebugger, 8419 boolean persistent) { 8420 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8421 "setDebugApp()"); 8422 8423 long ident = Binder.clearCallingIdentity(); 8424 try { 8425 // Note that this is not really thread safe if there are multiple 8426 // callers into it at the same time, but that's not a situation we 8427 // care about. 8428 if (persistent) { 8429 final ContentResolver resolver = mContext.getContentResolver(); 8430 Settings.Global.putString( 8431 resolver, Settings.Global.DEBUG_APP, 8432 packageName); 8433 Settings.Global.putInt( 8434 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8435 waitForDebugger ? 1 : 0); 8436 } 8437 8438 synchronized (this) { 8439 if (!persistent) { 8440 mOrigDebugApp = mDebugApp; 8441 mOrigWaitForDebugger = mWaitForDebugger; 8442 } 8443 mDebugApp = packageName; 8444 mWaitForDebugger = waitForDebugger; 8445 mDebugTransient = !persistent; 8446 if (packageName != null) { 8447 forceStopPackageLocked(packageName, -1, false, false, true, true, 8448 false, UserHandle.USER_ALL, "set debug app"); 8449 } 8450 } 8451 } finally { 8452 Binder.restoreCallingIdentity(ident); 8453 } 8454 } 8455 8456 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8457 synchronized (this) { 8458 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8459 if (!isDebuggable) { 8460 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8461 throw new SecurityException("Process not debuggable: " + app.packageName); 8462 } 8463 } 8464 8465 mOpenGlTraceApp = processName; 8466 } 8467 } 8468 8469 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8470 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8471 synchronized (this) { 8472 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8473 if (!isDebuggable) { 8474 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8475 throw new SecurityException("Process not debuggable: " + app.packageName); 8476 } 8477 } 8478 mProfileApp = processName; 8479 mProfileFile = profileFile; 8480 if (mProfileFd != null) { 8481 try { 8482 mProfileFd.close(); 8483 } catch (IOException e) { 8484 } 8485 mProfileFd = null; 8486 } 8487 mProfileFd = profileFd; 8488 mProfileType = 0; 8489 mAutoStopProfiler = autoStopProfiler; 8490 } 8491 } 8492 8493 @Override 8494 public void setAlwaysFinish(boolean enabled) { 8495 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8496 "setAlwaysFinish()"); 8497 8498 Settings.Global.putInt( 8499 mContext.getContentResolver(), 8500 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8501 8502 synchronized (this) { 8503 mAlwaysFinishActivities = enabled; 8504 } 8505 } 8506 8507 @Override 8508 public void setActivityController(IActivityController controller) { 8509 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8510 "setActivityController()"); 8511 synchronized (this) { 8512 mController = controller; 8513 Watchdog.getInstance().setActivityController(controller); 8514 } 8515 } 8516 8517 @Override 8518 public void setUserIsMonkey(boolean userIsMonkey) { 8519 synchronized (this) { 8520 synchronized (mPidsSelfLocked) { 8521 final int callingPid = Binder.getCallingPid(); 8522 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8523 if (precessRecord == null) { 8524 throw new SecurityException("Unknown process: " + callingPid); 8525 } 8526 if (precessRecord.instrumentationUiAutomationConnection == null) { 8527 throw new SecurityException("Only an instrumentation process " 8528 + "with a UiAutomation can call setUserIsMonkey"); 8529 } 8530 } 8531 mUserIsMonkey = userIsMonkey; 8532 } 8533 } 8534 8535 @Override 8536 public boolean isUserAMonkey() { 8537 synchronized (this) { 8538 // If there is a controller also implies the user is a monkey. 8539 return (mUserIsMonkey || mController != null); 8540 } 8541 } 8542 8543 public void requestBugReport() { 8544 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8545 SystemProperties.set("ctl.start", "bugreport"); 8546 } 8547 8548 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8549 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8550 } 8551 8552 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8553 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8554 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8555 } 8556 return KEY_DISPATCHING_TIMEOUT; 8557 } 8558 8559 @Override 8560 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8561 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8562 != PackageManager.PERMISSION_GRANTED) { 8563 throw new SecurityException("Requires permission " 8564 + android.Manifest.permission.FILTER_EVENTS); 8565 } 8566 ProcessRecord proc; 8567 long timeout; 8568 synchronized (this) { 8569 synchronized (mPidsSelfLocked) { 8570 proc = mPidsSelfLocked.get(pid); 8571 } 8572 timeout = getInputDispatchingTimeoutLocked(proc); 8573 } 8574 8575 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8576 return -1; 8577 } 8578 8579 return timeout; 8580 } 8581 8582 /** 8583 * Handle input dispatching timeouts. 8584 * Returns whether input dispatching should be aborted or not. 8585 */ 8586 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8587 final ActivityRecord activity, final ActivityRecord parent, 8588 final boolean aboveSystem, String reason) { 8589 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8590 != PackageManager.PERMISSION_GRANTED) { 8591 throw new SecurityException("Requires permission " 8592 + android.Manifest.permission.FILTER_EVENTS); 8593 } 8594 8595 final String annotation; 8596 if (reason == null) { 8597 annotation = "Input dispatching timed out"; 8598 } else { 8599 annotation = "Input dispatching timed out (" + reason + ")"; 8600 } 8601 8602 if (proc != null) { 8603 synchronized (this) { 8604 if (proc.debugging) { 8605 return false; 8606 } 8607 8608 if (mDidDexOpt) { 8609 // Give more time since we were dexopting. 8610 mDidDexOpt = false; 8611 return false; 8612 } 8613 8614 if (proc.instrumentationClass != null) { 8615 Bundle info = new Bundle(); 8616 info.putString("shortMsg", "keyDispatchingTimedOut"); 8617 info.putString("longMsg", annotation); 8618 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8619 return true; 8620 } 8621 } 8622 mHandler.post(new Runnable() { 8623 @Override 8624 public void run() { 8625 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8626 } 8627 }); 8628 } 8629 8630 return true; 8631 } 8632 8633 public Bundle getAssistContextExtras(int requestType) { 8634 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8635 "getAssistContextExtras()"); 8636 PendingAssistExtras pae; 8637 Bundle extras = new Bundle(); 8638 synchronized (this) { 8639 ActivityRecord activity = getFocusedStack().mResumedActivity; 8640 if (activity == null) { 8641 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8642 return null; 8643 } 8644 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8645 if (activity.app == null || activity.app.thread == null) { 8646 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8647 return extras; 8648 } 8649 if (activity.app.pid == Binder.getCallingPid()) { 8650 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8651 return extras; 8652 } 8653 pae = new PendingAssistExtras(activity); 8654 try { 8655 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8656 requestType); 8657 mPendingAssistExtras.add(pae); 8658 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8659 } catch (RemoteException e) { 8660 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8661 return extras; 8662 } 8663 } 8664 synchronized (pae) { 8665 while (!pae.haveResult) { 8666 try { 8667 pae.wait(); 8668 } catch (InterruptedException e) { 8669 } 8670 } 8671 if (pae.result != null) { 8672 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8673 } 8674 } 8675 synchronized (this) { 8676 mPendingAssistExtras.remove(pae); 8677 mHandler.removeCallbacks(pae); 8678 } 8679 return extras; 8680 } 8681 8682 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8683 PendingAssistExtras pae = (PendingAssistExtras)token; 8684 synchronized (pae) { 8685 pae.result = extras; 8686 pae.haveResult = true; 8687 pae.notifyAll(); 8688 } 8689 } 8690 8691 public void registerProcessObserver(IProcessObserver observer) { 8692 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8693 "registerProcessObserver()"); 8694 synchronized (this) { 8695 mProcessObservers.register(observer); 8696 } 8697 } 8698 8699 @Override 8700 public void unregisterProcessObserver(IProcessObserver observer) { 8701 synchronized (this) { 8702 mProcessObservers.unregister(observer); 8703 } 8704 } 8705 8706 @Override 8707 public boolean convertFromTranslucent(IBinder token) { 8708 final long origId = Binder.clearCallingIdentity(); 8709 try { 8710 synchronized (this) { 8711 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8712 if (r == null) { 8713 return false; 8714 } 8715 if (r.changeWindowTranslucency(true)) { 8716 mWindowManager.setAppFullscreen(token, true); 8717 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8718 return true; 8719 } 8720 return false; 8721 } 8722 } finally { 8723 Binder.restoreCallingIdentity(origId); 8724 } 8725 } 8726 8727 @Override 8728 public boolean convertToTranslucent(IBinder token) { 8729 final long origId = Binder.clearCallingIdentity(); 8730 try { 8731 synchronized (this) { 8732 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8733 if (r == null) { 8734 return false; 8735 } 8736 if (r.changeWindowTranslucency(false)) { 8737 r.task.stack.convertToTranslucent(r); 8738 mWindowManager.setAppFullscreen(token, false); 8739 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8740 return true; 8741 } 8742 return false; 8743 } 8744 } finally { 8745 Binder.restoreCallingIdentity(origId); 8746 } 8747 } 8748 8749 @Override 8750 public void setImmersive(IBinder token, boolean immersive) { 8751 synchronized(this) { 8752 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8753 if (r == null) { 8754 throw new IllegalArgumentException(); 8755 } 8756 r.immersive = immersive; 8757 8758 // update associated state if we're frontmost 8759 if (r == mFocusedActivity) { 8760 if (DEBUG_IMMERSIVE) { 8761 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8762 } 8763 applyUpdateLockStateLocked(r); 8764 } 8765 } 8766 } 8767 8768 @Override 8769 public boolean isImmersive(IBinder token) { 8770 synchronized (this) { 8771 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8772 if (r == null) { 8773 throw new IllegalArgumentException(); 8774 } 8775 return r.immersive; 8776 } 8777 } 8778 8779 public boolean isTopActivityImmersive() { 8780 enforceNotIsolatedCaller("startActivity"); 8781 synchronized (this) { 8782 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8783 return (r != null) ? r.immersive : false; 8784 } 8785 } 8786 8787 public final void enterSafeMode() { 8788 synchronized(this) { 8789 // It only makes sense to do this before the system is ready 8790 // and started launching other packages. 8791 if (!mSystemReady) { 8792 try { 8793 AppGlobals.getPackageManager().enterSafeMode(); 8794 } catch (RemoteException e) { 8795 } 8796 } 8797 } 8798 } 8799 8800 public final void showSafeModeOverlay() { 8801 View v = LayoutInflater.from(mContext).inflate( 8802 com.android.internal.R.layout.safe_mode, null); 8803 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8804 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8805 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8806 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8807 lp.gravity = Gravity.BOTTOM | Gravity.START; 8808 lp.format = v.getBackground().getOpacity(); 8809 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8810 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8811 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8812 ((WindowManager)mContext.getSystemService( 8813 Context.WINDOW_SERVICE)).addView(v, lp); 8814 } 8815 8816 public void noteWakeupAlarm(IIntentSender sender) { 8817 if (!(sender instanceof PendingIntentRecord)) { 8818 return; 8819 } 8820 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8821 synchronized (stats) { 8822 if (mBatteryStatsService.isOnBattery()) { 8823 mBatteryStatsService.enforceCallingPermission(); 8824 PendingIntentRecord rec = (PendingIntentRecord)sender; 8825 int MY_UID = Binder.getCallingUid(); 8826 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8827 BatteryStatsImpl.Uid.Pkg pkg = 8828 stats.getPackageStatsLocked(uid, rec.key.packageName); 8829 pkg.incWakeupsLocked(); 8830 } 8831 } 8832 } 8833 8834 public boolean killPids(int[] pids, String pReason, boolean secure) { 8835 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8836 throw new SecurityException("killPids only available to the system"); 8837 } 8838 String reason = (pReason == null) ? "Unknown" : pReason; 8839 // XXX Note: don't acquire main activity lock here, because the window 8840 // manager calls in with its locks held. 8841 8842 boolean killed = false; 8843 synchronized (mPidsSelfLocked) { 8844 int[] types = new int[pids.length]; 8845 int worstType = 0; 8846 for (int i=0; i<pids.length; i++) { 8847 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8848 if (proc != null) { 8849 int type = proc.setAdj; 8850 types[i] = type; 8851 if (type > worstType) { 8852 worstType = type; 8853 } 8854 } 8855 } 8856 8857 // If the worst oom_adj is somewhere in the cached proc LRU range, 8858 // then constrain it so we will kill all cached procs. 8859 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8860 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8861 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8862 } 8863 8864 // If this is not a secure call, don't let it kill processes that 8865 // are important. 8866 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8867 worstType = ProcessList.SERVICE_ADJ; 8868 } 8869 8870 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8871 for (int i=0; i<pids.length; i++) { 8872 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8873 if (proc == null) { 8874 continue; 8875 } 8876 int adj = proc.setAdj; 8877 if (adj >= worstType && !proc.killedByAm) { 8878 killUnneededProcessLocked(proc, reason); 8879 killed = true; 8880 } 8881 } 8882 } 8883 return killed; 8884 } 8885 8886 @Override 8887 public void killUid(int uid, String reason) { 8888 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8889 throw new SecurityException("killUid only available to the system"); 8890 } 8891 synchronized (this) { 8892 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8893 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8894 reason != null ? reason : "kill uid"); 8895 } 8896 } 8897 8898 @Override 8899 public boolean killProcessesBelowForeground(String reason) { 8900 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8901 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8902 } 8903 8904 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8905 } 8906 8907 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8908 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8909 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8910 } 8911 8912 boolean killed = false; 8913 synchronized (mPidsSelfLocked) { 8914 final int size = mPidsSelfLocked.size(); 8915 for (int i = 0; i < size; i++) { 8916 final int pid = mPidsSelfLocked.keyAt(i); 8917 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8918 if (proc == null) continue; 8919 8920 final int adj = proc.setAdj; 8921 if (adj > belowAdj && !proc.killedByAm) { 8922 killUnneededProcessLocked(proc, reason); 8923 killed = true; 8924 } 8925 } 8926 } 8927 return killed; 8928 } 8929 8930 @Override 8931 public void hang(final IBinder who, boolean allowRestart) { 8932 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8933 != PackageManager.PERMISSION_GRANTED) { 8934 throw new SecurityException("Requires permission " 8935 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8936 } 8937 8938 final IBinder.DeathRecipient death = new DeathRecipient() { 8939 @Override 8940 public void binderDied() { 8941 synchronized (this) { 8942 notifyAll(); 8943 } 8944 } 8945 }; 8946 8947 try { 8948 who.linkToDeath(death, 0); 8949 } catch (RemoteException e) { 8950 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8951 return; 8952 } 8953 8954 synchronized (this) { 8955 Watchdog.getInstance().setAllowRestart(allowRestart); 8956 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8957 synchronized (death) { 8958 while (who.isBinderAlive()) { 8959 try { 8960 death.wait(); 8961 } catch (InterruptedException e) { 8962 } 8963 } 8964 } 8965 Watchdog.getInstance().setAllowRestart(true); 8966 } 8967 } 8968 8969 @Override 8970 public void restart() { 8971 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8972 != PackageManager.PERMISSION_GRANTED) { 8973 throw new SecurityException("Requires permission " 8974 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8975 } 8976 8977 Log.i(TAG, "Sending shutdown broadcast..."); 8978 8979 BroadcastReceiver br = new BroadcastReceiver() { 8980 @Override public void onReceive(Context context, Intent intent) { 8981 // Now the broadcast is done, finish up the low-level shutdown. 8982 Log.i(TAG, "Shutting down activity manager..."); 8983 shutdown(10000); 8984 Log.i(TAG, "Shutdown complete, restarting!"); 8985 Process.killProcess(Process.myPid()); 8986 System.exit(10); 8987 } 8988 }; 8989 8990 // First send the high-level shut down broadcast. 8991 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8992 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8993 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8994 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8995 mContext.sendOrderedBroadcastAsUser(intent, 8996 UserHandle.ALL, null, br, mHandler, 0, null, null); 8997 */ 8998 br.onReceive(mContext, intent); 8999 } 9000 9001 private long getLowRamTimeSinceIdle(long now) { 9002 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9003 } 9004 9005 @Override 9006 public void performIdleMaintenance() { 9007 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9008 != PackageManager.PERMISSION_GRANTED) { 9009 throw new SecurityException("Requires permission " 9010 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9011 } 9012 9013 synchronized (this) { 9014 final long now = SystemClock.uptimeMillis(); 9015 final long timeSinceLastIdle = now - mLastIdleTime; 9016 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9017 mLastIdleTime = now; 9018 mLowRamTimeSinceLastIdle = 0; 9019 if (mLowRamStartTime != 0) { 9020 mLowRamStartTime = now; 9021 } 9022 9023 StringBuilder sb = new StringBuilder(128); 9024 sb.append("Idle maintenance over "); 9025 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9026 sb.append(" low RAM for "); 9027 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9028 Slog.i(TAG, sb.toString()); 9029 9030 // If at least 1/3 of our time since the last idle period has been spent 9031 // with RAM low, then we want to kill processes. 9032 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9033 9034 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9035 ProcessRecord proc = mLruProcesses.get(i); 9036 if (proc.notCachedSinceIdle) { 9037 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9038 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9039 if (doKilling && proc.initialIdlePss != 0 9040 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9041 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9042 + " from " + proc.initialIdlePss + ")"); 9043 } 9044 } 9045 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9046 proc.notCachedSinceIdle = true; 9047 proc.initialIdlePss = 0; 9048 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9049 mSleeping, now); 9050 } 9051 } 9052 9053 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9054 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9055 } 9056 } 9057 9058 public final void startRunning(String pkg, String cls, String action, 9059 String data) { 9060 synchronized(this) { 9061 if (mStartRunning) { 9062 return; 9063 } 9064 mStartRunning = true; 9065 mTopComponent = pkg != null && cls != null 9066 ? new ComponentName(pkg, cls) : null; 9067 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9068 mTopData = data; 9069 if (!mSystemReady) { 9070 return; 9071 } 9072 } 9073 9074 systemReady(null); 9075 } 9076 9077 private void retrieveSettings() { 9078 final ContentResolver resolver = mContext.getContentResolver(); 9079 String debugApp = Settings.Global.getString( 9080 resolver, Settings.Global.DEBUG_APP); 9081 boolean waitForDebugger = Settings.Global.getInt( 9082 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9083 boolean alwaysFinishActivities = Settings.Global.getInt( 9084 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9085 boolean forceRtl = Settings.Global.getInt( 9086 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9087 // Transfer any global setting for forcing RTL layout, into a System Property 9088 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9089 9090 Configuration configuration = new Configuration(); 9091 Settings.System.getConfiguration(resolver, configuration); 9092 if (forceRtl) { 9093 // This will take care of setting the correct layout direction flags 9094 configuration.setLayoutDirection(configuration.locale); 9095 } 9096 9097 synchronized (this) { 9098 mDebugApp = mOrigDebugApp = debugApp; 9099 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9100 mAlwaysFinishActivities = alwaysFinishActivities; 9101 // This happens before any activities are started, so we can 9102 // change mConfiguration in-place. 9103 updateConfigurationLocked(configuration, null, false, true); 9104 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9105 } 9106 } 9107 9108 public boolean testIsSystemReady() { 9109 // no need to synchronize(this) just to read & return the value 9110 return mSystemReady; 9111 } 9112 9113 private static File getCalledPreBootReceiversFile() { 9114 File dataDir = Environment.getDataDirectory(); 9115 File systemDir = new File(dataDir, "system"); 9116 File fname = new File(systemDir, "called_pre_boots.dat"); 9117 return fname; 9118 } 9119 9120 static final int LAST_DONE_VERSION = 10000; 9121 9122 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9123 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9124 File file = getCalledPreBootReceiversFile(); 9125 FileInputStream fis = null; 9126 try { 9127 fis = new FileInputStream(file); 9128 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9129 int fvers = dis.readInt(); 9130 if (fvers == LAST_DONE_VERSION) { 9131 String vers = dis.readUTF(); 9132 String codename = dis.readUTF(); 9133 String build = dis.readUTF(); 9134 if (android.os.Build.VERSION.RELEASE.equals(vers) 9135 && android.os.Build.VERSION.CODENAME.equals(codename) 9136 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9137 int num = dis.readInt(); 9138 while (num > 0) { 9139 num--; 9140 String pkg = dis.readUTF(); 9141 String cls = dis.readUTF(); 9142 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9143 } 9144 } 9145 } 9146 } catch (FileNotFoundException e) { 9147 } catch (IOException e) { 9148 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9149 } finally { 9150 if (fis != null) { 9151 try { 9152 fis.close(); 9153 } catch (IOException e) { 9154 } 9155 } 9156 } 9157 return lastDoneReceivers; 9158 } 9159 9160 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9161 File file = getCalledPreBootReceiversFile(); 9162 FileOutputStream fos = null; 9163 DataOutputStream dos = null; 9164 try { 9165 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9166 fos = new FileOutputStream(file); 9167 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9168 dos.writeInt(LAST_DONE_VERSION); 9169 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9170 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9171 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9172 dos.writeInt(list.size()); 9173 for (int i=0; i<list.size(); i++) { 9174 dos.writeUTF(list.get(i).getPackageName()); 9175 dos.writeUTF(list.get(i).getClassName()); 9176 } 9177 } catch (IOException e) { 9178 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9179 file.delete(); 9180 } finally { 9181 FileUtils.sync(fos); 9182 if (dos != null) { 9183 try { 9184 dos.close(); 9185 } catch (IOException e) { 9186 // TODO Auto-generated catch block 9187 e.printStackTrace(); 9188 } 9189 } 9190 } 9191 } 9192 9193 public void systemReady(final Runnable goingCallback) { 9194 synchronized(this) { 9195 if (mSystemReady) { 9196 if (goingCallback != null) goingCallback.run(); 9197 return; 9198 } 9199 9200 // Check to see if there are any update receivers to run. 9201 if (!mDidUpdate) { 9202 if (mWaitingUpdate) { 9203 return; 9204 } 9205 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9206 List<ResolveInfo> ris = null; 9207 try { 9208 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9209 intent, null, 0, 0); 9210 } catch (RemoteException e) { 9211 } 9212 if (ris != null) { 9213 for (int i=ris.size()-1; i>=0; i--) { 9214 if ((ris.get(i).activityInfo.applicationInfo.flags 9215 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9216 ris.remove(i); 9217 } 9218 } 9219 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9220 9221 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9222 9223 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9224 for (int i=0; i<ris.size(); i++) { 9225 ActivityInfo ai = ris.get(i).activityInfo; 9226 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9227 if (lastDoneReceivers.contains(comp)) { 9228 // We already did the pre boot receiver for this app with the current 9229 // platform version, so don't do it again... 9230 ris.remove(i); 9231 i--; 9232 // ...however, do keep it as one that has been done, so we don't 9233 // forget about it when rewriting the file of last done receivers. 9234 doneReceivers.add(comp); 9235 } 9236 } 9237 9238 final int[] users = getUsersLocked(); 9239 for (int i=0; i<ris.size(); i++) { 9240 ActivityInfo ai = ris.get(i).activityInfo; 9241 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9242 doneReceivers.add(comp); 9243 intent.setComponent(comp); 9244 for (int j=0; j<users.length; j++) { 9245 IIntentReceiver finisher = null; 9246 if (i == ris.size()-1 && j == users.length-1) { 9247 finisher = new IIntentReceiver.Stub() { 9248 public void performReceive(Intent intent, int resultCode, 9249 String data, Bundle extras, boolean ordered, 9250 boolean sticky, int sendingUser) { 9251 // The raw IIntentReceiver interface is called 9252 // with the AM lock held, so redispatch to 9253 // execute our code without the lock. 9254 mHandler.post(new Runnable() { 9255 public void run() { 9256 synchronized (ActivityManagerService.this) { 9257 mDidUpdate = true; 9258 } 9259 writeLastDonePreBootReceivers(doneReceivers); 9260 showBootMessage(mContext.getText( 9261 R.string.android_upgrading_complete), 9262 false); 9263 systemReady(goingCallback); 9264 } 9265 }); 9266 } 9267 }; 9268 } 9269 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9270 + " for user " + users[j]); 9271 broadcastIntentLocked(null, null, intent, null, finisher, 9272 0, null, null, null, AppOpsManager.OP_NONE, 9273 true, false, MY_PID, Process.SYSTEM_UID, 9274 users[j]); 9275 if (finisher != null) { 9276 mWaitingUpdate = true; 9277 } 9278 } 9279 } 9280 } 9281 if (mWaitingUpdate) { 9282 return; 9283 } 9284 mDidUpdate = true; 9285 } 9286 9287 mAppOpsService.systemReady(); 9288 mSystemReady = true; 9289 if (!mStartRunning) { 9290 return; 9291 } 9292 } 9293 9294 ArrayList<ProcessRecord> procsToKill = null; 9295 synchronized(mPidsSelfLocked) { 9296 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9297 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9298 if (!isAllowedWhileBooting(proc.info)){ 9299 if (procsToKill == null) { 9300 procsToKill = new ArrayList<ProcessRecord>(); 9301 } 9302 procsToKill.add(proc); 9303 } 9304 } 9305 } 9306 9307 synchronized(this) { 9308 if (procsToKill != null) { 9309 for (int i=procsToKill.size()-1; i>=0; i--) { 9310 ProcessRecord proc = procsToKill.get(i); 9311 Slog.i(TAG, "Removing system update proc: " + proc); 9312 removeProcessLocked(proc, true, false, "system update done"); 9313 } 9314 } 9315 9316 // Now that we have cleaned up any update processes, we 9317 // are ready to start launching real processes and know that 9318 // we won't trample on them any more. 9319 mProcessesReady = true; 9320 } 9321 9322 Slog.i(TAG, "System now ready"); 9323 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9324 SystemClock.uptimeMillis()); 9325 9326 synchronized(this) { 9327 // Make sure we have no pre-ready processes sitting around. 9328 9329 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 9330 ResolveInfo ri = mContext.getPackageManager() 9331 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9332 STOCK_PM_FLAGS); 9333 CharSequence errorMsg = null; 9334 if (ri != null) { 9335 ActivityInfo ai = ri.activityInfo; 9336 ApplicationInfo app = ai.applicationInfo; 9337 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9338 mTopAction = Intent.ACTION_FACTORY_TEST; 9339 mTopData = null; 9340 mTopComponent = new ComponentName(app.packageName, 9341 ai.name); 9342 } else { 9343 errorMsg = mContext.getResources().getText( 9344 com.android.internal.R.string.factorytest_not_system); 9345 } 9346 } else { 9347 errorMsg = mContext.getResources().getText( 9348 com.android.internal.R.string.factorytest_no_action); 9349 } 9350 if (errorMsg != null) { 9351 mTopAction = null; 9352 mTopData = null; 9353 mTopComponent = null; 9354 Message msg = Message.obtain(); 9355 msg.what = SHOW_FACTORY_ERROR_MSG; 9356 msg.getData().putCharSequence("msg", errorMsg); 9357 mHandler.sendMessage(msg); 9358 } 9359 } 9360 } 9361 9362 retrieveSettings(); 9363 9364 synchronized (this) { 9365 readGrantedUriPermissionsLocked(); 9366 } 9367 9368 if (goingCallback != null) goingCallback.run(); 9369 9370 synchronized (this) { 9371 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 9372 try { 9373 List apps = AppGlobals.getPackageManager(). 9374 getPersistentApplications(STOCK_PM_FLAGS); 9375 if (apps != null) { 9376 int N = apps.size(); 9377 int i; 9378 for (i=0; i<N; i++) { 9379 ApplicationInfo info 9380 = (ApplicationInfo)apps.get(i); 9381 if (info != null && 9382 !info.packageName.equals("android")) { 9383 addAppLocked(info, false); 9384 } 9385 } 9386 } 9387 } catch (RemoteException ex) { 9388 // pm is in same process, this will never happen. 9389 } 9390 } 9391 9392 // Start up initial activity. 9393 mBooting = true; 9394 9395 try { 9396 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9397 Message msg = Message.obtain(); 9398 msg.what = SHOW_UID_ERROR_MSG; 9399 mHandler.sendMessage(msg); 9400 } 9401 } catch (RemoteException e) { 9402 } 9403 9404 long ident = Binder.clearCallingIdentity(); 9405 try { 9406 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9407 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9408 | Intent.FLAG_RECEIVER_FOREGROUND); 9409 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9410 broadcastIntentLocked(null, null, intent, 9411 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9412 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9413 intent = new Intent(Intent.ACTION_USER_STARTING); 9414 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9415 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9416 broadcastIntentLocked(null, null, intent, 9417 null, new IIntentReceiver.Stub() { 9418 @Override 9419 public void performReceive(Intent intent, int resultCode, String data, 9420 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9421 throws RemoteException { 9422 } 9423 }, 0, null, null, 9424 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9425 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9426 } finally { 9427 Binder.restoreCallingIdentity(ident); 9428 } 9429 mStackSupervisor.resumeTopActivitiesLocked(); 9430 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9431 } 9432 } 9433 9434 private boolean makeAppCrashingLocked(ProcessRecord app, 9435 String shortMsg, String longMsg, String stackTrace) { 9436 app.crashing = true; 9437 app.crashingReport = generateProcessError(app, 9438 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9439 startAppProblemLocked(app); 9440 app.stopFreezingAllLocked(); 9441 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9442 } 9443 9444 private void makeAppNotRespondingLocked(ProcessRecord app, 9445 String activity, String shortMsg, String longMsg) { 9446 app.notResponding = true; 9447 app.notRespondingReport = generateProcessError(app, 9448 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9449 activity, shortMsg, longMsg, null); 9450 startAppProblemLocked(app); 9451 app.stopFreezingAllLocked(); 9452 } 9453 9454 /** 9455 * Generate a process error record, suitable for attachment to a ProcessRecord. 9456 * 9457 * @param app The ProcessRecord in which the error occurred. 9458 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9459 * ActivityManager.AppErrorStateInfo 9460 * @param activity The activity associated with the crash, if known. 9461 * @param shortMsg Short message describing the crash. 9462 * @param longMsg Long message describing the crash. 9463 * @param stackTrace Full crash stack trace, may be null. 9464 * 9465 * @return Returns a fully-formed AppErrorStateInfo record. 9466 */ 9467 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9468 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9469 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9470 9471 report.condition = condition; 9472 report.processName = app.processName; 9473 report.pid = app.pid; 9474 report.uid = app.info.uid; 9475 report.tag = activity; 9476 report.shortMsg = shortMsg; 9477 report.longMsg = longMsg; 9478 report.stackTrace = stackTrace; 9479 9480 return report; 9481 } 9482 9483 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9484 synchronized (this) { 9485 app.crashing = false; 9486 app.crashingReport = null; 9487 app.notResponding = false; 9488 app.notRespondingReport = null; 9489 if (app.anrDialog == fromDialog) { 9490 app.anrDialog = null; 9491 } 9492 if (app.waitDialog == fromDialog) { 9493 app.waitDialog = null; 9494 } 9495 if (app.pid > 0 && app.pid != MY_PID) { 9496 handleAppCrashLocked(app, null, null, null); 9497 killUnneededProcessLocked(app, "user request after error"); 9498 } 9499 } 9500 } 9501 9502 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9503 String stackTrace) { 9504 if (mHeadless) { 9505 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 9506 return false; 9507 } 9508 long now = SystemClock.uptimeMillis(); 9509 9510 Long crashTime; 9511 if (!app.isolated) { 9512 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9513 } else { 9514 crashTime = null; 9515 } 9516 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9517 // This process loses! 9518 Slog.w(TAG, "Process " + app.info.processName 9519 + " has crashed too many times: killing!"); 9520 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9521 app.userId, app.info.processName, app.uid); 9522 mStackSupervisor.handleAppCrashLocked(app); 9523 if (!app.persistent) { 9524 // We don't want to start this process again until the user 9525 // explicitly does so... but for persistent process, we really 9526 // need to keep it running. If a persistent process is actually 9527 // repeatedly crashing, then badness for everyone. 9528 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9529 app.info.processName); 9530 if (!app.isolated) { 9531 // XXX We don't have a way to mark isolated processes 9532 // as bad, since they don't have a peristent identity. 9533 mBadProcesses.put(app.info.processName, app.uid, 9534 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9535 mProcessCrashTimes.remove(app.info.processName, app.uid); 9536 } 9537 app.bad = true; 9538 app.removed = true; 9539 // Don't let services in this process be restarted and potentially 9540 // annoy the user repeatedly. Unless it is persistent, since those 9541 // processes run critical code. 9542 removeProcessLocked(app, false, false, "crash"); 9543 mStackSupervisor.resumeTopActivitiesLocked(); 9544 return false; 9545 } 9546 mStackSupervisor.resumeTopActivitiesLocked(); 9547 } else { 9548 mStackSupervisor.finishTopRunningActivityLocked(app); 9549 } 9550 9551 // Bump up the crash count of any services currently running in the proc. 9552 for (int i=app.services.size()-1; i>=0; i--) { 9553 // Any services running in the application need to be placed 9554 // back in the pending list. 9555 ServiceRecord sr = app.services.valueAt(i); 9556 sr.crashCount++; 9557 } 9558 9559 // If the crashing process is what we consider to be the "home process" and it has been 9560 // replaced by a third-party app, clear the package preferred activities from packages 9561 // with a home activity running in the process to prevent a repeatedly crashing app 9562 // from blocking the user to manually clear the list. 9563 final ArrayList<ActivityRecord> activities = app.activities; 9564 if (app == mHomeProcess && activities.size() > 0 9565 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9566 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9567 final ActivityRecord r = activities.get(activityNdx); 9568 if (r.isHomeActivity()) { 9569 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9570 try { 9571 ActivityThread.getPackageManager() 9572 .clearPackagePreferredActivities(r.packageName); 9573 } catch (RemoteException c) { 9574 // pm is in same process, this will never happen. 9575 } 9576 } 9577 } 9578 } 9579 9580 if (!app.isolated) { 9581 // XXX Can't keep track of crash times for isolated processes, 9582 // because they don't have a perisistent identity. 9583 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9584 } 9585 9586 return true; 9587 } 9588 9589 void startAppProblemLocked(ProcessRecord app) { 9590 if (app.userId == mCurrentUserId) { 9591 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9592 mContext, app.info.packageName, app.info.flags); 9593 } else { 9594 // If this app is not running under the current user, then we 9595 // can't give it a report button because that would require 9596 // launching the report UI under a different user. 9597 app.errorReportReceiver = null; 9598 } 9599 skipCurrentReceiverLocked(app); 9600 } 9601 9602 void skipCurrentReceiverLocked(ProcessRecord app) { 9603 for (BroadcastQueue queue : mBroadcastQueues) { 9604 queue.skipCurrentReceiverLocked(app); 9605 } 9606 } 9607 9608 /** 9609 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9610 * The application process will exit immediately after this call returns. 9611 * @param app object of the crashing app, null for the system server 9612 * @param crashInfo describing the exception 9613 */ 9614 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9615 ProcessRecord r = findAppProcess(app, "Crash"); 9616 final String processName = app == null ? "system_server" 9617 : (r == null ? "unknown" : r.processName); 9618 9619 handleApplicationCrashInner("crash", r, processName, crashInfo); 9620 } 9621 9622 /* Native crash reporting uses this inner version because it needs to be somewhat 9623 * decoupled from the AM-managed cleanup lifecycle 9624 */ 9625 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9626 ApplicationErrorReport.CrashInfo crashInfo) { 9627 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9628 UserHandle.getUserId(Binder.getCallingUid()), processName, 9629 r == null ? -1 : r.info.flags, 9630 crashInfo.exceptionClassName, 9631 crashInfo.exceptionMessage, 9632 crashInfo.throwFileName, 9633 crashInfo.throwLineNumber); 9634 9635 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9636 9637 crashApplication(r, crashInfo); 9638 } 9639 9640 public void handleApplicationStrictModeViolation( 9641 IBinder app, 9642 int violationMask, 9643 StrictMode.ViolationInfo info) { 9644 ProcessRecord r = findAppProcess(app, "StrictMode"); 9645 if (r == null) { 9646 return; 9647 } 9648 9649 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9650 Integer stackFingerprint = info.hashCode(); 9651 boolean logIt = true; 9652 synchronized (mAlreadyLoggedViolatedStacks) { 9653 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9654 logIt = false; 9655 // TODO: sub-sample into EventLog for these, with 9656 // the info.durationMillis? Then we'd get 9657 // the relative pain numbers, without logging all 9658 // the stack traces repeatedly. We'd want to do 9659 // likewise in the client code, which also does 9660 // dup suppression, before the Binder call. 9661 } else { 9662 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9663 mAlreadyLoggedViolatedStacks.clear(); 9664 } 9665 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9666 } 9667 } 9668 if (logIt) { 9669 logStrictModeViolationToDropBox(r, info); 9670 } 9671 } 9672 9673 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9674 AppErrorResult result = new AppErrorResult(); 9675 synchronized (this) { 9676 final long origId = Binder.clearCallingIdentity(); 9677 9678 Message msg = Message.obtain(); 9679 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9680 HashMap<String, Object> data = new HashMap<String, Object>(); 9681 data.put("result", result); 9682 data.put("app", r); 9683 data.put("violationMask", violationMask); 9684 data.put("info", info); 9685 msg.obj = data; 9686 mHandler.sendMessage(msg); 9687 9688 Binder.restoreCallingIdentity(origId); 9689 } 9690 int res = result.get(); 9691 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9692 } 9693 } 9694 9695 // Depending on the policy in effect, there could be a bunch of 9696 // these in quick succession so we try to batch these together to 9697 // minimize disk writes, number of dropbox entries, and maximize 9698 // compression, by having more fewer, larger records. 9699 private void logStrictModeViolationToDropBox( 9700 ProcessRecord process, 9701 StrictMode.ViolationInfo info) { 9702 if (info == null) { 9703 return; 9704 } 9705 final boolean isSystemApp = process == null || 9706 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9707 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9708 final String processName = process == null ? "unknown" : process.processName; 9709 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9710 final DropBoxManager dbox = (DropBoxManager) 9711 mContext.getSystemService(Context.DROPBOX_SERVICE); 9712 9713 // Exit early if the dropbox isn't configured to accept this report type. 9714 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9715 9716 boolean bufferWasEmpty; 9717 boolean needsFlush; 9718 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9719 synchronized (sb) { 9720 bufferWasEmpty = sb.length() == 0; 9721 appendDropBoxProcessHeaders(process, processName, sb); 9722 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9723 sb.append("System-App: ").append(isSystemApp).append("\n"); 9724 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9725 if (info.violationNumThisLoop != 0) { 9726 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9727 } 9728 if (info.numAnimationsRunning != 0) { 9729 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9730 } 9731 if (info.broadcastIntentAction != null) { 9732 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9733 } 9734 if (info.durationMillis != -1) { 9735 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9736 } 9737 if (info.numInstances != -1) { 9738 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9739 } 9740 if (info.tags != null) { 9741 for (String tag : info.tags) { 9742 sb.append("Span-Tag: ").append(tag).append("\n"); 9743 } 9744 } 9745 sb.append("\n"); 9746 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9747 sb.append(info.crashInfo.stackTrace); 9748 } 9749 sb.append("\n"); 9750 9751 // Only buffer up to ~64k. Various logging bits truncate 9752 // things at 128k. 9753 needsFlush = (sb.length() > 64 * 1024); 9754 } 9755 9756 // Flush immediately if the buffer's grown too large, or this 9757 // is a non-system app. Non-system apps are isolated with a 9758 // different tag & policy and not batched. 9759 // 9760 // Batching is useful during internal testing with 9761 // StrictMode settings turned up high. Without batching, 9762 // thousands of separate files could be created on boot. 9763 if (!isSystemApp || needsFlush) { 9764 new Thread("Error dump: " + dropboxTag) { 9765 @Override 9766 public void run() { 9767 String report; 9768 synchronized (sb) { 9769 report = sb.toString(); 9770 sb.delete(0, sb.length()); 9771 sb.trimToSize(); 9772 } 9773 if (report.length() != 0) { 9774 dbox.addText(dropboxTag, report); 9775 } 9776 } 9777 }.start(); 9778 return; 9779 } 9780 9781 // System app batching: 9782 if (!bufferWasEmpty) { 9783 // An existing dropbox-writing thread is outstanding, so 9784 // we don't need to start it up. The existing thread will 9785 // catch the buffer appends we just did. 9786 return; 9787 } 9788 9789 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9790 // (After this point, we shouldn't access AMS internal data structures.) 9791 new Thread("Error dump: " + dropboxTag) { 9792 @Override 9793 public void run() { 9794 // 5 second sleep to let stacks arrive and be batched together 9795 try { 9796 Thread.sleep(5000); // 5 seconds 9797 } catch (InterruptedException e) {} 9798 9799 String errorReport; 9800 synchronized (mStrictModeBuffer) { 9801 errorReport = mStrictModeBuffer.toString(); 9802 if (errorReport.length() == 0) { 9803 return; 9804 } 9805 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9806 mStrictModeBuffer.trimToSize(); 9807 } 9808 dbox.addText(dropboxTag, errorReport); 9809 } 9810 }.start(); 9811 } 9812 9813 /** 9814 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9815 * @param app object of the crashing app, null for the system server 9816 * @param tag reported by the caller 9817 * @param crashInfo describing the context of the error 9818 * @return true if the process should exit immediately (WTF is fatal) 9819 */ 9820 public boolean handleApplicationWtf(IBinder app, String tag, 9821 ApplicationErrorReport.CrashInfo crashInfo) { 9822 ProcessRecord r = findAppProcess(app, "WTF"); 9823 final String processName = app == null ? "system_server" 9824 : (r == null ? "unknown" : r.processName); 9825 9826 EventLog.writeEvent(EventLogTags.AM_WTF, 9827 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9828 processName, 9829 r == null ? -1 : r.info.flags, 9830 tag, crashInfo.exceptionMessage); 9831 9832 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9833 9834 if (r != null && r.pid != Process.myPid() && 9835 Settings.Global.getInt(mContext.getContentResolver(), 9836 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9837 crashApplication(r, crashInfo); 9838 return true; 9839 } else { 9840 return false; 9841 } 9842 } 9843 9844 /** 9845 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9846 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9847 */ 9848 private ProcessRecord findAppProcess(IBinder app, String reason) { 9849 if (app == null) { 9850 return null; 9851 } 9852 9853 synchronized (this) { 9854 final int NP = mProcessNames.getMap().size(); 9855 for (int ip=0; ip<NP; ip++) { 9856 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9857 final int NA = apps.size(); 9858 for (int ia=0; ia<NA; ia++) { 9859 ProcessRecord p = apps.valueAt(ia); 9860 if (p.thread != null && p.thread.asBinder() == app) { 9861 return p; 9862 } 9863 } 9864 } 9865 9866 Slog.w(TAG, "Can't find mystery application for " + reason 9867 + " from pid=" + Binder.getCallingPid() 9868 + " uid=" + Binder.getCallingUid() + ": " + app); 9869 return null; 9870 } 9871 } 9872 9873 /** 9874 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9875 * to append various headers to the dropbox log text. 9876 */ 9877 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9878 StringBuilder sb) { 9879 // Watchdog thread ends up invoking this function (with 9880 // a null ProcessRecord) to add the stack file to dropbox. 9881 // Do not acquire a lock on this (am) in such cases, as it 9882 // could cause a potential deadlock, if and when watchdog 9883 // is invoked due to unavailability of lock on am and it 9884 // would prevent watchdog from killing system_server. 9885 if (process == null) { 9886 sb.append("Process: ").append(processName).append("\n"); 9887 return; 9888 } 9889 // Note: ProcessRecord 'process' is guarded by the service 9890 // instance. (notably process.pkgList, which could otherwise change 9891 // concurrently during execution of this method) 9892 synchronized (this) { 9893 sb.append("Process: ").append(processName).append("\n"); 9894 int flags = process.info.flags; 9895 IPackageManager pm = AppGlobals.getPackageManager(); 9896 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9897 for (int ip=0; ip<process.pkgList.size(); ip++) { 9898 String pkg = process.pkgList.keyAt(ip); 9899 sb.append("Package: ").append(pkg); 9900 try { 9901 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9902 if (pi != null) { 9903 sb.append(" v").append(pi.versionCode); 9904 if (pi.versionName != null) { 9905 sb.append(" (").append(pi.versionName).append(")"); 9906 } 9907 } 9908 } catch (RemoteException e) { 9909 Slog.e(TAG, "Error getting package info: " + pkg, e); 9910 } 9911 sb.append("\n"); 9912 } 9913 } 9914 } 9915 9916 private static String processClass(ProcessRecord process) { 9917 if (process == null || process.pid == MY_PID) { 9918 return "system_server"; 9919 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9920 return "system_app"; 9921 } else { 9922 return "data_app"; 9923 } 9924 } 9925 9926 /** 9927 * Write a description of an error (crash, WTF, ANR) to the drop box. 9928 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9929 * @param process which caused the error, null means the system server 9930 * @param activity which triggered the error, null if unknown 9931 * @param parent activity related to the error, null if unknown 9932 * @param subject line related to the error, null if absent 9933 * @param report in long form describing the error, null if absent 9934 * @param logFile to include in the report, null if none 9935 * @param crashInfo giving an application stack trace, null if absent 9936 */ 9937 public void addErrorToDropBox(String eventType, 9938 ProcessRecord process, String processName, ActivityRecord activity, 9939 ActivityRecord parent, String subject, 9940 final String report, final File logFile, 9941 final ApplicationErrorReport.CrashInfo crashInfo) { 9942 // NOTE -- this must never acquire the ActivityManagerService lock, 9943 // otherwise the watchdog may be prevented from resetting the system. 9944 9945 final String dropboxTag = processClass(process) + "_" + eventType; 9946 final DropBoxManager dbox = (DropBoxManager) 9947 mContext.getSystemService(Context.DROPBOX_SERVICE); 9948 9949 // Exit early if the dropbox isn't configured to accept this report type. 9950 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9951 9952 final StringBuilder sb = new StringBuilder(1024); 9953 appendDropBoxProcessHeaders(process, processName, sb); 9954 if (activity != null) { 9955 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9956 } 9957 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9958 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9959 } 9960 if (parent != null && parent != activity) { 9961 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9962 } 9963 if (subject != null) { 9964 sb.append("Subject: ").append(subject).append("\n"); 9965 } 9966 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9967 if (Debug.isDebuggerConnected()) { 9968 sb.append("Debugger: Connected\n"); 9969 } 9970 sb.append("\n"); 9971 9972 // Do the rest in a worker thread to avoid blocking the caller on I/O 9973 // (After this point, we shouldn't access AMS internal data structures.) 9974 Thread worker = new Thread("Error dump: " + dropboxTag) { 9975 @Override 9976 public void run() { 9977 if (report != null) { 9978 sb.append(report); 9979 } 9980 if (logFile != null) { 9981 try { 9982 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9983 "\n\n[[TRUNCATED]]")); 9984 } catch (IOException e) { 9985 Slog.e(TAG, "Error reading " + logFile, e); 9986 } 9987 } 9988 if (crashInfo != null && crashInfo.stackTrace != null) { 9989 sb.append(crashInfo.stackTrace); 9990 } 9991 9992 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9993 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9994 if (lines > 0) { 9995 sb.append("\n"); 9996 9997 // Merge several logcat streams, and take the last N lines 9998 InputStreamReader input = null; 9999 try { 10000 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10001 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10002 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10003 10004 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10005 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10006 input = new InputStreamReader(logcat.getInputStream()); 10007 10008 int num; 10009 char[] buf = new char[8192]; 10010 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10011 } catch (IOException e) { 10012 Slog.e(TAG, "Error running logcat", e); 10013 } finally { 10014 if (input != null) try { input.close(); } catch (IOException e) {} 10015 } 10016 } 10017 10018 dbox.addText(dropboxTag, sb.toString()); 10019 } 10020 }; 10021 10022 if (process == null) { 10023 // If process is null, we are being called from some internal code 10024 // and may be about to die -- run this synchronously. 10025 worker.run(); 10026 } else { 10027 worker.start(); 10028 } 10029 } 10030 10031 /** 10032 * Bring up the "unexpected error" dialog box for a crashing app. 10033 * Deal with edge cases (intercepts from instrumented applications, 10034 * ActivityController, error intent receivers, that sort of thing). 10035 * @param r the application crashing 10036 * @param crashInfo describing the failure 10037 */ 10038 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10039 long timeMillis = System.currentTimeMillis(); 10040 String shortMsg = crashInfo.exceptionClassName; 10041 String longMsg = crashInfo.exceptionMessage; 10042 String stackTrace = crashInfo.stackTrace; 10043 if (shortMsg != null && longMsg != null) { 10044 longMsg = shortMsg + ": " + longMsg; 10045 } else if (shortMsg != null) { 10046 longMsg = shortMsg; 10047 } 10048 10049 AppErrorResult result = new AppErrorResult(); 10050 synchronized (this) { 10051 if (mController != null) { 10052 try { 10053 String name = r != null ? r.processName : null; 10054 int pid = r != null ? r.pid : Binder.getCallingPid(); 10055 if (!mController.appCrashed(name, pid, 10056 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10057 Slog.w(TAG, "Force-killing crashed app " + name 10058 + " at watcher's request"); 10059 Process.killProcess(pid); 10060 return; 10061 } 10062 } catch (RemoteException e) { 10063 mController = null; 10064 Watchdog.getInstance().setActivityController(null); 10065 } 10066 } 10067 10068 final long origId = Binder.clearCallingIdentity(); 10069 10070 // If this process is running instrumentation, finish it. 10071 if (r != null && r.instrumentationClass != null) { 10072 Slog.w(TAG, "Error in app " + r.processName 10073 + " running instrumentation " + r.instrumentationClass + ":"); 10074 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10075 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10076 Bundle info = new Bundle(); 10077 info.putString("shortMsg", shortMsg); 10078 info.putString("longMsg", longMsg); 10079 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10080 Binder.restoreCallingIdentity(origId); 10081 return; 10082 } 10083 10084 // If we can't identify the process or it's already exceeded its crash quota, 10085 // quit right away without showing a crash dialog. 10086 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10087 Binder.restoreCallingIdentity(origId); 10088 return; 10089 } 10090 10091 Message msg = Message.obtain(); 10092 msg.what = SHOW_ERROR_MSG; 10093 HashMap data = new HashMap(); 10094 data.put("result", result); 10095 data.put("app", r); 10096 msg.obj = data; 10097 mHandler.sendMessage(msg); 10098 10099 Binder.restoreCallingIdentity(origId); 10100 } 10101 10102 int res = result.get(); 10103 10104 Intent appErrorIntent = null; 10105 synchronized (this) { 10106 if (r != null && !r.isolated) { 10107 // XXX Can't keep track of crash time for isolated processes, 10108 // since they don't have a persistent identity. 10109 mProcessCrashTimes.put(r.info.processName, r.uid, 10110 SystemClock.uptimeMillis()); 10111 } 10112 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10113 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10114 } 10115 } 10116 10117 if (appErrorIntent != null) { 10118 try { 10119 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10120 } catch (ActivityNotFoundException e) { 10121 Slog.w(TAG, "bug report receiver dissappeared", e); 10122 } 10123 } 10124 } 10125 10126 Intent createAppErrorIntentLocked(ProcessRecord r, 10127 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10128 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10129 if (report == null) { 10130 return null; 10131 } 10132 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10133 result.setComponent(r.errorReportReceiver); 10134 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10135 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10136 return result; 10137 } 10138 10139 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10140 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10141 if (r.errorReportReceiver == null) { 10142 return null; 10143 } 10144 10145 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10146 return null; 10147 } 10148 10149 ApplicationErrorReport report = new ApplicationErrorReport(); 10150 report.packageName = r.info.packageName; 10151 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10152 report.processName = r.processName; 10153 report.time = timeMillis; 10154 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10155 10156 if (r.crashing || r.forceCrashReport) { 10157 report.type = ApplicationErrorReport.TYPE_CRASH; 10158 report.crashInfo = crashInfo; 10159 } else if (r.notResponding) { 10160 report.type = ApplicationErrorReport.TYPE_ANR; 10161 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10162 10163 report.anrInfo.activity = r.notRespondingReport.tag; 10164 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10165 report.anrInfo.info = r.notRespondingReport.longMsg; 10166 } 10167 10168 return report; 10169 } 10170 10171 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10172 enforceNotIsolatedCaller("getProcessesInErrorState"); 10173 // assume our apps are happy - lazy create the list 10174 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10175 10176 final boolean allUsers = ActivityManager.checkUidPermission( 10177 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10178 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10179 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10180 10181 synchronized (this) { 10182 10183 // iterate across all processes 10184 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10185 ProcessRecord app = mLruProcesses.get(i); 10186 if (!allUsers && app.userId != userId) { 10187 continue; 10188 } 10189 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10190 // This one's in trouble, so we'll generate a report for it 10191 // crashes are higher priority (in case there's a crash *and* an anr) 10192 ActivityManager.ProcessErrorStateInfo report = null; 10193 if (app.crashing) { 10194 report = app.crashingReport; 10195 } else if (app.notResponding) { 10196 report = app.notRespondingReport; 10197 } 10198 10199 if (report != null) { 10200 if (errList == null) { 10201 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10202 } 10203 errList.add(report); 10204 } else { 10205 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10206 " crashing = " + app.crashing + 10207 " notResponding = " + app.notResponding); 10208 } 10209 } 10210 } 10211 } 10212 10213 return errList; 10214 } 10215 10216 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10217 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10218 if (currApp != null) { 10219 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10220 } 10221 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10222 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10223 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10224 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10225 if (currApp != null) { 10226 currApp.lru = 0; 10227 } 10228 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10229 } else if (adj >= ProcessList.SERVICE_ADJ) { 10230 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10231 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10232 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10233 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10234 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10235 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10236 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10237 } else { 10238 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10239 } 10240 } 10241 10242 private void fillInProcMemInfo(ProcessRecord app, 10243 ActivityManager.RunningAppProcessInfo outInfo) { 10244 outInfo.pid = app.pid; 10245 outInfo.uid = app.info.uid; 10246 if (mHeavyWeightProcess == app) { 10247 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10248 } 10249 if (app.persistent) { 10250 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10251 } 10252 if (app.activities.size() > 0) { 10253 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10254 } 10255 outInfo.lastTrimLevel = app.trimMemoryLevel; 10256 int adj = app.curAdj; 10257 outInfo.importance = oomAdjToImportance(adj, outInfo); 10258 outInfo.importanceReasonCode = app.adjTypeCode; 10259 } 10260 10261 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10262 enforceNotIsolatedCaller("getRunningAppProcesses"); 10263 // Lazy instantiation of list 10264 List<ActivityManager.RunningAppProcessInfo> runList = null; 10265 final boolean allUsers = ActivityManager.checkUidPermission( 10266 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10267 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10268 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10269 synchronized (this) { 10270 // Iterate across all processes 10271 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10272 ProcessRecord app = mLruProcesses.get(i); 10273 if (!allUsers && app.userId != userId) { 10274 continue; 10275 } 10276 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10277 // Generate process state info for running application 10278 ActivityManager.RunningAppProcessInfo currApp = 10279 new ActivityManager.RunningAppProcessInfo(app.processName, 10280 app.pid, app.getPackageList()); 10281 fillInProcMemInfo(app, currApp); 10282 if (app.adjSource instanceof ProcessRecord) { 10283 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10284 currApp.importanceReasonImportance = oomAdjToImportance( 10285 app.adjSourceOom, null); 10286 } else if (app.adjSource instanceof ActivityRecord) { 10287 ActivityRecord r = (ActivityRecord)app.adjSource; 10288 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10289 } 10290 if (app.adjTarget instanceof ComponentName) { 10291 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10292 } 10293 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10294 // + " lru=" + currApp.lru); 10295 if (runList == null) { 10296 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10297 } 10298 runList.add(currApp); 10299 } 10300 } 10301 } 10302 return runList; 10303 } 10304 10305 public List<ApplicationInfo> getRunningExternalApplications() { 10306 enforceNotIsolatedCaller("getRunningExternalApplications"); 10307 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10308 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10309 if (runningApps != null && runningApps.size() > 0) { 10310 Set<String> extList = new HashSet<String>(); 10311 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10312 if (app.pkgList != null) { 10313 for (String pkg : app.pkgList) { 10314 extList.add(pkg); 10315 } 10316 } 10317 } 10318 IPackageManager pm = AppGlobals.getPackageManager(); 10319 for (String pkg : extList) { 10320 try { 10321 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10322 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10323 retList.add(info); 10324 } 10325 } catch (RemoteException e) { 10326 } 10327 } 10328 } 10329 return retList; 10330 } 10331 10332 @Override 10333 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10334 enforceNotIsolatedCaller("getMyMemoryState"); 10335 synchronized (this) { 10336 ProcessRecord proc; 10337 synchronized (mPidsSelfLocked) { 10338 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10339 } 10340 fillInProcMemInfo(proc, outInfo); 10341 } 10342 } 10343 10344 @Override 10345 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10346 if (checkCallingPermission(android.Manifest.permission.DUMP) 10347 != PackageManager.PERMISSION_GRANTED) { 10348 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10349 + Binder.getCallingPid() 10350 + ", uid=" + Binder.getCallingUid() 10351 + " without permission " 10352 + android.Manifest.permission.DUMP); 10353 return; 10354 } 10355 10356 boolean dumpAll = false; 10357 boolean dumpClient = false; 10358 String dumpPackage = null; 10359 10360 int opti = 0; 10361 while (opti < args.length) { 10362 String opt = args[opti]; 10363 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10364 break; 10365 } 10366 opti++; 10367 if ("-a".equals(opt)) { 10368 dumpAll = true; 10369 } else if ("-c".equals(opt)) { 10370 dumpClient = true; 10371 } else if ("-h".equals(opt)) { 10372 pw.println("Activity manager dump options:"); 10373 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10374 pw.println(" cmd may be one of:"); 10375 pw.println(" a[ctivities]: activity stack state"); 10376 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10377 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10378 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10379 pw.println(" o[om]: out of memory management"); 10380 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10381 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10382 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10383 pw.println(" service [COMP_SPEC]: service client-side state"); 10384 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10385 pw.println(" all: dump all activities"); 10386 pw.println(" top: dump the top activity"); 10387 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10388 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10389 pw.println(" a partial substring in a component name, a"); 10390 pw.println(" hex object identifier."); 10391 pw.println(" -a: include all available server state."); 10392 pw.println(" -c: include client state."); 10393 return; 10394 } else { 10395 pw.println("Unknown argument: " + opt + "; use -h for help"); 10396 } 10397 } 10398 10399 long origId = Binder.clearCallingIdentity(); 10400 boolean more = false; 10401 // Is the caller requesting to dump a particular piece of data? 10402 if (opti < args.length) { 10403 String cmd = args[opti]; 10404 opti++; 10405 if ("activities".equals(cmd) || "a".equals(cmd)) { 10406 synchronized (this) { 10407 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10408 } 10409 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10410 String[] newArgs; 10411 String name; 10412 if (opti >= args.length) { 10413 name = null; 10414 newArgs = EMPTY_STRING_ARRAY; 10415 } else { 10416 name = args[opti]; 10417 opti++; 10418 newArgs = new String[args.length - opti]; 10419 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10420 args.length - opti); 10421 } 10422 synchronized (this) { 10423 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10424 } 10425 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10426 String[] newArgs; 10427 String name; 10428 if (opti >= args.length) { 10429 name = null; 10430 newArgs = EMPTY_STRING_ARRAY; 10431 } else { 10432 name = args[opti]; 10433 opti++; 10434 newArgs = new String[args.length - opti]; 10435 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10436 args.length - opti); 10437 } 10438 synchronized (this) { 10439 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10440 } 10441 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10442 String[] newArgs; 10443 String name; 10444 if (opti >= args.length) { 10445 name = null; 10446 newArgs = EMPTY_STRING_ARRAY; 10447 } else { 10448 name = args[opti]; 10449 opti++; 10450 newArgs = new String[args.length - opti]; 10451 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10452 args.length - opti); 10453 } 10454 synchronized (this) { 10455 dumpProcessesLocked(fd, pw, args, opti, true, name); 10456 } 10457 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10458 synchronized (this) { 10459 dumpOomLocked(fd, pw, args, opti, true); 10460 } 10461 } else if ("provider".equals(cmd)) { 10462 String[] newArgs; 10463 String name; 10464 if (opti >= args.length) { 10465 name = null; 10466 newArgs = EMPTY_STRING_ARRAY; 10467 } else { 10468 name = args[opti]; 10469 opti++; 10470 newArgs = new String[args.length - opti]; 10471 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10472 } 10473 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10474 pw.println("No providers match: " + name); 10475 pw.println("Use -h for help."); 10476 } 10477 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10478 synchronized (this) { 10479 dumpProvidersLocked(fd, pw, args, opti, true, null); 10480 } 10481 } else if ("service".equals(cmd)) { 10482 String[] newArgs; 10483 String name; 10484 if (opti >= args.length) { 10485 name = null; 10486 newArgs = EMPTY_STRING_ARRAY; 10487 } else { 10488 name = args[opti]; 10489 opti++; 10490 newArgs = new String[args.length - opti]; 10491 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10492 args.length - opti); 10493 } 10494 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10495 pw.println("No services match: " + name); 10496 pw.println("Use -h for help."); 10497 } 10498 } else if ("package".equals(cmd)) { 10499 String[] newArgs; 10500 if (opti >= args.length) { 10501 pw.println("package: no package name specified"); 10502 pw.println("Use -h for help."); 10503 } else { 10504 dumpPackage = args[opti]; 10505 opti++; 10506 newArgs = new String[args.length - opti]; 10507 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10508 args.length - opti); 10509 args = newArgs; 10510 opti = 0; 10511 more = true; 10512 } 10513 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10514 synchronized (this) { 10515 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10516 } 10517 } else { 10518 // Dumping a single activity? 10519 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10520 pw.println("Bad activity command, or no activities match: " + cmd); 10521 pw.println("Use -h for help."); 10522 } 10523 } 10524 if (!more) { 10525 Binder.restoreCallingIdentity(origId); 10526 return; 10527 } 10528 } 10529 10530 // No piece of data specified, dump everything. 10531 synchronized (this) { 10532 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10533 pw.println(); 10534 if (dumpAll) { 10535 pw.println("-------------------------------------------------------------------------------"); 10536 } 10537 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10538 pw.println(); 10539 if (dumpAll) { 10540 pw.println("-------------------------------------------------------------------------------"); 10541 } 10542 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10543 pw.println(); 10544 if (dumpAll) { 10545 pw.println("-------------------------------------------------------------------------------"); 10546 } 10547 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10548 pw.println(); 10549 if (dumpAll) { 10550 pw.println("-------------------------------------------------------------------------------"); 10551 } 10552 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10553 pw.println(); 10554 if (dumpAll) { 10555 pw.println("-------------------------------------------------------------------------------"); 10556 } 10557 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10558 } 10559 Binder.restoreCallingIdentity(origId); 10560 } 10561 10562 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10563 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10564 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10565 10566 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10567 dumpPackage); 10568 boolean needSep = printedAnything; 10569 10570 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10571 dumpPackage, needSep, " mFocusedActivity: "); 10572 if (printed) { 10573 printedAnything = true; 10574 needSep = false; 10575 } 10576 10577 if (dumpPackage == null) { 10578 if (needSep) { 10579 pw.println(); 10580 } 10581 needSep = true; 10582 printedAnything = true; 10583 mStackSupervisor.dump(pw, " "); 10584 } 10585 10586 if (mRecentTasks.size() > 0) { 10587 boolean printedHeader = false; 10588 10589 final int N = mRecentTasks.size(); 10590 for (int i=0; i<N; i++) { 10591 TaskRecord tr = mRecentTasks.get(i); 10592 if (dumpPackage != null) { 10593 if (tr.realActivity == null || 10594 !dumpPackage.equals(tr.realActivity)) { 10595 continue; 10596 } 10597 } 10598 if (!printedHeader) { 10599 if (needSep) { 10600 pw.println(); 10601 } 10602 pw.println(" Recent tasks:"); 10603 printedHeader = true; 10604 printedAnything = true; 10605 } 10606 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10607 pw.println(tr); 10608 if (dumpAll) { 10609 mRecentTasks.get(i).dump(pw, " "); 10610 } 10611 } 10612 } 10613 10614 if (!printedAnything) { 10615 pw.println(" (nothing)"); 10616 } 10617 } 10618 10619 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10620 int opti, boolean dumpAll, String dumpPackage) { 10621 boolean needSep = false; 10622 boolean printedAnything = false; 10623 int numPers = 0; 10624 10625 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10626 10627 if (dumpAll) { 10628 final int NP = mProcessNames.getMap().size(); 10629 for (int ip=0; ip<NP; ip++) { 10630 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10631 final int NA = procs.size(); 10632 for (int ia=0; ia<NA; ia++) { 10633 ProcessRecord r = procs.valueAt(ia); 10634 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10635 continue; 10636 } 10637 if (!needSep) { 10638 pw.println(" All known processes:"); 10639 needSep = true; 10640 printedAnything = true; 10641 } 10642 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10643 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10644 pw.print(" "); pw.println(r); 10645 r.dump(pw, " "); 10646 if (r.persistent) { 10647 numPers++; 10648 } 10649 } 10650 } 10651 } 10652 10653 if (mIsolatedProcesses.size() > 0) { 10654 boolean printed = false; 10655 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10656 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10657 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10658 continue; 10659 } 10660 if (!printed) { 10661 if (needSep) { 10662 pw.println(); 10663 } 10664 pw.println(" Isolated process list (sorted by uid):"); 10665 printedAnything = true; 10666 printed = true; 10667 needSep = true; 10668 } 10669 pw.println(String.format("%sIsolated #%2d: %s", 10670 " ", i, r.toString())); 10671 } 10672 } 10673 10674 if (mLruProcesses.size() > 0) { 10675 if (needSep) { 10676 pw.println(); 10677 } 10678 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10679 pw.print(" total, non-act at "); 10680 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10681 pw.print(", non-svc at "); 10682 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10683 pw.println("):"); 10684 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10685 needSep = true; 10686 printedAnything = true; 10687 } 10688 10689 if (dumpAll || dumpPackage != null) { 10690 synchronized (mPidsSelfLocked) { 10691 boolean printed = false; 10692 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10693 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10694 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10695 continue; 10696 } 10697 if (!printed) { 10698 if (needSep) pw.println(); 10699 needSep = true; 10700 pw.println(" PID mappings:"); 10701 printed = true; 10702 printedAnything = true; 10703 } 10704 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10705 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10706 } 10707 } 10708 } 10709 10710 if (mForegroundProcesses.size() > 0) { 10711 synchronized (mPidsSelfLocked) { 10712 boolean printed = false; 10713 for (int i=0; i<mForegroundProcesses.size(); i++) { 10714 ProcessRecord r = mPidsSelfLocked.get( 10715 mForegroundProcesses.valueAt(i).pid); 10716 if (dumpPackage != null && (r == null 10717 || !r.pkgList.containsKey(dumpPackage))) { 10718 continue; 10719 } 10720 if (!printed) { 10721 if (needSep) pw.println(); 10722 needSep = true; 10723 pw.println(" Foreground Processes:"); 10724 printed = true; 10725 printedAnything = true; 10726 } 10727 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10728 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10729 } 10730 } 10731 } 10732 10733 if (mPersistentStartingProcesses.size() > 0) { 10734 if (needSep) pw.println(); 10735 needSep = true; 10736 printedAnything = true; 10737 pw.println(" Persisent processes that are starting:"); 10738 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10739 "Starting Norm", "Restarting PERS", dumpPackage); 10740 } 10741 10742 if (mRemovedProcesses.size() > 0) { 10743 if (needSep) pw.println(); 10744 needSep = true; 10745 printedAnything = true; 10746 pw.println(" Processes that are being removed:"); 10747 dumpProcessList(pw, this, mRemovedProcesses, " ", 10748 "Removed Norm", "Removed PERS", dumpPackage); 10749 } 10750 10751 if (mProcessesOnHold.size() > 0) { 10752 if (needSep) pw.println(); 10753 needSep = true; 10754 printedAnything = true; 10755 pw.println(" Processes that are on old until the system is ready:"); 10756 dumpProcessList(pw, this, mProcessesOnHold, " ", 10757 "OnHold Norm", "OnHold PERS", dumpPackage); 10758 } 10759 10760 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10761 10762 if (mProcessCrashTimes.getMap().size() > 0) { 10763 boolean printed = false; 10764 long now = SystemClock.uptimeMillis(); 10765 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10766 final int NP = pmap.size(); 10767 for (int ip=0; ip<NP; ip++) { 10768 String pname = pmap.keyAt(ip); 10769 SparseArray<Long> uids = pmap.valueAt(ip); 10770 final int N = uids.size(); 10771 for (int i=0; i<N; i++) { 10772 int puid = uids.keyAt(i); 10773 ProcessRecord r = mProcessNames.get(pname, puid); 10774 if (dumpPackage != null && (r == null 10775 || !r.pkgList.containsKey(dumpPackage))) { 10776 continue; 10777 } 10778 if (!printed) { 10779 if (needSep) pw.println(); 10780 needSep = true; 10781 pw.println(" Time since processes crashed:"); 10782 printed = true; 10783 printedAnything = true; 10784 } 10785 pw.print(" Process "); pw.print(pname); 10786 pw.print(" uid "); pw.print(puid); 10787 pw.print(": last crashed "); 10788 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10789 pw.println(" ago"); 10790 } 10791 } 10792 } 10793 10794 if (mBadProcesses.getMap().size() > 0) { 10795 boolean printed = false; 10796 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10797 final int NP = pmap.size(); 10798 for (int ip=0; ip<NP; ip++) { 10799 String pname = pmap.keyAt(ip); 10800 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10801 final int N = uids.size(); 10802 for (int i=0; i<N; i++) { 10803 int puid = uids.keyAt(i); 10804 ProcessRecord r = mProcessNames.get(pname, puid); 10805 if (dumpPackage != null && (r == null 10806 || !r.pkgList.containsKey(dumpPackage))) { 10807 continue; 10808 } 10809 if (!printed) { 10810 if (needSep) pw.println(); 10811 needSep = true; 10812 pw.println(" Bad processes:"); 10813 printedAnything = true; 10814 } 10815 BadProcessInfo info = uids.valueAt(i); 10816 pw.print(" Bad process "); pw.print(pname); 10817 pw.print(" uid "); pw.print(puid); 10818 pw.print(": crashed at time "); pw.println(info.time); 10819 if (info.shortMsg != null) { 10820 pw.print(" Short msg: "); pw.println(info.shortMsg); 10821 } 10822 if (info.longMsg != null) { 10823 pw.print(" Long msg: "); pw.println(info.longMsg); 10824 } 10825 if (info.stack != null) { 10826 pw.println(" Stack:"); 10827 int lastPos = 0; 10828 for (int pos=0; pos<info.stack.length(); pos++) { 10829 if (info.stack.charAt(pos) == '\n') { 10830 pw.print(" "); 10831 pw.write(info.stack, lastPos, pos-lastPos); 10832 pw.println(); 10833 lastPos = pos+1; 10834 } 10835 } 10836 if (lastPos < info.stack.length()) { 10837 pw.print(" "); 10838 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10839 pw.println(); 10840 } 10841 } 10842 } 10843 } 10844 } 10845 10846 if (dumpPackage == null) { 10847 pw.println(); 10848 needSep = false; 10849 pw.println(" mStartedUsers:"); 10850 for (int i=0; i<mStartedUsers.size(); i++) { 10851 UserStartedState uss = mStartedUsers.valueAt(i); 10852 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10853 pw.print(": "); uss.dump("", pw); 10854 } 10855 pw.print(" mStartedUserArray: ["); 10856 for (int i=0; i<mStartedUserArray.length; i++) { 10857 if (i > 0) pw.print(", "); 10858 pw.print(mStartedUserArray[i]); 10859 } 10860 pw.println("]"); 10861 pw.print(" mUserLru: ["); 10862 for (int i=0; i<mUserLru.size(); i++) { 10863 if (i > 0) pw.print(", "); 10864 pw.print(mUserLru.get(i)); 10865 } 10866 pw.println("]"); 10867 if (dumpAll) { 10868 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10869 } 10870 } 10871 if (mHomeProcess != null && (dumpPackage == null 10872 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10873 if (needSep) { 10874 pw.println(); 10875 needSep = false; 10876 } 10877 pw.println(" mHomeProcess: " + mHomeProcess); 10878 } 10879 if (mPreviousProcess != null && (dumpPackage == null 10880 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10881 if (needSep) { 10882 pw.println(); 10883 needSep = false; 10884 } 10885 pw.println(" mPreviousProcess: " + mPreviousProcess); 10886 } 10887 if (dumpAll) { 10888 StringBuilder sb = new StringBuilder(128); 10889 sb.append(" mPreviousProcessVisibleTime: "); 10890 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10891 pw.println(sb); 10892 } 10893 if (mHeavyWeightProcess != null && (dumpPackage == null 10894 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10895 if (needSep) { 10896 pw.println(); 10897 needSep = false; 10898 } 10899 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10900 } 10901 if (dumpPackage == null) { 10902 pw.println(" mConfiguration: " + mConfiguration); 10903 } 10904 if (dumpAll) { 10905 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10906 if (mCompatModePackages.getPackages().size() > 0) { 10907 boolean printed = false; 10908 for (Map.Entry<String, Integer> entry 10909 : mCompatModePackages.getPackages().entrySet()) { 10910 String pkg = entry.getKey(); 10911 int mode = entry.getValue(); 10912 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10913 continue; 10914 } 10915 if (!printed) { 10916 pw.println(" mScreenCompatPackages:"); 10917 printed = true; 10918 } 10919 pw.print(" "); pw.print(pkg); pw.print(": "); 10920 pw.print(mode); pw.println(); 10921 } 10922 } 10923 } 10924 if (dumpPackage == null) { 10925 if (mSleeping || mWentToSleep || mLockScreenShown) { 10926 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10927 + " mLockScreenShown " + mLockScreenShown); 10928 } 10929 if (mShuttingDown) { 10930 pw.println(" mShuttingDown=" + mShuttingDown); 10931 } 10932 } 10933 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10934 || mOrigWaitForDebugger) { 10935 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10936 || dumpPackage.equals(mOrigDebugApp)) { 10937 if (needSep) { 10938 pw.println(); 10939 needSep = false; 10940 } 10941 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10942 + " mDebugTransient=" + mDebugTransient 10943 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10944 } 10945 } 10946 if (mOpenGlTraceApp != null) { 10947 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10948 if (needSep) { 10949 pw.println(); 10950 needSep = false; 10951 } 10952 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10953 } 10954 } 10955 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10956 || mProfileFd != null) { 10957 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10958 if (needSep) { 10959 pw.println(); 10960 needSep = false; 10961 } 10962 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10963 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10964 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10965 + mAutoStopProfiler); 10966 } 10967 } 10968 if (dumpPackage == null) { 10969 if (mAlwaysFinishActivities || mController != null) { 10970 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10971 + " mController=" + mController); 10972 } 10973 if (dumpAll) { 10974 pw.println(" Total persistent processes: " + numPers); 10975 pw.println(" mStartRunning=" + mStartRunning 10976 + " mProcessesReady=" + mProcessesReady 10977 + " mSystemReady=" + mSystemReady); 10978 pw.println(" mBooting=" + mBooting 10979 + " mBooted=" + mBooted 10980 + " mFactoryTest=" + mFactoryTest); 10981 pw.print(" mLastPowerCheckRealtime="); 10982 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10983 pw.println(""); 10984 pw.print(" mLastPowerCheckUptime="); 10985 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10986 pw.println(""); 10987 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10988 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10989 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10990 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10991 + " (" + mLruProcesses.size() + " total)" 10992 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10993 + " mNumServiceProcs=" + mNumServiceProcs 10994 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10995 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10996 + " mLastMemoryLevel" + mLastMemoryLevel 10997 + " mLastNumProcesses" + mLastNumProcesses); 10998 long now = SystemClock.uptimeMillis(); 10999 pw.print(" mLastIdleTime="); 11000 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11001 pw.print(" mLowRamSinceLastIdle="); 11002 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11003 pw.println(); 11004 } 11005 } 11006 11007 if (!printedAnything) { 11008 pw.println(" (nothing)"); 11009 } 11010 } 11011 11012 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11013 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11014 if (mProcessesToGc.size() > 0) { 11015 boolean printed = false; 11016 long now = SystemClock.uptimeMillis(); 11017 for (int i=0; i<mProcessesToGc.size(); i++) { 11018 ProcessRecord proc = mProcessesToGc.get(i); 11019 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11020 continue; 11021 } 11022 if (!printed) { 11023 if (needSep) pw.println(); 11024 needSep = true; 11025 pw.println(" Processes that are waiting to GC:"); 11026 printed = true; 11027 } 11028 pw.print(" Process "); pw.println(proc); 11029 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11030 pw.print(", last gced="); 11031 pw.print(now-proc.lastRequestedGc); 11032 pw.print(" ms ago, last lowMem="); 11033 pw.print(now-proc.lastLowMemory); 11034 pw.println(" ms ago"); 11035 11036 } 11037 } 11038 return needSep; 11039 } 11040 11041 void printOomLevel(PrintWriter pw, String name, int adj) { 11042 pw.print(" "); 11043 if (adj >= 0) { 11044 pw.print(' '); 11045 if (adj < 10) pw.print(' '); 11046 } else { 11047 if (adj > -10) pw.print(' '); 11048 } 11049 pw.print(adj); 11050 pw.print(": "); 11051 pw.print(name); 11052 pw.print(" ("); 11053 pw.print(mProcessList.getMemLevel(adj)/1024); 11054 pw.println(" kB)"); 11055 } 11056 11057 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11058 int opti, boolean dumpAll) { 11059 boolean needSep = false; 11060 11061 if (mLruProcesses.size() > 0) { 11062 if (needSep) pw.println(); 11063 needSep = true; 11064 pw.println(" OOM levels:"); 11065 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11066 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11067 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11068 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11069 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11070 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11071 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11072 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11073 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11074 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11075 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11076 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11077 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11078 11079 if (needSep) pw.println(); 11080 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11081 pw.print(" total, non-act at "); 11082 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11083 pw.print(", non-svc at "); 11084 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11085 pw.println("):"); 11086 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11087 needSep = true; 11088 } 11089 11090 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11091 11092 pw.println(); 11093 pw.println(" mHomeProcess: " + mHomeProcess); 11094 pw.println(" mPreviousProcess: " + mPreviousProcess); 11095 if (mHeavyWeightProcess != null) { 11096 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11097 } 11098 11099 return true; 11100 } 11101 11102 /** 11103 * There are three ways to call this: 11104 * - no provider specified: dump all the providers 11105 * - a flattened component name that matched an existing provider was specified as the 11106 * first arg: dump that one provider 11107 * - the first arg isn't the flattened component name of an existing provider: 11108 * dump all providers whose component contains the first arg as a substring 11109 */ 11110 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11111 int opti, boolean dumpAll) { 11112 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11113 } 11114 11115 static class ItemMatcher { 11116 ArrayList<ComponentName> components; 11117 ArrayList<String> strings; 11118 ArrayList<Integer> objects; 11119 boolean all; 11120 11121 ItemMatcher() { 11122 all = true; 11123 } 11124 11125 void build(String name) { 11126 ComponentName componentName = ComponentName.unflattenFromString(name); 11127 if (componentName != null) { 11128 if (components == null) { 11129 components = new ArrayList<ComponentName>(); 11130 } 11131 components.add(componentName); 11132 all = false; 11133 } else { 11134 int objectId = 0; 11135 // Not a '/' separated full component name; maybe an object ID? 11136 try { 11137 objectId = Integer.parseInt(name, 16); 11138 if (objects == null) { 11139 objects = new ArrayList<Integer>(); 11140 } 11141 objects.add(objectId); 11142 all = false; 11143 } catch (RuntimeException e) { 11144 // Not an integer; just do string match. 11145 if (strings == null) { 11146 strings = new ArrayList<String>(); 11147 } 11148 strings.add(name); 11149 all = false; 11150 } 11151 } 11152 } 11153 11154 int build(String[] args, int opti) { 11155 for (; opti<args.length; opti++) { 11156 String name = args[opti]; 11157 if ("--".equals(name)) { 11158 return opti+1; 11159 } 11160 build(name); 11161 } 11162 return opti; 11163 } 11164 11165 boolean match(Object object, ComponentName comp) { 11166 if (all) { 11167 return true; 11168 } 11169 if (components != null) { 11170 for (int i=0; i<components.size(); i++) { 11171 if (components.get(i).equals(comp)) { 11172 return true; 11173 } 11174 } 11175 } 11176 if (objects != null) { 11177 for (int i=0; i<objects.size(); i++) { 11178 if (System.identityHashCode(object) == objects.get(i)) { 11179 return true; 11180 } 11181 } 11182 } 11183 if (strings != null) { 11184 String flat = comp.flattenToString(); 11185 for (int i=0; i<strings.size(); i++) { 11186 if (flat.contains(strings.get(i))) { 11187 return true; 11188 } 11189 } 11190 } 11191 return false; 11192 } 11193 } 11194 11195 /** 11196 * There are three things that cmd can be: 11197 * - a flattened component name that matches an existing activity 11198 * - the cmd arg isn't the flattened component name of an existing activity: 11199 * dump all activity whose component contains the cmd as a substring 11200 * - A hex number of the ActivityRecord object instance. 11201 */ 11202 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11203 int opti, boolean dumpAll) { 11204 ArrayList<ActivityRecord> activities; 11205 11206 synchronized (this) { 11207 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11208 } 11209 11210 if (activities.size() <= 0) { 11211 return false; 11212 } 11213 11214 String[] newArgs = new String[args.length - opti]; 11215 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11216 11217 TaskRecord lastTask = null; 11218 boolean needSep = false; 11219 for (int i=activities.size()-1; i>=0; i--) { 11220 ActivityRecord r = activities.get(i); 11221 if (needSep) { 11222 pw.println(); 11223 } 11224 needSep = true; 11225 synchronized (this) { 11226 if (lastTask != r.task) { 11227 lastTask = r.task; 11228 pw.print("TASK "); pw.print(lastTask.affinity); 11229 pw.print(" id="); pw.println(lastTask.taskId); 11230 if (dumpAll) { 11231 lastTask.dump(pw, " "); 11232 } 11233 } 11234 } 11235 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11236 } 11237 return true; 11238 } 11239 11240 /** 11241 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11242 * there is a thread associated with the activity. 11243 */ 11244 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11245 final ActivityRecord r, String[] args, boolean dumpAll) { 11246 String innerPrefix = prefix + " "; 11247 synchronized (this) { 11248 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11249 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11250 pw.print(" pid="); 11251 if (r.app != null) pw.println(r.app.pid); 11252 else pw.println("(not running)"); 11253 if (dumpAll) { 11254 r.dump(pw, innerPrefix); 11255 } 11256 } 11257 if (r.app != null && r.app.thread != null) { 11258 // flush anything that is already in the PrintWriter since the thread is going 11259 // to write to the file descriptor directly 11260 pw.flush(); 11261 try { 11262 TransferPipe tp = new TransferPipe(); 11263 try { 11264 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11265 r.appToken, innerPrefix, args); 11266 tp.go(fd); 11267 } finally { 11268 tp.kill(); 11269 } 11270 } catch (IOException e) { 11271 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11272 } catch (RemoteException e) { 11273 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11274 } 11275 } 11276 } 11277 11278 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11279 int opti, boolean dumpAll, String dumpPackage) { 11280 boolean needSep = false; 11281 boolean onlyHistory = false; 11282 boolean printedAnything = false; 11283 11284 if ("history".equals(dumpPackage)) { 11285 if (opti < args.length && "-s".equals(args[opti])) { 11286 dumpAll = false; 11287 } 11288 onlyHistory = true; 11289 dumpPackage = null; 11290 } 11291 11292 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11293 if (!onlyHistory && dumpAll) { 11294 if (mRegisteredReceivers.size() > 0) { 11295 boolean printed = false; 11296 Iterator it = mRegisteredReceivers.values().iterator(); 11297 while (it.hasNext()) { 11298 ReceiverList r = (ReceiverList)it.next(); 11299 if (dumpPackage != null && (r.app == null || 11300 !dumpPackage.equals(r.app.info.packageName))) { 11301 continue; 11302 } 11303 if (!printed) { 11304 pw.println(" Registered Receivers:"); 11305 needSep = true; 11306 printed = true; 11307 printedAnything = true; 11308 } 11309 pw.print(" * "); pw.println(r); 11310 r.dump(pw, " "); 11311 } 11312 } 11313 11314 if (mReceiverResolver.dump(pw, needSep ? 11315 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11316 " ", dumpPackage, false)) { 11317 needSep = true; 11318 printedAnything = true; 11319 } 11320 } 11321 11322 for (BroadcastQueue q : mBroadcastQueues) { 11323 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11324 printedAnything |= needSep; 11325 } 11326 11327 needSep = true; 11328 11329 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11330 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11331 if (needSep) { 11332 pw.println(); 11333 } 11334 needSep = true; 11335 printedAnything = true; 11336 pw.print(" Sticky broadcasts for user "); 11337 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11338 StringBuilder sb = new StringBuilder(128); 11339 for (Map.Entry<String, ArrayList<Intent>> ent 11340 : mStickyBroadcasts.valueAt(user).entrySet()) { 11341 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11342 if (dumpAll) { 11343 pw.println(":"); 11344 ArrayList<Intent> intents = ent.getValue(); 11345 final int N = intents.size(); 11346 for (int i=0; i<N; i++) { 11347 sb.setLength(0); 11348 sb.append(" Intent: "); 11349 intents.get(i).toShortString(sb, false, true, false, false); 11350 pw.println(sb.toString()); 11351 Bundle bundle = intents.get(i).getExtras(); 11352 if (bundle != null) { 11353 pw.print(" "); 11354 pw.println(bundle.toString()); 11355 } 11356 } 11357 } else { 11358 pw.println(""); 11359 } 11360 } 11361 } 11362 } 11363 11364 if (!onlyHistory && dumpAll) { 11365 pw.println(); 11366 for (BroadcastQueue queue : mBroadcastQueues) { 11367 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11368 + queue.mBroadcastsScheduled); 11369 } 11370 pw.println(" mHandler:"); 11371 mHandler.dump(new PrintWriterPrinter(pw), " "); 11372 needSep = true; 11373 printedAnything = true; 11374 } 11375 11376 if (!printedAnything) { 11377 pw.println(" (nothing)"); 11378 } 11379 } 11380 11381 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11382 int opti, boolean dumpAll, String dumpPackage) { 11383 boolean needSep; 11384 boolean printedAnything = false; 11385 11386 ItemMatcher matcher = new ItemMatcher(); 11387 matcher.build(args, opti); 11388 11389 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11390 11391 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11392 printedAnything |= needSep; 11393 11394 if (mLaunchingProviders.size() > 0) { 11395 boolean printed = false; 11396 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11397 ContentProviderRecord r = mLaunchingProviders.get(i); 11398 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11399 continue; 11400 } 11401 if (!printed) { 11402 if (needSep) pw.println(); 11403 needSep = true; 11404 pw.println(" Launching content providers:"); 11405 printed = true; 11406 printedAnything = true; 11407 } 11408 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11409 pw.println(r); 11410 } 11411 } 11412 11413 if (mGrantedUriPermissions.size() > 0) { 11414 boolean printed = false; 11415 int dumpUid = -2; 11416 if (dumpPackage != null) { 11417 try { 11418 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11419 } catch (NameNotFoundException e) { 11420 dumpUid = -1; 11421 } 11422 } 11423 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11424 int uid = mGrantedUriPermissions.keyAt(i); 11425 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11426 continue; 11427 } 11428 ArrayMap<Uri, UriPermission> perms 11429 = mGrantedUriPermissions.valueAt(i); 11430 if (!printed) { 11431 if (needSep) pw.println(); 11432 needSep = true; 11433 pw.println(" Granted Uri Permissions:"); 11434 printed = true; 11435 printedAnything = true; 11436 } 11437 pw.print(" * UID "); pw.print(uid); 11438 pw.println(" holds:"); 11439 for (UriPermission perm : perms.values()) { 11440 pw.print(" "); pw.println(perm); 11441 if (dumpAll) { 11442 perm.dump(pw, " "); 11443 } 11444 } 11445 } 11446 } 11447 11448 if (!printedAnything) { 11449 pw.println(" (nothing)"); 11450 } 11451 } 11452 11453 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11454 int opti, boolean dumpAll, String dumpPackage) { 11455 boolean printed = false; 11456 11457 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11458 11459 if (mIntentSenderRecords.size() > 0) { 11460 Iterator<WeakReference<PendingIntentRecord>> it 11461 = mIntentSenderRecords.values().iterator(); 11462 while (it.hasNext()) { 11463 WeakReference<PendingIntentRecord> ref = it.next(); 11464 PendingIntentRecord rec = ref != null ? ref.get(): null; 11465 if (dumpPackage != null && (rec == null 11466 || !dumpPackage.equals(rec.key.packageName))) { 11467 continue; 11468 } 11469 printed = true; 11470 if (rec != null) { 11471 pw.print(" * "); pw.println(rec); 11472 if (dumpAll) { 11473 rec.dump(pw, " "); 11474 } 11475 } else { 11476 pw.print(" * "); pw.println(ref); 11477 } 11478 } 11479 } 11480 11481 if (!printed) { 11482 pw.println(" (nothing)"); 11483 } 11484 } 11485 11486 private static final int dumpProcessList(PrintWriter pw, 11487 ActivityManagerService service, List list, 11488 String prefix, String normalLabel, String persistentLabel, 11489 String dumpPackage) { 11490 int numPers = 0; 11491 final int N = list.size()-1; 11492 for (int i=N; i>=0; i--) { 11493 ProcessRecord r = (ProcessRecord)list.get(i); 11494 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11495 continue; 11496 } 11497 pw.println(String.format("%s%s #%2d: %s", 11498 prefix, (r.persistent ? persistentLabel : normalLabel), 11499 i, r.toString())); 11500 if (r.persistent) { 11501 numPers++; 11502 } 11503 } 11504 return numPers; 11505 } 11506 11507 private static final boolean dumpProcessOomList(PrintWriter pw, 11508 ActivityManagerService service, List<ProcessRecord> origList, 11509 String prefix, String normalLabel, String persistentLabel, 11510 boolean inclDetails, String dumpPackage) { 11511 11512 ArrayList<Pair<ProcessRecord, Integer>> list 11513 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11514 for (int i=0; i<origList.size(); i++) { 11515 ProcessRecord r = origList.get(i); 11516 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11517 continue; 11518 } 11519 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11520 } 11521 11522 if (list.size() <= 0) { 11523 return false; 11524 } 11525 11526 Comparator<Pair<ProcessRecord, Integer>> comparator 11527 = new Comparator<Pair<ProcessRecord, Integer>>() { 11528 @Override 11529 public int compare(Pair<ProcessRecord, Integer> object1, 11530 Pair<ProcessRecord, Integer> object2) { 11531 if (object1.first.setAdj != object2.first.setAdj) { 11532 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11533 } 11534 if (object1.second.intValue() != object2.second.intValue()) { 11535 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11536 } 11537 return 0; 11538 } 11539 }; 11540 11541 Collections.sort(list, comparator); 11542 11543 final long curRealtime = SystemClock.elapsedRealtime(); 11544 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11545 final long curUptime = SystemClock.uptimeMillis(); 11546 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11547 11548 for (int i=list.size()-1; i>=0; i--) { 11549 ProcessRecord r = list.get(i).first; 11550 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11551 char schedGroup; 11552 switch (r.setSchedGroup) { 11553 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11554 schedGroup = 'B'; 11555 break; 11556 case Process.THREAD_GROUP_DEFAULT: 11557 schedGroup = 'F'; 11558 break; 11559 default: 11560 schedGroup = '?'; 11561 break; 11562 } 11563 char foreground; 11564 if (r.foregroundActivities) { 11565 foreground = 'A'; 11566 } else if (r.foregroundServices) { 11567 foreground = 'S'; 11568 } else { 11569 foreground = ' '; 11570 } 11571 String procState = ProcessList.makeProcStateString(r.curProcState); 11572 pw.print(prefix); 11573 pw.print(r.persistent ? persistentLabel : normalLabel); 11574 pw.print(" #"); 11575 int num = (origList.size()-1)-list.get(i).second; 11576 if (num < 10) pw.print(' '); 11577 pw.print(num); 11578 pw.print(": "); 11579 pw.print(oomAdj); 11580 pw.print(' '); 11581 pw.print(schedGroup); 11582 pw.print('/'); 11583 pw.print(foreground); 11584 pw.print('/'); 11585 pw.print(procState); 11586 pw.print(" trm:"); 11587 if (r.trimMemoryLevel < 10) pw.print(' '); 11588 pw.print(r.trimMemoryLevel); 11589 pw.print(' '); 11590 pw.print(r.toShortString()); 11591 pw.print(" ("); 11592 pw.print(r.adjType); 11593 pw.println(')'); 11594 if (r.adjSource != null || r.adjTarget != null) { 11595 pw.print(prefix); 11596 pw.print(" "); 11597 if (r.adjTarget instanceof ComponentName) { 11598 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11599 } else if (r.adjTarget != null) { 11600 pw.print(r.adjTarget.toString()); 11601 } else { 11602 pw.print("{null}"); 11603 } 11604 pw.print("<="); 11605 if (r.adjSource instanceof ProcessRecord) { 11606 pw.print("Proc{"); 11607 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11608 pw.println("}"); 11609 } else if (r.adjSource != null) { 11610 pw.println(r.adjSource.toString()); 11611 } else { 11612 pw.println("{null}"); 11613 } 11614 } 11615 if (inclDetails) { 11616 pw.print(prefix); 11617 pw.print(" "); 11618 pw.print("oom: max="); pw.print(r.maxAdj); 11619 pw.print(" curRaw="); pw.print(r.curRawAdj); 11620 pw.print(" setRaw="); pw.print(r.setRawAdj); 11621 pw.print(" cur="); pw.print(r.curAdj); 11622 pw.print(" set="); pw.println(r.setAdj); 11623 pw.print(prefix); 11624 pw.print(" "); 11625 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11626 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11627 pw.print(" lastPss="); pw.print(r.lastPss); 11628 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11629 pw.print(prefix); 11630 pw.print(" "); 11631 pw.print("keeping="); pw.print(r.keeping); 11632 pw.print(" cached="); pw.print(r.cached); 11633 pw.print(" empty="); pw.print(r.empty); 11634 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11635 11636 if (!r.keeping) { 11637 if (r.lastWakeTime != 0) { 11638 long wtime; 11639 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11640 synchronized (stats) { 11641 wtime = stats.getProcessWakeTime(r.info.uid, 11642 r.pid, curRealtime); 11643 } 11644 long timeUsed = wtime - r.lastWakeTime; 11645 pw.print(prefix); 11646 pw.print(" "); 11647 pw.print("keep awake over "); 11648 TimeUtils.formatDuration(realtimeSince, pw); 11649 pw.print(" used "); 11650 TimeUtils.formatDuration(timeUsed, pw); 11651 pw.print(" ("); 11652 pw.print((timeUsed*100)/realtimeSince); 11653 pw.println("%)"); 11654 } 11655 if (r.lastCpuTime != 0) { 11656 long timeUsed = r.curCpuTime - r.lastCpuTime; 11657 pw.print(prefix); 11658 pw.print(" "); 11659 pw.print("run cpu over "); 11660 TimeUtils.formatDuration(uptimeSince, pw); 11661 pw.print(" used "); 11662 TimeUtils.formatDuration(timeUsed, pw); 11663 pw.print(" ("); 11664 pw.print((timeUsed*100)/uptimeSince); 11665 pw.println("%)"); 11666 } 11667 } 11668 } 11669 } 11670 return true; 11671 } 11672 11673 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11674 ArrayList<ProcessRecord> procs; 11675 synchronized (this) { 11676 if (args != null && args.length > start 11677 && args[start].charAt(0) != '-') { 11678 procs = new ArrayList<ProcessRecord>(); 11679 int pid = -1; 11680 try { 11681 pid = Integer.parseInt(args[start]); 11682 } catch (NumberFormatException e) { 11683 } 11684 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11685 ProcessRecord proc = mLruProcesses.get(i); 11686 if (proc.pid == pid) { 11687 procs.add(proc); 11688 } else if (proc.processName.equals(args[start])) { 11689 procs.add(proc); 11690 } 11691 } 11692 if (procs.size() <= 0) { 11693 return null; 11694 } 11695 } else { 11696 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11697 } 11698 } 11699 return procs; 11700 } 11701 11702 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11703 PrintWriter pw, String[] args) { 11704 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11705 if (procs == null) { 11706 pw.println("No process found for: " + args[0]); 11707 return; 11708 } 11709 11710 long uptime = SystemClock.uptimeMillis(); 11711 long realtime = SystemClock.elapsedRealtime(); 11712 pw.println("Applications Graphics Acceleration Info:"); 11713 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11714 11715 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11716 ProcessRecord r = procs.get(i); 11717 if (r.thread != null) { 11718 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11719 pw.flush(); 11720 try { 11721 TransferPipe tp = new TransferPipe(); 11722 try { 11723 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11724 tp.go(fd); 11725 } finally { 11726 tp.kill(); 11727 } 11728 } catch (IOException e) { 11729 pw.println("Failure while dumping the app: " + r); 11730 pw.flush(); 11731 } catch (RemoteException e) { 11732 pw.println("Got a RemoteException while dumping the app " + r); 11733 pw.flush(); 11734 } 11735 } 11736 } 11737 } 11738 11739 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11740 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11741 if (procs == null) { 11742 pw.println("No process found for: " + args[0]); 11743 return; 11744 } 11745 11746 pw.println("Applications Database Info:"); 11747 11748 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11749 ProcessRecord r = procs.get(i); 11750 if (r.thread != null) { 11751 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11752 pw.flush(); 11753 try { 11754 TransferPipe tp = new TransferPipe(); 11755 try { 11756 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11757 tp.go(fd); 11758 } finally { 11759 tp.kill(); 11760 } 11761 } catch (IOException e) { 11762 pw.println("Failure while dumping the app: " + r); 11763 pw.flush(); 11764 } catch (RemoteException e) { 11765 pw.println("Got a RemoteException while dumping the app " + r); 11766 pw.flush(); 11767 } 11768 } 11769 } 11770 } 11771 11772 final static class MemItem { 11773 final boolean isProc; 11774 final String label; 11775 final String shortLabel; 11776 final long pss; 11777 final int id; 11778 final boolean hasActivities; 11779 ArrayList<MemItem> subitems; 11780 11781 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11782 boolean _hasActivities) { 11783 isProc = true; 11784 label = _label; 11785 shortLabel = _shortLabel; 11786 pss = _pss; 11787 id = _id; 11788 hasActivities = _hasActivities; 11789 } 11790 11791 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11792 isProc = false; 11793 label = _label; 11794 shortLabel = _shortLabel; 11795 pss = _pss; 11796 id = _id; 11797 hasActivities = false; 11798 } 11799 } 11800 11801 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11802 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11803 if (sort && !isCompact) { 11804 Collections.sort(items, new Comparator<MemItem>() { 11805 @Override 11806 public int compare(MemItem lhs, MemItem rhs) { 11807 if (lhs.pss < rhs.pss) { 11808 return 1; 11809 } else if (lhs.pss > rhs.pss) { 11810 return -1; 11811 } 11812 return 0; 11813 } 11814 }); 11815 } 11816 11817 for (int i=0; i<items.size(); i++) { 11818 MemItem mi = items.get(i); 11819 if (!isCompact) { 11820 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11821 } else if (mi.isProc) { 11822 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11823 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11824 pw.println(mi.hasActivities ? ",a" : ",e"); 11825 } else { 11826 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11827 pw.println(mi.pss); 11828 } 11829 if (mi.subitems != null) { 11830 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11831 true, isCompact); 11832 } 11833 } 11834 } 11835 11836 // These are in KB. 11837 static final long[] DUMP_MEM_BUCKETS = new long[] { 11838 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11839 120*1024, 160*1024, 200*1024, 11840 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11841 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11842 }; 11843 11844 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11845 boolean stackLike) { 11846 int start = label.lastIndexOf('.'); 11847 if (start >= 0) start++; 11848 else start = 0; 11849 int end = label.length(); 11850 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11851 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11852 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11853 out.append(bucket); 11854 out.append(stackLike ? "MB." : "MB "); 11855 out.append(label, start, end); 11856 return; 11857 } 11858 } 11859 out.append(memKB/1024); 11860 out.append(stackLike ? "MB." : "MB "); 11861 out.append(label, start, end); 11862 } 11863 11864 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11865 ProcessList.NATIVE_ADJ, 11866 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11867 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11868 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11869 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11870 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11871 }; 11872 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11873 "Native", 11874 "System", "Persistent", "Foreground", 11875 "Visible", "Perceptible", 11876 "Heavy Weight", "Backup", 11877 "A Services", "Home", 11878 "Previous", "B Services", "Cached" 11879 }; 11880 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11881 "native", 11882 "sys", "pers", "fore", 11883 "vis", "percept", 11884 "heavy", "backup", 11885 "servicea", "home", 11886 "prev", "serviceb", "cached" 11887 }; 11888 11889 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11890 long realtime, boolean isCheckinRequest, boolean isCompact) { 11891 if (isCheckinRequest || isCompact) { 11892 // short checkin version 11893 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11894 } else { 11895 pw.println("Applications Memory Usage (kB):"); 11896 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11897 } 11898 } 11899 11900 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11901 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11902 boolean dumpDetails = false; 11903 boolean dumpFullDetails = false; 11904 boolean dumpDalvik = false; 11905 boolean oomOnly = false; 11906 boolean isCompact = false; 11907 boolean localOnly = false; 11908 11909 int opti = 0; 11910 while (opti < args.length) { 11911 String opt = args[opti]; 11912 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11913 break; 11914 } 11915 opti++; 11916 if ("-a".equals(opt)) { 11917 dumpDetails = true; 11918 dumpFullDetails = true; 11919 dumpDalvik = true; 11920 } else if ("-d".equals(opt)) { 11921 dumpDalvik = true; 11922 } else if ("-c".equals(opt)) { 11923 isCompact = true; 11924 } else if ("--oom".equals(opt)) { 11925 oomOnly = true; 11926 } else if ("--local".equals(opt)) { 11927 localOnly = true; 11928 } else if ("-h".equals(opt)) { 11929 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11930 pw.println(" -a: include all available information for each process."); 11931 pw.println(" -d: include dalvik details when dumping process details."); 11932 pw.println(" -c: dump in a compact machine-parseable representation."); 11933 pw.println(" --oom: only show processes organized by oom adj."); 11934 pw.println(" --local: only collect details locally, don't call process."); 11935 pw.println("If [process] is specified it can be the name or "); 11936 pw.println("pid of a specific process to dump."); 11937 return; 11938 } else { 11939 pw.println("Unknown argument: " + opt + "; use -h for help"); 11940 } 11941 } 11942 11943 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11944 long uptime = SystemClock.uptimeMillis(); 11945 long realtime = SystemClock.elapsedRealtime(); 11946 final long[] tmpLong = new long[1]; 11947 11948 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11949 if (procs == null) { 11950 // No Java processes. Maybe they want to print a native process. 11951 if (args != null && args.length > opti 11952 && args[opti].charAt(0) != '-') { 11953 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11954 = new ArrayList<ProcessCpuTracker.Stats>(); 11955 updateCpuStatsNow(); 11956 int findPid = -1; 11957 try { 11958 findPid = Integer.parseInt(args[opti]); 11959 } catch (NumberFormatException e) { 11960 } 11961 synchronized (mProcessCpuThread) { 11962 final int N = mProcessCpuTracker.countStats(); 11963 for (int i=0; i<N; i++) { 11964 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11965 if (st.pid == findPid || (st.baseName != null 11966 && st.baseName.equals(args[opti]))) { 11967 nativeProcs.add(st); 11968 } 11969 } 11970 } 11971 if (nativeProcs.size() > 0) { 11972 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11973 isCompact); 11974 Debug.MemoryInfo mi = null; 11975 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11976 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11977 final int pid = r.pid; 11978 if (!isCheckinRequest && dumpDetails) { 11979 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11980 } 11981 if (mi == null) { 11982 mi = new Debug.MemoryInfo(); 11983 } 11984 if (dumpDetails || (!brief && !oomOnly)) { 11985 Debug.getMemoryInfo(pid, mi); 11986 } else { 11987 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11988 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11989 } 11990 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11991 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11992 if (isCheckinRequest) { 11993 pw.println(); 11994 } 11995 } 11996 return; 11997 } 11998 } 11999 pw.println("No process found for: " + args[opti]); 12000 return; 12001 } 12002 12003 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12004 dumpDetails = true; 12005 } 12006 12007 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12008 12009 String[] innerArgs = new String[args.length-opti]; 12010 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12011 12012 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12013 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12014 long nativePss=0, dalvikPss=0, otherPss=0; 12015 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12016 12017 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12018 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12019 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12020 12021 long totalPss = 0; 12022 long cachedPss = 0; 12023 12024 Debug.MemoryInfo mi = null; 12025 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12026 final ProcessRecord r = procs.get(i); 12027 final IApplicationThread thread; 12028 final int pid; 12029 final int oomAdj; 12030 final boolean hasActivities; 12031 synchronized (this) { 12032 thread = r.thread; 12033 pid = r.pid; 12034 oomAdj = r.getSetAdjWithServices(); 12035 hasActivities = r.activities.size() > 0; 12036 } 12037 if (thread != null) { 12038 if (!isCheckinRequest && dumpDetails) { 12039 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12040 } 12041 if (mi == null) { 12042 mi = new Debug.MemoryInfo(); 12043 } 12044 if (dumpDetails || (!brief && !oomOnly)) { 12045 Debug.getMemoryInfo(pid, mi); 12046 } else { 12047 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12048 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12049 } 12050 if (dumpDetails) { 12051 if (localOnly) { 12052 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12053 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12054 if (isCheckinRequest) { 12055 pw.println(); 12056 } 12057 } else { 12058 try { 12059 pw.flush(); 12060 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12061 dumpDalvik, innerArgs); 12062 } catch (RemoteException e) { 12063 if (!isCheckinRequest) { 12064 pw.println("Got RemoteException!"); 12065 pw.flush(); 12066 } 12067 } 12068 } 12069 } 12070 12071 final long myTotalPss = mi.getTotalPss(); 12072 final long myTotalUss = mi.getTotalUss(); 12073 12074 synchronized (this) { 12075 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12076 // Record this for posterity if the process has been stable. 12077 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12078 } 12079 } 12080 12081 if (!isCheckinRequest && mi != null) { 12082 totalPss += myTotalPss; 12083 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12084 (hasActivities ? " / activities)" : ")"), 12085 r.processName, myTotalPss, pid, hasActivities); 12086 procMems.add(pssItem); 12087 procMemsMap.put(pid, pssItem); 12088 12089 nativePss += mi.nativePss; 12090 dalvikPss += mi.dalvikPss; 12091 otherPss += mi.otherPss; 12092 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12093 long mem = mi.getOtherPss(j); 12094 miscPss[j] += mem; 12095 otherPss -= mem; 12096 } 12097 12098 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12099 cachedPss += myTotalPss; 12100 } 12101 12102 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12103 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12104 || oomIndex == (oomPss.length-1)) { 12105 oomPss[oomIndex] += myTotalPss; 12106 if (oomProcs[oomIndex] == null) { 12107 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12108 } 12109 oomProcs[oomIndex].add(pssItem); 12110 break; 12111 } 12112 } 12113 } 12114 } 12115 } 12116 12117 if (!isCheckinRequest && procs.size() > 1) { 12118 // If we are showing aggregations, also look for native processes to 12119 // include so that our aggregations are more accurate. 12120 updateCpuStatsNow(); 12121 synchronized (mProcessCpuThread) { 12122 final int N = mProcessCpuTracker.countStats(); 12123 for (int i=0; i<N; i++) { 12124 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12125 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12126 if (mi == null) { 12127 mi = new Debug.MemoryInfo(); 12128 } 12129 if (!brief && !oomOnly) { 12130 Debug.getMemoryInfo(st.pid, mi); 12131 } else { 12132 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12133 mi.nativePrivateDirty = (int)tmpLong[0]; 12134 } 12135 12136 final long myTotalPss = mi.getTotalPss(); 12137 totalPss += myTotalPss; 12138 12139 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12140 st.name, myTotalPss, st.pid, false); 12141 procMems.add(pssItem); 12142 12143 nativePss += mi.nativePss; 12144 dalvikPss += mi.dalvikPss; 12145 otherPss += mi.otherPss; 12146 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12147 long mem = mi.getOtherPss(j); 12148 miscPss[j] += mem; 12149 otherPss -= mem; 12150 } 12151 oomPss[0] += myTotalPss; 12152 if (oomProcs[0] == null) { 12153 oomProcs[0] = new ArrayList<MemItem>(); 12154 } 12155 oomProcs[0].add(pssItem); 12156 } 12157 } 12158 } 12159 12160 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12161 12162 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12163 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12164 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12165 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12166 String label = Debug.MemoryInfo.getOtherLabel(j); 12167 catMems.add(new MemItem(label, label, miscPss[j], j)); 12168 } 12169 12170 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12171 for (int j=0; j<oomPss.length; j++) { 12172 if (oomPss[j] != 0) { 12173 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12174 : DUMP_MEM_OOM_LABEL[j]; 12175 MemItem item = new MemItem(label, label, oomPss[j], 12176 DUMP_MEM_OOM_ADJ[j]); 12177 item.subitems = oomProcs[j]; 12178 oomMems.add(item); 12179 } 12180 } 12181 12182 if (!brief && !oomOnly && !isCompact) { 12183 pw.println(); 12184 pw.println("Total PSS by process:"); 12185 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12186 pw.println(); 12187 } 12188 if (!isCompact) { 12189 pw.println("Total PSS by OOM adjustment:"); 12190 } 12191 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12192 if (!brief && !oomOnly) { 12193 PrintWriter out = categoryPw != null ? categoryPw : pw; 12194 if (!isCompact) { 12195 out.println(); 12196 out.println("Total PSS by category:"); 12197 } 12198 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12199 } 12200 if (!isCompact) { 12201 pw.println(); 12202 } 12203 MemInfoReader memInfo = new MemInfoReader(); 12204 memInfo.readMemInfo(); 12205 if (!brief) { 12206 if (!isCompact) { 12207 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12208 pw.println(" kB"); 12209 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12210 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12211 pw.print(cachedPss); pw.print(" cached pss + "); 12212 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12213 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12214 } else { 12215 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12216 pw.print(cachedPss + memInfo.getCachedSizeKb() 12217 + memInfo.getFreeSizeKb()); pw.print(","); 12218 pw.println(totalPss - cachedPss); 12219 } 12220 } 12221 if (!isCompact) { 12222 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12223 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12224 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12225 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12226 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12227 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12228 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12229 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12230 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12231 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12232 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12233 } 12234 if (!brief) { 12235 if (memInfo.getZramTotalSizeKb() != 0) { 12236 if (!isCompact) { 12237 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12238 pw.print(" kB physical used for "); 12239 pw.print(memInfo.getSwapTotalSizeKb() 12240 - memInfo.getSwapFreeSizeKb()); 12241 pw.print(" kB in swap ("); 12242 pw.print(memInfo.getSwapTotalSizeKb()); 12243 pw.println(" kB total swap)"); 12244 } else { 12245 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12246 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12247 pw.println(memInfo.getSwapFreeSizeKb()); 12248 } 12249 } 12250 final int[] SINGLE_LONG_FORMAT = new int[] { 12251 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12252 }; 12253 long[] longOut = new long[1]; 12254 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12255 SINGLE_LONG_FORMAT, null, longOut, null); 12256 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12257 longOut[0] = 0; 12258 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12259 SINGLE_LONG_FORMAT, null, longOut, null); 12260 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12261 longOut[0] = 0; 12262 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12263 SINGLE_LONG_FORMAT, null, longOut, null); 12264 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12265 longOut[0] = 0; 12266 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12267 SINGLE_LONG_FORMAT, null, longOut, null); 12268 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12269 if (!isCompact) { 12270 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12271 pw.print(" KSM: "); pw.print(sharing); 12272 pw.print(" kB saved from shared "); 12273 pw.print(shared); pw.println(" kB"); 12274 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12275 pw.print(voltile); pw.println(" kB volatile"); 12276 } 12277 pw.print(" Tuning: "); 12278 pw.print(ActivityManager.staticGetMemoryClass()); 12279 pw.print(" (large "); 12280 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12281 pw.print("), oom "); 12282 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12283 pw.print(" kB"); 12284 pw.print(", restore limit "); 12285 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12286 pw.print(" kB"); 12287 if (ActivityManager.isLowRamDeviceStatic()) { 12288 pw.print(" (low-ram)"); 12289 } 12290 if (ActivityManager.isHighEndGfx()) { 12291 pw.print(" (high-end-gfx)"); 12292 } 12293 pw.println(); 12294 } else { 12295 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12296 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12297 pw.println(voltile); 12298 pw.print("tuning,"); 12299 pw.print(ActivityManager.staticGetMemoryClass()); 12300 pw.print(','); 12301 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12302 pw.print(','); 12303 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12304 if (ActivityManager.isLowRamDeviceStatic()) { 12305 pw.print(",low-ram"); 12306 } 12307 if (ActivityManager.isHighEndGfx()) { 12308 pw.print(",high-end-gfx"); 12309 } 12310 pw.println(); 12311 } 12312 } 12313 } 12314 } 12315 12316 /** 12317 * Searches array of arguments for the specified string 12318 * @param args array of argument strings 12319 * @param value value to search for 12320 * @return true if the value is contained in the array 12321 */ 12322 private static boolean scanArgs(String[] args, String value) { 12323 if (args != null) { 12324 for (String arg : args) { 12325 if (value.equals(arg)) { 12326 return true; 12327 } 12328 } 12329 } 12330 return false; 12331 } 12332 12333 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12334 ContentProviderRecord cpr, boolean always) { 12335 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12336 12337 if (!inLaunching || always) { 12338 synchronized (cpr) { 12339 cpr.launchingApp = null; 12340 cpr.notifyAll(); 12341 } 12342 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12343 String names[] = cpr.info.authority.split(";"); 12344 for (int j = 0; j < names.length; j++) { 12345 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12346 } 12347 } 12348 12349 for (int i=0; i<cpr.connections.size(); i++) { 12350 ContentProviderConnection conn = cpr.connections.get(i); 12351 if (conn.waiting) { 12352 // If this connection is waiting for the provider, then we don't 12353 // need to mess with its process unless we are always removing 12354 // or for some reason the provider is not currently launching. 12355 if (inLaunching && !always) { 12356 continue; 12357 } 12358 } 12359 ProcessRecord capp = conn.client; 12360 conn.dead = true; 12361 if (conn.stableCount > 0) { 12362 if (!capp.persistent && capp.thread != null 12363 && capp.pid != 0 12364 && capp.pid != MY_PID) { 12365 killUnneededProcessLocked(capp, "depends on provider " 12366 + cpr.name.flattenToShortString() 12367 + " in dying proc " + (proc != null ? proc.processName : "??")); 12368 } 12369 } else if (capp.thread != null && conn.provider.provider != null) { 12370 try { 12371 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12372 } catch (RemoteException e) { 12373 } 12374 // In the protocol here, we don't expect the client to correctly 12375 // clean up this connection, we'll just remove it. 12376 cpr.connections.remove(i); 12377 conn.client.conProviders.remove(conn); 12378 } 12379 } 12380 12381 if (inLaunching && always) { 12382 mLaunchingProviders.remove(cpr); 12383 } 12384 return inLaunching; 12385 } 12386 12387 /** 12388 * Main code for cleaning up a process when it has gone away. This is 12389 * called both as a result of the process dying, or directly when stopping 12390 * a process when running in single process mode. 12391 */ 12392 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12393 boolean restarting, boolean allowRestart, int index) { 12394 if (index >= 0) { 12395 removeLruProcessLocked(app); 12396 } 12397 12398 mProcessesToGc.remove(app); 12399 mPendingPssProcesses.remove(app); 12400 12401 // Dismiss any open dialogs. 12402 if (app.crashDialog != null && !app.forceCrashReport) { 12403 app.crashDialog.dismiss(); 12404 app.crashDialog = null; 12405 } 12406 if (app.anrDialog != null) { 12407 app.anrDialog.dismiss(); 12408 app.anrDialog = null; 12409 } 12410 if (app.waitDialog != null) { 12411 app.waitDialog.dismiss(); 12412 app.waitDialog = null; 12413 } 12414 12415 app.crashing = false; 12416 app.notResponding = false; 12417 12418 app.resetPackageList(mProcessStats); 12419 app.unlinkDeathRecipient(); 12420 app.makeInactive(mProcessStats); 12421 app.forcingToForeground = null; 12422 app.foregroundServices = false; 12423 app.foregroundActivities = false; 12424 app.hasShownUi = false; 12425 app.hasAboveClient = false; 12426 12427 mServices.killServicesLocked(app, allowRestart); 12428 12429 boolean restart = false; 12430 12431 // Remove published content providers. 12432 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12433 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12434 final boolean always = app.bad || !allowRestart; 12435 if (removeDyingProviderLocked(app, cpr, always) || always) { 12436 // We left the provider in the launching list, need to 12437 // restart it. 12438 restart = true; 12439 } 12440 12441 cpr.provider = null; 12442 cpr.proc = null; 12443 } 12444 app.pubProviders.clear(); 12445 12446 // Take care of any launching providers waiting for this process. 12447 if (checkAppInLaunchingProvidersLocked(app, false)) { 12448 restart = true; 12449 } 12450 12451 // Unregister from connected content providers. 12452 if (!app.conProviders.isEmpty()) { 12453 for (int i=0; i<app.conProviders.size(); i++) { 12454 ContentProviderConnection conn = app.conProviders.get(i); 12455 conn.provider.connections.remove(conn); 12456 } 12457 app.conProviders.clear(); 12458 } 12459 12460 // At this point there may be remaining entries in mLaunchingProviders 12461 // where we were the only one waiting, so they are no longer of use. 12462 // Look for these and clean up if found. 12463 // XXX Commented out for now. Trying to figure out a way to reproduce 12464 // the actual situation to identify what is actually going on. 12465 if (false) { 12466 for (int i=0; i<mLaunchingProviders.size(); i++) { 12467 ContentProviderRecord cpr = (ContentProviderRecord) 12468 mLaunchingProviders.get(i); 12469 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12470 synchronized (cpr) { 12471 cpr.launchingApp = null; 12472 cpr.notifyAll(); 12473 } 12474 } 12475 } 12476 } 12477 12478 skipCurrentReceiverLocked(app); 12479 12480 // Unregister any receivers. 12481 for (int i=app.receivers.size()-1; i>=0; i--) { 12482 removeReceiverLocked(app.receivers.valueAt(i)); 12483 } 12484 app.receivers.clear(); 12485 12486 // If the app is undergoing backup, tell the backup manager about it 12487 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12488 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12489 + mBackupTarget.appInfo + " died during backup"); 12490 try { 12491 IBackupManager bm = IBackupManager.Stub.asInterface( 12492 ServiceManager.getService(Context.BACKUP_SERVICE)); 12493 bm.agentDisconnected(app.info.packageName); 12494 } catch (RemoteException e) { 12495 // can't happen; backup manager is local 12496 } 12497 } 12498 12499 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12500 ProcessChangeItem item = mPendingProcessChanges.get(i); 12501 if (item.pid == app.pid) { 12502 mPendingProcessChanges.remove(i); 12503 mAvailProcessChanges.add(item); 12504 } 12505 } 12506 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12507 12508 // If the caller is restarting this app, then leave it in its 12509 // current lists and let the caller take care of it. 12510 if (restarting) { 12511 return; 12512 } 12513 12514 if (!app.persistent || app.isolated) { 12515 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12516 "Removing non-persistent process during cleanup: " + app); 12517 mProcessNames.remove(app.processName, app.uid); 12518 mIsolatedProcesses.remove(app.uid); 12519 if (mHeavyWeightProcess == app) { 12520 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12521 mHeavyWeightProcess.userId, 0)); 12522 mHeavyWeightProcess = null; 12523 } 12524 } else if (!app.removed) { 12525 // This app is persistent, so we need to keep its record around. 12526 // If it is not already on the pending app list, add it there 12527 // and start a new process for it. 12528 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12529 mPersistentStartingProcesses.add(app); 12530 restart = true; 12531 } 12532 } 12533 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12534 "Clean-up removing on hold: " + app); 12535 mProcessesOnHold.remove(app); 12536 12537 if (app == mHomeProcess) { 12538 mHomeProcess = null; 12539 } 12540 if (app == mPreviousProcess) { 12541 mPreviousProcess = null; 12542 } 12543 12544 if (restart && !app.isolated) { 12545 // We have components that still need to be running in the 12546 // process, so re-launch it. 12547 mProcessNames.put(app.processName, app.uid, app); 12548 startProcessLocked(app, "restart", app.processName); 12549 } else if (app.pid > 0 && app.pid != MY_PID) { 12550 // Goodbye! 12551 synchronized (mPidsSelfLocked) { 12552 mPidsSelfLocked.remove(app.pid); 12553 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12554 } 12555 app.setPid(0); 12556 } 12557 } 12558 12559 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12560 // Look through the content providers we are waiting to have launched, 12561 // and if any run in this process then either schedule a restart of 12562 // the process or kill the client waiting for it if this process has 12563 // gone bad. 12564 int NL = mLaunchingProviders.size(); 12565 boolean restart = false; 12566 for (int i=0; i<NL; i++) { 12567 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12568 if (cpr.launchingApp == app) { 12569 if (!alwaysBad && !app.bad) { 12570 restart = true; 12571 } else { 12572 removeDyingProviderLocked(app, cpr, true); 12573 // cpr should have been removed from mLaunchingProviders 12574 NL = mLaunchingProviders.size(); 12575 i--; 12576 } 12577 } 12578 } 12579 return restart; 12580 } 12581 12582 // ========================================================= 12583 // SERVICES 12584 // ========================================================= 12585 12586 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12587 int flags) { 12588 enforceNotIsolatedCaller("getServices"); 12589 synchronized (this) { 12590 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12591 } 12592 } 12593 12594 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12595 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12596 synchronized (this) { 12597 return mServices.getRunningServiceControlPanelLocked(name); 12598 } 12599 } 12600 12601 public ComponentName startService(IApplicationThread caller, Intent service, 12602 String resolvedType, int userId) { 12603 enforceNotIsolatedCaller("startService"); 12604 // Refuse possible leaked file descriptors 12605 if (service != null && service.hasFileDescriptors() == true) { 12606 throw new IllegalArgumentException("File descriptors passed in Intent"); 12607 } 12608 12609 if (DEBUG_SERVICE) 12610 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12611 synchronized(this) { 12612 final int callingPid = Binder.getCallingPid(); 12613 final int callingUid = Binder.getCallingUid(); 12614 final long origId = Binder.clearCallingIdentity(); 12615 ComponentName res = mServices.startServiceLocked(caller, service, 12616 resolvedType, callingPid, callingUid, userId); 12617 Binder.restoreCallingIdentity(origId); 12618 return res; 12619 } 12620 } 12621 12622 ComponentName startServiceInPackage(int uid, 12623 Intent service, String resolvedType, int userId) { 12624 synchronized(this) { 12625 if (DEBUG_SERVICE) 12626 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12627 final long origId = Binder.clearCallingIdentity(); 12628 ComponentName res = mServices.startServiceLocked(null, service, 12629 resolvedType, -1, uid, userId); 12630 Binder.restoreCallingIdentity(origId); 12631 return res; 12632 } 12633 } 12634 12635 public int stopService(IApplicationThread caller, Intent service, 12636 String resolvedType, int userId) { 12637 enforceNotIsolatedCaller("stopService"); 12638 // Refuse possible leaked file descriptors 12639 if (service != null && service.hasFileDescriptors() == true) { 12640 throw new IllegalArgumentException("File descriptors passed in Intent"); 12641 } 12642 12643 synchronized(this) { 12644 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12645 } 12646 } 12647 12648 public IBinder peekService(Intent service, String resolvedType) { 12649 enforceNotIsolatedCaller("peekService"); 12650 // Refuse possible leaked file descriptors 12651 if (service != null && service.hasFileDescriptors() == true) { 12652 throw new IllegalArgumentException("File descriptors passed in Intent"); 12653 } 12654 synchronized(this) { 12655 return mServices.peekServiceLocked(service, resolvedType); 12656 } 12657 } 12658 12659 public boolean stopServiceToken(ComponentName className, IBinder token, 12660 int startId) { 12661 synchronized(this) { 12662 return mServices.stopServiceTokenLocked(className, token, startId); 12663 } 12664 } 12665 12666 public void setServiceForeground(ComponentName className, IBinder token, 12667 int id, Notification notification, boolean removeNotification) { 12668 synchronized(this) { 12669 mServices.setServiceForegroundLocked(className, token, id, notification, 12670 removeNotification); 12671 } 12672 } 12673 12674 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12675 boolean requireFull, String name, String callerPackage) { 12676 final int callingUserId = UserHandle.getUserId(callingUid); 12677 if (callingUserId != userId) { 12678 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12679 if ((requireFull || checkComponentPermission( 12680 android.Manifest.permission.INTERACT_ACROSS_USERS, 12681 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12682 && checkComponentPermission( 12683 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12684 callingPid, callingUid, -1, true) 12685 != PackageManager.PERMISSION_GRANTED) { 12686 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12687 // In this case, they would like to just execute as their 12688 // owner user instead of failing. 12689 userId = callingUserId; 12690 } else { 12691 StringBuilder builder = new StringBuilder(128); 12692 builder.append("Permission Denial: "); 12693 builder.append(name); 12694 if (callerPackage != null) { 12695 builder.append(" from "); 12696 builder.append(callerPackage); 12697 } 12698 builder.append(" asks to run as user "); 12699 builder.append(userId); 12700 builder.append(" but is calling from user "); 12701 builder.append(UserHandle.getUserId(callingUid)); 12702 builder.append("; this requires "); 12703 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12704 if (!requireFull) { 12705 builder.append(" or "); 12706 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12707 } 12708 String msg = builder.toString(); 12709 Slog.w(TAG, msg); 12710 throw new SecurityException(msg); 12711 } 12712 } 12713 } 12714 if (userId == UserHandle.USER_CURRENT 12715 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12716 // Note that we may be accessing this outside of a lock... 12717 // shouldn't be a big deal, if this is being called outside 12718 // of a locked context there is intrinsically a race with 12719 // the value the caller will receive and someone else changing it. 12720 userId = mCurrentUserId; 12721 } 12722 if (!allowAll && userId < 0) { 12723 throw new IllegalArgumentException( 12724 "Call does not support special user #" + userId); 12725 } 12726 } 12727 return userId; 12728 } 12729 12730 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12731 String className, int flags) { 12732 boolean result = false; 12733 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12734 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12735 if (ActivityManager.checkUidPermission( 12736 android.Manifest.permission.INTERACT_ACROSS_USERS, 12737 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12738 ComponentName comp = new ComponentName(aInfo.packageName, className); 12739 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12740 + " requests FLAG_SINGLE_USER, but app does not hold " 12741 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12742 Slog.w(TAG, msg); 12743 throw new SecurityException(msg); 12744 } 12745 result = true; 12746 } 12747 } else if (componentProcessName == aInfo.packageName) { 12748 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12749 } else if ("system".equals(componentProcessName)) { 12750 result = true; 12751 } 12752 if (DEBUG_MU) { 12753 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12754 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12755 } 12756 return result; 12757 } 12758 12759 public int bindService(IApplicationThread caller, IBinder token, 12760 Intent service, String resolvedType, 12761 IServiceConnection connection, int flags, int userId) { 12762 enforceNotIsolatedCaller("bindService"); 12763 // Refuse possible leaked file descriptors 12764 if (service != null && service.hasFileDescriptors() == true) { 12765 throw new IllegalArgumentException("File descriptors passed in Intent"); 12766 } 12767 12768 synchronized(this) { 12769 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12770 connection, flags, userId); 12771 } 12772 } 12773 12774 public boolean unbindService(IServiceConnection connection) { 12775 synchronized (this) { 12776 return mServices.unbindServiceLocked(connection); 12777 } 12778 } 12779 12780 public void publishService(IBinder token, Intent intent, IBinder service) { 12781 // Refuse possible leaked file descriptors 12782 if (intent != null && intent.hasFileDescriptors() == true) { 12783 throw new IllegalArgumentException("File descriptors passed in Intent"); 12784 } 12785 12786 synchronized(this) { 12787 if (!(token instanceof ServiceRecord)) { 12788 throw new IllegalArgumentException("Invalid service token"); 12789 } 12790 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12791 } 12792 } 12793 12794 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12795 // Refuse possible leaked file descriptors 12796 if (intent != null && intent.hasFileDescriptors() == true) { 12797 throw new IllegalArgumentException("File descriptors passed in Intent"); 12798 } 12799 12800 synchronized(this) { 12801 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12802 } 12803 } 12804 12805 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12806 synchronized(this) { 12807 if (!(token instanceof ServiceRecord)) { 12808 throw new IllegalArgumentException("Invalid service token"); 12809 } 12810 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12811 } 12812 } 12813 12814 // ========================================================= 12815 // BACKUP AND RESTORE 12816 // ========================================================= 12817 12818 // Cause the target app to be launched if necessary and its backup agent 12819 // instantiated. The backup agent will invoke backupAgentCreated() on the 12820 // activity manager to announce its creation. 12821 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12822 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12823 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12824 12825 synchronized(this) { 12826 // !!! TODO: currently no check here that we're already bound 12827 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12828 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12829 synchronized (stats) { 12830 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12831 } 12832 12833 // Backup agent is now in use, its package can't be stopped. 12834 try { 12835 AppGlobals.getPackageManager().setPackageStoppedState( 12836 app.packageName, false, UserHandle.getUserId(app.uid)); 12837 } catch (RemoteException e) { 12838 } catch (IllegalArgumentException e) { 12839 Slog.w(TAG, "Failed trying to unstop package " 12840 + app.packageName + ": " + e); 12841 } 12842 12843 BackupRecord r = new BackupRecord(ss, app, backupMode); 12844 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12845 ? new ComponentName(app.packageName, app.backupAgentName) 12846 : new ComponentName("android", "FullBackupAgent"); 12847 // startProcessLocked() returns existing proc's record if it's already running 12848 ProcessRecord proc = startProcessLocked(app.processName, app, 12849 false, 0, "backup", hostingName, false, false, false); 12850 if (proc == null) { 12851 Slog.e(TAG, "Unable to start backup agent process " + r); 12852 return false; 12853 } 12854 12855 r.app = proc; 12856 mBackupTarget = r; 12857 mBackupAppName = app.packageName; 12858 12859 // Try not to kill the process during backup 12860 updateOomAdjLocked(proc); 12861 12862 // If the process is already attached, schedule the creation of the backup agent now. 12863 // If it is not yet live, this will be done when it attaches to the framework. 12864 if (proc.thread != null) { 12865 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12866 try { 12867 proc.thread.scheduleCreateBackupAgent(app, 12868 compatibilityInfoForPackageLocked(app), backupMode); 12869 } catch (RemoteException e) { 12870 // Will time out on the backup manager side 12871 } 12872 } else { 12873 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12874 } 12875 // Invariants: at this point, the target app process exists and the application 12876 // is either already running or in the process of coming up. mBackupTarget and 12877 // mBackupAppName describe the app, so that when it binds back to the AM we 12878 // know that it's scheduled for a backup-agent operation. 12879 } 12880 12881 return true; 12882 } 12883 12884 @Override 12885 public void clearPendingBackup() { 12886 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12887 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12888 12889 synchronized (this) { 12890 mBackupTarget = null; 12891 mBackupAppName = null; 12892 } 12893 } 12894 12895 // A backup agent has just come up 12896 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12897 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12898 + " = " + agent); 12899 12900 synchronized(this) { 12901 if (!agentPackageName.equals(mBackupAppName)) { 12902 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12903 return; 12904 } 12905 } 12906 12907 long oldIdent = Binder.clearCallingIdentity(); 12908 try { 12909 IBackupManager bm = IBackupManager.Stub.asInterface( 12910 ServiceManager.getService(Context.BACKUP_SERVICE)); 12911 bm.agentConnected(agentPackageName, agent); 12912 } catch (RemoteException e) { 12913 // can't happen; the backup manager service is local 12914 } catch (Exception e) { 12915 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12916 e.printStackTrace(); 12917 } finally { 12918 Binder.restoreCallingIdentity(oldIdent); 12919 } 12920 } 12921 12922 // done with this agent 12923 public void unbindBackupAgent(ApplicationInfo appInfo) { 12924 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12925 if (appInfo == null) { 12926 Slog.w(TAG, "unbind backup agent for null app"); 12927 return; 12928 } 12929 12930 synchronized(this) { 12931 try { 12932 if (mBackupAppName == null) { 12933 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12934 return; 12935 } 12936 12937 if (!mBackupAppName.equals(appInfo.packageName)) { 12938 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12939 return; 12940 } 12941 12942 // Not backing this app up any more; reset its OOM adjustment 12943 final ProcessRecord proc = mBackupTarget.app; 12944 updateOomAdjLocked(proc); 12945 12946 // If the app crashed during backup, 'thread' will be null here 12947 if (proc.thread != null) { 12948 try { 12949 proc.thread.scheduleDestroyBackupAgent(appInfo, 12950 compatibilityInfoForPackageLocked(appInfo)); 12951 } catch (Exception e) { 12952 Slog.e(TAG, "Exception when unbinding backup agent:"); 12953 e.printStackTrace(); 12954 } 12955 } 12956 } finally { 12957 mBackupTarget = null; 12958 mBackupAppName = null; 12959 } 12960 } 12961 } 12962 // ========================================================= 12963 // BROADCASTS 12964 // ========================================================= 12965 12966 private final List getStickiesLocked(String action, IntentFilter filter, 12967 List cur, int userId) { 12968 final ContentResolver resolver = mContext.getContentResolver(); 12969 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12970 if (stickies == null) { 12971 return cur; 12972 } 12973 final ArrayList<Intent> list = stickies.get(action); 12974 if (list == null) { 12975 return cur; 12976 } 12977 int N = list.size(); 12978 for (int i=0; i<N; i++) { 12979 Intent intent = list.get(i); 12980 if (filter.match(resolver, intent, true, TAG) >= 0) { 12981 if (cur == null) { 12982 cur = new ArrayList<Intent>(); 12983 } 12984 cur.add(intent); 12985 } 12986 } 12987 return cur; 12988 } 12989 12990 boolean isPendingBroadcastProcessLocked(int pid) { 12991 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12992 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12993 } 12994 12995 void skipPendingBroadcastLocked(int pid) { 12996 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12997 for (BroadcastQueue queue : mBroadcastQueues) { 12998 queue.skipPendingBroadcastLocked(pid); 12999 } 13000 } 13001 13002 // The app just attached; send any pending broadcasts that it should receive 13003 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13004 boolean didSomething = false; 13005 for (BroadcastQueue queue : mBroadcastQueues) { 13006 didSomething |= queue.sendPendingBroadcastsLocked(app); 13007 } 13008 return didSomething; 13009 } 13010 13011 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13012 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13013 enforceNotIsolatedCaller("registerReceiver"); 13014 int callingUid; 13015 int callingPid; 13016 synchronized(this) { 13017 ProcessRecord callerApp = null; 13018 if (caller != null) { 13019 callerApp = getRecordForAppLocked(caller); 13020 if (callerApp == null) { 13021 throw new SecurityException( 13022 "Unable to find app for caller " + caller 13023 + " (pid=" + Binder.getCallingPid() 13024 + ") when registering receiver " + receiver); 13025 } 13026 if (callerApp.info.uid != Process.SYSTEM_UID && 13027 !callerApp.pkgList.containsKey(callerPackage) && 13028 !"android".equals(callerPackage)) { 13029 throw new SecurityException("Given caller package " + callerPackage 13030 + " is not running in process " + callerApp); 13031 } 13032 callingUid = callerApp.info.uid; 13033 callingPid = callerApp.pid; 13034 } else { 13035 callerPackage = null; 13036 callingUid = Binder.getCallingUid(); 13037 callingPid = Binder.getCallingPid(); 13038 } 13039 13040 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13041 true, true, "registerReceiver", callerPackage); 13042 13043 List allSticky = null; 13044 13045 // Look for any matching sticky broadcasts... 13046 Iterator actions = filter.actionsIterator(); 13047 if (actions != null) { 13048 while (actions.hasNext()) { 13049 String action = (String)actions.next(); 13050 allSticky = getStickiesLocked(action, filter, allSticky, 13051 UserHandle.USER_ALL); 13052 allSticky = getStickiesLocked(action, filter, allSticky, 13053 UserHandle.getUserId(callingUid)); 13054 } 13055 } else { 13056 allSticky = getStickiesLocked(null, filter, allSticky, 13057 UserHandle.USER_ALL); 13058 allSticky = getStickiesLocked(null, filter, allSticky, 13059 UserHandle.getUserId(callingUid)); 13060 } 13061 13062 // The first sticky in the list is returned directly back to 13063 // the client. 13064 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13065 13066 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13067 + ": " + sticky); 13068 13069 if (receiver == null) { 13070 return sticky; 13071 } 13072 13073 ReceiverList rl 13074 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13075 if (rl == null) { 13076 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13077 userId, receiver); 13078 if (rl.app != null) { 13079 rl.app.receivers.add(rl); 13080 } else { 13081 try { 13082 receiver.asBinder().linkToDeath(rl, 0); 13083 } catch (RemoteException e) { 13084 return sticky; 13085 } 13086 rl.linkedToDeath = true; 13087 } 13088 mRegisteredReceivers.put(receiver.asBinder(), rl); 13089 } else if (rl.uid != callingUid) { 13090 throw new IllegalArgumentException( 13091 "Receiver requested to register for uid " + callingUid 13092 + " was previously registered for uid " + rl.uid); 13093 } else if (rl.pid != callingPid) { 13094 throw new IllegalArgumentException( 13095 "Receiver requested to register for pid " + callingPid 13096 + " was previously registered for pid " + rl.pid); 13097 } else if (rl.userId != userId) { 13098 throw new IllegalArgumentException( 13099 "Receiver requested to register for user " + userId 13100 + " was previously registered for user " + rl.userId); 13101 } 13102 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13103 permission, callingUid, userId); 13104 rl.add(bf); 13105 if (!bf.debugCheck()) { 13106 Slog.w(TAG, "==> For Dynamic broadast"); 13107 } 13108 mReceiverResolver.addFilter(bf); 13109 13110 // Enqueue broadcasts for all existing stickies that match 13111 // this filter. 13112 if (allSticky != null) { 13113 ArrayList receivers = new ArrayList(); 13114 receivers.add(bf); 13115 13116 int N = allSticky.size(); 13117 for (int i=0; i<N; i++) { 13118 Intent intent = (Intent)allSticky.get(i); 13119 BroadcastQueue queue = broadcastQueueForIntent(intent); 13120 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13121 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13122 null, null, false, true, true, -1); 13123 queue.enqueueParallelBroadcastLocked(r); 13124 queue.scheduleBroadcastsLocked(); 13125 } 13126 } 13127 13128 return sticky; 13129 } 13130 } 13131 13132 public void unregisterReceiver(IIntentReceiver receiver) { 13133 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13134 13135 final long origId = Binder.clearCallingIdentity(); 13136 try { 13137 boolean doTrim = false; 13138 13139 synchronized(this) { 13140 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13141 if (rl != null) { 13142 if (rl.curBroadcast != null) { 13143 BroadcastRecord r = rl.curBroadcast; 13144 final boolean doNext = finishReceiverLocked( 13145 receiver.asBinder(), r.resultCode, r.resultData, 13146 r.resultExtras, r.resultAbort); 13147 if (doNext) { 13148 doTrim = true; 13149 r.queue.processNextBroadcast(false); 13150 } 13151 } 13152 13153 if (rl.app != null) { 13154 rl.app.receivers.remove(rl); 13155 } 13156 removeReceiverLocked(rl); 13157 if (rl.linkedToDeath) { 13158 rl.linkedToDeath = false; 13159 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13160 } 13161 } 13162 } 13163 13164 // If we actually concluded any broadcasts, we might now be able 13165 // to trim the recipients' apps from our working set 13166 if (doTrim) { 13167 trimApplications(); 13168 return; 13169 } 13170 13171 } finally { 13172 Binder.restoreCallingIdentity(origId); 13173 } 13174 } 13175 13176 void removeReceiverLocked(ReceiverList rl) { 13177 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13178 int N = rl.size(); 13179 for (int i=0; i<N; i++) { 13180 mReceiverResolver.removeFilter(rl.get(i)); 13181 } 13182 } 13183 13184 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13185 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13186 ProcessRecord r = mLruProcesses.get(i); 13187 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13188 try { 13189 r.thread.dispatchPackageBroadcast(cmd, packages); 13190 } catch (RemoteException ex) { 13191 } 13192 } 13193 } 13194 } 13195 13196 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13197 int[] users) { 13198 List<ResolveInfo> receivers = null; 13199 try { 13200 HashSet<ComponentName> singleUserReceivers = null; 13201 boolean scannedFirstReceivers = false; 13202 for (int user : users) { 13203 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13204 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13205 if (user != 0 && newReceivers != null) { 13206 // If this is not the primary user, we need to check for 13207 // any receivers that should be filtered out. 13208 for (int i=0; i<newReceivers.size(); i++) { 13209 ResolveInfo ri = newReceivers.get(i); 13210 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13211 newReceivers.remove(i); 13212 i--; 13213 } 13214 } 13215 } 13216 if (newReceivers != null && newReceivers.size() == 0) { 13217 newReceivers = null; 13218 } 13219 if (receivers == null) { 13220 receivers = newReceivers; 13221 } else if (newReceivers != null) { 13222 // We need to concatenate the additional receivers 13223 // found with what we have do far. This would be easy, 13224 // but we also need to de-dup any receivers that are 13225 // singleUser. 13226 if (!scannedFirstReceivers) { 13227 // Collect any single user receivers we had already retrieved. 13228 scannedFirstReceivers = true; 13229 for (int i=0; i<receivers.size(); i++) { 13230 ResolveInfo ri = receivers.get(i); 13231 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13232 ComponentName cn = new ComponentName( 13233 ri.activityInfo.packageName, ri.activityInfo.name); 13234 if (singleUserReceivers == null) { 13235 singleUserReceivers = new HashSet<ComponentName>(); 13236 } 13237 singleUserReceivers.add(cn); 13238 } 13239 } 13240 } 13241 // Add the new results to the existing results, tracking 13242 // and de-dupping single user receivers. 13243 for (int i=0; i<newReceivers.size(); i++) { 13244 ResolveInfo ri = newReceivers.get(i); 13245 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13246 ComponentName cn = new ComponentName( 13247 ri.activityInfo.packageName, ri.activityInfo.name); 13248 if (singleUserReceivers == null) { 13249 singleUserReceivers = new HashSet<ComponentName>(); 13250 } 13251 if (!singleUserReceivers.contains(cn)) { 13252 singleUserReceivers.add(cn); 13253 receivers.add(ri); 13254 } 13255 } else { 13256 receivers.add(ri); 13257 } 13258 } 13259 } 13260 } 13261 } catch (RemoteException ex) { 13262 // pm is in same process, this will never happen. 13263 } 13264 return receivers; 13265 } 13266 13267 private final int broadcastIntentLocked(ProcessRecord callerApp, 13268 String callerPackage, Intent intent, String resolvedType, 13269 IIntentReceiver resultTo, int resultCode, String resultData, 13270 Bundle map, String requiredPermission, int appOp, 13271 boolean ordered, boolean sticky, int callingPid, int callingUid, 13272 int userId) { 13273 intent = new Intent(intent); 13274 13275 // By default broadcasts do not go to stopped apps. 13276 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13277 13278 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13279 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13280 + " ordered=" + ordered + " userid=" + userId); 13281 if ((resultTo != null) && !ordered) { 13282 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13283 } 13284 13285 userId = handleIncomingUser(callingPid, callingUid, userId, 13286 true, false, "broadcast", callerPackage); 13287 13288 // Make sure that the user who is receiving this broadcast is started. 13289 // If not, we will just skip it. 13290 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13291 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13292 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13293 Slog.w(TAG, "Skipping broadcast of " + intent 13294 + ": user " + userId + " is stopped"); 13295 return ActivityManager.BROADCAST_SUCCESS; 13296 } 13297 } 13298 13299 /* 13300 * Prevent non-system code (defined here to be non-persistent 13301 * processes) from sending protected broadcasts. 13302 */ 13303 int callingAppId = UserHandle.getAppId(callingUid); 13304 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13305 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13306 callingUid == 0) { 13307 // Always okay. 13308 } else if (callerApp == null || !callerApp.persistent) { 13309 try { 13310 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13311 intent.getAction())) { 13312 String msg = "Permission Denial: not allowed to send broadcast " 13313 + intent.getAction() + " from pid=" 13314 + callingPid + ", uid=" + callingUid; 13315 Slog.w(TAG, msg); 13316 throw new SecurityException(msg); 13317 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13318 // Special case for compatibility: we don't want apps to send this, 13319 // but historically it has not been protected and apps may be using it 13320 // to poke their own app widget. So, instead of making it protected, 13321 // just limit it to the caller. 13322 if (callerApp == null) { 13323 String msg = "Permission Denial: not allowed to send broadcast " 13324 + intent.getAction() + " from unknown caller."; 13325 Slog.w(TAG, msg); 13326 throw new SecurityException(msg); 13327 } else if (intent.getComponent() != null) { 13328 // They are good enough to send to an explicit component... verify 13329 // it is being sent to the calling app. 13330 if (!intent.getComponent().getPackageName().equals( 13331 callerApp.info.packageName)) { 13332 String msg = "Permission Denial: not allowed to send broadcast " 13333 + intent.getAction() + " to " 13334 + intent.getComponent().getPackageName() + " from " 13335 + callerApp.info.packageName; 13336 Slog.w(TAG, msg); 13337 throw new SecurityException(msg); 13338 } 13339 } else { 13340 // Limit broadcast to their own package. 13341 intent.setPackage(callerApp.info.packageName); 13342 } 13343 } 13344 } catch (RemoteException e) { 13345 Slog.w(TAG, "Remote exception", e); 13346 return ActivityManager.BROADCAST_SUCCESS; 13347 } 13348 } 13349 13350 // Handle special intents: if this broadcast is from the package 13351 // manager about a package being removed, we need to remove all of 13352 // its activities from the history stack. 13353 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13354 intent.getAction()); 13355 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13356 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13357 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13358 || uidRemoved) { 13359 if (checkComponentPermission( 13360 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13361 callingPid, callingUid, -1, true) 13362 == PackageManager.PERMISSION_GRANTED) { 13363 if (uidRemoved) { 13364 final Bundle intentExtras = intent.getExtras(); 13365 final int uid = intentExtras != null 13366 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13367 if (uid >= 0) { 13368 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13369 synchronized (bs) { 13370 bs.removeUidStatsLocked(uid); 13371 } 13372 mAppOpsService.uidRemoved(uid); 13373 } 13374 } else { 13375 // If resources are unavailable just force stop all 13376 // those packages and flush the attribute cache as well. 13377 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13378 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13379 if (list != null && (list.length > 0)) { 13380 for (String pkg : list) { 13381 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13382 "storage unmount"); 13383 } 13384 sendPackageBroadcastLocked( 13385 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13386 } 13387 } else { 13388 Uri data = intent.getData(); 13389 String ssp; 13390 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13391 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13392 intent.getAction()); 13393 boolean fullUninstall = removed && 13394 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13395 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13396 forceStopPackageLocked(ssp, UserHandle.getAppId( 13397 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13398 false, fullUninstall, userId, 13399 removed ? "pkg removed" : "pkg changed"); 13400 } 13401 if (removed) { 13402 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13403 new String[] {ssp}, userId); 13404 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13405 mAppOpsService.packageRemoved( 13406 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13407 13408 // Remove all permissions granted from/to this package 13409 removeUriPermissionsForPackageLocked(ssp, userId, true); 13410 } 13411 } 13412 } 13413 } 13414 } 13415 } else { 13416 String msg = "Permission Denial: " + intent.getAction() 13417 + " broadcast from " + callerPackage + " (pid=" + callingPid 13418 + ", uid=" + callingUid + ")" 13419 + " requires " 13420 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13421 Slog.w(TAG, msg); 13422 throw new SecurityException(msg); 13423 } 13424 13425 // Special case for adding a package: by default turn on compatibility 13426 // mode. 13427 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13428 Uri data = intent.getData(); 13429 String ssp; 13430 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13431 mCompatModePackages.handlePackageAddedLocked(ssp, 13432 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13433 } 13434 } 13435 13436 /* 13437 * If this is the time zone changed action, queue up a message that will reset the timezone 13438 * of all currently running processes. This message will get queued up before the broadcast 13439 * happens. 13440 */ 13441 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13442 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13443 } 13444 13445 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13446 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13447 } 13448 13449 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13450 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13451 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13452 } 13453 13454 // Add to the sticky list if requested. 13455 if (sticky) { 13456 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13457 callingPid, callingUid) 13458 != PackageManager.PERMISSION_GRANTED) { 13459 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13460 + callingPid + ", uid=" + callingUid 13461 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13462 Slog.w(TAG, msg); 13463 throw new SecurityException(msg); 13464 } 13465 if (requiredPermission != null) { 13466 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13467 + " and enforce permission " + requiredPermission); 13468 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13469 } 13470 if (intent.getComponent() != null) { 13471 throw new SecurityException( 13472 "Sticky broadcasts can't target a specific component"); 13473 } 13474 // We use userId directly here, since the "all" target is maintained 13475 // as a separate set of sticky broadcasts. 13476 if (userId != UserHandle.USER_ALL) { 13477 // But first, if this is not a broadcast to all users, then 13478 // make sure it doesn't conflict with an existing broadcast to 13479 // all users. 13480 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13481 UserHandle.USER_ALL); 13482 if (stickies != null) { 13483 ArrayList<Intent> list = stickies.get(intent.getAction()); 13484 if (list != null) { 13485 int N = list.size(); 13486 int i; 13487 for (i=0; i<N; i++) { 13488 if (intent.filterEquals(list.get(i))) { 13489 throw new IllegalArgumentException( 13490 "Sticky broadcast " + intent + " for user " 13491 + userId + " conflicts with existing global broadcast"); 13492 } 13493 } 13494 } 13495 } 13496 } 13497 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13498 if (stickies == null) { 13499 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13500 mStickyBroadcasts.put(userId, stickies); 13501 } 13502 ArrayList<Intent> list = stickies.get(intent.getAction()); 13503 if (list == null) { 13504 list = new ArrayList<Intent>(); 13505 stickies.put(intent.getAction(), list); 13506 } 13507 int N = list.size(); 13508 int i; 13509 for (i=0; i<N; i++) { 13510 if (intent.filterEquals(list.get(i))) { 13511 // This sticky already exists, replace it. 13512 list.set(i, new Intent(intent)); 13513 break; 13514 } 13515 } 13516 if (i >= N) { 13517 list.add(new Intent(intent)); 13518 } 13519 } 13520 13521 int[] users; 13522 if (userId == UserHandle.USER_ALL) { 13523 // Caller wants broadcast to go to all started users. 13524 users = mStartedUserArray; 13525 } else { 13526 // Caller wants broadcast to go to one specific user. 13527 users = new int[] {userId}; 13528 } 13529 13530 // Figure out who all will receive this broadcast. 13531 List receivers = null; 13532 List<BroadcastFilter> registeredReceivers = null; 13533 // Need to resolve the intent to interested receivers... 13534 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13535 == 0) { 13536 receivers = collectReceiverComponents(intent, resolvedType, users); 13537 } 13538 if (intent.getComponent() == null) { 13539 registeredReceivers = mReceiverResolver.queryIntent(intent, 13540 resolvedType, false, userId); 13541 } 13542 13543 final boolean replacePending = 13544 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13545 13546 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13547 + " replacePending=" + replacePending); 13548 13549 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13550 if (!ordered && NR > 0) { 13551 // If we are not serializing this broadcast, then send the 13552 // registered receivers separately so they don't wait for the 13553 // components to be launched. 13554 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13555 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13556 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13557 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13558 ordered, sticky, false, userId); 13559 if (DEBUG_BROADCAST) Slog.v( 13560 TAG, "Enqueueing parallel broadcast " + r); 13561 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13562 if (!replaced) { 13563 queue.enqueueParallelBroadcastLocked(r); 13564 queue.scheduleBroadcastsLocked(); 13565 } 13566 registeredReceivers = null; 13567 NR = 0; 13568 } 13569 13570 // Merge into one list. 13571 int ir = 0; 13572 if (receivers != null) { 13573 // A special case for PACKAGE_ADDED: do not allow the package 13574 // being added to see this broadcast. This prevents them from 13575 // using this as a back door to get run as soon as they are 13576 // installed. Maybe in the future we want to have a special install 13577 // broadcast or such for apps, but we'd like to deliberately make 13578 // this decision. 13579 String skipPackages[] = null; 13580 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13581 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13582 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13583 Uri data = intent.getData(); 13584 if (data != null) { 13585 String pkgName = data.getSchemeSpecificPart(); 13586 if (pkgName != null) { 13587 skipPackages = new String[] { pkgName }; 13588 } 13589 } 13590 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13591 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13592 } 13593 if (skipPackages != null && (skipPackages.length > 0)) { 13594 for (String skipPackage : skipPackages) { 13595 if (skipPackage != null) { 13596 int NT = receivers.size(); 13597 for (int it=0; it<NT; it++) { 13598 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13599 if (curt.activityInfo.packageName.equals(skipPackage)) { 13600 receivers.remove(it); 13601 it--; 13602 NT--; 13603 } 13604 } 13605 } 13606 } 13607 } 13608 13609 int NT = receivers != null ? receivers.size() : 0; 13610 int it = 0; 13611 ResolveInfo curt = null; 13612 BroadcastFilter curr = null; 13613 while (it < NT && ir < NR) { 13614 if (curt == null) { 13615 curt = (ResolveInfo)receivers.get(it); 13616 } 13617 if (curr == null) { 13618 curr = registeredReceivers.get(ir); 13619 } 13620 if (curr.getPriority() >= curt.priority) { 13621 // Insert this broadcast record into the final list. 13622 receivers.add(it, curr); 13623 ir++; 13624 curr = null; 13625 it++; 13626 NT++; 13627 } else { 13628 // Skip to the next ResolveInfo in the final list. 13629 it++; 13630 curt = null; 13631 } 13632 } 13633 } 13634 while (ir < NR) { 13635 if (receivers == null) { 13636 receivers = new ArrayList(); 13637 } 13638 receivers.add(registeredReceivers.get(ir)); 13639 ir++; 13640 } 13641 13642 if ((receivers != null && receivers.size() > 0) 13643 || resultTo != null) { 13644 BroadcastQueue queue = broadcastQueueForIntent(intent); 13645 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13646 callerPackage, callingPid, callingUid, resolvedType, 13647 requiredPermission, appOp, receivers, resultTo, resultCode, 13648 resultData, map, ordered, sticky, false, userId); 13649 if (DEBUG_BROADCAST) Slog.v( 13650 TAG, "Enqueueing ordered broadcast " + r 13651 + ": prev had " + queue.mOrderedBroadcasts.size()); 13652 if (DEBUG_BROADCAST) { 13653 int seq = r.intent.getIntExtra("seq", -1); 13654 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13655 } 13656 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13657 if (!replaced) { 13658 queue.enqueueOrderedBroadcastLocked(r); 13659 queue.scheduleBroadcastsLocked(); 13660 } 13661 } 13662 13663 return ActivityManager.BROADCAST_SUCCESS; 13664 } 13665 13666 final Intent verifyBroadcastLocked(Intent intent) { 13667 // Refuse possible leaked file descriptors 13668 if (intent != null && intent.hasFileDescriptors() == true) { 13669 throw new IllegalArgumentException("File descriptors passed in Intent"); 13670 } 13671 13672 int flags = intent.getFlags(); 13673 13674 if (!mProcessesReady) { 13675 // if the caller really truly claims to know what they're doing, go 13676 // ahead and allow the broadcast without launching any receivers 13677 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13678 intent = new Intent(intent); 13679 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13680 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13681 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13682 + " before boot completion"); 13683 throw new IllegalStateException("Cannot broadcast before boot completed"); 13684 } 13685 } 13686 13687 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13688 throw new IllegalArgumentException( 13689 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13690 } 13691 13692 return intent; 13693 } 13694 13695 public final int broadcastIntent(IApplicationThread caller, 13696 Intent intent, String resolvedType, IIntentReceiver resultTo, 13697 int resultCode, String resultData, Bundle map, 13698 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13699 enforceNotIsolatedCaller("broadcastIntent"); 13700 synchronized(this) { 13701 intent = verifyBroadcastLocked(intent); 13702 13703 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13704 final int callingPid = Binder.getCallingPid(); 13705 final int callingUid = Binder.getCallingUid(); 13706 final long origId = Binder.clearCallingIdentity(); 13707 int res = broadcastIntentLocked(callerApp, 13708 callerApp != null ? callerApp.info.packageName : null, 13709 intent, resolvedType, resultTo, 13710 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13711 callingPid, callingUid, userId); 13712 Binder.restoreCallingIdentity(origId); 13713 return res; 13714 } 13715 } 13716 13717 int broadcastIntentInPackage(String packageName, int uid, 13718 Intent intent, String resolvedType, IIntentReceiver resultTo, 13719 int resultCode, String resultData, Bundle map, 13720 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13721 synchronized(this) { 13722 intent = verifyBroadcastLocked(intent); 13723 13724 final long origId = Binder.clearCallingIdentity(); 13725 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13726 resultTo, resultCode, resultData, map, requiredPermission, 13727 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13728 Binder.restoreCallingIdentity(origId); 13729 return res; 13730 } 13731 } 13732 13733 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13734 // Refuse possible leaked file descriptors 13735 if (intent != null && intent.hasFileDescriptors() == true) { 13736 throw new IllegalArgumentException("File descriptors passed in Intent"); 13737 } 13738 13739 userId = handleIncomingUser(Binder.getCallingPid(), 13740 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13741 13742 synchronized(this) { 13743 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13744 != PackageManager.PERMISSION_GRANTED) { 13745 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13746 + Binder.getCallingPid() 13747 + ", uid=" + Binder.getCallingUid() 13748 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13749 Slog.w(TAG, msg); 13750 throw new SecurityException(msg); 13751 } 13752 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13753 if (stickies != null) { 13754 ArrayList<Intent> list = stickies.get(intent.getAction()); 13755 if (list != null) { 13756 int N = list.size(); 13757 int i; 13758 for (i=0; i<N; i++) { 13759 if (intent.filterEquals(list.get(i))) { 13760 list.remove(i); 13761 break; 13762 } 13763 } 13764 if (list.size() <= 0) { 13765 stickies.remove(intent.getAction()); 13766 } 13767 } 13768 if (stickies.size() <= 0) { 13769 mStickyBroadcasts.remove(userId); 13770 } 13771 } 13772 } 13773 } 13774 13775 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13776 String resultData, Bundle resultExtras, boolean resultAbort) { 13777 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13778 if (r == null) { 13779 Slog.w(TAG, "finishReceiver called but not found on queue"); 13780 return false; 13781 } 13782 13783 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13784 } 13785 13786 void backgroundServicesFinishedLocked(int userId) { 13787 for (BroadcastQueue queue : mBroadcastQueues) { 13788 queue.backgroundServicesFinishedLocked(userId); 13789 } 13790 } 13791 13792 public void finishReceiver(IBinder who, int resultCode, String resultData, 13793 Bundle resultExtras, boolean resultAbort) { 13794 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13795 13796 // Refuse possible leaked file descriptors 13797 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13798 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13799 } 13800 13801 final long origId = Binder.clearCallingIdentity(); 13802 try { 13803 boolean doNext = false; 13804 BroadcastRecord r; 13805 13806 synchronized(this) { 13807 r = broadcastRecordForReceiverLocked(who); 13808 if (r != null) { 13809 doNext = r.queue.finishReceiverLocked(r, resultCode, 13810 resultData, resultExtras, resultAbort, true); 13811 } 13812 } 13813 13814 if (doNext) { 13815 r.queue.processNextBroadcast(false); 13816 } 13817 trimApplications(); 13818 } finally { 13819 Binder.restoreCallingIdentity(origId); 13820 } 13821 } 13822 13823 // ========================================================= 13824 // INSTRUMENTATION 13825 // ========================================================= 13826 13827 public boolean startInstrumentation(ComponentName className, 13828 String profileFile, int flags, Bundle arguments, 13829 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13830 int userId) { 13831 enforceNotIsolatedCaller("startInstrumentation"); 13832 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13833 userId, false, true, "startInstrumentation", null); 13834 // Refuse possible leaked file descriptors 13835 if (arguments != null && arguments.hasFileDescriptors()) { 13836 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13837 } 13838 13839 synchronized(this) { 13840 InstrumentationInfo ii = null; 13841 ApplicationInfo ai = null; 13842 try { 13843 ii = mContext.getPackageManager().getInstrumentationInfo( 13844 className, STOCK_PM_FLAGS); 13845 ai = AppGlobals.getPackageManager().getApplicationInfo( 13846 ii.targetPackage, STOCK_PM_FLAGS, userId); 13847 } catch (PackageManager.NameNotFoundException e) { 13848 } catch (RemoteException e) { 13849 } 13850 if (ii == null) { 13851 reportStartInstrumentationFailure(watcher, className, 13852 "Unable to find instrumentation info for: " + className); 13853 return false; 13854 } 13855 if (ai == null) { 13856 reportStartInstrumentationFailure(watcher, className, 13857 "Unable to find instrumentation target package: " + ii.targetPackage); 13858 return false; 13859 } 13860 13861 int match = mContext.getPackageManager().checkSignatures( 13862 ii.targetPackage, ii.packageName); 13863 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13864 String msg = "Permission Denial: starting instrumentation " 13865 + className + " from pid=" 13866 + Binder.getCallingPid() 13867 + ", uid=" + Binder.getCallingPid() 13868 + " not allowed because package " + ii.packageName 13869 + " does not have a signature matching the target " 13870 + ii.targetPackage; 13871 reportStartInstrumentationFailure(watcher, className, msg); 13872 throw new SecurityException(msg); 13873 } 13874 13875 final long origId = Binder.clearCallingIdentity(); 13876 // Instrumentation can kill and relaunch even persistent processes 13877 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 13878 "start instr"); 13879 ProcessRecord app = addAppLocked(ai, false); 13880 app.instrumentationClass = className; 13881 app.instrumentationInfo = ai; 13882 app.instrumentationProfileFile = profileFile; 13883 app.instrumentationArguments = arguments; 13884 app.instrumentationWatcher = watcher; 13885 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13886 app.instrumentationResultClass = className; 13887 Binder.restoreCallingIdentity(origId); 13888 } 13889 13890 return true; 13891 } 13892 13893 /** 13894 * Report errors that occur while attempting to start Instrumentation. Always writes the 13895 * error to the logs, but if somebody is watching, send the report there too. This enables 13896 * the "am" command to report errors with more information. 13897 * 13898 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13899 * @param cn The component name of the instrumentation. 13900 * @param report The error report. 13901 */ 13902 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13903 ComponentName cn, String report) { 13904 Slog.w(TAG, report); 13905 try { 13906 if (watcher != null) { 13907 Bundle results = new Bundle(); 13908 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13909 results.putString("Error", report); 13910 watcher.instrumentationStatus(cn, -1, results); 13911 } 13912 } catch (RemoteException e) { 13913 Slog.w(TAG, e); 13914 } 13915 } 13916 13917 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13918 if (app.instrumentationWatcher != null) { 13919 try { 13920 // NOTE: IInstrumentationWatcher *must* be oneway here 13921 app.instrumentationWatcher.instrumentationFinished( 13922 app.instrumentationClass, 13923 resultCode, 13924 results); 13925 } catch (RemoteException e) { 13926 } 13927 } 13928 if (app.instrumentationUiAutomationConnection != null) { 13929 try { 13930 app.instrumentationUiAutomationConnection.shutdown(); 13931 } catch (RemoteException re) { 13932 /* ignore */ 13933 } 13934 // Only a UiAutomation can set this flag and now that 13935 // it is finished we make sure it is reset to its default. 13936 mUserIsMonkey = false; 13937 } 13938 app.instrumentationWatcher = null; 13939 app.instrumentationUiAutomationConnection = null; 13940 app.instrumentationClass = null; 13941 app.instrumentationInfo = null; 13942 app.instrumentationProfileFile = null; 13943 app.instrumentationArguments = null; 13944 13945 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 13946 "finished inst"); 13947 } 13948 13949 public void finishInstrumentation(IApplicationThread target, 13950 int resultCode, Bundle results) { 13951 int userId = UserHandle.getCallingUserId(); 13952 // Refuse possible leaked file descriptors 13953 if (results != null && results.hasFileDescriptors()) { 13954 throw new IllegalArgumentException("File descriptors passed in Intent"); 13955 } 13956 13957 synchronized(this) { 13958 ProcessRecord app = getRecordForAppLocked(target); 13959 if (app == null) { 13960 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13961 return; 13962 } 13963 final long origId = Binder.clearCallingIdentity(); 13964 finishInstrumentationLocked(app, resultCode, results); 13965 Binder.restoreCallingIdentity(origId); 13966 } 13967 } 13968 13969 // ========================================================= 13970 // CONFIGURATION 13971 // ========================================================= 13972 13973 public ConfigurationInfo getDeviceConfigurationInfo() { 13974 ConfigurationInfo config = new ConfigurationInfo(); 13975 synchronized (this) { 13976 config.reqTouchScreen = mConfiguration.touchscreen; 13977 config.reqKeyboardType = mConfiguration.keyboard; 13978 config.reqNavigation = mConfiguration.navigation; 13979 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13980 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13981 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13982 } 13983 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13984 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13985 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13986 } 13987 config.reqGlEsVersion = GL_ES_VERSION; 13988 } 13989 return config; 13990 } 13991 13992 ActivityStack getFocusedStack() { 13993 return mStackSupervisor.getFocusedStack(); 13994 } 13995 13996 public Configuration getConfiguration() { 13997 Configuration ci; 13998 synchronized(this) { 13999 ci = new Configuration(mConfiguration); 14000 } 14001 return ci; 14002 } 14003 14004 public void updatePersistentConfiguration(Configuration values) { 14005 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14006 "updateConfiguration()"); 14007 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14008 "updateConfiguration()"); 14009 if (values == null) { 14010 throw new NullPointerException("Configuration must not be null"); 14011 } 14012 14013 synchronized(this) { 14014 final long origId = Binder.clearCallingIdentity(); 14015 updateConfigurationLocked(values, null, true, false); 14016 Binder.restoreCallingIdentity(origId); 14017 } 14018 } 14019 14020 public void updateConfiguration(Configuration values) { 14021 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14022 "updateConfiguration()"); 14023 14024 synchronized(this) { 14025 if (values == null && mWindowManager != null) { 14026 // sentinel: fetch the current configuration from the window manager 14027 values = mWindowManager.computeNewConfiguration(); 14028 } 14029 14030 if (mWindowManager != null) { 14031 mProcessList.applyDisplaySize(mWindowManager); 14032 } 14033 14034 final long origId = Binder.clearCallingIdentity(); 14035 if (values != null) { 14036 Settings.System.clearConfiguration(values); 14037 } 14038 updateConfigurationLocked(values, null, false, false); 14039 Binder.restoreCallingIdentity(origId); 14040 } 14041 } 14042 14043 /** 14044 * Do either or both things: (1) change the current configuration, and (2) 14045 * make sure the given activity is running with the (now) current 14046 * configuration. Returns true if the activity has been left running, or 14047 * false if <var>starting</var> is being destroyed to match the new 14048 * configuration. 14049 * @param persistent TODO 14050 */ 14051 boolean updateConfigurationLocked(Configuration values, 14052 ActivityRecord starting, boolean persistent, boolean initLocale) { 14053 // do nothing if we are headless 14054 if (mHeadless) return true; 14055 14056 int changes = 0; 14057 14058 if (values != null) { 14059 Configuration newConfig = new Configuration(mConfiguration); 14060 changes = newConfig.updateFrom(values); 14061 if (changes != 0) { 14062 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14063 Slog.i(TAG, "Updating configuration to: " + values); 14064 } 14065 14066 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14067 14068 if (values.locale != null && !initLocale) { 14069 saveLocaleLocked(values.locale, 14070 !values.locale.equals(mConfiguration.locale), 14071 values.userSetLocale); 14072 } 14073 14074 mConfigurationSeq++; 14075 if (mConfigurationSeq <= 0) { 14076 mConfigurationSeq = 1; 14077 } 14078 newConfig.seq = mConfigurationSeq; 14079 mConfiguration = newConfig; 14080 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14081 14082 final Configuration configCopy = new Configuration(mConfiguration); 14083 14084 // TODO: If our config changes, should we auto dismiss any currently 14085 // showing dialogs? 14086 mShowDialogs = shouldShowDialogs(newConfig); 14087 14088 AttributeCache ac = AttributeCache.instance(); 14089 if (ac != null) { 14090 ac.updateConfiguration(configCopy); 14091 } 14092 14093 // Make sure all resources in our process are updated 14094 // right now, so that anyone who is going to retrieve 14095 // resource values after we return will be sure to get 14096 // the new ones. This is especially important during 14097 // boot, where the first config change needs to guarantee 14098 // all resources have that config before following boot 14099 // code is executed. 14100 mSystemThread.applyConfigurationToResources(configCopy); 14101 14102 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14103 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14104 msg.obj = new Configuration(configCopy); 14105 mHandler.sendMessage(msg); 14106 } 14107 14108 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14109 ProcessRecord app = mLruProcesses.get(i); 14110 try { 14111 if (app.thread != null) { 14112 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14113 + app.processName + " new config " + mConfiguration); 14114 app.thread.scheduleConfigurationChanged(configCopy); 14115 } 14116 } catch (Exception e) { 14117 } 14118 } 14119 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14120 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14121 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14122 | Intent.FLAG_RECEIVER_FOREGROUND); 14123 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14124 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14125 Process.SYSTEM_UID, UserHandle.USER_ALL); 14126 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14127 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14128 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14129 broadcastIntentLocked(null, null, intent, 14130 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14131 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14132 } 14133 } 14134 } 14135 14136 boolean kept = true; 14137 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14138 if (changes != 0 && starting == null) { 14139 // If the configuration changed, and the caller is not already 14140 // in the process of starting an activity, then find the top 14141 // activity to check if its configuration needs to change. 14142 starting = mainStack.topRunningActivityLocked(null); 14143 } 14144 14145 if (starting != null) { 14146 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14147 // And we need to make sure at this point that all other activities 14148 // are made visible with the correct configuration. 14149 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14150 } 14151 14152 if (values != null && mWindowManager != null) { 14153 mWindowManager.setNewConfiguration(mConfiguration); 14154 } 14155 14156 return kept; 14157 } 14158 14159 /** 14160 * Decide based on the configuration whether we should shouw the ANR, 14161 * crash, etc dialogs. The idea is that if there is no affordnace to 14162 * press the on-screen buttons, we shouldn't show the dialog. 14163 * 14164 * A thought: SystemUI might also want to get told about this, the Power 14165 * dialog / global actions also might want different behaviors. 14166 */ 14167 private static final boolean shouldShowDialogs(Configuration config) { 14168 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14169 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14170 } 14171 14172 /** 14173 * Save the locale. You must be inside a synchronized (this) block. 14174 */ 14175 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14176 if(isDiff) { 14177 SystemProperties.set("user.language", l.getLanguage()); 14178 SystemProperties.set("user.region", l.getCountry()); 14179 } 14180 14181 if(isPersist) { 14182 SystemProperties.set("persist.sys.language", l.getLanguage()); 14183 SystemProperties.set("persist.sys.country", l.getCountry()); 14184 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14185 } 14186 } 14187 14188 @Override 14189 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14190 ActivityRecord srec = ActivityRecord.forToken(token); 14191 return srec != null && srec.task.affinity != null && 14192 srec.task.affinity.equals(destAffinity); 14193 } 14194 14195 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14196 Intent resultData) { 14197 14198 synchronized (this) { 14199 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14200 if (stack != null) { 14201 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14202 } 14203 return false; 14204 } 14205 } 14206 14207 public int getLaunchedFromUid(IBinder activityToken) { 14208 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14209 if (srec == null) { 14210 return -1; 14211 } 14212 return srec.launchedFromUid; 14213 } 14214 14215 public String getLaunchedFromPackage(IBinder activityToken) { 14216 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14217 if (srec == null) { 14218 return null; 14219 } 14220 return srec.launchedFromPackage; 14221 } 14222 14223 // ========================================================= 14224 // LIFETIME MANAGEMENT 14225 // ========================================================= 14226 14227 // Returns which broadcast queue the app is the current [or imminent] receiver 14228 // on, or 'null' if the app is not an active broadcast recipient. 14229 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14230 BroadcastRecord r = app.curReceiver; 14231 if (r != null) { 14232 return r.queue; 14233 } 14234 14235 // It's not the current receiver, but it might be starting up to become one 14236 synchronized (this) { 14237 for (BroadcastQueue queue : mBroadcastQueues) { 14238 r = queue.mPendingBroadcast; 14239 if (r != null && r.curApp == app) { 14240 // found it; report which queue it's in 14241 return queue; 14242 } 14243 } 14244 } 14245 14246 return null; 14247 } 14248 14249 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14250 boolean doingAll, long now) { 14251 if (mAdjSeq == app.adjSeq) { 14252 // This adjustment has already been computed. 14253 return app.curRawAdj; 14254 } 14255 14256 if (app.thread == null) { 14257 app.adjSeq = mAdjSeq; 14258 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14259 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14260 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14261 } 14262 14263 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14264 app.adjSource = null; 14265 app.adjTarget = null; 14266 app.empty = false; 14267 app.cached = false; 14268 14269 final int activitiesSize = app.activities.size(); 14270 14271 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14272 // The max adjustment doesn't allow this app to be anything 14273 // below foreground, so it is not worth doing work for it. 14274 app.adjType = "fixed"; 14275 app.adjSeq = mAdjSeq; 14276 app.curRawAdj = app.maxAdj; 14277 app.foregroundActivities = false; 14278 app.keeping = true; 14279 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14280 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14281 // System process can do UI, and when they do we want to have 14282 // them trim their memory after the user leaves the UI. To 14283 // facilitate this, here we need to determine whether or not it 14284 // is currently showing UI. 14285 app.systemNoUi = true; 14286 if (app == TOP_APP) { 14287 app.systemNoUi = false; 14288 } else if (activitiesSize > 0) { 14289 for (int j = 0; j < activitiesSize; j++) { 14290 final ActivityRecord r = app.activities.get(j); 14291 if (r.visible) { 14292 app.systemNoUi = false; 14293 } 14294 } 14295 } 14296 if (!app.systemNoUi) { 14297 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14298 } 14299 return (app.curAdj=app.maxAdj); 14300 } 14301 14302 app.keeping = false; 14303 app.systemNoUi = false; 14304 14305 // Determine the importance of the process, starting with most 14306 // important to least, and assign an appropriate OOM adjustment. 14307 int adj; 14308 int schedGroup; 14309 int procState; 14310 boolean foregroundActivities = false; 14311 boolean interesting = false; 14312 BroadcastQueue queue; 14313 if (app == TOP_APP) { 14314 // The last app on the list is the foreground app. 14315 adj = ProcessList.FOREGROUND_APP_ADJ; 14316 schedGroup = Process.THREAD_GROUP_DEFAULT; 14317 app.adjType = "top-activity"; 14318 foregroundActivities = true; 14319 interesting = true; 14320 procState = ActivityManager.PROCESS_STATE_TOP; 14321 } else if (app.instrumentationClass != null) { 14322 // Don't want to kill running instrumentation. 14323 adj = ProcessList.FOREGROUND_APP_ADJ; 14324 schedGroup = Process.THREAD_GROUP_DEFAULT; 14325 app.adjType = "instrumentation"; 14326 interesting = true; 14327 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14328 } else if ((queue = isReceivingBroadcast(app)) != null) { 14329 // An app that is currently receiving a broadcast also 14330 // counts as being in the foreground for OOM killer purposes. 14331 // It's placed in a sched group based on the nature of the 14332 // broadcast as reflected by which queue it's active in. 14333 adj = ProcessList.FOREGROUND_APP_ADJ; 14334 schedGroup = (queue == mFgBroadcastQueue) 14335 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14336 app.adjType = "broadcast"; 14337 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14338 } else if (app.executingServices.size() > 0) { 14339 // An app that is currently executing a service callback also 14340 // counts as being in the foreground. 14341 adj = ProcessList.FOREGROUND_APP_ADJ; 14342 schedGroup = app.execServicesFg ? 14343 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14344 app.adjType = "exec-service"; 14345 procState = ActivityManager.PROCESS_STATE_SERVICE; 14346 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14347 } else { 14348 // As far as we know the process is empty. We may change our mind later. 14349 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14350 // At this point we don't actually know the adjustment. Use the cached adj 14351 // value that the caller wants us to. 14352 adj = cachedAdj; 14353 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14354 app.cached = true; 14355 app.empty = true; 14356 app.adjType = "cch-empty"; 14357 } 14358 14359 // Examine all activities if not already foreground. 14360 if (!foregroundActivities && activitiesSize > 0) { 14361 for (int j = 0; j < activitiesSize; j++) { 14362 final ActivityRecord r = app.activities.get(j); 14363 if (r.app != app) { 14364 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14365 + app + "?!?"); 14366 continue; 14367 } 14368 if (r.visible) { 14369 // App has a visible activity; only upgrade adjustment. 14370 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14371 adj = ProcessList.VISIBLE_APP_ADJ; 14372 app.adjType = "visible"; 14373 } 14374 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14375 procState = ActivityManager.PROCESS_STATE_TOP; 14376 } 14377 schedGroup = Process.THREAD_GROUP_DEFAULT; 14378 app.cached = false; 14379 app.empty = false; 14380 foregroundActivities = true; 14381 break; 14382 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14383 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14384 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14385 app.adjType = "pausing"; 14386 } 14387 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14388 procState = ActivityManager.PROCESS_STATE_TOP; 14389 } 14390 schedGroup = Process.THREAD_GROUP_DEFAULT; 14391 app.cached = false; 14392 app.empty = false; 14393 foregroundActivities = true; 14394 } else if (r.state == ActivityState.STOPPING) { 14395 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14396 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14397 app.adjType = "stopping"; 14398 } 14399 // For the process state, we will at this point consider the 14400 // process to be cached. It will be cached either as an activity 14401 // or empty depending on whether the activity is finishing. We do 14402 // this so that we can treat the process as cached for purposes of 14403 // memory trimming (determing current memory level, trim command to 14404 // send to process) since there can be an arbitrary number of stopping 14405 // processes and they should soon all go into the cached state. 14406 if (!r.finishing) { 14407 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14408 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14409 } 14410 } 14411 app.cached = false; 14412 app.empty = false; 14413 foregroundActivities = true; 14414 } else { 14415 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14416 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14417 app.adjType = "cch-act"; 14418 } 14419 } 14420 } 14421 } 14422 14423 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14424 if (app.foregroundServices) { 14425 // The user is aware of this app, so make it visible. 14426 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14427 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14428 app.cached = false; 14429 app.adjType = "fg-service"; 14430 schedGroup = Process.THREAD_GROUP_DEFAULT; 14431 } else if (app.forcingToForeground != null) { 14432 // The user is aware of this app, so make it visible. 14433 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14434 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14435 app.cached = false; 14436 app.adjType = "force-fg"; 14437 app.adjSource = app.forcingToForeground; 14438 schedGroup = Process.THREAD_GROUP_DEFAULT; 14439 } 14440 } 14441 14442 if (app.foregroundServices) { 14443 interesting = true; 14444 } 14445 14446 if (app == mHeavyWeightProcess) { 14447 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14448 // We don't want to kill the current heavy-weight process. 14449 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14450 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14451 app.cached = false; 14452 app.adjType = "heavy"; 14453 } 14454 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14455 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14456 } 14457 } 14458 14459 if (app == mHomeProcess) { 14460 if (adj > ProcessList.HOME_APP_ADJ) { 14461 // This process is hosting what we currently consider to be the 14462 // home app, so we don't want to let it go into the background. 14463 adj = ProcessList.HOME_APP_ADJ; 14464 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14465 app.cached = false; 14466 app.adjType = "home"; 14467 } 14468 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14469 procState = ActivityManager.PROCESS_STATE_HOME; 14470 } 14471 } 14472 14473 if (app == mPreviousProcess && app.activities.size() > 0) { 14474 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14475 // This was the previous process that showed UI to the user. 14476 // We want to try to keep it around more aggressively, to give 14477 // a good experience around switching between two apps. 14478 adj = ProcessList.PREVIOUS_APP_ADJ; 14479 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14480 app.cached = false; 14481 app.adjType = "previous"; 14482 } 14483 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14484 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14485 } 14486 } 14487 14488 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14489 + " reason=" + app.adjType); 14490 14491 // By default, we use the computed adjustment. It may be changed if 14492 // there are applications dependent on our services or providers, but 14493 // this gives us a baseline and makes sure we don't get into an 14494 // infinite recursion. 14495 app.adjSeq = mAdjSeq; 14496 app.curRawAdj = adj; 14497 app.hasStartedServices = false; 14498 14499 if (mBackupTarget != null && app == mBackupTarget.app) { 14500 // If possible we want to avoid killing apps while they're being backed up 14501 if (adj > ProcessList.BACKUP_APP_ADJ) { 14502 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14503 adj = ProcessList.BACKUP_APP_ADJ; 14504 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14505 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14506 } 14507 app.adjType = "backup"; 14508 app.cached = false; 14509 } 14510 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14511 procState = ActivityManager.PROCESS_STATE_BACKUP; 14512 } 14513 } 14514 14515 boolean mayBeTop = false; 14516 14517 for (int is = app.services.size()-1; 14518 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14519 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14520 || procState > ActivityManager.PROCESS_STATE_TOP); 14521 is--) { 14522 ServiceRecord s = app.services.valueAt(is); 14523 if (s.startRequested) { 14524 app.hasStartedServices = true; 14525 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14526 procState = ActivityManager.PROCESS_STATE_SERVICE; 14527 } 14528 if (app.hasShownUi && app != mHomeProcess) { 14529 // If this process has shown some UI, let it immediately 14530 // go to the LRU list because it may be pretty heavy with 14531 // UI stuff. We'll tag it with a label just to help 14532 // debug and understand what is going on. 14533 if (adj > ProcessList.SERVICE_ADJ) { 14534 app.adjType = "cch-started-ui-services"; 14535 } 14536 } else { 14537 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14538 // This service has seen some activity within 14539 // recent memory, so we will keep its process ahead 14540 // of the background processes. 14541 if (adj > ProcessList.SERVICE_ADJ) { 14542 adj = ProcessList.SERVICE_ADJ; 14543 app.adjType = "started-services"; 14544 app.cached = false; 14545 } 14546 } 14547 // If we have let the service slide into the background 14548 // state, still have some text describing what it is doing 14549 // even though the service no longer has an impact. 14550 if (adj > ProcessList.SERVICE_ADJ) { 14551 app.adjType = "cch-started-services"; 14552 } 14553 } 14554 // Don't kill this process because it is doing work; it 14555 // has said it is doing work. 14556 app.keeping = true; 14557 } 14558 for (int conni = s.connections.size()-1; 14559 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14560 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14561 || procState > ActivityManager.PROCESS_STATE_TOP); 14562 conni--) { 14563 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14564 for (int i = 0; 14565 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14566 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14567 || procState > ActivityManager.PROCESS_STATE_TOP); 14568 i++) { 14569 // XXX should compute this based on the max of 14570 // all connected clients. 14571 ConnectionRecord cr = clist.get(i); 14572 if (cr.binding.client == app) { 14573 // Binding to ourself is not interesting. 14574 continue; 14575 } 14576 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14577 ProcessRecord client = cr.binding.client; 14578 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14579 TOP_APP, doingAll, now); 14580 int clientProcState = client.curProcState; 14581 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14582 // If the other app is cached for any reason, for purposes here 14583 // we are going to consider it empty. The specific cached state 14584 // doesn't propagate except under certain conditions. 14585 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14586 } 14587 String adjType = null; 14588 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14589 // Not doing bind OOM management, so treat 14590 // this guy more like a started service. 14591 if (app.hasShownUi && app != mHomeProcess) { 14592 // If this process has shown some UI, let it immediately 14593 // go to the LRU list because it may be pretty heavy with 14594 // UI stuff. We'll tag it with a label just to help 14595 // debug and understand what is going on. 14596 if (adj > clientAdj) { 14597 adjType = "cch-bound-ui-services"; 14598 } 14599 app.cached = false; 14600 clientAdj = adj; 14601 clientProcState = procState; 14602 } else { 14603 if (now >= (s.lastActivity 14604 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14605 // This service has not seen activity within 14606 // recent memory, so allow it to drop to the 14607 // LRU list if there is no other reason to keep 14608 // it around. We'll also tag it with a label just 14609 // to help debug and undertand what is going on. 14610 if (adj > clientAdj) { 14611 adjType = "cch-bound-services"; 14612 } 14613 clientAdj = adj; 14614 } 14615 } 14616 } 14617 if (adj > clientAdj) { 14618 // If this process has recently shown UI, and 14619 // the process that is binding to it is less 14620 // important than being visible, then we don't 14621 // care about the binding as much as we care 14622 // about letting this process get into the LRU 14623 // list to be killed and restarted if needed for 14624 // memory. 14625 if (app.hasShownUi && app != mHomeProcess 14626 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14627 adjType = "cch-bound-ui-services"; 14628 } else { 14629 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14630 |Context.BIND_IMPORTANT)) != 0) { 14631 adj = clientAdj; 14632 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14633 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14634 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14635 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14636 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14637 adj = clientAdj; 14638 } else { 14639 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14640 adj = ProcessList.VISIBLE_APP_ADJ; 14641 } 14642 } 14643 if (!client.cached) { 14644 app.cached = false; 14645 } 14646 if (client.keeping) { 14647 app.keeping = true; 14648 } 14649 adjType = "service"; 14650 } 14651 } 14652 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14653 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14654 schedGroup = Process.THREAD_GROUP_DEFAULT; 14655 } 14656 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14657 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14658 // Special handling of clients who are in the top state. 14659 // We *may* want to consider this process to be in the 14660 // top state as well, but only if there is not another 14661 // reason for it to be running. Being on the top is a 14662 // special state, meaning you are specifically running 14663 // for the current top app. If the process is already 14664 // running in the background for some other reason, it 14665 // is more important to continue considering it to be 14666 // in the background state. 14667 mayBeTop = true; 14668 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14669 } else { 14670 // Special handling for above-top states (persistent 14671 // processes). These should not bring the current process 14672 // into the top state, since they are not on top. Instead 14673 // give them the best state after that. 14674 clientProcState = 14675 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14676 } 14677 } 14678 } else { 14679 if (clientProcState < 14680 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14681 clientProcState = 14682 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14683 } 14684 } 14685 if (procState > clientProcState) { 14686 procState = clientProcState; 14687 } 14688 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14689 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14690 app.pendingUiClean = true; 14691 } 14692 if (adjType != null) { 14693 app.adjType = adjType; 14694 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14695 .REASON_SERVICE_IN_USE; 14696 app.adjSource = cr.binding.client; 14697 app.adjSourceOom = clientAdj; 14698 app.adjTarget = s.name; 14699 } 14700 } 14701 final ActivityRecord a = cr.activity; 14702 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14703 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14704 (a.visible || a.state == ActivityState.RESUMED 14705 || a.state == ActivityState.PAUSING)) { 14706 adj = ProcessList.FOREGROUND_APP_ADJ; 14707 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14708 schedGroup = Process.THREAD_GROUP_DEFAULT; 14709 } 14710 app.cached = false; 14711 app.adjType = "service"; 14712 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14713 .REASON_SERVICE_IN_USE; 14714 app.adjSource = a; 14715 app.adjSourceOom = adj; 14716 app.adjTarget = s.name; 14717 } 14718 } 14719 } 14720 } 14721 } 14722 14723 for (int provi = app.pubProviders.size()-1; 14724 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14725 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14726 || procState > ActivityManager.PROCESS_STATE_TOP); 14727 provi--) { 14728 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14729 for (int i = cpr.connections.size()-1; 14730 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14731 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14732 || procState > ActivityManager.PROCESS_STATE_TOP); 14733 i--) { 14734 ContentProviderConnection conn = cpr.connections.get(i); 14735 ProcessRecord client = conn.client; 14736 if (client == app) { 14737 // Being our own client is not interesting. 14738 continue; 14739 } 14740 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14741 int clientProcState = client.curProcState; 14742 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14743 // If the other app is cached for any reason, for purposes here 14744 // we are going to consider it empty. 14745 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14746 } 14747 if (adj > clientAdj) { 14748 if (app.hasShownUi && app != mHomeProcess 14749 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14750 app.adjType = "cch-ui-provider"; 14751 } else { 14752 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14753 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14754 app.adjType = "provider"; 14755 } 14756 app.cached &= client.cached; 14757 app.keeping |= client.keeping; 14758 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14759 .REASON_PROVIDER_IN_USE; 14760 app.adjSource = client; 14761 app.adjSourceOom = clientAdj; 14762 app.adjTarget = cpr.name; 14763 } 14764 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14765 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14766 // Special handling of clients who are in the top state. 14767 // We *may* want to consider this process to be in the 14768 // top state as well, but only if there is not another 14769 // reason for it to be running. Being on the top is a 14770 // special state, meaning you are specifically running 14771 // for the current top app. If the process is already 14772 // running in the background for some other reason, it 14773 // is more important to continue considering it to be 14774 // in the background state. 14775 mayBeTop = true; 14776 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14777 } else { 14778 // Special handling for above-top states (persistent 14779 // processes). These should not bring the current process 14780 // into the top state, since they are not on top. Instead 14781 // give them the best state after that. 14782 clientProcState = 14783 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14784 } 14785 } 14786 if (procState > clientProcState) { 14787 procState = clientProcState; 14788 } 14789 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14790 schedGroup = Process.THREAD_GROUP_DEFAULT; 14791 } 14792 } 14793 // If the provider has external (non-framework) process 14794 // dependencies, ensure that its adjustment is at least 14795 // FOREGROUND_APP_ADJ. 14796 if (cpr.hasExternalProcessHandles()) { 14797 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14798 adj = ProcessList.FOREGROUND_APP_ADJ; 14799 schedGroup = Process.THREAD_GROUP_DEFAULT; 14800 app.cached = false; 14801 app.keeping = true; 14802 app.adjType = "provider"; 14803 app.adjTarget = cpr.name; 14804 } 14805 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14806 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14807 } 14808 } 14809 } 14810 14811 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14812 // A client of one of our services or providers is in the top state. We 14813 // *may* want to be in the top state, but not if we are already running in 14814 // the background for some other reason. For the decision here, we are going 14815 // to pick out a few specific states that we want to remain in when a client 14816 // is top (states that tend to be longer-term) and otherwise allow it to go 14817 // to the top state. 14818 switch (procState) { 14819 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14820 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14821 case ActivityManager.PROCESS_STATE_SERVICE: 14822 // These all are longer-term states, so pull them up to the top 14823 // of the background states, but not all the way to the top state. 14824 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14825 break; 14826 default: 14827 // Otherwise, top is a better choice, so take it. 14828 procState = ActivityManager.PROCESS_STATE_TOP; 14829 break; 14830 } 14831 } 14832 14833 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14834 // This is a cached process, but with client activities. Mark it so. 14835 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14836 app.adjType = "cch-client-act"; 14837 } 14838 14839 if (adj == ProcessList.SERVICE_ADJ) { 14840 if (doingAll) { 14841 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14842 mNewNumServiceProcs++; 14843 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14844 if (!app.serviceb) { 14845 // This service isn't far enough down on the LRU list to 14846 // normally be a B service, but if we are low on RAM and it 14847 // is large we want to force it down since we would prefer to 14848 // keep launcher over it. 14849 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14850 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14851 app.serviceHighRam = true; 14852 app.serviceb = true; 14853 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14854 } else { 14855 mNewNumAServiceProcs++; 14856 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14857 } 14858 } else { 14859 app.serviceHighRam = false; 14860 } 14861 } 14862 if (app.serviceb) { 14863 adj = ProcessList.SERVICE_B_ADJ; 14864 } 14865 } 14866 14867 app.curRawAdj = adj; 14868 14869 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14870 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14871 if (adj > app.maxAdj) { 14872 adj = app.maxAdj; 14873 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14874 schedGroup = Process.THREAD_GROUP_DEFAULT; 14875 } 14876 } 14877 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14878 app.keeping = true; 14879 } 14880 14881 // Do final modification to adj. Everything we do between here and applying 14882 // the final setAdj must be done in this function, because we will also use 14883 // it when computing the final cached adj later. Note that we don't need to 14884 // worry about this for max adj above, since max adj will always be used to 14885 // keep it out of the cached vaues. 14886 adj = app.modifyRawOomAdj(adj); 14887 14888 app.curProcState = procState; 14889 14890 int importance = app.memImportance; 14891 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14892 app.curAdj = adj; 14893 app.curSchedGroup = schedGroup; 14894 if (!interesting) { 14895 // For this reporting, if there is not something explicitly 14896 // interesting in this process then we will push it to the 14897 // background importance. 14898 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14899 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14900 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14901 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14902 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14903 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14904 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14905 } else if (adj >= ProcessList.SERVICE_ADJ) { 14906 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14907 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14908 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14909 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14910 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14911 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14912 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14913 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14914 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14915 } else { 14916 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14917 } 14918 } 14919 14920 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14921 if (foregroundActivities != app.foregroundActivities) { 14922 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14923 } 14924 if (changes != 0) { 14925 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14926 app.memImportance = importance; 14927 app.foregroundActivities = foregroundActivities; 14928 int i = mPendingProcessChanges.size()-1; 14929 ProcessChangeItem item = null; 14930 while (i >= 0) { 14931 item = mPendingProcessChanges.get(i); 14932 if (item.pid == app.pid) { 14933 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14934 break; 14935 } 14936 i--; 14937 } 14938 if (i < 0) { 14939 // No existing item in pending changes; need a new one. 14940 final int NA = mAvailProcessChanges.size(); 14941 if (NA > 0) { 14942 item = mAvailProcessChanges.remove(NA-1); 14943 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14944 } else { 14945 item = new ProcessChangeItem(); 14946 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14947 } 14948 item.changes = 0; 14949 item.pid = app.pid; 14950 item.uid = app.info.uid; 14951 if (mPendingProcessChanges.size() == 0) { 14952 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14953 "*** Enqueueing dispatch processes changed!"); 14954 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14955 } 14956 mPendingProcessChanges.add(item); 14957 } 14958 item.changes |= changes; 14959 item.importance = importance; 14960 item.foregroundActivities = foregroundActivities; 14961 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14962 + Integer.toHexString(System.identityHashCode(item)) 14963 + " " + app.toShortString() + ": changes=" + item.changes 14964 + " importance=" + item.importance 14965 + " foreground=" + item.foregroundActivities 14966 + " type=" + app.adjType + " source=" + app.adjSource 14967 + " target=" + app.adjTarget); 14968 } 14969 14970 return app.curRawAdj; 14971 } 14972 14973 /** 14974 * Schedule PSS collection of a process. 14975 */ 14976 void requestPssLocked(ProcessRecord proc, int procState) { 14977 if (mPendingPssProcesses.contains(proc)) { 14978 return; 14979 } 14980 if (mPendingPssProcesses.size() == 0) { 14981 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14982 } 14983 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14984 proc.pssProcState = procState; 14985 mPendingPssProcesses.add(proc); 14986 } 14987 14988 /** 14989 * Schedule PSS collection of all processes. 14990 */ 14991 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14992 if (!always) { 14993 if (now < (mLastFullPssTime + 14994 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14995 return; 14996 } 14997 } 14998 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14999 mLastFullPssTime = now; 15000 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15001 mPendingPssProcesses.clear(); 15002 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15003 ProcessRecord app = mLruProcesses.get(i); 15004 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15005 app.pssProcState = app.setProcState; 15006 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15007 mSleeping, now); 15008 mPendingPssProcesses.add(app); 15009 } 15010 } 15011 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15012 } 15013 15014 /** 15015 * Ask a given process to GC right now. 15016 */ 15017 final void performAppGcLocked(ProcessRecord app) { 15018 try { 15019 app.lastRequestedGc = SystemClock.uptimeMillis(); 15020 if (app.thread != null) { 15021 if (app.reportLowMemory) { 15022 app.reportLowMemory = false; 15023 app.thread.scheduleLowMemory(); 15024 } else { 15025 app.thread.processInBackground(); 15026 } 15027 } 15028 } catch (Exception e) { 15029 // whatever. 15030 } 15031 } 15032 15033 /** 15034 * Returns true if things are idle enough to perform GCs. 15035 */ 15036 private final boolean canGcNowLocked() { 15037 boolean processingBroadcasts = false; 15038 for (BroadcastQueue q : mBroadcastQueues) { 15039 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15040 processingBroadcasts = true; 15041 } 15042 } 15043 return !processingBroadcasts 15044 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15045 } 15046 15047 /** 15048 * Perform GCs on all processes that are waiting for it, but only 15049 * if things are idle. 15050 */ 15051 final void performAppGcsLocked() { 15052 final int N = mProcessesToGc.size(); 15053 if (N <= 0) { 15054 return; 15055 } 15056 if (canGcNowLocked()) { 15057 while (mProcessesToGc.size() > 0) { 15058 ProcessRecord proc = mProcessesToGc.remove(0); 15059 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15060 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15061 <= SystemClock.uptimeMillis()) { 15062 // To avoid spamming the system, we will GC processes one 15063 // at a time, waiting a few seconds between each. 15064 performAppGcLocked(proc); 15065 scheduleAppGcsLocked(); 15066 return; 15067 } else { 15068 // It hasn't been long enough since we last GCed this 15069 // process... put it in the list to wait for its time. 15070 addProcessToGcListLocked(proc); 15071 break; 15072 } 15073 } 15074 } 15075 15076 scheduleAppGcsLocked(); 15077 } 15078 } 15079 15080 /** 15081 * If all looks good, perform GCs on all processes waiting for them. 15082 */ 15083 final void performAppGcsIfAppropriateLocked() { 15084 if (canGcNowLocked()) { 15085 performAppGcsLocked(); 15086 return; 15087 } 15088 // Still not idle, wait some more. 15089 scheduleAppGcsLocked(); 15090 } 15091 15092 /** 15093 * Schedule the execution of all pending app GCs. 15094 */ 15095 final void scheduleAppGcsLocked() { 15096 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15097 15098 if (mProcessesToGc.size() > 0) { 15099 // Schedule a GC for the time to the next process. 15100 ProcessRecord proc = mProcessesToGc.get(0); 15101 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15102 15103 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15104 long now = SystemClock.uptimeMillis(); 15105 if (when < (now+GC_TIMEOUT)) { 15106 when = now + GC_TIMEOUT; 15107 } 15108 mHandler.sendMessageAtTime(msg, when); 15109 } 15110 } 15111 15112 /** 15113 * Add a process to the array of processes waiting to be GCed. Keeps the 15114 * list in sorted order by the last GC time. The process can't already be 15115 * on the list. 15116 */ 15117 final void addProcessToGcListLocked(ProcessRecord proc) { 15118 boolean added = false; 15119 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15120 if (mProcessesToGc.get(i).lastRequestedGc < 15121 proc.lastRequestedGc) { 15122 added = true; 15123 mProcessesToGc.add(i+1, proc); 15124 break; 15125 } 15126 } 15127 if (!added) { 15128 mProcessesToGc.add(0, proc); 15129 } 15130 } 15131 15132 /** 15133 * Set up to ask a process to GC itself. This will either do it 15134 * immediately, or put it on the list of processes to gc the next 15135 * time things are idle. 15136 */ 15137 final void scheduleAppGcLocked(ProcessRecord app) { 15138 long now = SystemClock.uptimeMillis(); 15139 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15140 return; 15141 } 15142 if (!mProcessesToGc.contains(app)) { 15143 addProcessToGcListLocked(app); 15144 scheduleAppGcsLocked(); 15145 } 15146 } 15147 15148 final void checkExcessivePowerUsageLocked(boolean doKills) { 15149 updateCpuStatsNow(); 15150 15151 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15152 boolean doWakeKills = doKills; 15153 boolean doCpuKills = doKills; 15154 if (mLastPowerCheckRealtime == 0) { 15155 doWakeKills = false; 15156 } 15157 if (mLastPowerCheckUptime == 0) { 15158 doCpuKills = false; 15159 } 15160 if (stats.isScreenOn()) { 15161 doWakeKills = false; 15162 } 15163 final long curRealtime = SystemClock.elapsedRealtime(); 15164 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15165 final long curUptime = SystemClock.uptimeMillis(); 15166 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15167 mLastPowerCheckRealtime = curRealtime; 15168 mLastPowerCheckUptime = curUptime; 15169 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15170 doWakeKills = false; 15171 } 15172 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15173 doCpuKills = false; 15174 } 15175 int i = mLruProcesses.size(); 15176 while (i > 0) { 15177 i--; 15178 ProcessRecord app = mLruProcesses.get(i); 15179 if (!app.keeping) { 15180 long wtime; 15181 synchronized (stats) { 15182 wtime = stats.getProcessWakeTime(app.info.uid, 15183 app.pid, curRealtime); 15184 } 15185 long wtimeUsed = wtime - app.lastWakeTime; 15186 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15187 if (DEBUG_POWER) { 15188 StringBuilder sb = new StringBuilder(128); 15189 sb.append("Wake for "); 15190 app.toShortString(sb); 15191 sb.append(": over "); 15192 TimeUtils.formatDuration(realtimeSince, sb); 15193 sb.append(" used "); 15194 TimeUtils.formatDuration(wtimeUsed, sb); 15195 sb.append(" ("); 15196 sb.append((wtimeUsed*100)/realtimeSince); 15197 sb.append("%)"); 15198 Slog.i(TAG, sb.toString()); 15199 sb.setLength(0); 15200 sb.append("CPU for "); 15201 app.toShortString(sb); 15202 sb.append(": over "); 15203 TimeUtils.formatDuration(uptimeSince, sb); 15204 sb.append(" used "); 15205 TimeUtils.formatDuration(cputimeUsed, sb); 15206 sb.append(" ("); 15207 sb.append((cputimeUsed*100)/uptimeSince); 15208 sb.append("%)"); 15209 Slog.i(TAG, sb.toString()); 15210 } 15211 // If a process has held a wake lock for more 15212 // than 50% of the time during this period, 15213 // that sounds bad. Kill! 15214 if (doWakeKills && realtimeSince > 0 15215 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15216 synchronized (stats) { 15217 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15218 realtimeSince, wtimeUsed); 15219 } 15220 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15221 + " during " + realtimeSince); 15222 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15223 } else if (doCpuKills && uptimeSince > 0 15224 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15225 synchronized (stats) { 15226 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15227 uptimeSince, cputimeUsed); 15228 } 15229 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15230 + " during " + uptimeSince); 15231 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15232 } else { 15233 app.lastWakeTime = wtime; 15234 app.lastCpuTime = app.curCpuTime; 15235 } 15236 } 15237 } 15238 } 15239 15240 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15241 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15242 boolean success = true; 15243 15244 if (app.curRawAdj != app.setRawAdj) { 15245 if (wasKeeping && !app.keeping) { 15246 // This app is no longer something we want to keep. Note 15247 // its current wake lock time to later know to kill it if 15248 // it is not behaving well. 15249 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15250 synchronized (stats) { 15251 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15252 app.pid, SystemClock.elapsedRealtime()); 15253 } 15254 app.lastCpuTime = app.curCpuTime; 15255 } 15256 15257 app.setRawAdj = app.curRawAdj; 15258 } 15259 15260 if (app.curAdj != app.setAdj) { 15261 if (Process.setOomAdj(app.pid, app.curAdj)) { 15262 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15263 TAG, "Set " + app.pid + " " + app.processName + 15264 " adj " + app.curAdj + ": " + app.adjType); 15265 app.setAdj = app.curAdj; 15266 } else { 15267 success = false; 15268 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 15269 } 15270 } 15271 if (app.setSchedGroup != app.curSchedGroup) { 15272 app.setSchedGroup = app.curSchedGroup; 15273 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15274 "Setting process group of " + app.processName 15275 + " to " + app.curSchedGroup); 15276 if (app.waitingToKill != null && 15277 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15278 killUnneededProcessLocked(app, app.waitingToKill); 15279 success = false; 15280 } else { 15281 if (true) { 15282 long oldId = Binder.clearCallingIdentity(); 15283 try { 15284 Process.setProcessGroup(app.pid, app.curSchedGroup); 15285 } catch (Exception e) { 15286 Slog.w(TAG, "Failed setting process group of " + app.pid 15287 + " to " + app.curSchedGroup); 15288 e.printStackTrace(); 15289 } finally { 15290 Binder.restoreCallingIdentity(oldId); 15291 } 15292 } else { 15293 if (app.thread != null) { 15294 try { 15295 app.thread.setSchedulingGroup(app.curSchedGroup); 15296 } catch (RemoteException e) { 15297 } 15298 } 15299 } 15300 Process.setSwappiness(app.pid, 15301 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15302 } 15303 } 15304 if (app.repProcState != app.curProcState) { 15305 app.repProcState = app.curProcState; 15306 if (!reportingProcessState && app.thread != null) { 15307 try { 15308 if (false) { 15309 //RuntimeException h = new RuntimeException("here"); 15310 Slog.i(TAG, "Sending new process state " + app.repProcState 15311 + " to " + app /*, h*/); 15312 } 15313 app.thread.setProcessState(app.repProcState); 15314 } catch (RemoteException e) { 15315 } 15316 } 15317 } 15318 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15319 app.setProcState)) { 15320 app.lastStateTime = now; 15321 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15322 mSleeping, now); 15323 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15324 + ProcessList.makeProcStateString(app.setProcState) + " to " 15325 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15326 + (app.nextPssTime-now) + ": " + app); 15327 } else { 15328 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15329 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15330 requestPssLocked(app, app.setProcState); 15331 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15332 mSleeping, now); 15333 } else if (false && DEBUG_PSS) { 15334 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15335 } 15336 } 15337 if (app.setProcState != app.curProcState) { 15338 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15339 "Proc state change of " + app.processName 15340 + " to " + app.curProcState); 15341 app.setProcState = app.curProcState; 15342 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15343 app.notCachedSinceIdle = false; 15344 } 15345 if (!doingAll) { 15346 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15347 } else { 15348 app.procStateChanged = true; 15349 } 15350 } 15351 return success; 15352 } 15353 15354 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15355 if (proc.thread != null && proc.baseProcessTracker != null) { 15356 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15357 } 15358 } 15359 15360 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15361 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15362 if (app.thread == null) { 15363 return false; 15364 } 15365 15366 final boolean wasKeeping = app.keeping; 15367 15368 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15369 15370 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15371 reportingProcessState, now); 15372 } 15373 15374 private final ActivityRecord resumedAppLocked() { 15375 return mStackSupervisor.resumedAppLocked(); 15376 } 15377 15378 final boolean updateOomAdjLocked(ProcessRecord app) { 15379 return updateOomAdjLocked(app, false); 15380 } 15381 15382 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15383 final ActivityRecord TOP_ACT = resumedAppLocked(); 15384 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15385 final boolean wasCached = app.cached; 15386 15387 mAdjSeq++; 15388 15389 // This is the desired cached adjusment we want to tell it to use. 15390 // If our app is currently cached, we know it, and that is it. Otherwise, 15391 // we don't know it yet, and it needs to now be cached we will then 15392 // need to do a complete oom adj. 15393 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15394 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15395 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15396 SystemClock.uptimeMillis()); 15397 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15398 // Changed to/from cached state, so apps after it in the LRU 15399 // list may also be changed. 15400 updateOomAdjLocked(); 15401 } 15402 return success; 15403 } 15404 15405 final void updateOomAdjLocked() { 15406 final ActivityRecord TOP_ACT = resumedAppLocked(); 15407 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15408 final long now = SystemClock.uptimeMillis(); 15409 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15410 final int N = mLruProcesses.size(); 15411 15412 if (false) { 15413 RuntimeException e = new RuntimeException(); 15414 e.fillInStackTrace(); 15415 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15416 } 15417 15418 mAdjSeq++; 15419 mNewNumServiceProcs = 0; 15420 mNewNumAServiceProcs = 0; 15421 15422 final int emptyProcessLimit; 15423 final int cachedProcessLimit; 15424 if (mProcessLimit <= 0) { 15425 emptyProcessLimit = cachedProcessLimit = 0; 15426 } else if (mProcessLimit == 1) { 15427 emptyProcessLimit = 1; 15428 cachedProcessLimit = 0; 15429 } else { 15430 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15431 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15432 } 15433 15434 // Let's determine how many processes we have running vs. 15435 // how many slots we have for background processes; we may want 15436 // to put multiple processes in a slot of there are enough of 15437 // them. 15438 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15439 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15440 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15441 if (numEmptyProcs > cachedProcessLimit) { 15442 // If there are more empty processes than our limit on cached 15443 // processes, then use the cached process limit for the factor. 15444 // This ensures that the really old empty processes get pushed 15445 // down to the bottom, so if we are running low on memory we will 15446 // have a better chance at keeping around more cached processes 15447 // instead of a gazillion empty processes. 15448 numEmptyProcs = cachedProcessLimit; 15449 } 15450 int emptyFactor = numEmptyProcs/numSlots; 15451 if (emptyFactor < 1) emptyFactor = 1; 15452 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15453 if (cachedFactor < 1) cachedFactor = 1; 15454 int stepCached = 0; 15455 int stepEmpty = 0; 15456 int numCached = 0; 15457 int numEmpty = 0; 15458 int numTrimming = 0; 15459 15460 mNumNonCachedProcs = 0; 15461 mNumCachedHiddenProcs = 0; 15462 15463 // First update the OOM adjustment for each of the 15464 // application processes based on their current state. 15465 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15466 int nextCachedAdj = curCachedAdj+1; 15467 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15468 int nextEmptyAdj = curEmptyAdj+2; 15469 for (int i=N-1; i>=0; i--) { 15470 ProcessRecord app = mLruProcesses.get(i); 15471 if (!app.killedByAm && app.thread != null) { 15472 app.procStateChanged = false; 15473 final boolean wasKeeping = app.keeping; 15474 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15475 15476 // If we haven't yet assigned the final cached adj 15477 // to the process, do that now. 15478 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15479 switch (app.curProcState) { 15480 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15481 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15482 // This process is a cached process holding activities... 15483 // assign it the next cached value for that type, and then 15484 // step that cached level. 15485 app.curRawAdj = curCachedAdj; 15486 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15487 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15488 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15489 + ")"); 15490 if (curCachedAdj != nextCachedAdj) { 15491 stepCached++; 15492 if (stepCached >= cachedFactor) { 15493 stepCached = 0; 15494 curCachedAdj = nextCachedAdj; 15495 nextCachedAdj += 2; 15496 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15497 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15498 } 15499 } 15500 } 15501 break; 15502 default: 15503 // For everything else, assign next empty cached process 15504 // level and bump that up. Note that this means that 15505 // long-running services that have dropped down to the 15506 // cached level will be treated as empty (since their process 15507 // state is still as a service), which is what we want. 15508 app.curRawAdj = curEmptyAdj; 15509 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15510 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15511 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15512 + ")"); 15513 if (curEmptyAdj != nextEmptyAdj) { 15514 stepEmpty++; 15515 if (stepEmpty >= emptyFactor) { 15516 stepEmpty = 0; 15517 curEmptyAdj = nextEmptyAdj; 15518 nextEmptyAdj += 2; 15519 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15520 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15521 } 15522 } 15523 } 15524 break; 15525 } 15526 } 15527 15528 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15529 15530 // Count the number of process types. 15531 switch (app.curProcState) { 15532 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15533 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15534 mNumCachedHiddenProcs++; 15535 numCached++; 15536 if (numCached > cachedProcessLimit) { 15537 killUnneededProcessLocked(app, "cached #" + numCached); 15538 } 15539 break; 15540 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15541 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15542 && app.lastActivityTime < oldTime) { 15543 killUnneededProcessLocked(app, "empty for " 15544 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15545 / 1000) + "s"); 15546 } else { 15547 numEmpty++; 15548 if (numEmpty > emptyProcessLimit) { 15549 killUnneededProcessLocked(app, "empty #" + numEmpty); 15550 } 15551 } 15552 break; 15553 default: 15554 mNumNonCachedProcs++; 15555 break; 15556 } 15557 15558 if (app.isolated && app.services.size() <= 0) { 15559 // If this is an isolated process, and there are no 15560 // services running in it, then the process is no longer 15561 // needed. We agressively kill these because we can by 15562 // definition not re-use the same process again, and it is 15563 // good to avoid having whatever code was running in them 15564 // left sitting around after no longer needed. 15565 killUnneededProcessLocked(app, "isolated not needed"); 15566 } 15567 15568 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15569 && !app.killedByAm) { 15570 numTrimming++; 15571 } 15572 } 15573 } 15574 15575 mNumServiceProcs = mNewNumServiceProcs; 15576 15577 // Now determine the memory trimming level of background processes. 15578 // Unfortunately we need to start at the back of the list to do this 15579 // properly. We only do this if the number of background apps we 15580 // are managing to keep around is less than half the maximum we desire; 15581 // if we are keeping a good number around, we'll let them use whatever 15582 // memory they want. 15583 final int numCachedAndEmpty = numCached + numEmpty; 15584 int memFactor; 15585 if (numCached <= ProcessList.TRIM_CACHED_APPS 15586 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15587 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15588 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15589 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15590 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15591 } else { 15592 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15593 } 15594 } else { 15595 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15596 } 15597 // We always allow the memory level to go up (better). We only allow it to go 15598 // down if we are in a state where that is allowed, *and* the total number of processes 15599 // has gone down since last time. 15600 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15601 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15602 + " last=" + mLastNumProcesses); 15603 if (memFactor > mLastMemoryLevel) { 15604 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15605 memFactor = mLastMemoryLevel; 15606 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15607 } 15608 } 15609 mLastMemoryLevel = memFactor; 15610 mLastNumProcesses = mLruProcesses.size(); 15611 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15612 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15613 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15614 if (mLowRamStartTime == 0) { 15615 mLowRamStartTime = now; 15616 } 15617 int step = 0; 15618 int fgTrimLevel; 15619 switch (memFactor) { 15620 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15621 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15622 break; 15623 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15624 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15625 break; 15626 default: 15627 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15628 break; 15629 } 15630 int factor = numTrimming/3; 15631 int minFactor = 2; 15632 if (mHomeProcess != null) minFactor++; 15633 if (mPreviousProcess != null) minFactor++; 15634 if (factor < minFactor) factor = minFactor; 15635 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15636 for (int i=N-1; i>=0; i--) { 15637 ProcessRecord app = mLruProcesses.get(i); 15638 if (allChanged || app.procStateChanged) { 15639 setProcessTrackerState(app, trackerMemFactor, now); 15640 app.procStateChanged = false; 15641 } 15642 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15643 && !app.killedByAm) { 15644 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15645 try { 15646 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15647 "Trimming memory of " + app.processName 15648 + " to " + curLevel); 15649 app.thread.scheduleTrimMemory(curLevel); 15650 } catch (RemoteException e) { 15651 } 15652 if (false) { 15653 // For now we won't do this; our memory trimming seems 15654 // to be good enough at this point that destroying 15655 // activities causes more harm than good. 15656 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15657 && app != mHomeProcess && app != mPreviousProcess) { 15658 // Need to do this on its own message because the stack may not 15659 // be in a consistent state at this point. 15660 // For these apps we will also finish their activities 15661 // to help them free memory. 15662 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15663 } 15664 } 15665 } 15666 app.trimMemoryLevel = curLevel; 15667 step++; 15668 if (step >= factor) { 15669 step = 0; 15670 switch (curLevel) { 15671 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15672 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15673 break; 15674 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15675 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15676 break; 15677 } 15678 } 15679 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15680 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15681 && app.thread != null) { 15682 try { 15683 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15684 "Trimming memory of heavy-weight " + app.processName 15685 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15686 app.thread.scheduleTrimMemory( 15687 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15688 } catch (RemoteException e) { 15689 } 15690 } 15691 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15692 } else { 15693 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15694 || app.systemNoUi) && app.pendingUiClean) { 15695 // If this application is now in the background and it 15696 // had done UI, then give it the special trim level to 15697 // have it free UI resources. 15698 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15699 if (app.trimMemoryLevel < level && app.thread != null) { 15700 try { 15701 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15702 "Trimming memory of bg-ui " + app.processName 15703 + " to " + level); 15704 app.thread.scheduleTrimMemory(level); 15705 } catch (RemoteException e) { 15706 } 15707 } 15708 app.pendingUiClean = false; 15709 } 15710 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15711 try { 15712 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15713 "Trimming memory of fg " + app.processName 15714 + " to " + fgTrimLevel); 15715 app.thread.scheduleTrimMemory(fgTrimLevel); 15716 } catch (RemoteException e) { 15717 } 15718 } 15719 app.trimMemoryLevel = fgTrimLevel; 15720 } 15721 } 15722 } else { 15723 if (mLowRamStartTime != 0) { 15724 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15725 mLowRamStartTime = 0; 15726 } 15727 for (int i=N-1; i>=0; i--) { 15728 ProcessRecord app = mLruProcesses.get(i); 15729 if (allChanged || app.procStateChanged) { 15730 setProcessTrackerState(app, trackerMemFactor, now); 15731 app.procStateChanged = false; 15732 } 15733 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15734 || app.systemNoUi) && app.pendingUiClean) { 15735 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15736 && app.thread != null) { 15737 try { 15738 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15739 "Trimming memory of ui hidden " + app.processName 15740 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15741 app.thread.scheduleTrimMemory( 15742 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15743 } catch (RemoteException e) { 15744 } 15745 } 15746 app.pendingUiClean = false; 15747 } 15748 app.trimMemoryLevel = 0; 15749 } 15750 } 15751 15752 if (mAlwaysFinishActivities) { 15753 // Need to do this on its own message because the stack may not 15754 // be in a consistent state at this point. 15755 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15756 } 15757 15758 if (allChanged) { 15759 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15760 } 15761 15762 if (mProcessStats.shouldWriteNowLocked(now)) { 15763 mHandler.post(new Runnable() { 15764 @Override public void run() { 15765 synchronized (ActivityManagerService.this) { 15766 mProcessStats.writeStateAsyncLocked(); 15767 } 15768 } 15769 }); 15770 } 15771 15772 if (DEBUG_OOM_ADJ) { 15773 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15774 } 15775 } 15776 15777 final void trimApplications() { 15778 synchronized (this) { 15779 int i; 15780 15781 // First remove any unused application processes whose package 15782 // has been removed. 15783 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15784 final ProcessRecord app = mRemovedProcesses.get(i); 15785 if (app.activities.size() == 0 15786 && app.curReceiver == null && app.services.size() == 0) { 15787 Slog.i( 15788 TAG, "Exiting empty application process " 15789 + app.processName + " (" 15790 + (app.thread != null ? app.thread.asBinder() : null) 15791 + ")\n"); 15792 if (app.pid > 0 && app.pid != MY_PID) { 15793 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15794 app.processName, app.setAdj, "empty"); 15795 app.killedByAm = true; 15796 Process.killProcessQuiet(app.pid); 15797 } else { 15798 try { 15799 app.thread.scheduleExit(); 15800 } catch (Exception e) { 15801 // Ignore exceptions. 15802 } 15803 } 15804 cleanUpApplicationRecordLocked(app, false, true, -1); 15805 mRemovedProcesses.remove(i); 15806 15807 if (app.persistent) { 15808 if (app.persistent) { 15809 addAppLocked(app.info, false); 15810 } 15811 } 15812 } 15813 } 15814 15815 // Now update the oom adj for all processes. 15816 updateOomAdjLocked(); 15817 } 15818 } 15819 15820 /** This method sends the specified signal to each of the persistent apps */ 15821 public void signalPersistentProcesses(int sig) throws RemoteException { 15822 if (sig != Process.SIGNAL_USR1) { 15823 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15824 } 15825 15826 synchronized (this) { 15827 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15828 != PackageManager.PERMISSION_GRANTED) { 15829 throw new SecurityException("Requires permission " 15830 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15831 } 15832 15833 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15834 ProcessRecord r = mLruProcesses.get(i); 15835 if (r.thread != null && r.persistent) { 15836 Process.sendSignal(r.pid, sig); 15837 } 15838 } 15839 } 15840 } 15841 15842 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15843 if (proc == null || proc == mProfileProc) { 15844 proc = mProfileProc; 15845 path = mProfileFile; 15846 profileType = mProfileType; 15847 clearProfilerLocked(); 15848 } 15849 if (proc == null) { 15850 return; 15851 } 15852 try { 15853 proc.thread.profilerControl(false, path, null, profileType); 15854 } catch (RemoteException e) { 15855 throw new IllegalStateException("Process disappeared"); 15856 } 15857 } 15858 15859 private void clearProfilerLocked() { 15860 if (mProfileFd != null) { 15861 try { 15862 mProfileFd.close(); 15863 } catch (IOException e) { 15864 } 15865 } 15866 mProfileApp = null; 15867 mProfileProc = null; 15868 mProfileFile = null; 15869 mProfileType = 0; 15870 mAutoStopProfiler = false; 15871 } 15872 15873 public boolean profileControl(String process, int userId, boolean start, 15874 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15875 15876 try { 15877 synchronized (this) { 15878 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15879 // its own permission. 15880 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15881 != PackageManager.PERMISSION_GRANTED) { 15882 throw new SecurityException("Requires permission " 15883 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15884 } 15885 15886 if (start && fd == null) { 15887 throw new IllegalArgumentException("null fd"); 15888 } 15889 15890 ProcessRecord proc = null; 15891 if (process != null) { 15892 proc = findProcessLocked(process, userId, "profileControl"); 15893 } 15894 15895 if (start && (proc == null || proc.thread == null)) { 15896 throw new IllegalArgumentException("Unknown process: " + process); 15897 } 15898 15899 if (start) { 15900 stopProfilerLocked(null, null, 0); 15901 setProfileApp(proc.info, proc.processName, path, fd, false); 15902 mProfileProc = proc; 15903 mProfileType = profileType; 15904 try { 15905 fd = fd.dup(); 15906 } catch (IOException e) { 15907 fd = null; 15908 } 15909 proc.thread.profilerControl(start, path, fd, profileType); 15910 fd = null; 15911 mProfileFd = null; 15912 } else { 15913 stopProfilerLocked(proc, path, profileType); 15914 if (fd != null) { 15915 try { 15916 fd.close(); 15917 } catch (IOException e) { 15918 } 15919 } 15920 } 15921 15922 return true; 15923 } 15924 } catch (RemoteException e) { 15925 throw new IllegalStateException("Process disappeared"); 15926 } finally { 15927 if (fd != null) { 15928 try { 15929 fd.close(); 15930 } catch (IOException e) { 15931 } 15932 } 15933 } 15934 } 15935 15936 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15937 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15938 userId, true, true, callName, null); 15939 ProcessRecord proc = null; 15940 try { 15941 int pid = Integer.parseInt(process); 15942 synchronized (mPidsSelfLocked) { 15943 proc = mPidsSelfLocked.get(pid); 15944 } 15945 } catch (NumberFormatException e) { 15946 } 15947 15948 if (proc == null) { 15949 ArrayMap<String, SparseArray<ProcessRecord>> all 15950 = mProcessNames.getMap(); 15951 SparseArray<ProcessRecord> procs = all.get(process); 15952 if (procs != null && procs.size() > 0) { 15953 proc = procs.valueAt(0); 15954 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15955 for (int i=1; i<procs.size(); i++) { 15956 ProcessRecord thisProc = procs.valueAt(i); 15957 if (thisProc.userId == userId) { 15958 proc = thisProc; 15959 break; 15960 } 15961 } 15962 } 15963 } 15964 } 15965 15966 return proc; 15967 } 15968 15969 public boolean dumpHeap(String process, int userId, boolean managed, 15970 String path, ParcelFileDescriptor fd) throws RemoteException { 15971 15972 try { 15973 synchronized (this) { 15974 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15975 // its own permission (same as profileControl). 15976 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15977 != PackageManager.PERMISSION_GRANTED) { 15978 throw new SecurityException("Requires permission " 15979 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15980 } 15981 15982 if (fd == null) { 15983 throw new IllegalArgumentException("null fd"); 15984 } 15985 15986 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15987 if (proc == null || proc.thread == null) { 15988 throw new IllegalArgumentException("Unknown process: " + process); 15989 } 15990 15991 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15992 if (!isDebuggable) { 15993 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15994 throw new SecurityException("Process not debuggable: " + proc); 15995 } 15996 } 15997 15998 proc.thread.dumpHeap(managed, path, fd); 15999 fd = null; 16000 return true; 16001 } 16002 } catch (RemoteException e) { 16003 throw new IllegalStateException("Process disappeared"); 16004 } finally { 16005 if (fd != null) { 16006 try { 16007 fd.close(); 16008 } catch (IOException e) { 16009 } 16010 } 16011 } 16012 } 16013 16014 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16015 public void monitor() { 16016 synchronized (this) { } 16017 } 16018 16019 void onCoreSettingsChange(Bundle settings) { 16020 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16021 ProcessRecord processRecord = mLruProcesses.get(i); 16022 try { 16023 if (processRecord.thread != null) { 16024 processRecord.thread.setCoreSettings(settings); 16025 } 16026 } catch (RemoteException re) { 16027 /* ignore */ 16028 } 16029 } 16030 } 16031 16032 // Multi-user methods 16033 16034 @Override 16035 public boolean switchUser(final int userId) { 16036 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16037 != PackageManager.PERMISSION_GRANTED) { 16038 String msg = "Permission Denial: switchUser() from pid=" 16039 + Binder.getCallingPid() 16040 + ", uid=" + Binder.getCallingUid() 16041 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16042 Slog.w(TAG, msg); 16043 throw new SecurityException(msg); 16044 } 16045 16046 final long ident = Binder.clearCallingIdentity(); 16047 try { 16048 synchronized (this) { 16049 final int oldUserId = mCurrentUserId; 16050 if (oldUserId == userId) { 16051 return true; 16052 } 16053 16054 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16055 if (userInfo == null) { 16056 Slog.w(TAG, "No user info for user #" + userId); 16057 return false; 16058 } 16059 16060 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16061 R.anim.screen_user_enter); 16062 16063 boolean needStart = false; 16064 16065 // If the user we are switching to is not currently started, then 16066 // we need to start it now. 16067 if (mStartedUsers.get(userId) == null) { 16068 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16069 updateStartedUserArrayLocked(); 16070 needStart = true; 16071 } 16072 16073 mCurrentUserId = userId; 16074 final Integer userIdInt = Integer.valueOf(userId); 16075 mUserLru.remove(userIdInt); 16076 mUserLru.add(userIdInt); 16077 16078 mWindowManager.setCurrentUser(userId); 16079 16080 // Once the internal notion of the active user has switched, we lock the device 16081 // with the option to show the user switcher on the keyguard. 16082 mWindowManager.lockNow(null); 16083 16084 final UserStartedState uss = mStartedUsers.get(userId); 16085 16086 // Make sure user is in the started state. If it is currently 16087 // stopping, we need to knock that off. 16088 if (uss.mState == UserStartedState.STATE_STOPPING) { 16089 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16090 // so we can just fairly silently bring the user back from 16091 // the almost-dead. 16092 uss.mState = UserStartedState.STATE_RUNNING; 16093 updateStartedUserArrayLocked(); 16094 needStart = true; 16095 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16096 // This means ACTION_SHUTDOWN has been sent, so we will 16097 // need to treat this as a new boot of the user. 16098 uss.mState = UserStartedState.STATE_BOOTING; 16099 updateStartedUserArrayLocked(); 16100 needStart = true; 16101 } 16102 16103 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16104 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16105 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16106 oldUserId, userId, uss)); 16107 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16108 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16109 if (needStart) { 16110 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16111 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16112 | Intent.FLAG_RECEIVER_FOREGROUND); 16113 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16114 broadcastIntentLocked(null, null, intent, 16115 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16116 false, false, MY_PID, Process.SYSTEM_UID, userId); 16117 } 16118 16119 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16120 if (userId != 0) { 16121 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16122 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16123 broadcastIntentLocked(null, null, intent, null, 16124 new IIntentReceiver.Stub() { 16125 public void performReceive(Intent intent, int resultCode, 16126 String data, Bundle extras, boolean ordered, 16127 boolean sticky, int sendingUser) { 16128 userInitialized(uss, userId); 16129 } 16130 }, 0, null, null, null, AppOpsManager.OP_NONE, 16131 true, false, MY_PID, Process.SYSTEM_UID, 16132 userId); 16133 uss.initializing = true; 16134 } else { 16135 getUserManagerLocked().makeInitialized(userInfo.id); 16136 } 16137 } 16138 16139 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16140 if (homeInFront) { 16141 startHomeActivityLocked(userId); 16142 } else { 16143 mStackSupervisor.resumeTopActivitiesLocked(); 16144 } 16145 16146 EventLogTags.writeAmSwitchUser(userId); 16147 getUserManagerLocked().userForeground(userId); 16148 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16149 if (needStart) { 16150 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16151 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16152 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16153 broadcastIntentLocked(null, null, intent, 16154 null, new IIntentReceiver.Stub() { 16155 @Override 16156 public void performReceive(Intent intent, int resultCode, String data, 16157 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16158 throws RemoteException { 16159 } 16160 }, 0, null, null, 16161 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16162 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16163 } 16164 } 16165 } finally { 16166 Binder.restoreCallingIdentity(ident); 16167 } 16168 16169 return true; 16170 } 16171 16172 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16173 long ident = Binder.clearCallingIdentity(); 16174 try { 16175 Intent intent; 16176 if (oldUserId >= 0) { 16177 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16178 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16179 | Intent.FLAG_RECEIVER_FOREGROUND); 16180 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16181 broadcastIntentLocked(null, null, intent, 16182 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16183 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16184 } 16185 if (newUserId >= 0) { 16186 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16187 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16188 | Intent.FLAG_RECEIVER_FOREGROUND); 16189 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16190 broadcastIntentLocked(null, null, intent, 16191 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16192 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16193 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16194 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16195 | Intent.FLAG_RECEIVER_FOREGROUND); 16196 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16197 broadcastIntentLocked(null, null, intent, 16198 null, null, 0, null, null, 16199 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16200 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16201 } 16202 } finally { 16203 Binder.restoreCallingIdentity(ident); 16204 } 16205 } 16206 16207 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16208 final int newUserId) { 16209 final int N = mUserSwitchObservers.beginBroadcast(); 16210 if (N > 0) { 16211 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16212 int mCount = 0; 16213 @Override 16214 public void sendResult(Bundle data) throws RemoteException { 16215 synchronized (ActivityManagerService.this) { 16216 if (mCurUserSwitchCallback == this) { 16217 mCount++; 16218 if (mCount == N) { 16219 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16220 } 16221 } 16222 } 16223 } 16224 }; 16225 synchronized (this) { 16226 uss.switching = true; 16227 mCurUserSwitchCallback = callback; 16228 } 16229 for (int i=0; i<N; i++) { 16230 try { 16231 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16232 newUserId, callback); 16233 } catch (RemoteException e) { 16234 } 16235 } 16236 } else { 16237 synchronized (this) { 16238 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16239 } 16240 } 16241 mUserSwitchObservers.finishBroadcast(); 16242 } 16243 16244 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16245 synchronized (this) { 16246 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16247 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16248 } 16249 } 16250 16251 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16252 mCurUserSwitchCallback = null; 16253 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16254 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16255 oldUserId, newUserId, uss)); 16256 } 16257 16258 void userInitialized(UserStartedState uss, int newUserId) { 16259 completeSwitchAndInitalize(uss, newUserId, true, false); 16260 } 16261 16262 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16263 completeSwitchAndInitalize(uss, newUserId, false, true); 16264 } 16265 16266 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16267 boolean clearInitializing, boolean clearSwitching) { 16268 boolean unfrozen = false; 16269 synchronized (this) { 16270 if (clearInitializing) { 16271 uss.initializing = false; 16272 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16273 } 16274 if (clearSwitching) { 16275 uss.switching = false; 16276 } 16277 if (!uss.switching && !uss.initializing) { 16278 mWindowManager.stopFreezingScreen(); 16279 unfrozen = true; 16280 } 16281 } 16282 if (unfrozen) { 16283 final int N = mUserSwitchObservers.beginBroadcast(); 16284 for (int i=0; i<N; i++) { 16285 try { 16286 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16287 } catch (RemoteException e) { 16288 } 16289 } 16290 mUserSwitchObservers.finishBroadcast(); 16291 } 16292 } 16293 16294 void finishUserSwitch(UserStartedState uss) { 16295 synchronized (this) { 16296 if (uss.mState == UserStartedState.STATE_BOOTING 16297 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16298 uss.mState = UserStartedState.STATE_RUNNING; 16299 final int userId = uss.mHandle.getIdentifier(); 16300 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16301 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16302 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16303 broadcastIntentLocked(null, null, intent, 16304 null, null, 0, null, null, 16305 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16306 true, false, MY_PID, Process.SYSTEM_UID, userId); 16307 } 16308 int num = mUserLru.size(); 16309 int i = 0; 16310 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16311 Integer oldUserId = mUserLru.get(i); 16312 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16313 if (oldUss == null) { 16314 // Shouldn't happen, but be sane if it does. 16315 mUserLru.remove(i); 16316 num--; 16317 continue; 16318 } 16319 if (oldUss.mState == UserStartedState.STATE_STOPPING 16320 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16321 // This user is already stopping, doesn't count. 16322 num--; 16323 i++; 16324 continue; 16325 } 16326 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16327 // Owner and current can't be stopped, but count as running. 16328 i++; 16329 continue; 16330 } 16331 // This is a user to be stopped. 16332 stopUserLocked(oldUserId, null); 16333 num--; 16334 i++; 16335 } 16336 } 16337 } 16338 16339 @Override 16340 public int stopUser(final int userId, final IStopUserCallback callback) { 16341 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16342 != PackageManager.PERMISSION_GRANTED) { 16343 String msg = "Permission Denial: switchUser() from pid=" 16344 + Binder.getCallingPid() 16345 + ", uid=" + Binder.getCallingUid() 16346 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16347 Slog.w(TAG, msg); 16348 throw new SecurityException(msg); 16349 } 16350 if (userId <= 0) { 16351 throw new IllegalArgumentException("Can't stop primary user " + userId); 16352 } 16353 synchronized (this) { 16354 return stopUserLocked(userId, callback); 16355 } 16356 } 16357 16358 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16359 if (mCurrentUserId == userId) { 16360 return ActivityManager.USER_OP_IS_CURRENT; 16361 } 16362 16363 final UserStartedState uss = mStartedUsers.get(userId); 16364 if (uss == null) { 16365 // User is not started, nothing to do... but we do need to 16366 // callback if requested. 16367 if (callback != null) { 16368 mHandler.post(new Runnable() { 16369 @Override 16370 public void run() { 16371 try { 16372 callback.userStopped(userId); 16373 } catch (RemoteException e) { 16374 } 16375 } 16376 }); 16377 } 16378 return ActivityManager.USER_OP_SUCCESS; 16379 } 16380 16381 if (callback != null) { 16382 uss.mStopCallbacks.add(callback); 16383 } 16384 16385 if (uss.mState != UserStartedState.STATE_STOPPING 16386 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16387 uss.mState = UserStartedState.STATE_STOPPING; 16388 updateStartedUserArrayLocked(); 16389 16390 long ident = Binder.clearCallingIdentity(); 16391 try { 16392 // We are going to broadcast ACTION_USER_STOPPING and then 16393 // once that is done send a final ACTION_SHUTDOWN and then 16394 // stop the user. 16395 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16396 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16397 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16398 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16399 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16400 // This is the result receiver for the final shutdown broadcast. 16401 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16402 @Override 16403 public void performReceive(Intent intent, int resultCode, String data, 16404 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16405 finishUserStop(uss); 16406 } 16407 }; 16408 // This is the result receiver for the initial stopping broadcast. 16409 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16410 @Override 16411 public void performReceive(Intent intent, int resultCode, String data, 16412 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16413 // On to the next. 16414 synchronized (ActivityManagerService.this) { 16415 if (uss.mState != UserStartedState.STATE_STOPPING) { 16416 // Whoops, we are being started back up. Abort, abort! 16417 return; 16418 } 16419 uss.mState = UserStartedState.STATE_SHUTDOWN; 16420 } 16421 broadcastIntentLocked(null, null, shutdownIntent, 16422 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16423 true, false, MY_PID, Process.SYSTEM_UID, userId); 16424 } 16425 }; 16426 // Kick things off. 16427 broadcastIntentLocked(null, null, stoppingIntent, 16428 null, stoppingReceiver, 0, null, null, 16429 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16430 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16431 } finally { 16432 Binder.restoreCallingIdentity(ident); 16433 } 16434 } 16435 16436 return ActivityManager.USER_OP_SUCCESS; 16437 } 16438 16439 void finishUserStop(UserStartedState uss) { 16440 final int userId = uss.mHandle.getIdentifier(); 16441 boolean stopped; 16442 ArrayList<IStopUserCallback> callbacks; 16443 synchronized (this) { 16444 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16445 if (mStartedUsers.get(userId) != uss) { 16446 stopped = false; 16447 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16448 stopped = false; 16449 } else { 16450 stopped = true; 16451 // User can no longer run. 16452 mStartedUsers.remove(userId); 16453 mUserLru.remove(Integer.valueOf(userId)); 16454 updateStartedUserArrayLocked(); 16455 16456 // Clean up all state and processes associated with the user. 16457 // Kill all the processes for the user. 16458 forceStopUserLocked(userId, "finish user"); 16459 } 16460 } 16461 16462 for (int i=0; i<callbacks.size(); i++) { 16463 try { 16464 if (stopped) callbacks.get(i).userStopped(userId); 16465 else callbacks.get(i).userStopAborted(userId); 16466 } catch (RemoteException e) { 16467 } 16468 } 16469 16470 mStackSupervisor.removeUserLocked(userId); 16471 } 16472 16473 @Override 16474 public UserInfo getCurrentUser() { 16475 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16476 != PackageManager.PERMISSION_GRANTED) && ( 16477 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16478 != PackageManager.PERMISSION_GRANTED)) { 16479 String msg = "Permission Denial: getCurrentUser() from pid=" 16480 + Binder.getCallingPid() 16481 + ", uid=" + Binder.getCallingUid() 16482 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16483 Slog.w(TAG, msg); 16484 throw new SecurityException(msg); 16485 } 16486 synchronized (this) { 16487 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16488 } 16489 } 16490 16491 int getCurrentUserIdLocked() { 16492 return mCurrentUserId; 16493 } 16494 16495 @Override 16496 public boolean isUserRunning(int userId, boolean orStopped) { 16497 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16498 != PackageManager.PERMISSION_GRANTED) { 16499 String msg = "Permission Denial: isUserRunning() from pid=" 16500 + Binder.getCallingPid() 16501 + ", uid=" + Binder.getCallingUid() 16502 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16503 Slog.w(TAG, msg); 16504 throw new SecurityException(msg); 16505 } 16506 synchronized (this) { 16507 return isUserRunningLocked(userId, orStopped); 16508 } 16509 } 16510 16511 boolean isUserRunningLocked(int userId, boolean orStopped) { 16512 UserStartedState state = mStartedUsers.get(userId); 16513 if (state == null) { 16514 return false; 16515 } 16516 if (orStopped) { 16517 return true; 16518 } 16519 return state.mState != UserStartedState.STATE_STOPPING 16520 && state.mState != UserStartedState.STATE_SHUTDOWN; 16521 } 16522 16523 @Override 16524 public int[] getRunningUserIds() { 16525 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16526 != PackageManager.PERMISSION_GRANTED) { 16527 String msg = "Permission Denial: isUserRunning() from pid=" 16528 + Binder.getCallingPid() 16529 + ", uid=" + Binder.getCallingUid() 16530 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16531 Slog.w(TAG, msg); 16532 throw new SecurityException(msg); 16533 } 16534 synchronized (this) { 16535 return mStartedUserArray; 16536 } 16537 } 16538 16539 private void updateStartedUserArrayLocked() { 16540 int num = 0; 16541 for (int i=0; i<mStartedUsers.size(); i++) { 16542 UserStartedState uss = mStartedUsers.valueAt(i); 16543 // This list does not include stopping users. 16544 if (uss.mState != UserStartedState.STATE_STOPPING 16545 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16546 num++; 16547 } 16548 } 16549 mStartedUserArray = new int[num]; 16550 num = 0; 16551 for (int i=0; i<mStartedUsers.size(); i++) { 16552 UserStartedState uss = mStartedUsers.valueAt(i); 16553 if (uss.mState != UserStartedState.STATE_STOPPING 16554 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16555 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16556 num++; 16557 } 16558 } 16559 } 16560 16561 @Override 16562 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16563 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16564 != PackageManager.PERMISSION_GRANTED) { 16565 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16566 + Binder.getCallingPid() 16567 + ", uid=" + Binder.getCallingUid() 16568 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16569 Slog.w(TAG, msg); 16570 throw new SecurityException(msg); 16571 } 16572 16573 mUserSwitchObservers.register(observer); 16574 } 16575 16576 @Override 16577 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16578 mUserSwitchObservers.unregister(observer); 16579 } 16580 16581 private boolean userExists(int userId) { 16582 if (userId == 0) { 16583 return true; 16584 } 16585 UserManagerService ums = getUserManagerLocked(); 16586 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16587 } 16588 16589 int[] getUsersLocked() { 16590 UserManagerService ums = getUserManagerLocked(); 16591 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16592 } 16593 16594 UserManagerService getUserManagerLocked() { 16595 if (mUserManager == null) { 16596 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16597 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16598 } 16599 return mUserManager; 16600 } 16601 16602 private int applyUserId(int uid, int userId) { 16603 return UserHandle.getUid(userId, uid); 16604 } 16605 16606 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16607 if (info == null) return null; 16608 ApplicationInfo newInfo = new ApplicationInfo(info); 16609 newInfo.uid = applyUserId(info.uid, userId); 16610 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16611 + info.packageName; 16612 return newInfo; 16613 } 16614 16615 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16616 if (aInfo == null 16617 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16618 return aInfo; 16619 } 16620 16621 ActivityInfo info = new ActivityInfo(aInfo); 16622 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16623 return info; 16624 } 16625 } 16626