ActivityManagerService.java revision 2f5c306b82eda6d213dae1d6dd53389a551201e3
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.CHANGE_CONFIGURATION; 20import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; 21import static android.Manifest.permission.INTERACT_ACROSS_USERS; 22import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 23import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 24import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; 25import static android.Manifest.permission.READ_FRAME_BUFFER; 26import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 27import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; 28import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW; 29import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 30import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 31import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID; 32import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; 33import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 34import static android.app.ActivityManager.StackId.PINNED_STACK_ID; 35import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS; 36import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; 37import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY; 38import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; 39import static android.content.pm.PackageManager.GET_PROVIDERS; 40import static android.content.pm.PackageManager.MATCH_ANY_USER; 41import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 42import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 43import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 44import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 45import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 46import static android.content.pm.PackageManager.PERMISSION_GRANTED; 47import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION; 48import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; 49import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; 50import static android.os.Build.VERSION_CODES.N; 51import static android.os.Process.BLUETOOTH_UID; 52import static android.os.Process.FIRST_APPLICATION_UID; 53import static android.os.Process.FIRST_ISOLATED_UID; 54import static android.os.Process.LAST_ISOLATED_UID; 55import static android.os.Process.NFC_UID; 56import static android.os.Process.PHONE_UID; 57import static android.os.Process.PROC_CHAR; 58import static android.os.Process.PROC_OUT_LONG; 59import static android.os.Process.PROC_PARENS; 60import static android.os.Process.PROC_SPACE_TERM; 61import static android.os.Process.ProcessStartResult; 62import static android.os.Process.ROOT_UID; 63import static android.os.Process.SCHED_FIFO; 64import static android.os.Process.SCHED_OTHER; 65import static android.os.Process.SCHED_RESET_ON_FORK; 66import static android.os.Process.SHELL_UID; 67import static android.os.Process.SIGNAL_QUIT; 68import static android.os.Process.SIGNAL_USR1; 69import static android.os.Process.SYSTEM_UID; 70import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE; 71import static android.os.Process.THREAD_GROUP_DEFAULT; 72import static android.os.Process.THREAD_GROUP_TOP_APP; 73import static android.os.Process.THREAD_PRIORITY_BACKGROUND; 74import static android.os.Process.THREAD_PRIORITY_FOREGROUND; 75import static android.os.Process.getFreeMemory; 76import static android.os.Process.getTotalMemory; 77import static android.os.Process.isThreadInProcess; 78import static android.os.Process.killProcess; 79import static android.os.Process.killProcessQuiet; 80import static android.os.Process.myPid; 81import static android.os.Process.myUid; 82import static android.os.Process.readProcFile; 83import static android.os.Process.removeAllProcessGroups; 84import static android.os.Process.sendSignal; 85import static android.os.Process.setProcessGroup; 86import static android.os.Process.setThreadPriority; 87import static android.os.Process.setThreadScheduler; 88import static android.os.Process.startWebView; 89import static android.os.Process.zygoteProcess; 90import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES; 91import static android.provider.Settings.Global.DEBUG_APP; 92import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; 93import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; 94import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL; 95import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS; 96import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER; 97import static android.provider.Settings.System.FONT_SCALE; 98import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION; 99import static android.text.format.DateUtils.DAY_IN_MILLIS; 100import static android.view.Display.DEFAULT_DISPLAY; 101import static android.view.Display.INVALID_DISPLAY; 102import static com.android.internal.util.XmlUtils.readBooleanAttribute; 103import static com.android.internal.util.XmlUtils.readIntAttribute; 104import static com.android.internal.util.XmlUtils.readLongAttribute; 105import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 106import static com.android.internal.util.XmlUtils.writeIntAttribute; 107import static com.android.internal.util.XmlUtils.writeLongAttribute; 108import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; 109import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR; 110import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK; 111import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP; 112import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST; 113import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND; 114import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT; 115import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP; 116import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; 117import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS; 118import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE; 119import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; 120import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU; 121import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; 122import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK; 123import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; 124import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON; 125import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; 126import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER; 127import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES; 128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS; 129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER; 130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS; 131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS; 132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE; 133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; 134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; 135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; 136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS; 137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION; 138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS; 139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY; 140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS; 141import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP; 142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST; 143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP; 144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION; 145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS; 146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE; 147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN; 148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK; 149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU; 150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU; 151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK; 152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ; 153import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER; 154import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES; 155import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS; 156import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER; 157import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS; 158import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS; 159import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE; 160import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; 161import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; 162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS; 163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION; 164import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY; 165import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND; 166import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 167import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 168import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED; 169import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME; 170import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY; 171import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS; 172import static com.android.server.am.ActivityStackSupervisor.ON_TOP; 173import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; 174import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; 175import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 176import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; 177import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; 178import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; 179import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT; 180import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE; 181import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN; 182import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH; 183import static com.android.server.wm.AppTransition.TRANSIT_NONE; 184import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE; 185import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN; 186import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT; 187import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 188import static org.xmlpull.v1.XmlPullParser.START_TAG; 189 190import android.Manifest; 191import android.Manifest.permission; 192import android.annotation.NonNull; 193import android.annotation.Nullable; 194import android.annotation.UserIdInt; 195import android.app.Activity; 196import android.app.ActivityManager; 197import android.app.ActivityManager.RunningTaskInfo; 198import android.app.ActivityManager.StackId; 199import android.app.ActivityManager.StackInfo; 200import android.app.ActivityManager.TaskSnapshot; 201import android.app.ActivityManager.TaskThumbnailInfo; 202import android.app.ActivityManagerInternal; 203import android.app.ActivityManagerInternal.SleepToken; 204import android.app.ActivityOptions; 205import android.app.ActivityThread; 206import android.app.AlertDialog; 207import android.app.AppGlobals; 208import android.app.AppOpsManager; 209import android.app.ApplicationErrorReport; 210import android.app.ApplicationThreadConstants; 211import android.app.BroadcastOptions; 212import android.app.ContentProviderHolder; 213import android.app.Dialog; 214import android.app.IActivityController; 215import android.app.IActivityManager; 216import android.app.IAppTask; 217import android.app.IApplicationThread; 218import android.app.IInstrumentationWatcher; 219import android.app.INotificationManager; 220import android.app.IProcessObserver; 221import android.app.IServiceConnection; 222import android.app.IStopUserCallback; 223import android.app.ITaskStackListener; 224import android.app.IUiAutomationConnection; 225import android.app.IUidObserver; 226import android.app.IUserSwitchObserver; 227import android.app.Instrumentation; 228import android.app.Notification; 229import android.app.NotificationManager; 230import android.app.PendingIntent; 231import android.app.PictureInPictureParams; 232import android.app.ProfilerInfo; 233import android.app.RemoteAction; 234import android.app.WaitResult; 235import android.app.admin.DevicePolicyManager; 236import android.app.assist.AssistContent; 237import android.app.assist.AssistStructure; 238import android.app.backup.IBackupManager; 239import android.app.usage.UsageEvents; 240import android.app.usage.UsageStatsManagerInternal; 241import android.appwidget.AppWidgetManager; 242import android.content.ActivityNotFoundException; 243import android.content.BroadcastReceiver; 244import android.content.ClipData; 245import android.content.ComponentCallbacks2; 246import android.content.ComponentName; 247import android.content.ContentProvider; 248import android.content.ContentResolver; 249import android.content.Context; 250import android.content.DialogInterface; 251import android.content.IContentProvider; 252import android.content.IIntentReceiver; 253import android.content.IIntentSender; 254import android.content.Intent; 255import android.content.IntentFilter; 256import android.content.pm.ActivityInfo; 257import android.content.pm.ApplicationInfo; 258import android.content.pm.ConfigurationInfo; 259import android.content.pm.IPackageDataObserver; 260import android.content.pm.IPackageManager; 261import android.content.pm.InstrumentationInfo; 262import android.content.pm.PackageInfo; 263import android.content.pm.PackageManager; 264import android.content.pm.PackageManager.NameNotFoundException; 265import android.content.pm.PackageManagerInternal; 266import android.content.pm.ParceledListSlice; 267import android.content.pm.PathPermission; 268import android.content.pm.PermissionInfo; 269import android.content.pm.ProviderInfo; 270import android.content.pm.ResolveInfo; 271import android.content.pm.SELinuxUtil; 272import android.content.pm.ServiceInfo; 273import android.content.pm.UserInfo; 274import android.content.res.CompatibilityInfo; 275import android.content.res.Configuration; 276import android.content.res.Resources; 277import android.database.ContentObserver; 278import android.graphics.Bitmap; 279import android.graphics.Point; 280import android.graphics.Rect; 281import android.location.LocationManager; 282import android.media.audiofx.AudioEffect; 283import android.metrics.LogMaker; 284import android.net.Proxy; 285import android.net.ProxyInfo; 286import android.net.Uri; 287import android.os.BatteryStats; 288import android.os.Binder; 289import android.os.Build; 290import android.os.Bundle; 291import android.os.Debug; 292import android.os.DropBoxManager; 293import android.os.Environment; 294import android.os.FactoryTest; 295import android.os.FileObserver; 296import android.os.FileUtils; 297import android.os.Handler; 298import android.os.IBinder; 299import android.os.IDeviceIdentifiersPolicyService; 300import android.os.IPermissionController; 301import android.os.IProcessInfoService; 302import android.os.IProgressListener; 303import android.os.LocaleList; 304import android.os.Looper; 305import android.os.Message; 306import android.os.Parcel; 307import android.os.ParcelFileDescriptor; 308import android.os.PersistableBundle; 309import android.os.PowerManager; 310import android.os.PowerManagerInternal; 311import android.os.Process; 312import android.os.RemoteCallbackList; 313import android.os.RemoteException; 314import android.os.ResultReceiver; 315import android.os.ServiceManager; 316import android.os.ShellCallback; 317import android.os.StrictMode; 318import android.os.SystemClock; 319import android.os.SystemProperties; 320import android.os.Trace; 321import android.os.TransactionTooLargeException; 322import android.os.UpdateLock; 323import android.os.UserHandle; 324import android.os.UserManager; 325import android.os.WorkSource; 326import android.os.storage.IStorageManager; 327import android.os.storage.StorageManager; 328import android.os.storage.StorageManagerInternal; 329import android.provider.Downloads; 330import android.provider.Settings; 331import android.service.voice.IVoiceInteractionSession; 332import android.service.voice.VoiceInteractionManagerInternal; 333import android.service.voice.VoiceInteractionSession; 334import android.telecom.TelecomManager; 335import android.text.TextUtils; 336import android.text.format.DateUtils; 337import android.text.format.Time; 338import android.text.style.SuggestionSpan; 339import android.util.ArrayMap; 340import android.util.ArraySet; 341import android.util.AtomicFile; 342import android.util.TimingsTraceLog; 343import android.util.DebugUtils; 344import android.util.DisplayMetrics; 345import android.util.EventLog; 346import android.util.Log; 347import android.util.Pair; 348import android.util.PrintWriterPrinter; 349import android.util.Slog; 350import android.util.SparseArray; 351import android.util.SparseIntArray; 352import android.util.TimeUtils; 353import android.util.Xml; 354import android.view.Gravity; 355import android.view.LayoutInflater; 356import android.view.View; 357import android.view.WindowManager; 358 359import com.android.server.job.JobSchedulerInternal; 360import com.google.android.collect.Lists; 361import com.google.android.collect.Maps; 362 363import com.android.internal.R; 364import com.android.internal.annotations.GuardedBy; 365import com.android.internal.annotations.VisibleForTesting; 366import com.android.internal.app.AssistUtils; 367import com.android.internal.app.DumpHeapActivity; 368import com.android.internal.app.IAppOpsCallback; 369import com.android.internal.app.IAppOpsService; 370import com.android.internal.app.IVoiceInteractor; 371import com.android.internal.app.ProcessMap; 372import com.android.internal.app.SystemUserHomeActivity; 373import com.android.internal.app.procstats.ProcessStats; 374import com.android.internal.logging.MetricsLogger; 375import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 376import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 377import com.android.internal.notification.SystemNotificationChannels; 378import com.android.internal.os.BackgroundThread; 379import com.android.internal.os.BatteryStatsImpl; 380import com.android.internal.os.IResultReceiver; 381import com.android.internal.os.ProcessCpuTracker; 382import com.android.internal.os.TransferPipe; 383import com.android.internal.os.Zygote; 384import com.android.internal.policy.IKeyguardDismissCallback; 385import com.android.internal.telephony.TelephonyIntents; 386import com.android.internal.util.ArrayUtils; 387import com.android.internal.util.DumpUtils; 388import com.android.internal.util.FastPrintWriter; 389import com.android.internal.util.FastXmlSerializer; 390import com.android.internal.util.MemInfoReader; 391import com.android.internal.util.Preconditions; 392import com.android.server.AppOpsService; 393import com.android.server.AttributeCache; 394import com.android.server.DeviceIdleController; 395import com.android.server.IntentResolver; 396import com.android.server.LocalServices; 397import com.android.server.LockGuard; 398import com.android.server.NetworkManagementInternal; 399import com.android.server.RescueParty; 400import com.android.server.ServiceThread; 401import com.android.server.SystemConfig; 402import com.android.server.SystemService; 403import com.android.server.SystemServiceManager; 404import com.android.server.ThreadPriorityBooster; 405import com.android.server.Watchdog; 406import com.android.server.am.ActivityStack.ActivityState; 407import com.android.server.firewall.IntentFirewall; 408import com.android.server.pm.Installer; 409import com.android.server.pm.Installer.InstallerException; 410import com.android.server.statusbar.StatusBarManagerInternal; 411import com.android.server.vr.VrManagerInternal; 412import com.android.server.wm.PinnedStackWindowController; 413import com.android.server.wm.WindowManagerService; 414 415import java.text.SimpleDateFormat; 416import org.xmlpull.v1.XmlPullParser; 417import org.xmlpull.v1.XmlPullParserException; 418import org.xmlpull.v1.XmlSerializer; 419 420import java.io.File; 421import java.io.FileDescriptor; 422import java.io.FileInputStream; 423import java.io.FileNotFoundException; 424import java.io.FileOutputStream; 425import java.io.IOException; 426import java.io.InputStreamReader; 427import java.io.PrintWriter; 428import java.io.StringWriter; 429import java.io.UnsupportedEncodingException; 430import java.lang.ref.WeakReference; 431import java.nio.charset.StandardCharsets; 432import java.text.DateFormat; 433import java.util.ArrayList; 434import java.util.Arrays; 435import java.util.Collections; 436import java.util.Comparator; 437import java.util.Date; 438import java.util.HashMap; 439import java.util.HashSet; 440import java.util.Iterator; 441import java.util.List; 442import java.util.Locale; 443import java.util.Map; 444import java.util.Objects; 445import java.util.Set; 446import java.util.concurrent.CountDownLatch; 447import java.util.concurrent.atomic.AtomicBoolean; 448import java.util.concurrent.atomic.AtomicLong; 449 450import dalvik.system.VMRuntime; 451import libcore.io.IoUtils; 452import libcore.util.EmptyArray; 453 454public class ActivityManagerService extends IActivityManager.Stub 455 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 456 457 /** 458 * Priority we boost main thread and RT of top app to. 459 */ 460 public static final int TOP_APP_PRIORITY_BOOST = -10; 461 462 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM; 463 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP; 464 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST; 465 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP; 466 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; 467 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; 468 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE; 469 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; 470 private static final String TAG_LRU = TAG + POSTFIX_LRU; 471 private static final String TAG_MU = TAG + POSTFIX_MU; 472 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK; 473 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ; 474 private static final String TAG_POWER = TAG + POSTFIX_POWER; 475 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS; 476 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES; 477 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER; 478 private static final String TAG_PSS = TAG + POSTFIX_PSS; 479 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; 480 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE; 481 private static final String TAG_STACK = TAG + POSTFIX_STACK; 482 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; 483 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS; 484 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION; 485 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; 486 487 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared 488 // here so that while the job scheduler can depend on AMS, the other way around 489 // need not be the case. 490 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE"; 491 492 /** Control over CPU and battery monitoring */ 493 // write battery stats every 30 minutes. 494 static final long BATTERY_STATS_TIME = 30 * 60 * 1000; 495 static final boolean MONITOR_CPU_USAGE = true; 496 // don't sample cpu less than every 5 seconds. 497 static final long MONITOR_CPU_MIN_TIME = 5 * 1000; 498 // wait possibly forever for next cpu sample. 499 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; 500 static final boolean MONITOR_THREAD_CPU_USAGE = false; 501 502 // The flags that are set for all calls we make to the package manager. 503 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 504 505 static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 506 507 // Amount of time after a call to stopAppSwitches() during which we will 508 // prevent further untrusted switches from happening. 509 static final long APP_SWITCH_DELAY_TIME = 5*1000; 510 511 // How long we wait for a launched process to attach to the activity manager 512 // before we decide it's never going to come up for real. 513 static final int PROC_START_TIMEOUT = 10*1000; 514 // How long we wait for an attached process to publish its content providers 515 // before we decide it must be hung. 516 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000; 517 518 // How long we wait for a launched process to attach to the activity manager 519 // before we decide it's never going to come up for real, when the process was 520 // started with a wrapper for instrumentation (such as Valgrind) because it 521 // could take much longer than usual. 522 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 523 524 // How long we allow a receiver to run before giving up on it. 525 static final int BROADCAST_FG_TIMEOUT = 10*1000; 526 static final int BROADCAST_BG_TIMEOUT = 60*1000; 527 528 // How long we wait until we timeout on key dispatching. 529 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 530 531 // How long we wait until we timeout on key dispatching during instrumentation. 532 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 533 534 // How long to wait in getAssistContextExtras for the activity and foreground services 535 // to respond with the result. 536 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 537 538 // How long top wait when going through the modern assist (which doesn't need to block 539 // on getting this result before starting to launch its UI). 540 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000; 541 542 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result. 543 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000; 544 545 // Maximum number of persisted Uri grants a package is allowed 546 static final int MAX_PERSISTED_URI_GRANTS = 128; 547 548 static final int MY_PID = myPid(); 549 550 static final String[] EMPTY_STRING_ARRAY = new String[0]; 551 552 // How many bytes to write into the dropbox log before truncating 553 static final int DROPBOX_MAX_SIZE = 192 * 1024; 554 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count 555 // as one line, but close enough for now. 556 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100; 557 558 // Access modes for handleIncomingUser. 559 static final int ALLOW_NON_FULL = 0; 560 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 561 static final int ALLOW_FULL_ONLY = 2; 562 563 // Necessary ApplicationInfo flags to mark an app as persistent 564 private static final int PERSISTENT_MASK = 565 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT; 566 567 // Intent sent when remote bugreport collection has been completed 568 private static final String INTENT_REMOTE_BUGREPORT_FINISHED = 569 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED"; 570 571 // Used to indicate that an app transition should be animated. 572 static final boolean ANIMATE = true; 573 574 // Determines whether to take full screen screenshots 575 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true; 576 577 /** 578 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}. 579 */ 580 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec 581 582 /** 583 * State indicating that there is no need for any blocking for network. 584 */ 585 @VisibleForTesting 586 static final int NETWORK_STATE_NO_CHANGE = 0; 587 588 /** 589 * State indicating that the main thread needs to be informed about the network wait. 590 */ 591 @VisibleForTesting 592 static final int NETWORK_STATE_BLOCK = 1; 593 594 /** 595 * State indicating that any threads waiting for network state to get updated can be unblocked. 596 */ 597 @VisibleForTesting 598 static final int NETWORK_STATE_UNBLOCK = 2; 599 600 // Max character limit for a notification title. If the notification title is larger than this 601 // the notification will not be legible to the user. 602 private static final int MAX_BUGREPORT_TITLE_SIZE = 50; 603 604 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds; 605 606 /** All system services */ 607 SystemServiceManager mSystemServiceManager; 608 AssistUtils mAssistUtils; 609 610 private Installer mInstaller; 611 612 /** Run all ActivityStacks through this */ 613 final ActivityStackSupervisor mStackSupervisor; 614 private final KeyguardController mKeyguardController; 615 616 final ActivityStarter mActivityStarter; 617 618 final TaskChangeNotificationController mTaskChangeNotificationController; 619 620 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter(); 621 622 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>(); 623 624 public final IntentFirewall mIntentFirewall; 625 626 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 627 // default action automatically. Important for devices without direct input 628 // devices. 629 private boolean mShowDialogs = true; 630 631 private final VrController mVrController; 632 633 // VR Vr2d Display Id. 634 int mVr2dDisplayId = INVALID_DISPLAY; 635 636 // Whether we should use SCHED_FIFO for UI and RenderThreads. 637 private boolean mUseFifoUiScheduling = false; 638 639 BroadcastQueue mFgBroadcastQueue; 640 BroadcastQueue mBgBroadcastQueue; 641 // Convenient for easy iteration over the queues. Foreground is first 642 // so that dispatch of foreground broadcasts gets precedence. 643 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 644 645 BroadcastStats mLastBroadcastStats; 646 BroadcastStats mCurBroadcastStats; 647 648 BroadcastQueue broadcastQueueForIntent(Intent intent) { 649 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 650 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST, 651 "Broadcast intent " + intent + " on " 652 + (isFg ? "foreground" : "background") + " queue"); 653 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 654 } 655 656 /** 657 * The last resumed activity. This is identical to the current resumed activity most 658 * of the time but could be different when we're pausing one activity before we resume 659 * another activity. 660 */ 661 private ActivityRecord mLastResumedActivity; 662 663 /** 664 * If non-null, we are tracking the time the user spends in the currently focused app. 665 */ 666 private AppTimeTracker mCurAppTimeTracker; 667 668 /** 669 * List of intents that were used to start the most recent tasks. 670 */ 671 final RecentTasks mRecentTasks; 672 673 /** 674 * For addAppTask: cached of the last activity component that was added. 675 */ 676 ComponentName mLastAddedTaskComponent; 677 678 /** 679 * For addAppTask: cached of the last activity uid that was added. 680 */ 681 int mLastAddedTaskUid; 682 683 /** 684 * For addAppTask: cached of the last ActivityInfo that was added. 685 */ 686 ActivityInfo mLastAddedTaskActivity; 687 688 /** 689 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId. 690 */ 691 SparseArray<String[]> mLockTaskPackages = new SparseArray<>(); 692 693 /** 694 * The package name of the DeviceOwner. This package is not permitted to have its data cleared. 695 */ 696 String mDeviceOwnerName; 697 698 final UserController mUserController; 699 700 final AppErrors mAppErrors; 701 702 /** 703 * Dump of the activity state at the time of the last ANR. Cleared after 704 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS} 705 */ 706 String mLastANRState; 707 708 /** 709 * Indicates the maximum time spent waiting for the network rules to get updated. 710 */ 711 @VisibleForTesting 712 long mWaitForNetworkTimeoutMs; 713 714 public boolean canShowErrorDialogs() { 715 return mShowDialogs && !mSleeping && !mShuttingDown 716 && !mKeyguardController.isKeyguardShowing() 717 && !(UserManager.isDeviceInDemoMode(mContext) 718 && mUserController.getCurrentUser().isDemo()); 719 } 720 721 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster( 722 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY); 723 724 static void boostPriorityForLockedSection() { 725 sThreadPriorityBooster.boost(); 726 } 727 728 static void resetPriorityAfterLockedSection() { 729 sThreadPriorityBooster.reset(); 730 } 731 732 public class PendingAssistExtras extends Binder implements Runnable { 733 public final ActivityRecord activity; 734 public boolean isHome; 735 public final Bundle extras; 736 public final Intent intent; 737 public final String hint; 738 public final IResultReceiver receiver; 739 public final int userHandle; 740 public boolean haveResult = false; 741 public Bundle result = null; 742 public AssistStructure structure = null; 743 public AssistContent content = null; 744 public Bundle receiverExtras; 745 746 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 747 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) { 748 activity = _activity; 749 extras = _extras; 750 intent = _intent; 751 hint = _hint; 752 receiver = _receiver; 753 receiverExtras = _receiverExtras; 754 userHandle = _userHandle; 755 } 756 757 @Override 758 public void run() { 759 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 760 synchronized (this) { 761 haveResult = true; 762 notifyAll(); 763 } 764 pendingAssistExtrasTimedOut(this); 765 } 766 } 767 768 final ArrayList<PendingAssistExtras> mPendingAssistExtras 769 = new ArrayList<PendingAssistExtras>(); 770 771 /** 772 * Process management. 773 */ 774 final ProcessList mProcessList = new ProcessList(); 775 776 /** 777 * All of the applications we currently have running organized by name. 778 * The keys are strings of the application package name (as 779 * returned by the package manager), and the keys are ApplicationRecord 780 * objects. 781 */ 782 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 783 784 /** 785 * Tracking long-term execution of processes to look for abuse and other 786 * bad app behavior. 787 */ 788 final ProcessStatsService mProcessStats; 789 790 /** 791 * The currently running isolated processes. 792 */ 793 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 794 795 /** 796 * Counter for assigning isolated process uids, to avoid frequently reusing the 797 * same ones. 798 */ 799 int mNextIsolatedProcessUid = 0; 800 801 /** 802 * The currently running heavy-weight process, if any. 803 */ 804 ProcessRecord mHeavyWeightProcess = null; 805 806 /** 807 * Non-persistent appId whitelist for background restrictions 808 */ 809 int[] mBackgroundAppIdWhitelist = new int[] { 810 BLUETOOTH_UID 811 }; 812 813 /** 814 * Broadcast actions that will always be deliverable to unlaunched/background apps 815 */ 816 ArraySet<String> mBackgroundLaunchBroadcasts; 817 818 /** 819 * All of the processes we currently have running organized by pid. 820 * The keys are the pid running the application. 821 * 822 * <p>NOTE: This object is protected by its own lock, NOT the global 823 * activity manager lock! 824 */ 825 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 826 827 /** 828 * All of the processes that have been forced to be important. The key 829 * is the pid of the caller who requested it (we hold a death 830 * link on it). 831 */ 832 abstract class ImportanceToken implements IBinder.DeathRecipient { 833 final int pid; 834 final IBinder token; 835 final String reason; 836 837 ImportanceToken(int _pid, IBinder _token, String _reason) { 838 pid = _pid; 839 token = _token; 840 reason = _reason; 841 } 842 843 @Override 844 public String toString() { 845 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this)) 846 + " " + reason + " " + pid + " " + token + " }"; 847 } 848 } 849 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>(); 850 851 /** 852 * List of records for processes that someone had tried to start before the 853 * system was ready. We don't start them at that point, but ensure they 854 * are started by the time booting is complete. 855 */ 856 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 857 858 /** 859 * List of persistent applications that are in the process 860 * of being started. 861 */ 862 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 863 864 /** 865 * Processes that are being forcibly torn down. 866 */ 867 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 868 869 /** 870 * List of running applications, sorted by recent usage. 871 * The first entry in the list is the least recently used. 872 */ 873 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 874 875 /** 876 * Where in mLruProcesses that the processes hosting activities start. 877 */ 878 int mLruProcessActivityStart = 0; 879 880 /** 881 * Where in mLruProcesses that the processes hosting services start. 882 * This is after (lower index) than mLruProcessesActivityStart. 883 */ 884 int mLruProcessServiceStart = 0; 885 886 /** 887 * List of processes that should gc as soon as things are idle. 888 */ 889 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 890 891 /** 892 * Processes we want to collect PSS data from. 893 */ 894 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 895 896 private boolean mBinderTransactionTrackingEnabled = false; 897 898 /** 899 * Last time we requested PSS data of all processes. 900 */ 901 long mLastFullPssTime = SystemClock.uptimeMillis(); 902 903 /** 904 * If set, the next time we collect PSS data we should do a full collection 905 * with data from native processes and the kernel. 906 */ 907 boolean mFullPssPending = false; 908 909 /** 910 * This is the process holding what we currently consider to be 911 * the "home" activity. 912 */ 913 ProcessRecord mHomeProcess; 914 915 /** 916 * This is the process holding the activity the user last visited that 917 * is in a different process from the one they are currently in. 918 */ 919 ProcessRecord mPreviousProcess; 920 921 /** 922 * The time at which the previous process was last visible. 923 */ 924 long mPreviousProcessVisibleTime; 925 926 /** 927 * Track all uids that have actively running processes. 928 */ 929 final SparseArray<UidRecord> mActiveUids = new SparseArray<>(); 930 931 /** 932 * This is for verifying the UID report flow. 933 */ 934 static final boolean VALIDATE_UID_STATES = true; 935 final SparseArray<UidRecord> mValidateUids = new SparseArray<>(); 936 937 /** 938 * Packages that the user has asked to have run in screen size 939 * compatibility mode instead of filling the screen. 940 */ 941 final CompatModePackages mCompatModePackages; 942 943 /** 944 * Set of IntentSenderRecord objects that are currently active. 945 */ 946 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 947 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 948 949 /** 950 * Fingerprints (hashCode()) of stack traces that we've 951 * already logged DropBox entries for. Guarded by itself. If 952 * something (rogue user app) forces this over 953 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 954 */ 955 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 956 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 957 958 /** 959 * Strict Mode background batched logging state. 960 * 961 * The string buffer is guarded by itself, and its lock is also 962 * used to determine if another batched write is already 963 * in-flight. 964 */ 965 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 966 967 /** 968 * Keeps track of all IIntentReceivers that have been registered for broadcasts. 969 * Hash keys are the receiver IBinder, hash value is a ReceiverList. 970 */ 971 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>(); 972 973 /** 974 * Resolver for broadcast intents to registered receivers. 975 * Holds BroadcastFilter (subclass of IntentFilter). 976 */ 977 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 978 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 979 @Override 980 protected boolean allowFilterResult( 981 BroadcastFilter filter, List<BroadcastFilter> dest) { 982 IBinder target = filter.receiverList.receiver.asBinder(); 983 for (int i = dest.size() - 1; i >= 0; i--) { 984 if (dest.get(i).receiverList.receiver.asBinder() == target) { 985 return false; 986 } 987 } 988 return true; 989 } 990 991 @Override 992 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 993 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 994 || userId == filter.owningUserId) { 995 return super.newResult(filter, match, userId); 996 } 997 return null; 998 } 999 1000 @Override 1001 protected BroadcastFilter[] newArray(int size) { 1002 return new BroadcastFilter[size]; 1003 } 1004 1005 @Override 1006 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 1007 return packageName.equals(filter.packageName); 1008 } 1009 }; 1010 1011 /** 1012 * State of all active sticky broadcasts per user. Keys are the action of the 1013 * sticky Intent, values are an ArrayList of all broadcasted intents with 1014 * that action (which should usually be one). The SparseArray is keyed 1015 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 1016 * for stickies that are sent to all users. 1017 */ 1018 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 1019 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 1020 1021 final ActiveServices mServices; 1022 1023 final static class Association { 1024 final int mSourceUid; 1025 final String mSourceProcess; 1026 final int mTargetUid; 1027 final ComponentName mTargetComponent; 1028 final String mTargetProcess; 1029 1030 int mCount; 1031 long mTime; 1032 1033 int mNesting; 1034 long mStartTime; 1035 1036 // states of the source process when the bind occurred. 1037 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1; 1038 long mLastStateUptime; 1039 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE 1040 - ActivityManager.MIN_PROCESS_STATE+1]; 1041 1042 Association(int sourceUid, String sourceProcess, int targetUid, 1043 ComponentName targetComponent, String targetProcess) { 1044 mSourceUid = sourceUid; 1045 mSourceProcess = sourceProcess; 1046 mTargetUid = targetUid; 1047 mTargetComponent = targetComponent; 1048 mTargetProcess = targetProcess; 1049 } 1050 } 1051 1052 /** 1053 * When service association tracking is enabled, this is all of the associations we 1054 * have seen. Mapping is target uid -> target component -> source uid -> source process name 1055 * -> association data. 1056 */ 1057 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>> 1058 mAssociations = new SparseArray<>(); 1059 boolean mTrackingAssociations; 1060 1061 /** 1062 * Backup/restore process management 1063 */ 1064 String mBackupAppName = null; 1065 BackupRecord mBackupTarget = null; 1066 1067 final ProviderMap mProviderMap; 1068 1069 /** 1070 * List of content providers who have clients waiting for them. The 1071 * application is currently being launched and the provider will be 1072 * removed from this list once it is published. 1073 */ 1074 final ArrayList<ContentProviderRecord> mLaunchingProviders 1075 = new ArrayList<ContentProviderRecord>(); 1076 1077 /** 1078 * File storing persisted {@link #mGrantedUriPermissions}. 1079 */ 1080 private final AtomicFile mGrantFile; 1081 1082 /** XML constants used in {@link #mGrantFile} */ 1083 private static final String TAG_URI_GRANTS = "uri-grants"; 1084 private static final String TAG_URI_GRANT = "uri-grant"; 1085 private static final String ATTR_USER_HANDLE = "userHandle"; 1086 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 1087 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 1088 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 1089 private static final String ATTR_TARGET_PKG = "targetPkg"; 1090 private static final String ATTR_URI = "uri"; 1091 private static final String ATTR_MODE_FLAGS = "modeFlags"; 1092 private static final String ATTR_CREATED_TIME = "createdTime"; 1093 private static final String ATTR_PREFIX = "prefix"; 1094 1095 /** 1096 * Global set of specific {@link Uri} permissions that have been granted. 1097 * This optimized lookup structure maps from {@link UriPermission#targetUid} 1098 * to {@link UriPermission#uri} to {@link UriPermission}. 1099 */ 1100 @GuardedBy("this") 1101 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 1102 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 1103 1104 public static class GrantUri { 1105 public final int sourceUserId; 1106 public final Uri uri; 1107 public boolean prefix; 1108 1109 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 1110 this.sourceUserId = sourceUserId; 1111 this.uri = uri; 1112 this.prefix = prefix; 1113 } 1114 1115 @Override 1116 public int hashCode() { 1117 int hashCode = 1; 1118 hashCode = 31 * hashCode + sourceUserId; 1119 hashCode = 31 * hashCode + uri.hashCode(); 1120 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 1121 return hashCode; 1122 } 1123 1124 @Override 1125 public boolean equals(Object o) { 1126 if (o instanceof GrantUri) { 1127 GrantUri other = (GrantUri) o; 1128 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 1129 && prefix == other.prefix; 1130 } 1131 return false; 1132 } 1133 1134 @Override 1135 public String toString() { 1136 String result = uri.toString() + " [user " + sourceUserId + "]"; 1137 if (prefix) result += " [prefix]"; 1138 return result; 1139 } 1140 1141 public String toSafeString() { 1142 String result = uri.toSafeString() + " [user " + sourceUserId + "]"; 1143 if (prefix) result += " [prefix]"; 1144 return result; 1145 } 1146 1147 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 1148 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 1149 ContentProvider.getUriWithoutUserId(uri), false); 1150 } 1151 } 1152 1153 CoreSettingsObserver mCoreSettingsObserver; 1154 1155 FontScaleSettingObserver mFontScaleSettingObserver; 1156 1157 private final class FontScaleSettingObserver extends ContentObserver { 1158 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE); 1159 1160 public FontScaleSettingObserver() { 1161 super(mHandler); 1162 ContentResolver resolver = mContext.getContentResolver(); 1163 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL); 1164 } 1165 1166 @Override 1167 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { 1168 if (mFontScaleUri.equals(uri)) { 1169 updateFontScaleIfNeeded(userId); 1170 } 1171 } 1172 } 1173 1174 /** 1175 * Thread-local storage used to carry caller permissions over through 1176 * indirect content-provider access. 1177 */ 1178 private class Identity { 1179 public final IBinder token; 1180 public final int pid; 1181 public final int uid; 1182 1183 Identity(IBinder _token, int _pid, int _uid) { 1184 token = _token; 1185 pid = _pid; 1186 uid = _uid; 1187 } 1188 } 1189 1190 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 1191 1192 /** 1193 * All information we have collected about the runtime performance of 1194 * any user id that can impact battery performance. 1195 */ 1196 final BatteryStatsService mBatteryStatsService; 1197 1198 /** 1199 * Information about component usage 1200 */ 1201 UsageStatsManagerInternal mUsageStatsService; 1202 1203 /** 1204 * Access to DeviceIdleController service. 1205 */ 1206 DeviceIdleController.LocalService mLocalDeviceIdleController; 1207 1208 /** 1209 * Set of app ids that are whitelisted for device idle and thus background check. 1210 */ 1211 int[] mDeviceIdleWhitelist = new int[0]; 1212 1213 /** 1214 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message 1215 */ 1216 int[] mDeviceIdleTempWhitelist = new int[0]; 1217 1218 static final class PendingTempWhitelist { 1219 final int targetUid; 1220 final long duration; 1221 final String tag; 1222 1223 PendingTempWhitelist(int _targetUid, long _duration, String _tag) { 1224 targetUid = _targetUid; 1225 duration = _duration; 1226 tag = _tag; 1227 } 1228 } 1229 1230 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>(); 1231 1232 /** 1233 * Information about and control over application operations 1234 */ 1235 final AppOpsService mAppOpsService; 1236 1237 /** Current sequencing integer of the configuration, for skipping old configurations. */ 1238 private int mConfigurationSeq; 1239 1240 /** 1241 * Temp object used when global and/or display override configuration is updated. It is also 1242 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust 1243 * anyone... 1244 */ 1245 private Configuration mTempConfig = new Configuration(); 1246 1247 private final UpdateConfigurationResult mTmpUpdateConfigurationResult = 1248 new UpdateConfigurationResult(); 1249 private static final class UpdateConfigurationResult { 1250 // Configuration changes that were updated. 1251 int changes; 1252 // If the activity was relaunched to match the new configuration. 1253 boolean activityRelaunched; 1254 1255 void reset() { 1256 changes = 0; 1257 activityRelaunched = false; 1258 } 1259 } 1260 1261 boolean mSuppressResizeConfigChanges; 1262 1263 /** 1264 * Hardware-reported OpenGLES version. 1265 */ 1266 final int GL_ES_VERSION; 1267 1268 /** 1269 * List of initialization arguments to pass to all processes when binding applications to them. 1270 * For example, references to the commonly used services. 1271 */ 1272 HashMap<String, IBinder> mAppBindArgs; 1273 HashMap<String, IBinder> mIsolatedAppBindArgs; 1274 1275 /** 1276 * Temporary to avoid allocations. Protected by main lock. 1277 */ 1278 final StringBuilder mStringBuilder = new StringBuilder(256); 1279 1280 /** 1281 * Used to control how we initialize the service. 1282 */ 1283 ComponentName mTopComponent; 1284 String mTopAction = Intent.ACTION_MAIN; 1285 String mTopData; 1286 1287 volatile boolean mProcessesReady = false; 1288 volatile boolean mSystemReady = false; 1289 volatile boolean mOnBattery = false; 1290 volatile int mFactoryTest; 1291 1292 @GuardedBy("this") boolean mBooting = false; 1293 @GuardedBy("this") boolean mCallFinishBooting = false; 1294 @GuardedBy("this") boolean mBootAnimationComplete = false; 1295 @GuardedBy("this") boolean mLaunchWarningShown = false; 1296 @GuardedBy("this") boolean mCheckedForSetup = false; 1297 1298 final Context mContext; 1299 1300 /** 1301 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can 1302 * change at runtime. Use mContext for non-UI purposes. 1303 */ 1304 final Context mUiContext; 1305 1306 /** 1307 * The time at which we will allow normal application switches again, 1308 * after a call to {@link #stopAppSwitches()}. 1309 */ 1310 long mAppSwitchesAllowedTime; 1311 1312 /** 1313 * This is set to true after the first switch after mAppSwitchesAllowedTime 1314 * is set; any switches after that will clear the time. 1315 */ 1316 boolean mDidAppSwitch; 1317 1318 /** 1319 * Last time (in uptime) at which we checked for power usage. 1320 */ 1321 long mLastPowerCheckUptime; 1322 1323 /** 1324 * Set while we are wanting to sleep, to prevent any 1325 * activities from being started/resumed. 1326 * 1327 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping. 1328 * 1329 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true 1330 * while in the sleep state until there is a pending transition out of sleep, in which case 1331 * mSleeping is set to false, and remains false while awake. 1332 * 1333 * Whether mSleeping can quickly toggled between true/false without the device actually 1334 * display changing states is undefined. 1335 */ 1336 private boolean mSleeping = false; 1337 1338 /** 1339 * The process state used for processes that are running the top activities. 1340 * This changes between TOP and TOP_SLEEPING to following mSleeping. 1341 */ 1342 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP; 1343 1344 /** 1345 * Set while we are running a voice interaction. This overrides 1346 * sleeping while it is active. 1347 */ 1348 IVoiceInteractionSession mRunningVoice; 1349 1350 /** 1351 * For some direct access we need to power manager. 1352 */ 1353 PowerManagerInternal mLocalPowerManager; 1354 1355 /** 1356 * We want to hold a wake lock while running a voice interaction session, since 1357 * this may happen with the screen off and we need to keep the CPU running to 1358 * be able to continue to interact with the user. 1359 */ 1360 PowerManager.WakeLock mVoiceWakeLock; 1361 1362 /** 1363 * State of external calls telling us if the device is awake or asleep. 1364 */ 1365 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 1366 1367 /** 1368 * Set if we are shutting down the system, similar to sleeping. 1369 */ 1370 boolean mShuttingDown = false; 1371 1372 /** 1373 * Current sequence id for oom_adj computation traversal. 1374 */ 1375 int mAdjSeq = 0; 1376 1377 /** 1378 * Current sequence id for process LRU updating. 1379 */ 1380 int mLruSeq = 0; 1381 1382 /** 1383 * Keep track of the non-cached/empty process we last found, to help 1384 * determine how to distribute cached/empty processes next time. 1385 */ 1386 int mNumNonCachedProcs = 0; 1387 1388 /** 1389 * Keep track of the number of cached hidden procs, to balance oom adj 1390 * distribution between those and empty procs. 1391 */ 1392 int mNumCachedHiddenProcs = 0; 1393 1394 /** 1395 * Keep track of the number of service processes we last found, to 1396 * determine on the next iteration which should be B services. 1397 */ 1398 int mNumServiceProcs = 0; 1399 int mNewNumAServiceProcs = 0; 1400 int mNewNumServiceProcs = 0; 1401 1402 /** 1403 * Allow the current computed overall memory level of the system to go down? 1404 * This is set to false when we are killing processes for reasons other than 1405 * memory management, so that the now smaller process list will not be taken as 1406 * an indication that memory is tighter. 1407 */ 1408 boolean mAllowLowerMemLevel = false; 1409 1410 /** 1411 * The last computed memory level, for holding when we are in a state that 1412 * processes are going away for other reasons. 1413 */ 1414 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1415 1416 /** 1417 * The last total number of process we have, to determine if changes actually look 1418 * like a shrinking number of process due to lower RAM. 1419 */ 1420 int mLastNumProcesses; 1421 1422 /** 1423 * The uptime of the last time we performed idle maintenance. 1424 */ 1425 long mLastIdleTime = SystemClock.uptimeMillis(); 1426 1427 /** 1428 * Total time spent with RAM that has been added in the past since the last idle time. 1429 */ 1430 long mLowRamTimeSinceLastIdle = 0; 1431 1432 /** 1433 * If RAM is currently low, when that horrible situation started. 1434 */ 1435 long mLowRamStartTime = 0; 1436 1437 /** 1438 * For reporting to battery stats the current top application. 1439 */ 1440 private String mCurResumedPackage = null; 1441 private int mCurResumedUid = -1; 1442 1443 /** 1444 * For reporting to battery stats the apps currently running foreground 1445 * service. The ProcessMap is package/uid tuples; each of these contain 1446 * an array of the currently foreground processes. 1447 */ 1448 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1449 = new ProcessMap<ArrayList<ProcessRecord>>(); 1450 1451 /** 1452 * Set if the systemServer made a call to enterSafeMode. 1453 */ 1454 boolean mSafeMode; 1455 1456 /** 1457 * If true, we are running under a test environment so will sample PSS from processes 1458 * much more rapidly to try to collect better data when the tests are rapidly 1459 * running through apps. 1460 */ 1461 boolean mTestPssMode = false; 1462 1463 String mDebugApp = null; 1464 boolean mWaitForDebugger = false; 1465 boolean mDebugTransient = false; 1466 String mOrigDebugApp = null; 1467 boolean mOrigWaitForDebugger = false; 1468 boolean mAlwaysFinishActivities = false; 1469 boolean mForceResizableActivities; 1470 /** 1471 * Flag that indicates if multi-window is enabled. 1472 * 1473 * For any particular form of multi-window to be enabled, generic multi-window must be enabled 1474 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or 1475 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set. 1476 * At least one of the forms of multi-window must be enabled in order for this flag to be 1477 * initialized to 'true'. 1478 * 1479 * @see #mSupportsSplitScreenMultiWindow 1480 * @see #mSupportsFreeformWindowManagement 1481 * @see #mSupportsPictureInPicture 1482 * @see #mSupportsMultiDisplay 1483 */ 1484 boolean mSupportsMultiWindow; 1485 boolean mSupportsSplitScreenMultiWindow; 1486 boolean mSupportsFreeformWindowManagement; 1487 boolean mSupportsPictureInPicture; 1488 boolean mSupportsMultiDisplay; 1489 boolean mSupportsLeanbackOnly; 1490 IActivityController mController = null; 1491 boolean mControllerIsAMonkey = false; 1492 String mProfileApp = null; 1493 ProcessRecord mProfileProc = null; 1494 ProfilerInfo mProfilerInfo = null; 1495 int mProfileType = 0; 1496 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>(); 1497 String mMemWatchDumpProcName; 1498 String mMemWatchDumpFile; 1499 int mMemWatchDumpPid; 1500 int mMemWatchDumpUid; 1501 String mTrackAllocationApp = null; 1502 String mNativeDebuggingApp = null; 1503 1504 final long[] mTmpLong = new long[2]; 1505 1506 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet(); 1507 1508 /** 1509 * A global counter for generating sequence numbers. 1510 * This value will be used when incrementing sequence numbers in individual uidRecords. 1511 * 1512 * Having a global counter ensures that seq numbers are monotonically increasing for a 1513 * particular uid even when the uidRecord is re-created. 1514 */ 1515 @GuardedBy("this") 1516 @VisibleForTesting 1517 long mProcStateSeqCounter = 0; 1518 1519 private final Injector mInjector; 1520 1521 static final class ProcessChangeItem { 1522 static final int CHANGE_ACTIVITIES = 1<<0; 1523 int changes; 1524 int uid; 1525 int pid; 1526 int processState; 1527 boolean foregroundActivities; 1528 } 1529 1530 static final class UidObserverRegistration { 1531 final int uid; 1532 final String pkg; 1533 final int which; 1534 final int cutpoint; 1535 1536 final SparseIntArray lastProcStates; 1537 1538 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) { 1539 uid = _uid; 1540 pkg = _pkg; 1541 which = _which; 1542 cutpoint = _cutpoint; 1543 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) { 1544 lastProcStates = new SparseIntArray(); 1545 } else { 1546 lastProcStates = null; 1547 } 1548 } 1549 } 1550 1551 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>(); 1552 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1553 1554 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>(); 1555 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>(); 1556 1557 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>(); 1558 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5]; 1559 1560 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>(); 1561 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>(); 1562 1563 OomAdjObserver mCurOomAdjObserver; 1564 int mCurOomAdjUid; 1565 1566 interface OomAdjObserver { 1567 void onOomAdjMessage(String msg); 1568 } 1569 1570 /** 1571 * Runtime CPU use collection thread. This object's lock is used to 1572 * perform synchronization with the thread (notifying it to run). 1573 */ 1574 final Thread mProcessCpuThread; 1575 1576 /** 1577 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1578 * Must acquire this object's lock when accessing it. 1579 * NOTE: this lock will be held while doing long operations (trawling 1580 * through all processes in /proc), so it should never be acquired by 1581 * any critical paths such as when holding the main activity manager lock. 1582 */ 1583 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1584 MONITOR_THREAD_CPU_USAGE); 1585 final AtomicLong mLastCpuTime = new AtomicLong(0); 1586 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1587 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1); 1588 1589 long mLastWriteTime = 0; 1590 1591 /** 1592 * Used to retain an update lock when the foreground activity is in 1593 * immersive mode. 1594 */ 1595 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1596 1597 /** 1598 * Set to true after the system has finished booting. 1599 */ 1600 boolean mBooted = false; 1601 1602 WindowManagerService mWindowManager; 1603 final ActivityThread mSystemThread; 1604 1605 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1606 final ProcessRecord mApp; 1607 final int mPid; 1608 final IApplicationThread mAppThread; 1609 1610 AppDeathRecipient(ProcessRecord app, int pid, 1611 IApplicationThread thread) { 1612 if (DEBUG_ALL) Slog.v( 1613 TAG, "New death recipient " + this 1614 + " for thread " + thread.asBinder()); 1615 mApp = app; 1616 mPid = pid; 1617 mAppThread = thread; 1618 } 1619 1620 @Override 1621 public void binderDied() { 1622 if (DEBUG_ALL) Slog.v( 1623 TAG, "Death received in " + this 1624 + " for thread " + mAppThread.asBinder()); 1625 synchronized(ActivityManagerService.this) { 1626 appDiedLocked(mApp, mPid, mAppThread, true); 1627 } 1628 } 1629 } 1630 1631 static final int SHOW_ERROR_UI_MSG = 1; 1632 static final int SHOW_NOT_RESPONDING_UI_MSG = 2; 1633 static final int SHOW_FACTORY_ERROR_UI_MSG = 3; 1634 static final int UPDATE_CONFIGURATION_MSG = 4; 1635 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1636 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6; 1637 static final int SERVICE_TIMEOUT_MSG = 12; 1638 static final int UPDATE_TIME_ZONE = 13; 1639 static final int SHOW_UID_ERROR_UI_MSG = 14; 1640 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15; 1641 static final int PROC_START_TIMEOUT_MSG = 20; 1642 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1643 static final int KILL_APPLICATION_MSG = 22; 1644 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1645 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1646 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1647 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26; 1648 static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27; 1649 static final int CLEAR_DNS_CACHE_MSG = 28; 1650 static final int UPDATE_HTTP_PROXY_MSG = 29; 1651 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30; 1652 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31; 1653 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32; 1654 static final int REPORT_MEM_USAGE_MSG = 33; 1655 static final int REPORT_USER_SWITCH_MSG = 34; 1656 static final int CONTINUE_USER_SWITCH_MSG = 35; 1657 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1658 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1659 static final int PERSIST_URI_GRANTS_MSG = 38; 1660 static final int REQUEST_ALL_PSS_MSG = 39; 1661 static final int START_PROFILES_MSG = 40; 1662 static final int UPDATE_TIME_PREFERENCE_MSG = 41; 1663 static final int SYSTEM_USER_START_MSG = 42; 1664 static final int SYSTEM_USER_CURRENT_MSG = 43; 1665 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1666 static final int FINISH_BOOTING_MSG = 45; 1667 static final int START_USER_SWITCH_UI_MSG = 46; 1668 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1669 static final int DISMISS_DIALOG_UI_MSG = 48; 1670 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49; 1671 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50; 1672 static final int DELETE_DUMPHEAP_MSG = 51; 1673 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52; 1674 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53; 1675 static final int REPORT_TIME_TRACKER_MSG = 54; 1676 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55; 1677 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56; 1678 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57; 1679 static final int IDLE_UIDS_MSG = 58; 1680 static final int SYSTEM_USER_UNLOCK_MSG = 59; 1681 static final int LOG_STACK_STATE = 60; 1682 static final int VR_MODE_CHANGE_MSG = 61; 1683 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62; 1684 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63; 1685 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64; 1686 static final int NOTIFY_VR_SLEEPING_MSG = 65; 1687 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66; 1688 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67; 1689 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68; 1690 static final int SERVICE_FOREGROUND_CRASH_MSG = 69; 1691 static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70; 1692 static final int START_USER_SWITCH_FG_MSG = 712; 1693 1694 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1695 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1696 static final int FIRST_COMPAT_MODE_MSG = 300; 1697 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1698 1699 static ServiceThread sKillThread = null; 1700 static KillHandler sKillHandler = null; 1701 1702 CompatModeDialog mCompatModeDialog; 1703 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog; 1704 long mLastMemUsageReportTime = 0; 1705 1706 /** 1707 * Flag whether the current user is a "monkey", i.e. whether 1708 * the UI is driven by a UI automation tool. 1709 */ 1710 private boolean mUserIsMonkey; 1711 1712 /** Flag whether the device has a Recents UI */ 1713 boolean mHasRecents; 1714 1715 /** The dimensions of the thumbnails in the Recents UI. */ 1716 int mThumbnailWidth; 1717 int mThumbnailHeight; 1718 float mFullscreenThumbnailScale; 1719 1720 final ServiceThread mHandlerThread; 1721 final MainHandler mHandler; 1722 final Handler mUiHandler; 1723 1724 final ActivityManagerConstants mConstants; 1725 1726 PackageManagerInternal mPackageManagerInt; 1727 1728 // VoiceInteraction session ID that changes for each new request except when 1729 // being called for multiwindow assist in a single session. 1730 private int mViSessionId = 1000; 1731 1732 final boolean mPermissionReviewRequired; 1733 1734 private static String sTheRealBuildSerial = Build.UNKNOWN; 1735 1736 /** 1737 * Current global configuration information. Contains general settings for the entire system, 1738 * also corresponds to the merged configuration of the default display. 1739 */ 1740 Configuration getGlobalConfiguration() { 1741 return mStackSupervisor.getConfiguration(); 1742 } 1743 1744 final class KillHandler extends Handler { 1745 static final int KILL_PROCESS_GROUP_MSG = 4000; 1746 1747 public KillHandler(Looper looper) { 1748 super(looper, null, true); 1749 } 1750 1751 @Override 1752 public void handleMessage(Message msg) { 1753 switch (msg.what) { 1754 case KILL_PROCESS_GROUP_MSG: 1755 { 1756 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup"); 1757 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */); 1758 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1759 } 1760 break; 1761 1762 default: 1763 super.handleMessage(msg); 1764 } 1765 } 1766 } 1767 1768 final class UiHandler extends Handler { 1769 public UiHandler() { 1770 super(com.android.server.UiThread.get().getLooper(), null, true); 1771 } 1772 1773 @Override 1774 public void handleMessage(Message msg) { 1775 switch (msg.what) { 1776 case SHOW_ERROR_UI_MSG: { 1777 mAppErrors.handleShowAppErrorUi(msg); 1778 ensureBootCompleted(); 1779 } break; 1780 case SHOW_NOT_RESPONDING_UI_MSG: { 1781 mAppErrors.handleShowAnrUi(msg); 1782 ensureBootCompleted(); 1783 } break; 1784 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: { 1785 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1786 synchronized (ActivityManagerService.this) { 1787 ProcessRecord proc = (ProcessRecord) data.get("app"); 1788 if (proc == null) { 1789 Slog.e(TAG, "App not found when showing strict mode dialog."); 1790 break; 1791 } 1792 if (proc.crashDialog != null) { 1793 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1794 return; 1795 } 1796 AppErrorResult res = (AppErrorResult) data.get("result"); 1797 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1798 Dialog d = new StrictModeViolationDialog(mUiContext, 1799 ActivityManagerService.this, res, proc); 1800 d.show(); 1801 proc.crashDialog = d; 1802 } else { 1803 // The device is asleep, so just pretend that the user 1804 // saw a crash dialog and hit "force quit". 1805 res.set(0); 1806 } 1807 } 1808 ensureBootCompleted(); 1809 } break; 1810 case SHOW_FACTORY_ERROR_UI_MSG: { 1811 Dialog d = new FactoryErrorDialog( 1812 mUiContext, msg.getData().getCharSequence("msg")); 1813 d.show(); 1814 ensureBootCompleted(); 1815 } break; 1816 case WAIT_FOR_DEBUGGER_UI_MSG: { 1817 synchronized (ActivityManagerService.this) { 1818 ProcessRecord app = (ProcessRecord)msg.obj; 1819 if (msg.arg1 != 0) { 1820 if (!app.waitedForDebugger) { 1821 Dialog d = new AppWaitingForDebuggerDialog( 1822 ActivityManagerService.this, 1823 mUiContext, app); 1824 app.waitDialog = d; 1825 app.waitedForDebugger = true; 1826 d.show(); 1827 } 1828 } else { 1829 if (app.waitDialog != null) { 1830 app.waitDialog.dismiss(); 1831 app.waitDialog = null; 1832 } 1833 } 1834 } 1835 } break; 1836 case SHOW_UID_ERROR_UI_MSG: { 1837 if (mShowDialogs) { 1838 AlertDialog d = new BaseErrorDialog(mUiContext); 1839 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1840 d.setCancelable(false); 1841 d.setTitle(mUiContext.getText(R.string.android_system_label)); 1842 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data)); 1843 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok), 1844 obtainMessage(DISMISS_DIALOG_UI_MSG, d)); 1845 d.show(); 1846 } 1847 } break; 1848 case SHOW_FINGERPRINT_ERROR_UI_MSG: { 1849 if (mShowDialogs) { 1850 AlertDialog d = new BaseErrorDialog(mUiContext); 1851 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1852 d.setCancelable(false); 1853 d.setTitle(mUiContext.getText(R.string.android_system_label)); 1854 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer)); 1855 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok), 1856 obtainMessage(DISMISS_DIALOG_UI_MSG, d)); 1857 d.show(); 1858 } 1859 } break; 1860 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: { 1861 synchronized (ActivityManagerService.this) { 1862 ActivityRecord ar = (ActivityRecord) msg.obj; 1863 if (mCompatModeDialog != null) { 1864 if (mCompatModeDialog.mAppInfo.packageName.equals( 1865 ar.info.applicationInfo.packageName)) { 1866 return; 1867 } 1868 mCompatModeDialog.dismiss(); 1869 mCompatModeDialog = null; 1870 } 1871 if (ar != null && false) { 1872 if (mCompatModePackages.getPackageAskCompatModeLocked( 1873 ar.packageName)) { 1874 int mode = mCompatModePackages.computeCompatModeLocked( 1875 ar.info.applicationInfo); 1876 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1877 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1878 mCompatModeDialog = new CompatModeDialog( 1879 ActivityManagerService.this, mUiContext, 1880 ar.info.applicationInfo); 1881 mCompatModeDialog.show(); 1882 } 1883 } 1884 } 1885 } 1886 break; 1887 } 1888 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: { 1889 synchronized (ActivityManagerService.this) { 1890 final ActivityRecord ar = (ActivityRecord) msg.obj; 1891 if (mUnsupportedDisplaySizeDialog != null) { 1892 mUnsupportedDisplaySizeDialog.dismiss(); 1893 mUnsupportedDisplaySizeDialog = null; 1894 } 1895 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked( 1896 ar.packageName)) { 1897 // TODO(multi-display): Show dialog on appropriate display. 1898 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog( 1899 ActivityManagerService.this, mUiContext, ar.info.applicationInfo); 1900 mUnsupportedDisplaySizeDialog.show(); 1901 } 1902 } 1903 break; 1904 } 1905 case START_USER_SWITCH_UI_MSG: { 1906 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj); 1907 break; 1908 } 1909 case DISMISS_DIALOG_UI_MSG: { 1910 final Dialog d = (Dialog) msg.obj; 1911 d.dismiss(); 1912 break; 1913 } 1914 case DISPATCH_PROCESSES_CHANGED_UI_MSG: { 1915 dispatchProcessesChanged(); 1916 break; 1917 } 1918 case DISPATCH_PROCESS_DIED_UI_MSG: { 1919 final int pid = msg.arg1; 1920 final int uid = msg.arg2; 1921 dispatchProcessDied(pid, uid); 1922 break; 1923 } 1924 case DISPATCH_UIDS_CHANGED_UI_MSG: { 1925 dispatchUidsChanged(); 1926 } break; 1927 case DISPATCH_OOM_ADJ_OBSERVER_MSG: { 1928 dispatchOomAdjObserver((String)msg.obj); 1929 } break; 1930 case PUSH_TEMP_WHITELIST_UI_MSG: { 1931 pushTempWhitelist(); 1932 } break; 1933 } 1934 } 1935 } 1936 1937 final class MainHandler extends Handler { 1938 public MainHandler(Looper looper) { 1939 super(looper, null, true); 1940 } 1941 1942 @Override 1943 public void handleMessage(Message msg) { 1944 switch (msg.what) { 1945 case UPDATE_CONFIGURATION_MSG: { 1946 final ContentResolver resolver = mContext.getContentResolver(); 1947 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj, 1948 msg.arg1); 1949 } break; 1950 case GC_BACKGROUND_PROCESSES_MSG: { 1951 synchronized (ActivityManagerService.this) { 1952 performAppGcsIfAppropriateLocked(); 1953 } 1954 } break; 1955 case SERVICE_TIMEOUT_MSG: { 1956 mServices.serviceTimeout((ProcessRecord)msg.obj); 1957 } break; 1958 case SERVICE_FOREGROUND_TIMEOUT_MSG: { 1959 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj); 1960 } break; 1961 case SERVICE_FOREGROUND_CRASH_MSG: { 1962 mServices.serviceForegroundCrash((ProcessRecord)msg.obj); 1963 } break; 1964 case DISPATCH_PENDING_INTENT_CANCEL_MSG: { 1965 RemoteCallbackList<IResultReceiver> callbacks 1966 = (RemoteCallbackList<IResultReceiver>)msg.obj; 1967 int N = callbacks.beginBroadcast(); 1968 for (int i = 0; i < N; i++) { 1969 try { 1970 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null); 1971 } catch (RemoteException e) { 1972 } 1973 } 1974 callbacks.finishBroadcast(); 1975 } break; 1976 case UPDATE_TIME_ZONE: { 1977 synchronized (ActivityManagerService.this) { 1978 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1979 ProcessRecord r = mLruProcesses.get(i); 1980 if (r.thread != null) { 1981 try { 1982 r.thread.updateTimeZone(); 1983 } catch (RemoteException ex) { 1984 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1985 } 1986 } 1987 } 1988 } 1989 } break; 1990 case CLEAR_DNS_CACHE_MSG: { 1991 synchronized (ActivityManagerService.this) { 1992 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1993 ProcessRecord r = mLruProcesses.get(i); 1994 if (r.thread != null) { 1995 try { 1996 r.thread.clearDnsCache(); 1997 } catch (RemoteException ex) { 1998 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1999 } 2000 } 2001 } 2002 } 2003 } break; 2004 case UPDATE_HTTP_PROXY_MSG: { 2005 ProxyInfo proxy = (ProxyInfo)msg.obj; 2006 String host = ""; 2007 String port = ""; 2008 String exclList = ""; 2009 Uri pacFileUrl = Uri.EMPTY; 2010 if (proxy != null) { 2011 host = proxy.getHost(); 2012 port = Integer.toString(proxy.getPort()); 2013 exclList = proxy.getExclusionListAsString(); 2014 pacFileUrl = proxy.getPacFileUrl(); 2015 } 2016 synchronized (ActivityManagerService.this) { 2017 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 2018 ProcessRecord r = mLruProcesses.get(i); 2019 if (r.thread != null) { 2020 try { 2021 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 2022 } catch (RemoteException ex) { 2023 Slog.w(TAG, "Failed to update http proxy for: " + 2024 r.info.processName); 2025 } 2026 } 2027 } 2028 } 2029 } break; 2030 case PROC_START_TIMEOUT_MSG: { 2031 ProcessRecord app = (ProcessRecord)msg.obj; 2032 synchronized (ActivityManagerService.this) { 2033 processStartTimedOutLocked(app); 2034 } 2035 } break; 2036 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: { 2037 ProcessRecord app = (ProcessRecord)msg.obj; 2038 synchronized (ActivityManagerService.this) { 2039 processContentProviderPublishTimedOutLocked(app); 2040 } 2041 } break; 2042 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 2043 synchronized (ActivityManagerService.this) { 2044 mActivityStarter.doPendingActivityLaunchesLocked(true); 2045 } 2046 } break; 2047 case KILL_APPLICATION_MSG: { 2048 synchronized (ActivityManagerService.this) { 2049 final int appId = msg.arg1; 2050 final int userId = msg.arg2; 2051 Bundle bundle = (Bundle)msg.obj; 2052 String pkg = bundle.getString("pkg"); 2053 String reason = bundle.getString("reason"); 2054 forceStopPackageLocked(pkg, appId, false, false, true, false, 2055 false, userId, reason); 2056 } 2057 } break; 2058 case FINALIZE_PENDING_INTENT_MSG: { 2059 ((PendingIntentRecord)msg.obj).completeFinalize(); 2060 } break; 2061 case POST_HEAVY_NOTIFICATION_MSG: { 2062 INotificationManager inm = NotificationManager.getService(); 2063 if (inm == null) { 2064 return; 2065 } 2066 2067 ActivityRecord root = (ActivityRecord)msg.obj; 2068 ProcessRecord process = root.app; 2069 if (process == null) { 2070 return; 2071 } 2072 2073 try { 2074 Context context = mContext.createPackageContext(process.info.packageName, 0); 2075 String text = mContext.getString(R.string.heavy_weight_notification, 2076 context.getApplicationInfo().loadLabel(context.getPackageManager())); 2077 Notification notification = 2078 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER) 2079 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 2080 .setWhen(0) 2081 .setOngoing(true) 2082 .setTicker(text) 2083 .setColor(mContext.getColor( 2084 com.android.internal.R.color.system_notification_accent_color)) 2085 .setContentTitle(text) 2086 .setContentText( 2087 mContext.getText(R.string.heavy_weight_notification_detail)) 2088 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0, 2089 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null, 2090 new UserHandle(root.userId))) 2091 .build(); 2092 try { 2093 inm.enqueueNotificationWithTag("android", "android", null, 2094 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, 2095 notification, root.userId); 2096 } catch (RuntimeException e) { 2097 Slog.w(ActivityManagerService.TAG, 2098 "Error showing notification for heavy-weight app", e); 2099 } catch (RemoteException e) { 2100 } 2101 } catch (NameNotFoundException e) { 2102 Slog.w(TAG, "Unable to create context for heavy notification", e); 2103 } 2104 } break; 2105 case CANCEL_HEAVY_NOTIFICATION_MSG: { 2106 INotificationManager inm = NotificationManager.getService(); 2107 if (inm == null) { 2108 return; 2109 } 2110 try { 2111 inm.cancelNotificationWithTag("android", null, 2112 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1); 2113 } catch (RuntimeException e) { 2114 Slog.w(ActivityManagerService.TAG, 2115 "Error canceling notification for service", e); 2116 } catch (RemoteException e) { 2117 } 2118 } break; 2119 case CHECK_EXCESSIVE_POWER_USE_MSG: { 2120 synchronized (ActivityManagerService.this) { 2121 checkExcessivePowerUsageLocked(); 2122 removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG); 2123 Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG); 2124 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL); 2125 } 2126 } break; 2127 case REPORT_MEM_USAGE_MSG: { 2128 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 2129 Thread thread = new Thread() { 2130 @Override public void run() { 2131 reportMemUsage(memInfos); 2132 } 2133 }; 2134 thread.start(); 2135 break; 2136 } 2137 case START_USER_SWITCH_FG_MSG: { 2138 mUserController.startUserInForeground(msg.arg1); 2139 break; 2140 } 2141 case REPORT_USER_SWITCH_MSG: { 2142 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2); 2143 break; 2144 } 2145 case CONTINUE_USER_SWITCH_MSG: { 2146 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2); 2147 break; 2148 } 2149 case USER_SWITCH_TIMEOUT_MSG: { 2150 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2); 2151 break; 2152 } 2153 case IMMERSIVE_MODE_LOCK_MSG: { 2154 final boolean nextState = (msg.arg1 != 0); 2155 if (mUpdateLock.isHeld() != nextState) { 2156 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, 2157 "Applying new update lock state '" + nextState 2158 + "' for " + (ActivityRecord)msg.obj); 2159 if (nextState) { 2160 mUpdateLock.acquire(); 2161 } else { 2162 mUpdateLock.release(); 2163 } 2164 } 2165 break; 2166 } 2167 case PERSIST_URI_GRANTS_MSG: { 2168 writeGrantedUriPermissions(); 2169 break; 2170 } 2171 case REQUEST_ALL_PSS_MSG: { 2172 synchronized (ActivityManagerService.this) { 2173 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 2174 } 2175 break; 2176 } 2177 case START_PROFILES_MSG: { 2178 synchronized (ActivityManagerService.this) { 2179 mUserController.startProfilesLocked(); 2180 } 2181 break; 2182 } 2183 case UPDATE_TIME_PREFERENCE_MSG: { 2184 // The user's time format preference might have changed. 2185 // For convenience we re-use the Intent extra values. 2186 synchronized (ActivityManagerService.this) { 2187 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2188 ProcessRecord r = mLruProcesses.get(i); 2189 if (r.thread != null) { 2190 try { 2191 r.thread.updateTimePrefs(msg.arg1); 2192 } catch (RemoteException ex) { 2193 Slog.w(TAG, "Failed to update preferences for: " 2194 + r.info.processName); 2195 } 2196 } 2197 } 2198 } 2199 break; 2200 } 2201 case SYSTEM_USER_START_MSG: { 2202 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 2203 Integer.toString(msg.arg1), msg.arg1); 2204 mSystemServiceManager.startUser(msg.arg1); 2205 break; 2206 } 2207 case SYSTEM_USER_UNLOCK_MSG: { 2208 final int userId = msg.arg1; 2209 mSystemServiceManager.unlockUser(userId); 2210 synchronized (ActivityManagerService.this) { 2211 mRecentTasks.loadUserRecentsLocked(userId); 2212 } 2213 if (userId == UserHandle.USER_SYSTEM) { 2214 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 2215 } 2216 installEncryptionUnawareProviders(userId); 2217 mUserController.finishUserUnlocked((UserState) msg.obj); 2218 break; 2219 } 2220 case SYSTEM_USER_CURRENT_MSG: { 2221 mBatteryStatsService.noteEvent( 2222 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 2223 Integer.toString(msg.arg2), msg.arg2); 2224 mBatteryStatsService.noteEvent( 2225 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 2226 Integer.toString(msg.arg1), msg.arg1); 2227 mSystemServiceManager.switchUser(msg.arg1); 2228 break; 2229 } 2230 case ENTER_ANIMATION_COMPLETE_MSG: { 2231 synchronized (ActivityManagerService.this) { 2232 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 2233 if (r != null && r.app != null && r.app.thread != null) { 2234 try { 2235 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 2236 } catch (RemoteException e) { 2237 } 2238 } 2239 } 2240 break; 2241 } 2242 case FINISH_BOOTING_MSG: { 2243 if (msg.arg1 != 0) { 2244 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); 2245 finishBooting(); 2246 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 2247 } 2248 if (msg.arg2 != 0) { 2249 enableScreenAfterBoot(); 2250 } 2251 break; 2252 } 2253 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 2254 try { 2255 Locale l = (Locale) msg.obj; 2256 IBinder service = ServiceManager.getService("mount"); 2257 IStorageManager storageManager = IStorageManager.Stub.asInterface(service); 2258 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 2259 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 2260 } catch (RemoteException e) { 2261 Log.e(TAG, "Error storing locale for decryption UI", e); 2262 } 2263 break; 2264 } 2265 case NOTIFY_CLEARTEXT_NETWORK_MSG: { 2266 final int uid = msg.arg1; 2267 final byte[] firstPacket = (byte[]) msg.obj; 2268 2269 synchronized (mPidsSelfLocked) { 2270 for (int i = 0; i < mPidsSelfLocked.size(); i++) { 2271 final ProcessRecord p = mPidsSelfLocked.valueAt(i); 2272 if (p.uid == uid) { 2273 try { 2274 p.thread.notifyCleartextNetwork(firstPacket); 2275 } catch (RemoteException ignored) { 2276 } 2277 } 2278 } 2279 } 2280 break; 2281 } 2282 case POST_DUMP_HEAP_NOTIFICATION_MSG: { 2283 final String procName; 2284 final int uid; 2285 final long memLimit; 2286 final String reportPackage; 2287 synchronized (ActivityManagerService.this) { 2288 procName = mMemWatchDumpProcName; 2289 uid = mMemWatchDumpUid; 2290 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid); 2291 if (val == null) { 2292 val = mMemWatchProcesses.get(procName, 0); 2293 } 2294 if (val != null) { 2295 memLimit = val.first; 2296 reportPackage = val.second; 2297 } else { 2298 memLimit = 0; 2299 reportPackage = null; 2300 } 2301 } 2302 if (procName == null) { 2303 return; 2304 } 2305 2306 if (DEBUG_PSS) Slog.d(TAG_PSS, 2307 "Showing dump heap notification from " + procName + "/" + uid); 2308 2309 INotificationManager inm = NotificationManager.getService(); 2310 if (inm == null) { 2311 return; 2312 } 2313 2314 String text = mContext.getString(R.string.dump_heap_notification, procName); 2315 2316 2317 Intent deleteIntent = new Intent(); 2318 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP); 2319 Intent intent = new Intent(); 2320 intent.setClassName("android", DumpHeapActivity.class.getName()); 2321 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName); 2322 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit); 2323 if (reportPackage != null) { 2324 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage); 2325 } 2326 int userId = UserHandle.getUserId(uid); 2327 Notification notification = 2328 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER) 2329 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 2330 .setWhen(0) 2331 .setOngoing(true) 2332 .setAutoCancel(true) 2333 .setTicker(text) 2334 .setColor(mContext.getColor( 2335 com.android.internal.R.color.system_notification_accent_color)) 2336 .setContentTitle(text) 2337 .setContentText( 2338 mContext.getText(R.string.dump_heap_notification_detail)) 2339 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0, 2340 intent, PendingIntent.FLAG_CANCEL_CURRENT, null, 2341 new UserHandle(userId))) 2342 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0, 2343 deleteIntent, 0, UserHandle.SYSTEM)) 2344 .build(); 2345 2346 try { 2347 inm.enqueueNotificationWithTag("android", "android", null, 2348 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION, 2349 notification, userId); 2350 } catch (RuntimeException e) { 2351 Slog.w(ActivityManagerService.TAG, 2352 "Error showing notification for dump heap", e); 2353 } catch (RemoteException e) { 2354 } 2355 } break; 2356 case DELETE_DUMPHEAP_MSG: { 2357 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(), 2358 null, DumpHeapActivity.JAVA_URI, 2359 Intent.FLAG_GRANT_READ_URI_PERMISSION 2360 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 2361 UserHandle.myUserId()); 2362 synchronized (ActivityManagerService.this) { 2363 mMemWatchDumpFile = null; 2364 mMemWatchDumpProcName = null; 2365 mMemWatchDumpPid = -1; 2366 mMemWatchDumpUid = -1; 2367 } 2368 } break; 2369 case FOREGROUND_PROFILE_CHANGED_MSG: { 2370 mUserController.dispatchForegroundProfileChanged(msg.arg1); 2371 } break; 2372 case REPORT_TIME_TRACKER_MSG: { 2373 AppTimeTracker tracker = (AppTimeTracker)msg.obj; 2374 tracker.deliverResult(mContext); 2375 } break; 2376 case REPORT_USER_SWITCH_COMPLETE_MSG: { 2377 mUserController.dispatchUserSwitchComplete(msg.arg1); 2378 } break; 2379 case REPORT_LOCKED_BOOT_COMPLETE_MSG: { 2380 mUserController.dispatchLockedBootComplete(msg.arg1); 2381 } break; 2382 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: { 2383 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj; 2384 try { 2385 connection.shutdown(); 2386 } catch (RemoteException e) { 2387 Slog.w(TAG, "Error shutting down UiAutomationConnection"); 2388 } 2389 // Only a UiAutomation can set this flag and now that 2390 // it is finished we make sure it is reset to its default. 2391 mUserIsMonkey = false; 2392 } break; 2393 case IDLE_UIDS_MSG: { 2394 idleUids(); 2395 } break; 2396 case VR_MODE_CHANGE_MSG: { 2397 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) { 2398 return; 2399 } 2400 synchronized (ActivityManagerService.this) { 2401 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked(); 2402 mWindowManager.disableNonVrUi(disableNonVrUi); 2403 if (disableNonVrUi) { 2404 // If we are in a VR mode where Picture-in-Picture mode is unsupported, 2405 // then remove the pinned stack. 2406 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack( 2407 PINNED_STACK_ID); 2408 if (pinnedStack != null) { 2409 mStackSupervisor.removeStackLocked(PINNED_STACK_ID); 2410 } 2411 } 2412 } 2413 } break; 2414 case NOTIFY_VR_SLEEPING_MSG: { 2415 notifyVrManagerOfSleepState(msg.arg1 != 0); 2416 } break; 2417 case HANDLE_TRUST_STORAGE_UPDATE_MSG: { 2418 synchronized (ActivityManagerService.this) { 2419 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 2420 ProcessRecord r = mLruProcesses.get(i); 2421 if (r.thread != null) { 2422 try { 2423 r.thread.handleTrustStorageUpdate(); 2424 } catch (RemoteException ex) { 2425 Slog.w(TAG, "Failed to handle trust storage update for: " + 2426 r.info.processName); 2427 } 2428 } 2429 } 2430 } 2431 } break; 2432 } 2433 } 2434 }; 2435 2436 static final int COLLECT_PSS_BG_MSG = 1; 2437 2438 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 2439 @Override 2440 public void handleMessage(Message msg) { 2441 switch (msg.what) { 2442 case COLLECT_PSS_BG_MSG: { 2443 long start = SystemClock.uptimeMillis(); 2444 MemInfoReader memInfo = null; 2445 synchronized (ActivityManagerService.this) { 2446 if (mFullPssPending) { 2447 mFullPssPending = false; 2448 memInfo = new MemInfoReader(); 2449 } 2450 } 2451 if (memInfo != null) { 2452 updateCpuStatsNow(); 2453 long nativeTotalPss = 0; 2454 final List<ProcessCpuTracker.Stats> stats; 2455 synchronized (mProcessCpuTracker) { 2456 stats = mProcessCpuTracker.getStats( (st)-> { 2457 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID; 2458 }); 2459 } 2460 final int N = stats.size(); 2461 for (int j = 0; j < N; j++) { 2462 synchronized (mPidsSelfLocked) { 2463 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) { 2464 // This is one of our own processes; skip it. 2465 continue; 2466 } 2467 } 2468 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null); 2469 } 2470 memInfo.readMemInfo(); 2471 synchronized (ActivityManagerService.this) { 2472 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in " 2473 + (SystemClock.uptimeMillis()-start) + "ms"); 2474 final long cachedKb = memInfo.getCachedSizeKb(); 2475 final long freeKb = memInfo.getFreeSizeKb(); 2476 final long zramKb = memInfo.getZramTotalSizeKb(); 2477 final long kernelKb = memInfo.getKernelUsedSizeKb(); 2478 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024, 2479 kernelKb*1024, nativeTotalPss*1024); 2480 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb, 2481 nativeTotalPss); 2482 } 2483 } 2484 2485 int num = 0; 2486 long[] tmp = new long[2]; 2487 do { 2488 ProcessRecord proc; 2489 int procState; 2490 int pid; 2491 long lastPssTime; 2492 synchronized (ActivityManagerService.this) { 2493 if (mPendingPssProcesses.size() <= 0) { 2494 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS, 2495 "Collected PSS of " + num + " processes in " 2496 + (SystemClock.uptimeMillis() - start) + "ms"); 2497 mPendingPssProcesses.clear(); 2498 return; 2499 } 2500 proc = mPendingPssProcesses.remove(0); 2501 procState = proc.pssProcState; 2502 lastPssTime = proc.lastPssTime; 2503 if (proc.thread != null && procState == proc.setProcState 2504 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 2505 < SystemClock.uptimeMillis()) { 2506 pid = proc.pid; 2507 } else { 2508 proc = null; 2509 pid = 0; 2510 } 2511 } 2512 if (proc != null) { 2513 long pss = Debug.getPss(pid, tmp, null); 2514 synchronized (ActivityManagerService.this) { 2515 if (pss != 0 && proc.thread != null && proc.setProcState == procState 2516 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 2517 num++; 2518 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], 2519 SystemClock.uptimeMillis()); 2520 } 2521 } 2522 } 2523 } while (true); 2524 } 2525 } 2526 } 2527 }; 2528 2529 public void setSystemProcess() { 2530 try { 2531 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2532 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2533 ServiceManager.addService("meminfo", new MemBinder(this)); 2534 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2535 ServiceManager.addService("dbinfo", new DbBinder(this)); 2536 if (MONITOR_CPU_USAGE) { 2537 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2538 } 2539 ServiceManager.addService("permission", new PermissionController(this)); 2540 ServiceManager.addService("processinfo", new ProcessInfoService(this)); 2541 2542 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2543 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); 2544 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2545 2546 synchronized (this) { 2547 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2548 app.persistent = true; 2549 app.pid = MY_PID; 2550 app.maxAdj = ProcessList.SYSTEM_ADJ; 2551 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2552 synchronized (mPidsSelfLocked) { 2553 mPidsSelfLocked.put(app.pid, app); 2554 } 2555 updateLruProcessLocked(app, false, null); 2556 updateOomAdjLocked(); 2557 } 2558 } catch (PackageManager.NameNotFoundException e) { 2559 throw new RuntimeException( 2560 "Unable to find android system package", e); 2561 } 2562 } 2563 2564 public void setWindowManager(WindowManagerService wm) { 2565 mWindowManager = wm; 2566 mStackSupervisor.setWindowManager(wm); 2567 mActivityStarter.setWindowManager(wm); 2568 } 2569 2570 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2571 mUsageStatsService = usageStatsManager; 2572 } 2573 2574 public void startObservingNativeCrashes() { 2575 final NativeCrashListener ncl = new NativeCrashListener(this); 2576 ncl.start(); 2577 } 2578 2579 public IAppOpsService getAppOpsService() { 2580 return mAppOpsService; 2581 } 2582 2583 static class MemBinder extends Binder { 2584 ActivityManagerService mActivityManagerService; 2585 MemBinder(ActivityManagerService activityManagerService) { 2586 mActivityManagerService = activityManagerService; 2587 } 2588 2589 @Override 2590 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2591 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, 2592 "meminfo", pw)) return; 2593 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2594 } 2595 } 2596 2597 static class GraphicsBinder extends Binder { 2598 ActivityManagerService mActivityManagerService; 2599 GraphicsBinder(ActivityManagerService activityManagerService) { 2600 mActivityManagerService = activityManagerService; 2601 } 2602 2603 @Override 2604 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2605 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, 2606 "gfxinfo", pw)) return; 2607 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2608 } 2609 } 2610 2611 static class DbBinder extends Binder { 2612 ActivityManagerService mActivityManagerService; 2613 DbBinder(ActivityManagerService activityManagerService) { 2614 mActivityManagerService = activityManagerService; 2615 } 2616 2617 @Override 2618 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2619 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, 2620 "dbinfo", pw)) return; 2621 mActivityManagerService.dumpDbInfo(fd, pw, args); 2622 } 2623 } 2624 2625 static class CpuBinder extends Binder { 2626 ActivityManagerService mActivityManagerService; 2627 CpuBinder(ActivityManagerService activityManagerService) { 2628 mActivityManagerService = activityManagerService; 2629 } 2630 2631 @Override 2632 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2633 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, 2634 "cpuinfo", pw)) return; 2635 synchronized (mActivityManagerService.mProcessCpuTracker) { 2636 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2637 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2638 SystemClock.uptimeMillis())); 2639 } 2640 } 2641 } 2642 2643 public static final class Lifecycle extends SystemService { 2644 private final ActivityManagerService mService; 2645 2646 public Lifecycle(Context context) { 2647 super(context); 2648 mService = new ActivityManagerService(context); 2649 } 2650 2651 @Override 2652 public void onStart() { 2653 mService.start(); 2654 } 2655 2656 @Override 2657 public void onCleanupUser(int userId) { 2658 mService.mBatteryStatsService.onCleanupUser(userId); 2659 } 2660 2661 public ActivityManagerService getService() { 2662 return mService; 2663 } 2664 } 2665 2666 @VisibleForTesting 2667 public ActivityManagerService(Injector injector) { 2668 mInjector = injector; 2669 mContext = mInjector.getContext(); 2670 mUiContext = null; 2671 GL_ES_VERSION = 0; 2672 mActivityStarter = null; 2673 mAppErrors = null; 2674 mAppOpsService = mInjector.getAppOpsService(null, null); 2675 mBatteryStatsService = null; 2676 mCompatModePackages = null; 2677 mConstants = null; 2678 mGrantFile = null; 2679 mHandler = null; 2680 mHandlerThread = null; 2681 mIntentFirewall = null; 2682 mKeyguardController = null; 2683 mPermissionReviewRequired = false; 2684 mProcessCpuThread = null; 2685 mProcessStats = null; 2686 mProviderMap = null; 2687 mRecentTasks = null; 2688 mServices = null; 2689 mStackSupervisor = null; 2690 mSystemThread = null; 2691 mTaskChangeNotificationController = null; 2692 mUiHandler = injector.getUiHandler(null); 2693 mUserController = null; 2694 mVrController = null; 2695 } 2696 2697 // Note: This method is invoked on the main thread but may need to attach various 2698 // handlers to other threads. So take care to be explicit about the looper. 2699 public ActivityManagerService(Context systemContext) { 2700 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY); 2701 mInjector = new Injector(); 2702 mContext = systemContext; 2703 2704 mFactoryTest = FactoryTest.getMode(); 2705 mSystemThread = ActivityThread.currentActivityThread(); 2706 mUiContext = mSystemThread.getSystemUiContext(); 2707 2708 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2709 2710 mPermissionReviewRequired = mContext.getResources().getBoolean( 2711 com.android.internal.R.bool.config_permissionReviewRequired); 2712 2713 mHandlerThread = new ServiceThread(TAG, 2714 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2715 mHandlerThread.start(); 2716 mHandler = new MainHandler(mHandlerThread.getLooper()); 2717 mUiHandler = mInjector.getUiHandler(this); 2718 2719 mConstants = new ActivityManagerConstants(this, mHandler); 2720 2721 /* static; one-time init here */ 2722 if (sKillHandler == null) { 2723 sKillThread = new ServiceThread(TAG + ":kill", 2724 THREAD_PRIORITY_BACKGROUND, true /* allowIo */); 2725 sKillThread.start(); 2726 sKillHandler = new KillHandler(sKillThread.getLooper()); 2727 } 2728 2729 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2730 "foreground", BROADCAST_FG_TIMEOUT, false); 2731 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2732 "background", BROADCAST_BG_TIMEOUT, true); 2733 mBroadcastQueues[0] = mFgBroadcastQueue; 2734 mBroadcastQueues[1] = mBgBroadcastQueue; 2735 2736 mServices = new ActiveServices(this); 2737 mProviderMap = new ProviderMap(this); 2738 mAppErrors = new AppErrors(mUiContext, this); 2739 2740 // TODO: Move creation of battery stats service outside of activity manager service. 2741 File dataDir = Environment.getDataDirectory(); 2742 File systemDir = new File(dataDir, "system"); 2743 systemDir.mkdirs(); 2744 mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler); 2745 mBatteryStatsService.getActiveStatistics().readLocked(); 2746 mBatteryStatsService.scheduleWriteToDisk(); 2747 mOnBattery = DEBUG_POWER ? true 2748 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2749 mBatteryStatsService.getActiveStatistics().setCallback(this); 2750 2751 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2752 2753 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler); 2754 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null, 2755 new IAppOpsCallback.Stub() { 2756 @Override public void opChanged(int op, int uid, String packageName) { 2757 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) { 2758 if (mAppOpsService.checkOperation(op, uid, packageName) 2759 != AppOpsManager.MODE_ALLOWED) { 2760 runInBackgroundDisabled(uid); 2761 } 2762 } 2763 } 2764 }); 2765 2766 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2767 2768 mUserController = new UserController(this); 2769 2770 mVrController = new VrController(this); 2771 2772 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2773 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2774 2775 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) { 2776 mUseFifoUiScheduling = true; 2777 } 2778 2779 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); 2780 mTempConfig.setToDefaults(); 2781 mTempConfig.setLocales(LocaleList.getDefault()); 2782 mConfigurationSeq = mTempConfig.seq = 1; 2783 mStackSupervisor = createStackSupervisor(); 2784 mStackSupervisor.onConfigurationChanged(mTempConfig); 2785 mKeyguardController = mStackSupervisor.mKeyguardController; 2786 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2787 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2788 mTaskChangeNotificationController = 2789 new TaskChangeNotificationController(this, mStackSupervisor, mHandler); 2790 mActivityStarter = new ActivityStarter(this, mStackSupervisor); 2791 mRecentTasks = new RecentTasks(this, mStackSupervisor); 2792 2793 mProcessCpuThread = new Thread("CpuTracker") { 2794 @Override 2795 public void run() { 2796 synchronized (mProcessCpuTracker) { 2797 mProcessCpuInitLatch.countDown(); 2798 mProcessCpuTracker.init(); 2799 } 2800 while (true) { 2801 try { 2802 try { 2803 synchronized(this) { 2804 final long now = SystemClock.uptimeMillis(); 2805 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2806 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2807 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2808 // + ", write delay=" + nextWriteDelay); 2809 if (nextWriteDelay < nextCpuDelay) { 2810 nextCpuDelay = nextWriteDelay; 2811 } 2812 if (nextCpuDelay > 0) { 2813 mProcessCpuMutexFree.set(true); 2814 this.wait(nextCpuDelay); 2815 } 2816 } 2817 } catch (InterruptedException e) { 2818 } 2819 updateCpuStatsNow(); 2820 } catch (Exception e) { 2821 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2822 } 2823 } 2824 } 2825 }; 2826 2827 Watchdog.getInstance().addMonitor(this); 2828 Watchdog.getInstance().addThread(mHandler); 2829 } 2830 2831 protected ActivityStackSupervisor createStackSupervisor() { 2832 return new ActivityStackSupervisor(this, mHandler.getLooper()); 2833 } 2834 2835 public void setSystemServiceManager(SystemServiceManager mgr) { 2836 mSystemServiceManager = mgr; 2837 } 2838 2839 public void setInstaller(Installer installer) { 2840 mInstaller = installer; 2841 } 2842 2843 private void start() { 2844 removeAllProcessGroups(); 2845 mProcessCpuThread.start(); 2846 2847 mBatteryStatsService.publish(); 2848 mAppOpsService.publish(mContext); 2849 Slog.d("AppOps", "AppOpsService published"); 2850 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2851 // Wait for the synchronized block started in mProcessCpuThread, 2852 // so that any other acccess to mProcessCpuTracker from main thread 2853 // will be blocked during mProcessCpuTracker initialization. 2854 try { 2855 mProcessCpuInitLatch.await(); 2856 } catch (InterruptedException e) { 2857 Slog.wtf(TAG, "Interrupted wait during start", e); 2858 Thread.currentThread().interrupt(); 2859 throw new IllegalStateException("Interrupted wait during start"); 2860 } 2861 } 2862 2863 void onUserStoppedLocked(int userId) { 2864 mRecentTasks.unloadUserDataFromMemoryLocked(userId); 2865 } 2866 2867 public void initPowerManagement() { 2868 mStackSupervisor.initPowerManagement(); 2869 mBatteryStatsService.initPowerManagement(); 2870 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class); 2871 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); 2872 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*"); 2873 mVoiceWakeLock.setReferenceCounted(false); 2874 } 2875 2876 private ArraySet<String> getBackgroundLaunchBroadcasts() { 2877 if (mBackgroundLaunchBroadcasts == null) { 2878 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts(); 2879 } 2880 return mBackgroundLaunchBroadcasts; 2881 } 2882 2883 @Override 2884 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2885 throws RemoteException { 2886 if (code == SYSPROPS_TRANSACTION) { 2887 // We need to tell all apps about the system property change. 2888 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2889 synchronized(this) { 2890 final int NP = mProcessNames.getMap().size(); 2891 for (int ip=0; ip<NP; ip++) { 2892 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2893 final int NA = apps.size(); 2894 for (int ia=0; ia<NA; ia++) { 2895 ProcessRecord app = apps.valueAt(ia); 2896 if (app.thread != null) { 2897 procs.add(app.thread.asBinder()); 2898 } 2899 } 2900 } 2901 } 2902 2903 int N = procs.size(); 2904 for (int i=0; i<N; i++) { 2905 Parcel data2 = Parcel.obtain(); 2906 try { 2907 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 2908 Binder.FLAG_ONEWAY); 2909 } catch (RemoteException e) { 2910 } 2911 data2.recycle(); 2912 } 2913 } 2914 try { 2915 return super.onTransact(code, data, reply, flags); 2916 } catch (RuntimeException e) { 2917 // The activity manager only throws security exceptions, so let's 2918 // log all others. 2919 if (!(e instanceof SecurityException)) { 2920 Slog.wtf(TAG, "Activity Manager Crash." 2921 + " UID:" + Binder.getCallingUid() 2922 + " PID:" + Binder.getCallingPid() 2923 + " TRANS:" + code, e); 2924 } 2925 throw e; 2926 } 2927 } 2928 2929 void updateCpuStats() { 2930 final long now = SystemClock.uptimeMillis(); 2931 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2932 return; 2933 } 2934 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2935 synchronized (mProcessCpuThread) { 2936 mProcessCpuThread.notify(); 2937 } 2938 } 2939 } 2940 2941 void updateCpuStatsNow() { 2942 synchronized (mProcessCpuTracker) { 2943 mProcessCpuMutexFree.set(false); 2944 final long now = SystemClock.uptimeMillis(); 2945 boolean haveNewCpuStats = false; 2946 2947 if (MONITOR_CPU_USAGE && 2948 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2949 mLastCpuTime.set(now); 2950 mProcessCpuTracker.update(); 2951 if (mProcessCpuTracker.hasGoodLastStats()) { 2952 haveNewCpuStats = true; 2953 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2954 //Slog.i(TAG, "Total CPU usage: " 2955 // + mProcessCpu.getTotalCpuPercent() + "%"); 2956 2957 // Slog the cpu usage if the property is set. 2958 if ("true".equals(SystemProperties.get("events.cpu"))) { 2959 int user = mProcessCpuTracker.getLastUserTime(); 2960 int system = mProcessCpuTracker.getLastSystemTime(); 2961 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2962 int irq = mProcessCpuTracker.getLastIrqTime(); 2963 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2964 int idle = mProcessCpuTracker.getLastIdleTime(); 2965 2966 int total = user + system + iowait + irq + softIrq + idle; 2967 if (total == 0) total = 1; 2968 2969 EventLog.writeEvent(EventLogTags.CPU, 2970 ((user+system+iowait+irq+softIrq) * 100) / total, 2971 (user * 100) / total, 2972 (system * 100) / total, 2973 (iowait * 100) / total, 2974 (irq * 100) / total, 2975 (softIrq * 100) / total); 2976 } 2977 } 2978 } 2979 2980 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2981 synchronized(bstats) { 2982 synchronized(mPidsSelfLocked) { 2983 if (haveNewCpuStats) { 2984 if (bstats.startAddingCpuLocked()) { 2985 int totalUTime = 0; 2986 int totalSTime = 0; 2987 final int N = mProcessCpuTracker.countStats(); 2988 for (int i=0; i<N; i++) { 2989 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2990 if (!st.working) { 2991 continue; 2992 } 2993 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2994 totalUTime += st.rel_utime; 2995 totalSTime += st.rel_stime; 2996 if (pr != null) { 2997 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2998 if (ps == null || !ps.isActive()) { 2999 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 3000 pr.info.uid, pr.processName); 3001 } 3002 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 3003 pr.curCpuTime += st.rel_utime + st.rel_stime; 3004 if (pr.lastCpuTime == 0) { 3005 pr.lastCpuTime = pr.curCpuTime; 3006 } 3007 } else { 3008 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 3009 if (ps == null || !ps.isActive()) { 3010 st.batteryStats = ps = bstats.getProcessStatsLocked( 3011 bstats.mapUid(st.uid), st.name); 3012 } 3013 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 3014 } 3015 } 3016 final int userTime = mProcessCpuTracker.getLastUserTime(); 3017 final int systemTime = mProcessCpuTracker.getLastSystemTime(); 3018 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime(); 3019 final int irqTime = mProcessCpuTracker.getLastIrqTime(); 3020 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime(); 3021 final int idleTime = mProcessCpuTracker.getLastIdleTime(); 3022 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime, 3023 systemTime, iowaitTime, irqTime, softIrqTime, idleTime); 3024 } 3025 } 3026 } 3027 3028 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 3029 mLastWriteTime = now; 3030 mBatteryStatsService.scheduleWriteToDisk(); 3031 } 3032 } 3033 } 3034 } 3035 3036 @Override 3037 public void batteryNeedsCpuUpdate() { 3038 updateCpuStatsNow(); 3039 } 3040 3041 @Override 3042 public void batteryPowerChanged(boolean onBattery) { 3043 // When plugging in, update the CPU stats first before changing 3044 // the plug state. 3045 updateCpuStatsNow(); 3046 synchronized (this) { 3047 synchronized(mPidsSelfLocked) { 3048 mOnBattery = DEBUG_POWER ? true : onBattery; 3049 } 3050 } 3051 } 3052 3053 @Override 3054 public void batterySendBroadcast(Intent intent) { 3055 synchronized (this) { 3056 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 3057 AppOpsManager.OP_NONE, null, false, false, 3058 -1, SYSTEM_UID, UserHandle.USER_ALL); 3059 } 3060 } 3061 3062 /** 3063 * Initialize the application bind args. These are passed to each 3064 * process when the bindApplication() IPC is sent to the process. They're 3065 * lazily setup to make sure the services are running when they're asked for. 3066 */ 3067 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 3068 // Isolated processes won't get this optimization, so that we don't 3069 // violate the rules about which services they have access to. 3070 if (isolated) { 3071 if (mIsolatedAppBindArgs == null) { 3072 mIsolatedAppBindArgs = new HashMap<>(); 3073 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package")); 3074 } 3075 return mIsolatedAppBindArgs; 3076 } 3077 3078 if (mAppBindArgs == null) { 3079 mAppBindArgs = new HashMap<>(); 3080 3081 // Setup the application init args 3082 mAppBindArgs.put("package", ServiceManager.getService("package")); 3083 mAppBindArgs.put("window", ServiceManager.getService("window")); 3084 mAppBindArgs.put(Context.ALARM_SERVICE, 3085 ServiceManager.getService(Context.ALARM_SERVICE)); 3086 } 3087 return mAppBindArgs; 3088 } 3089 3090 /** 3091 * Update AMS states when an activity is resumed. This should only be called by 3092 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed. 3093 */ 3094 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) { 3095 final TaskRecord task = r.getTask(); 3096 if (task.isApplicationTask()) { 3097 if (mCurAppTimeTracker != r.appTimeTracker) { 3098 // We are switching app tracking. Complete the current one. 3099 if (mCurAppTimeTracker != null) { 3100 mCurAppTimeTracker.stop(); 3101 mHandler.obtainMessage( 3102 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget(); 3103 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker); 3104 mCurAppTimeTracker = null; 3105 } 3106 if (r.appTimeTracker != null) { 3107 mCurAppTimeTracker = r.appTimeTracker; 3108 startTimeTrackingFocusedActivityLocked(); 3109 } 3110 } else { 3111 startTimeTrackingFocusedActivityLocked(); 3112 } 3113 } else { 3114 r.appTimeTracker = null; 3115 } 3116 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null 3117 // TODO: Probably not, because we don't want to resume voice on switching 3118 // back to this activity 3119 if (task.voiceInteractor != null) { 3120 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid); 3121 } else { 3122 finishRunningVoiceLocked(); 3123 3124 if (mLastResumedActivity != null) { 3125 final IVoiceInteractionSession session; 3126 3127 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask(); 3128 if (lastResumedActivityTask != null 3129 && lastResumedActivityTask.voiceSession != null) { 3130 session = lastResumedActivityTask.voiceSession; 3131 } else { 3132 session = mLastResumedActivity.voiceSession; 3133 } 3134 3135 if (session != null) { 3136 // We had been in a voice interaction session, but now focused has 3137 // move to something different. Just finish the session, we can't 3138 // return to it and retain the proper state and synchronization with 3139 // the voice interaction service. 3140 finishVoiceTask(session); 3141 } 3142 } 3143 } 3144 3145 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) { 3146 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG); 3147 mHandler.obtainMessage( 3148 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget(); 3149 } 3150 mLastResumedActivity = r; 3151 3152 mWindowManager.setFocusedApp(r.appToken, true); 3153 3154 applyUpdateLockStateLocked(r); 3155 applyUpdateVrModeLocked(r); 3156 3157 EventLogTags.writeAmSetResumedActivity( 3158 r == null ? -1 : r.userId, 3159 r == null ? "NULL" : r.shortComponentName, 3160 reason); 3161 } 3162 3163 @Override 3164 public void setFocusedStack(int stackId) { 3165 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()"); 3166 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId); 3167 final long callingId = Binder.clearCallingIdentity(); 3168 try { 3169 synchronized (this) { 3170 final ActivityStack stack = mStackSupervisor.getStack(stackId); 3171 if (stack == null) { 3172 return; 3173 } 3174 final ActivityRecord r = stack.topRunningActivityLocked(); 3175 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) { 3176 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 3177 } 3178 } 3179 } finally { 3180 Binder.restoreCallingIdentity(callingId); 3181 } 3182 } 3183 3184 @Override 3185 public void setFocusedTask(int taskId) { 3186 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()"); 3187 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId); 3188 final long callingId = Binder.clearCallingIdentity(); 3189 try { 3190 synchronized (this) { 3191 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 3192 if (task == null) { 3193 return; 3194 } 3195 final ActivityRecord r = task.topRunningActivityLocked(); 3196 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) { 3197 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 3198 } 3199 } 3200 } finally { 3201 Binder.restoreCallingIdentity(callingId); 3202 } 3203 } 3204 3205 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 3206 @Override 3207 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 3208 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()"); 3209 mTaskChangeNotificationController.registerTaskStackListener(listener); 3210 } 3211 3212 /** 3213 * Unregister a task stack listener so that it stops receiving callbacks. 3214 */ 3215 @Override 3216 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException { 3217 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()"); 3218 mTaskChangeNotificationController.unregisterTaskStackListener(listener); 3219 } 3220 3221 @Override 3222 public void notifyActivityDrawn(IBinder token) { 3223 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token); 3224 synchronized (this) { 3225 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token); 3226 if (r != null) { 3227 r.getStack().notifyActivityDrawnLocked(r); 3228 } 3229 } 3230 } 3231 3232 final void applyUpdateLockStateLocked(ActivityRecord r) { 3233 // Modifications to the UpdateLock state are done on our handler, outside 3234 // the activity manager's locks. The new state is determined based on the 3235 // state *now* of the relevant activity record. The object is passed to 3236 // the handler solely for logging detail, not to be consulted/modified. 3237 final boolean nextState = r != null && r.immersive; 3238 mHandler.sendMessage( 3239 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 3240 } 3241 3242 final void applyUpdateVrModeLocked(ActivityRecord r) { 3243 // VR apps are expected to run in a main display. If an app is turning on VR for 3244 // itself, but lives in a dynamic stack, then make sure that it is moved to the main 3245 // fullscreen stack before enabling VR Mode. 3246 // TODO: The goal of this code is to keep the VR app on the main display. When the 3247 // stack implementation changes in the future, keep in mind that the use of the fullscreen 3248 // stack is a means to move the activity to the main display and a moveActivityToDisplay() 3249 // option would be a better choice here. 3250 if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) { 3251 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId() 3252 + " to main stack for VR"); 3253 moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */); 3254 } 3255 mHandler.sendMessage( 3256 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r)); 3257 } 3258 3259 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) { 3260 mHandler.sendMessage( 3261 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0)); 3262 } 3263 3264 private void notifyVrManagerOfSleepState(boolean isSleeping) { 3265 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 3266 if (vrService == null) { 3267 return; 3268 } 3269 vrService.onSleepStateChanged(isSleeping); 3270 } 3271 3272 final void showAskCompatModeDialogLocked(ActivityRecord r) { 3273 Message msg = Message.obtain(); 3274 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG; 3275 msg.obj = r.getTask().askedCompatMode ? null : r; 3276 mUiHandler.sendMessage(msg); 3277 } 3278 3279 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) { 3280 final Configuration globalConfig = getGlobalConfiguration(); 3281 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE 3282 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) { 3283 final Message msg = Message.obtain(); 3284 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG; 3285 msg.obj = r; 3286 mUiHandler.sendMessage(msg); 3287 } 3288 } 3289 3290 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 3291 String what, Object obj, ProcessRecord srcApp) { 3292 app.lastActivityTime = now; 3293 3294 if (app.activities.size() > 0) { 3295 // Don't want to touch dependent processes that are hosting activities. 3296 return index; 3297 } 3298 3299 int lrui = mLruProcesses.lastIndexOf(app); 3300 if (lrui < 0) { 3301 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 3302 + what + " " + obj + " from " + srcApp); 3303 return index; 3304 } 3305 3306 if (lrui >= index) { 3307 // Don't want to cause this to move dependent processes *back* in the 3308 // list as if they were less frequently used. 3309 return index; 3310 } 3311 3312 if (lrui >= mLruProcessActivityStart) { 3313 // Don't want to touch dependent processes that are hosting activities. 3314 return index; 3315 } 3316 3317 mLruProcesses.remove(lrui); 3318 if (index > 0) { 3319 index--; 3320 } 3321 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index 3322 + " in LRU list: " + app); 3323 mLruProcesses.add(index, app); 3324 return index; 3325 } 3326 3327 static void killProcessGroup(int uid, int pid) { 3328 if (sKillHandler != null) { 3329 sKillHandler.sendMessage( 3330 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid)); 3331 } else { 3332 Slog.w(TAG, "Asked to kill process group before system bringup!"); 3333 Process.killProcessGroup(uid, pid); 3334 } 3335 } 3336 3337 final void removeLruProcessLocked(ProcessRecord app) { 3338 int lrui = mLruProcesses.lastIndexOf(app); 3339 if (lrui >= 0) { 3340 if (!app.killed) { 3341 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 3342 killProcessQuiet(app.pid); 3343 killProcessGroup(app.uid, app.pid); 3344 } 3345 if (lrui <= mLruProcessActivityStart) { 3346 mLruProcessActivityStart--; 3347 } 3348 if (lrui <= mLruProcessServiceStart) { 3349 mLruProcessServiceStart--; 3350 } 3351 mLruProcesses.remove(lrui); 3352 } 3353 } 3354 3355 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 3356 ProcessRecord client) { 3357 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 3358 || app.treatLikeActivity; 3359 final boolean hasService = false; // not impl yet. app.services.size() > 0; 3360 if (!activityChange && hasActivity) { 3361 // The process has activities, so we are only allowing activity-based adjustments 3362 // to move it. It should be kept in the front of the list with other 3363 // processes that have activities, and we don't want those to change their 3364 // order except due to activity operations. 3365 return; 3366 } 3367 3368 mLruSeq++; 3369 final long now = SystemClock.uptimeMillis(); 3370 app.lastActivityTime = now; 3371 3372 // First a quick reject: if the app is already at the position we will 3373 // put it, then there is nothing to do. 3374 if (hasActivity) { 3375 final int N = mLruProcesses.size(); 3376 if (N > 0 && mLruProcesses.get(N-1) == app) { 3377 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app); 3378 return; 3379 } 3380 } else { 3381 if (mLruProcessServiceStart > 0 3382 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 3383 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app); 3384 return; 3385 } 3386 } 3387 3388 int lrui = mLruProcesses.lastIndexOf(app); 3389 3390 if (app.persistent && lrui >= 0) { 3391 // We don't care about the position of persistent processes, as long as 3392 // they are in the list. 3393 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app); 3394 return; 3395 } 3396 3397 /* In progress: compute new position first, so we can avoid doing work 3398 if the process is not actually going to move. Not yet working. 3399 int addIndex; 3400 int nextIndex; 3401 boolean inActivity = false, inService = false; 3402 if (hasActivity) { 3403 // Process has activities, put it at the very tipsy-top. 3404 addIndex = mLruProcesses.size(); 3405 nextIndex = mLruProcessServiceStart; 3406 inActivity = true; 3407 } else if (hasService) { 3408 // Process has services, put it at the top of the service list. 3409 addIndex = mLruProcessActivityStart; 3410 nextIndex = mLruProcessServiceStart; 3411 inActivity = true; 3412 inService = true; 3413 } else { 3414 // Process not otherwise of interest, it goes to the top of the non-service area. 3415 addIndex = mLruProcessServiceStart; 3416 if (client != null) { 3417 int clientIndex = mLruProcesses.lastIndexOf(client); 3418 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 3419 + app); 3420 if (clientIndex >= 0 && addIndex > clientIndex) { 3421 addIndex = clientIndex; 3422 } 3423 } 3424 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 3425 } 3426 3427 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 3428 + mLruProcessActivityStart + "): " + app); 3429 */ 3430 3431 if (lrui >= 0) { 3432 if (lrui < mLruProcessActivityStart) { 3433 mLruProcessActivityStart--; 3434 } 3435 if (lrui < mLruProcessServiceStart) { 3436 mLruProcessServiceStart--; 3437 } 3438 /* 3439 if (addIndex > lrui) { 3440 addIndex--; 3441 } 3442 if (nextIndex > lrui) { 3443 nextIndex--; 3444 } 3445 */ 3446 mLruProcesses.remove(lrui); 3447 } 3448 3449 /* 3450 mLruProcesses.add(addIndex, app); 3451 if (inActivity) { 3452 mLruProcessActivityStart++; 3453 } 3454 if (inService) { 3455 mLruProcessActivityStart++; 3456 } 3457 */ 3458 3459 int nextIndex; 3460 if (hasActivity) { 3461 final int N = mLruProcesses.size(); 3462 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) { 3463 // Process doesn't have activities, but has clients with 3464 // activities... move it up, but one below the top (the top 3465 // should always have a real activity). 3466 if (DEBUG_LRU) Slog.d(TAG_LRU, 3467 "Adding to second-top of LRU activity list: " + app); 3468 mLruProcesses.add(N - 1, app); 3469 // To keep it from spamming the LRU list (by making a bunch of clients), 3470 // we will push down any other entries owned by the app. 3471 final int uid = app.info.uid; 3472 for (int i = N - 2; i > mLruProcessActivityStart; i--) { 3473 ProcessRecord subProc = mLruProcesses.get(i); 3474 if (subProc.info.uid == uid) { 3475 // We want to push this one down the list. If the process after 3476 // it is for the same uid, however, don't do so, because we don't 3477 // want them internally to be re-ordered. 3478 if (mLruProcesses.get(i - 1).info.uid != uid) { 3479 if (DEBUG_LRU) Slog.d(TAG_LRU, 3480 "Pushing uid " + uid + " swapping at " + i + ": " 3481 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1)); 3482 ProcessRecord tmp = mLruProcesses.get(i); 3483 mLruProcesses.set(i, mLruProcesses.get(i - 1)); 3484 mLruProcesses.set(i - 1, tmp); 3485 i--; 3486 } 3487 } else { 3488 // A gap, we can stop here. 3489 break; 3490 } 3491 } 3492 } else { 3493 // Process has activities, put it at the very tipsy-top. 3494 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app); 3495 mLruProcesses.add(app); 3496 } 3497 nextIndex = mLruProcessServiceStart; 3498 } else if (hasService) { 3499 // Process has services, put it at the top of the service list. 3500 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app); 3501 mLruProcesses.add(mLruProcessActivityStart, app); 3502 nextIndex = mLruProcessServiceStart; 3503 mLruProcessActivityStart++; 3504 } else { 3505 // Process not otherwise of interest, it goes to the top of the non-service area. 3506 int index = mLruProcessServiceStart; 3507 if (client != null) { 3508 // If there is a client, don't allow the process to be moved up higher 3509 // in the list than that client. 3510 int clientIndex = mLruProcesses.lastIndexOf(client); 3511 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client 3512 + " when updating " + app); 3513 if (clientIndex <= lrui) { 3514 // Don't allow the client index restriction to push it down farther in the 3515 // list than it already is. 3516 clientIndex = lrui; 3517 } 3518 if (clientIndex >= 0 && index > clientIndex) { 3519 index = clientIndex; 3520 } 3521 } 3522 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app); 3523 mLruProcesses.add(index, app); 3524 nextIndex = index-1; 3525 mLruProcessActivityStart++; 3526 mLruProcessServiceStart++; 3527 } 3528 3529 // If the app is currently using a content provider or service, 3530 // bump those processes as well. 3531 for (int j=app.connections.size()-1; j>=0; j--) { 3532 ConnectionRecord cr = app.connections.valueAt(j); 3533 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 3534 && cr.binding.service.app != null 3535 && cr.binding.service.app.lruSeq != mLruSeq 3536 && !cr.binding.service.app.persistent) { 3537 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 3538 "service connection", cr, app); 3539 } 3540 } 3541 for (int j=app.conProviders.size()-1; j>=0; j--) { 3542 ContentProviderRecord cpr = app.conProviders.get(j).provider; 3543 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 3544 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 3545 "provider reference", cpr, app); 3546 } 3547 } 3548 } 3549 3550 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 3551 if (uid == SYSTEM_UID) { 3552 // The system gets to run in any process. If there are multiple 3553 // processes with the same uid, just pick the first (this 3554 // should never happen). 3555 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 3556 if (procs == null) return null; 3557 final int procCount = procs.size(); 3558 for (int i = 0; i < procCount; i++) { 3559 final int procUid = procs.keyAt(i); 3560 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) { 3561 // Don't use an app process or different user process for system component. 3562 continue; 3563 } 3564 return procs.valueAt(i); 3565 } 3566 } 3567 ProcessRecord proc = mProcessNames.get(processName, uid); 3568 if (false && proc != null && !keepIfLarge 3569 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 3570 && proc.lastCachedPss >= 4000) { 3571 // Turn this condition on to cause killing to happen regularly, for testing. 3572 if (proc.baseProcessTracker != null) { 3573 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 3574 } 3575 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 3576 } else if (proc != null && !keepIfLarge 3577 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 3578 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 3579 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 3580 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 3581 if (proc.baseProcessTracker != null) { 3582 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 3583 } 3584 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 3585 } 3586 } 3587 return proc; 3588 } 3589 3590 void notifyPackageUse(String packageName, int reason) { 3591 synchronized(this) { 3592 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason); 3593 } 3594 } 3595 3596 boolean isNextTransitionForward() { 3597 int transit = mWindowManager.getPendingAppTransition(); 3598 return transit == TRANSIT_ACTIVITY_OPEN 3599 || transit == TRANSIT_TASK_OPEN 3600 || transit == TRANSIT_TASK_TO_FRONT; 3601 } 3602 3603 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 3604 String processName, String abiOverride, int uid, Runnable crashHandler) { 3605 synchronized(this) { 3606 ApplicationInfo info = new ApplicationInfo(); 3607 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 3608 // For isolated processes, the former contains the parent's uid and the latter the 3609 // actual uid of the isolated process. 3610 // In the special case introduced by this method (which is, starting an isolated 3611 // process directly from the SystemServer without an actual parent app process) the 3612 // closest thing to a parent's uid is SYSTEM_UID. 3613 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 3614 // the |isolated| logic in the ProcessRecord constructor. 3615 info.uid = SYSTEM_UID; 3616 info.processName = processName; 3617 info.className = entryPoint; 3618 info.packageName = "android"; 3619 info.seInfoUser = SELinuxUtil.COMPLETE_STR; 3620 ProcessRecord proc = startProcessLocked(processName, info /* info */, 3621 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 3622 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 3623 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 3624 crashHandler); 3625 return proc != null ? proc.pid : 0; 3626 } 3627 } 3628 3629 final ProcessRecord startProcessLocked(String processName, 3630 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 3631 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 3632 boolean isolated, boolean keepIfLarge) { 3633 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 3634 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 3635 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 3636 null /* crashHandler */); 3637 } 3638 3639 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 3640 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 3641 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 3642 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 3643 long startTime = SystemClock.elapsedRealtime(); 3644 ProcessRecord app; 3645 if (!isolated) { 3646 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 3647 checkTime(startTime, "startProcess: after getProcessRecord"); 3648 3649 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) { 3650 // If we are in the background, then check to see if this process 3651 // is bad. If so, we will just silently fail. 3652 if (mAppErrors.isBadProcessLocked(info)) { 3653 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 3654 + "/" + info.processName); 3655 return null; 3656 } 3657 } else { 3658 // When the user is explicitly starting a process, then clear its 3659 // crash count so that we won't make it bad until they see at 3660 // least one crash dialog again, and make the process good again 3661 // if it had been bad. 3662 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 3663 + "/" + info.processName); 3664 mAppErrors.resetProcessCrashTimeLocked(info); 3665 if (mAppErrors.isBadProcessLocked(info)) { 3666 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 3667 UserHandle.getUserId(info.uid), info.uid, 3668 info.processName); 3669 mAppErrors.clearBadProcessLocked(info); 3670 if (app != null) { 3671 app.bad = false; 3672 } 3673 } 3674 } 3675 } else { 3676 // If this is an isolated process, it can't re-use an existing process. 3677 app = null; 3678 } 3679 3680 // We don't have to do anything more if: 3681 // (1) There is an existing application record; and 3682 // (2) The caller doesn't think it is dead, OR there is no thread 3683 // object attached to it so we know it couldn't have crashed; and 3684 // (3) There is a pid assigned to it, so it is either starting or 3685 // already running. 3686 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName 3687 + " app=" + app + " knownToBeDead=" + knownToBeDead 3688 + " thread=" + (app != null ? app.thread : null) 3689 + " pid=" + (app != null ? app.pid : -1)); 3690 if (app != null && app.pid > 0) { 3691 if ((!knownToBeDead && !app.killed) || app.thread == null) { 3692 // We already have the app running, or are waiting for it to 3693 // come up (we have a pid but not yet its thread), so keep it. 3694 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app); 3695 // If this is a new package in the process, add the package to the list 3696 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3697 checkTime(startTime, "startProcess: done, added package to proc"); 3698 return app; 3699 } 3700 3701 // An application record is attached to a previous process, 3702 // clean it up now. 3703 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app); 3704 checkTime(startTime, "startProcess: bad proc running, killing"); 3705 killProcessGroup(app.uid, app.pid); 3706 handleAppDiedLocked(app, true, true); 3707 checkTime(startTime, "startProcess: done killing old proc"); 3708 } 3709 3710 String hostingNameStr = hostingName != null 3711 ? hostingName.flattenToShortString() : null; 3712 3713 if (app == null) { 3714 checkTime(startTime, "startProcess: creating new process record"); 3715 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3716 if (app == null) { 3717 Slog.w(TAG, "Failed making new process record for " 3718 + processName + "/" + info.uid + " isolated=" + isolated); 3719 return null; 3720 } 3721 app.crashHandler = crashHandler; 3722 checkTime(startTime, "startProcess: done creating new process record"); 3723 } else { 3724 // If this is a new package in the process, add the package to the list 3725 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3726 checkTime(startTime, "startProcess: added package to existing proc"); 3727 } 3728 3729 // If the system is not ready yet, then hold off on starting this 3730 // process until it is. 3731 if (!mProcessesReady 3732 && !isAllowedWhileBooting(info) 3733 && !allowWhileBooting) { 3734 if (!mProcessesOnHold.contains(app)) { 3735 mProcessesOnHold.add(app); 3736 } 3737 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, 3738 "System not ready, putting on hold: " + app); 3739 checkTime(startTime, "startProcess: returning with proc on hold"); 3740 return app; 3741 } 3742 3743 checkTime(startTime, "startProcess: stepping in to startProcess"); 3744 startProcessLocked( 3745 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3746 checkTime(startTime, "startProcess: done starting proc!"); 3747 return (app.pid != 0) ? app : null; 3748 } 3749 3750 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3751 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3752 } 3753 3754 private final void startProcessLocked(ProcessRecord app, 3755 String hostingType, String hostingNameStr) { 3756 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3757 null /* entryPoint */, null /* entryPointArgs */); 3758 } 3759 3760 private final void startProcessLocked(ProcessRecord app, String hostingType, 3761 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3762 long startTime = SystemClock.elapsedRealtime(); 3763 if (app.pid > 0 && app.pid != MY_PID) { 3764 checkTime(startTime, "startProcess: removing from pids map"); 3765 synchronized (mPidsSelfLocked) { 3766 mPidsSelfLocked.remove(app.pid); 3767 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3768 } 3769 checkTime(startTime, "startProcess: done removing from pids map"); 3770 app.setPid(0); 3771 } 3772 3773 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES, 3774 "startProcessLocked removing on hold: " + app); 3775 mProcessesOnHold.remove(app); 3776 3777 checkTime(startTime, "startProcess: starting to update cpu stats"); 3778 updateCpuStats(); 3779 checkTime(startTime, "startProcess: done updating cpu stats"); 3780 3781 try { 3782 try { 3783 final int userId = UserHandle.getUserId(app.uid); 3784 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId); 3785 } catch (RemoteException e) { 3786 throw e.rethrowAsRuntimeException(); 3787 } 3788 3789 int uid = app.uid; 3790 int[] gids = null; 3791 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3792 if (!app.isolated) { 3793 int[] permGids = null; 3794 try { 3795 checkTime(startTime, "startProcess: getting gids from package manager"); 3796 final IPackageManager pm = AppGlobals.getPackageManager(); 3797 permGids = pm.getPackageGids(app.info.packageName, 3798 MATCH_DEBUG_TRIAGED_MISSING, app.userId); 3799 StorageManagerInternal storageManagerInternal = LocalServices.getService( 3800 StorageManagerInternal.class); 3801 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid, 3802 app.info.packageName); 3803 } catch (RemoteException e) { 3804 throw e.rethrowAsRuntimeException(); 3805 } 3806 3807 /* 3808 * Add shared application and profile GIDs so applications can share some 3809 * resources like shared libraries and access user-wide resources 3810 */ 3811 if (ArrayUtils.isEmpty(permGids)) { 3812 gids = new int[3]; 3813 } else { 3814 gids = new int[permGids.length + 3]; 3815 System.arraycopy(permGids, 0, gids, 3, permGids.length); 3816 } 3817 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3818 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid)); 3819 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3820 } 3821 checkTime(startTime, "startProcess: building args"); 3822 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3823 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3824 && mTopComponent != null 3825 && app.processName.equals(mTopComponent.getPackageName())) { 3826 uid = 0; 3827 } 3828 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3829 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3830 uid = 0; 3831 } 3832 } 3833 int runtimeFlags = 0; 3834 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3835 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP; 3836 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE; 3837 // Also turn on CheckJNI for debuggable apps. It's quite 3838 // awkward to turn on otherwise. 3839 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3840 } 3841 // Run the app in safe mode if its manifest requests so or the 3842 // system is booted in safe mode. 3843 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3844 mSafeMode == true) { 3845 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3846 } 3847 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3848 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3849 } 3850 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info"); 3851 if ("true".equals(genDebugInfoProperty)) { 3852 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; 3853 } 3854 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3855 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3856 } 3857 if ("1".equals(SystemProperties.get("debug.assert"))) { 3858 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3859 } 3860 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) { 3861 // Enable all debug flags required by the native debugger. 3862 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything 3863 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info 3864 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations 3865 mNativeDebuggingApp = null; 3866 } 3867 3868 if (app.info.isPrivilegedApp() && 3869 !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) { 3870 runtimeFlags |= Zygote.DISABLE_VERIFIER; 3871 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; 3872 } 3873 3874 String invokeWith = null; 3875 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3876 // Debuggable apps may include a wrapper script with their library directory. 3877 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh"; 3878 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3879 try { 3880 if (new File(wrapperFileName).exists()) { 3881 invokeWith = "/system/bin/logwrapper " + wrapperFileName; 3882 } 3883 } finally { 3884 StrictMode.setThreadPolicy(oldPolicy); 3885 } 3886 } 3887 3888 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3889 if (requiredAbi == null) { 3890 requiredAbi = Build.SUPPORTED_ABIS[0]; 3891 } 3892 3893 String instructionSet = null; 3894 if (app.info.primaryCpuAbi != null) { 3895 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3896 } 3897 3898 app.gids = gids; 3899 app.requiredAbi = requiredAbi; 3900 app.instructionSet = instructionSet; 3901 3902 // the per-user SELinux context must be set 3903 if (TextUtils.isEmpty(app.info.seInfoUser)) { 3904 Slog.wtf(TAG, "SELinux tag not defined", 3905 new IllegalStateException("SELinux tag not defined for " 3906 + app.info.packageName + " (uid " + app.uid + ")")); 3907 } 3908 final String seInfo = app.info.seInfo 3909 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser); 3910 // Start the process. It will either succeed and return a result containing 3911 // the PID of the new process, or else throw a RuntimeException. 3912 boolean isActivityProcess = (entryPoint == null); 3913 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3914 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + 3915 app.processName); 3916 checkTime(startTime, "startProcess: asking zygote to start proc"); 3917 ProcessStartResult startResult; 3918 if (hostingType.equals("webview_service")) { 3919 startResult = startWebView(entryPoint, 3920 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 3921 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 3922 app.info.dataDir, null, entryPointArgs); 3923 } else { 3924 startResult = Process.start(entryPoint, 3925 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 3926 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 3927 app.info.dataDir, invokeWith, entryPointArgs); 3928 } 3929 checkTime(startTime, "startProcess: returned from zygote!"); 3930 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 3931 3932 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3933 checkTime(startTime, "startProcess: done updating battery stats"); 3934 3935 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3936 UserHandle.getUserId(uid), startResult.pid, uid, 3937 app.processName, hostingType, 3938 hostingNameStr != null ? hostingNameStr : ""); 3939 3940 try { 3941 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid, 3942 seInfo, app.info.sourceDir, startResult.pid); 3943 } catch (RemoteException ex) { 3944 // Ignore 3945 } 3946 3947 if (app.persistent) { 3948 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3949 } 3950 3951 checkTime(startTime, "startProcess: building log message"); 3952 StringBuilder buf = mStringBuilder; 3953 buf.setLength(0); 3954 buf.append("Start proc "); 3955 buf.append(startResult.pid); 3956 buf.append(':'); 3957 buf.append(app.processName); 3958 buf.append('/'); 3959 UserHandle.formatUid(buf, uid); 3960 if (!isActivityProcess) { 3961 buf.append(" ["); 3962 buf.append(entryPoint); 3963 buf.append("]"); 3964 } 3965 buf.append(" for "); 3966 buf.append(hostingType); 3967 if (hostingNameStr != null) { 3968 buf.append(" "); 3969 buf.append(hostingNameStr); 3970 } 3971 Slog.i(TAG, buf.toString()); 3972 app.setPid(startResult.pid); 3973 app.usingWrapper = startResult.usingWrapper; 3974 app.removed = false; 3975 app.killed = false; 3976 app.killedByAm = false; 3977 checkTime(startTime, "startProcess: starting to update pids map"); 3978 ProcessRecord oldApp; 3979 synchronized (mPidsSelfLocked) { 3980 oldApp = mPidsSelfLocked.get(startResult.pid); 3981 } 3982 // If there is already an app occupying that pid that hasn't been cleaned up 3983 if (oldApp != null && !app.isolated) { 3984 // Clean up anything relating to this pid first 3985 Slog.w(TAG, "Reusing pid " + startResult.pid 3986 + " while app is still mapped to it"); 3987 cleanUpApplicationRecordLocked(oldApp, false, false, -1, 3988 true /*replacingPid*/); 3989 } 3990 synchronized (mPidsSelfLocked) { 3991 this.mPidsSelfLocked.put(startResult.pid, app); 3992 if (isActivityProcess) { 3993 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3994 msg.obj = app; 3995 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3996 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3997 } 3998 } 3999 checkTime(startTime, "startProcess: done updating pids map"); 4000 } catch (RuntimeException e) { 4001 Slog.e(TAG, "Failure starting process " + app.processName, e); 4002 4003 // Something went very wrong while trying to start this process; one 4004 // common case is when the package is frozen due to an active 4005 // upgrade. To recover, clean up any active bookkeeping related to 4006 // starting this process. (We already invoked this method once when 4007 // the package was initially frozen through KILL_APPLICATION_MSG, so 4008 // it doesn't hurt to use it again.) 4009 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false, 4010 false, true, false, false, UserHandle.getUserId(app.userId), "start failure"); 4011 } 4012 } 4013 4014 void updateUsageStats(ActivityRecord component, boolean resumed) { 4015 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, 4016 "updateUsageStats: comp=" + component + "res=" + resumed); 4017 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4018 if (resumed) { 4019 if (mUsageStatsService != null) { 4020 mUsageStatsService.reportEvent(component.realActivity, component.userId, 4021 UsageEvents.Event.MOVE_TO_FOREGROUND); 4022 } 4023 synchronized (stats) { 4024 stats.noteActivityResumedLocked(component.app.uid); 4025 } 4026 } else { 4027 if (mUsageStatsService != null) { 4028 mUsageStatsService.reportEvent(component.realActivity, component.userId, 4029 UsageEvents.Event.MOVE_TO_BACKGROUND); 4030 } 4031 synchronized (stats) { 4032 stats.noteActivityPausedLocked(component.app.uid); 4033 } 4034 } 4035 } 4036 4037 Intent getHomeIntent() { 4038 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 4039 intent.setComponent(mTopComponent); 4040 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); 4041 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 4042 intent.addCategory(Intent.CATEGORY_HOME); 4043 } 4044 return intent; 4045 } 4046 4047 boolean startHomeActivityLocked(int userId, String reason) { 4048 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 4049 && mTopAction == null) { 4050 // We are running in factory test mode, but unable to find 4051 // the factory test app, so just sit around displaying the 4052 // error message and don't try to start anything. 4053 return false; 4054 } 4055 Intent intent = getHomeIntent(); 4056 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 4057 if (aInfo != null) { 4058 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name)); 4059 // Don't do this if the home app is currently being 4060 // instrumented. 4061 aInfo = new ActivityInfo(aInfo); 4062 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 4063 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 4064 aInfo.applicationInfo.uid, true); 4065 if (app == null || app.instr == null) { 4066 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 4067 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid); 4068 // For ANR debugging to verify if the user activity is the one that actually 4069 // launched. 4070 final String myReason = reason + ":" + userId + ":" + resolvedUserId; 4071 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason); 4072 } 4073 } else { 4074 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable()); 4075 } 4076 4077 return true; 4078 } 4079 4080 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 4081 ActivityInfo ai = null; 4082 ComponentName comp = intent.getComponent(); 4083 try { 4084 if (comp != null) { 4085 // Factory test. 4086 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 4087 } else { 4088 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 4089 intent, 4090 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 4091 flags, userId); 4092 4093 if (info != null) { 4094 ai = info.activityInfo; 4095 } 4096 } 4097 } catch (RemoteException e) { 4098 // ignore 4099 } 4100 4101 return ai; 4102 } 4103 4104 /** 4105 * Starts the "new version setup screen" if appropriate. 4106 */ 4107 void startSetupActivityLocked() { 4108 // Only do this once per boot. 4109 if (mCheckedForSetup) { 4110 return; 4111 } 4112 4113 // We will show this screen if the current one is a different 4114 // version than the last one shown, and we are not running in 4115 // low-level factory test mode. 4116 final ContentResolver resolver = mContext.getContentResolver(); 4117 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 4118 Settings.Global.getInt(resolver, 4119 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 4120 mCheckedForSetup = true; 4121 4122 // See if we should be showing the platform update setup UI. 4123 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 4124 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent, 4125 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA); 4126 if (!ris.isEmpty()) { 4127 final ResolveInfo ri = ris.get(0); 4128 String vers = ri.activityInfo.metaData != null 4129 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 4130 : null; 4131 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 4132 vers = ri.activityInfo.applicationInfo.metaData.getString( 4133 Intent.METADATA_SETUP_VERSION); 4134 } 4135 String lastVers = Settings.Secure.getString( 4136 resolver, Settings.Secure.LAST_SETUP_SHOWN); 4137 if (vers != null && !vers.equals(lastVers)) { 4138 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 4139 intent.setComponent(new ComponentName( 4140 ri.activityInfo.packageName, ri.activityInfo.name)); 4141 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/, 4142 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0, 4143 null, 0, 0, 0, null, false, false, null, null, "startSetupActivity"); 4144 } 4145 } 4146 } 4147 } 4148 4149 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 4150 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 4151 } 4152 4153 void enforceNotIsolatedCaller(String caller) { 4154 if (UserHandle.isIsolated(Binder.getCallingUid())) { 4155 throw new SecurityException("Isolated process not allowed to call " + caller); 4156 } 4157 } 4158 4159 void enforceShellRestriction(String restriction, int userHandle) { 4160 if (Binder.getCallingUid() == SHELL_UID) { 4161 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) { 4162 throw new SecurityException("Shell does not have permission to access user " 4163 + userHandle); 4164 } 4165 } 4166 } 4167 4168 @Override 4169 public int getFrontActivityScreenCompatMode() { 4170 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 4171 synchronized (this) { 4172 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 4173 } 4174 } 4175 4176 @Override 4177 public void setFrontActivityScreenCompatMode(int mode) { 4178 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 4179 "setFrontActivityScreenCompatMode"); 4180 synchronized (this) { 4181 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 4182 } 4183 } 4184 4185 @Override 4186 public int getPackageScreenCompatMode(String packageName) { 4187 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 4188 synchronized (this) { 4189 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 4190 } 4191 } 4192 4193 @Override 4194 public void setPackageScreenCompatMode(String packageName, int mode) { 4195 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 4196 "setPackageScreenCompatMode"); 4197 synchronized (this) { 4198 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 4199 } 4200 } 4201 4202 @Override 4203 public boolean getPackageAskScreenCompat(String packageName) { 4204 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 4205 synchronized (this) { 4206 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 4207 } 4208 } 4209 4210 @Override 4211 public void setPackageAskScreenCompat(String packageName, boolean ask) { 4212 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 4213 "setPackageAskScreenCompat"); 4214 synchronized (this) { 4215 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 4216 } 4217 } 4218 4219 private boolean hasUsageStatsPermission(String callingPackage) { 4220 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS, 4221 Binder.getCallingUid(), callingPackage); 4222 if (mode == AppOpsManager.MODE_DEFAULT) { 4223 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS) 4224 == PackageManager.PERMISSION_GRANTED; 4225 } 4226 return mode == AppOpsManager.MODE_ALLOWED; 4227 } 4228 4229 @Override 4230 public int getPackageProcessState(String packageName, String callingPackage) { 4231 if (!hasUsageStatsPermission(callingPackage)) { 4232 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, 4233 "getPackageProcessState"); 4234 } 4235 4236 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT; 4237 synchronized (this) { 4238 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4239 final ProcessRecord proc = mLruProcesses.get(i); 4240 if (procState > proc.setProcState) { 4241 if (proc.pkgList.containsKey(packageName) || 4242 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) { 4243 procState = proc.setProcState; 4244 } 4245 } 4246 } 4247 } 4248 return procState; 4249 } 4250 4251 @Override 4252 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) 4253 throws RemoteException { 4254 synchronized (this) { 4255 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel"); 4256 if (app == null) { 4257 throw new IllegalArgumentException("Unknown process: " + process); 4258 } 4259 if (app.thread == null) { 4260 throw new IllegalArgumentException("Process has no app thread"); 4261 } 4262 if (app.trimMemoryLevel >= level) { 4263 throw new IllegalArgumentException( 4264 "Unable to set a higher trim level than current level"); 4265 } 4266 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN || 4267 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) { 4268 throw new IllegalArgumentException("Unable to set a background trim level " 4269 + "on a foreground process"); 4270 } 4271 app.thread.scheduleTrimMemory(level); 4272 app.trimMemoryLevel = level; 4273 return true; 4274 } 4275 } 4276 4277 private void dispatchProcessesChanged() { 4278 int N; 4279 synchronized (this) { 4280 N = mPendingProcessChanges.size(); 4281 if (mActiveProcessChanges.length < N) { 4282 mActiveProcessChanges = new ProcessChangeItem[N]; 4283 } 4284 mPendingProcessChanges.toArray(mActiveProcessChanges); 4285 mPendingProcessChanges.clear(); 4286 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 4287 "*** Delivering " + N + " process changes"); 4288 } 4289 4290 int i = mProcessObservers.beginBroadcast(); 4291 while (i > 0) { 4292 i--; 4293 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 4294 if (observer != null) { 4295 try { 4296 for (int j=0; j<N; j++) { 4297 ProcessChangeItem item = mActiveProcessChanges[j]; 4298 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 4299 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 4300 "ACTIVITIES CHANGED pid=" + item.pid + " uid=" 4301 + item.uid + ": " + item.foregroundActivities); 4302 observer.onForegroundActivitiesChanged(item.pid, item.uid, 4303 item.foregroundActivities); 4304 } 4305 } 4306 } catch (RemoteException e) { 4307 } 4308 } 4309 } 4310 mProcessObservers.finishBroadcast(); 4311 4312 synchronized (this) { 4313 for (int j=0; j<N; j++) { 4314 mAvailProcessChanges.add(mActiveProcessChanges[j]); 4315 } 4316 } 4317 } 4318 4319 private void dispatchProcessDied(int pid, int uid) { 4320 int i = mProcessObservers.beginBroadcast(); 4321 while (i > 0) { 4322 i--; 4323 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 4324 if (observer != null) { 4325 try { 4326 observer.onProcessDied(pid, uid); 4327 } catch (RemoteException e) { 4328 } 4329 } 4330 } 4331 mProcessObservers.finishBroadcast(); 4332 } 4333 4334 @VisibleForTesting 4335 void dispatchUidsChanged() { 4336 int N; 4337 synchronized (this) { 4338 N = mPendingUidChanges.size(); 4339 if (mActiveUidChanges.length < N) { 4340 mActiveUidChanges = new UidRecord.ChangeItem[N]; 4341 } 4342 for (int i=0; i<N; i++) { 4343 final UidRecord.ChangeItem change = mPendingUidChanges.get(i); 4344 mActiveUidChanges[i] = change; 4345 if (change.uidRecord != null) { 4346 change.uidRecord.pendingChange = null; 4347 change.uidRecord = null; 4348 } 4349 } 4350 mPendingUidChanges.clear(); 4351 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4352 "*** Delivering " + N + " uid changes"); 4353 } 4354 4355 int i = mUidObservers.beginBroadcast(); 4356 while (i > 0) { 4357 i--; 4358 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i), 4359 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N); 4360 } 4361 mUidObservers.finishBroadcast(); 4362 4363 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) { 4364 for (int j = 0; j < N; ++j) { 4365 final UidRecord.ChangeItem item = mActiveUidChanges[j]; 4366 if ((item.change & UidRecord.CHANGE_GONE) != 0) { 4367 mValidateUids.remove(item.uid); 4368 } else { 4369 UidRecord validateUid = mValidateUids.get(item.uid); 4370 if (validateUid == null) { 4371 validateUid = new UidRecord(item.uid); 4372 mValidateUids.put(item.uid, validateUid); 4373 } 4374 if ((item.change & UidRecord.CHANGE_IDLE) != 0) { 4375 validateUid.idle = true; 4376 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) { 4377 validateUid.idle = false; 4378 } 4379 validateUid.curProcState = validateUid.setProcState = item.processState; 4380 validateUid.lastDispatchedProcStateSeq = item.procStateSeq; 4381 } 4382 } 4383 } 4384 4385 synchronized (this) { 4386 for (int j = 0; j < N; j++) { 4387 mAvailUidChanges.add(mActiveUidChanges[j]); 4388 } 4389 } 4390 } 4391 4392 private void dispatchUidsChangedForObserver(IUidObserver observer, 4393 UidObserverRegistration reg, int changesSize) { 4394 if (observer == null) { 4395 return; 4396 } 4397 try { 4398 for (int j = 0; j < changesSize; j++) { 4399 UidRecord.ChangeItem item = mActiveUidChanges[j]; 4400 final int change = item.change; 4401 if (change == UidRecord.CHANGE_PROCSTATE && 4402 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) { 4403 // No-op common case: no significant change, the observer is not 4404 // interested in all proc state changes. 4405 continue; 4406 } 4407 if ((change & UidRecord.CHANGE_IDLE) != 0) { 4408 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) { 4409 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4410 "UID idle uid=" + item.uid); 4411 observer.onUidIdle(item.uid, item.ephemeral); 4412 } 4413 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) { 4414 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) { 4415 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4416 "UID active uid=" + item.uid); 4417 observer.onUidActive(item.uid); 4418 } 4419 } 4420 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) { 4421 if ((change & UidRecord.CHANGE_CACHED) != 0) { 4422 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4423 "UID cached uid=" + item.uid); 4424 observer.onUidCachedChanged(item.uid, true); 4425 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) { 4426 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4427 "UID active uid=" + item.uid); 4428 observer.onUidCachedChanged(item.uid, false); 4429 } 4430 } 4431 if ((change & UidRecord.CHANGE_GONE) != 0) { 4432 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) { 4433 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4434 "UID gone uid=" + item.uid); 4435 observer.onUidGone(item.uid, item.ephemeral); 4436 } 4437 if (reg.lastProcStates != null) { 4438 reg.lastProcStates.delete(item.uid); 4439 } 4440 } else { 4441 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { 4442 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4443 "UID CHANGED uid=" + item.uid 4444 + ": " + item.processState); 4445 boolean doReport = true; 4446 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) { 4447 final int lastState = reg.lastProcStates.get(item.uid, 4448 ActivityManager.PROCESS_STATE_UNKNOWN); 4449 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) { 4450 final boolean lastAboveCut = lastState <= reg.cutpoint; 4451 final boolean newAboveCut = item.processState <= reg.cutpoint; 4452 doReport = lastAboveCut != newAboveCut; 4453 } else { 4454 doReport = item.processState 4455 != ActivityManager.PROCESS_STATE_NONEXISTENT; 4456 } 4457 } 4458 if (doReport) { 4459 if (reg.lastProcStates != null) { 4460 reg.lastProcStates.put(item.uid, item.processState); 4461 } 4462 observer.onUidStateChanged(item.uid, item.processState, 4463 item.procStateSeq); 4464 } 4465 } 4466 } 4467 } 4468 } catch (RemoteException e) { 4469 } 4470 } 4471 4472 void dispatchOomAdjObserver(String msg) { 4473 OomAdjObserver observer; 4474 synchronized (this) { 4475 observer = mCurOomAdjObserver; 4476 } 4477 4478 if (observer != null) { 4479 observer.onOomAdjMessage(msg); 4480 } 4481 } 4482 4483 void setOomAdjObserver(int uid, OomAdjObserver observer) { 4484 synchronized (this) { 4485 mCurOomAdjUid = uid; 4486 mCurOomAdjObserver = observer; 4487 } 4488 } 4489 4490 void clearOomAdjObserver() { 4491 synchronized (this) { 4492 mCurOomAdjUid = -1; 4493 mCurOomAdjObserver = null; 4494 } 4495 } 4496 4497 void reportOomAdjMessageLocked(String tag, String msg) { 4498 Slog.d(tag, msg); 4499 if (mCurOomAdjObserver != null) { 4500 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget(); 4501 } 4502 } 4503 4504 @Override 4505 public final int startActivity(IApplicationThread caller, String callingPackage, 4506 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4507 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { 4508 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 4509 resultWho, requestCode, startFlags, profilerInfo, bOptions, 4510 UserHandle.getCallingUserId()); 4511 } 4512 4513 @Override 4514 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 4515 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4516 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { 4517 enforceNotIsolatedCaller("startActivity"); 4518 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4519 userId, false, ALLOW_FULL_ONLY, "startActivity", null); 4520 // TODO: Switch to user app stacks here. 4521 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, 4522 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 4523 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser"); 4524 } 4525 4526 @Override 4527 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 4528 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4529 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity, 4530 int userId) { 4531 4532 // This is very dangerous -- it allows you to perform a start activity (including 4533 // permission grants) as any app that may launch one of your own activities. So 4534 // we will only allow this to be done from activities that are part of the core framework, 4535 // and then only when they are running as the system. 4536 final ActivityRecord sourceRecord; 4537 final int targetUid; 4538 final String targetPackage; 4539 synchronized (this) { 4540 if (resultTo == null) { 4541 throw new SecurityException("Must be called from an activity"); 4542 } 4543 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 4544 if (sourceRecord == null) { 4545 throw new SecurityException("Called with bad activity token: " + resultTo); 4546 } 4547 if (!sourceRecord.info.packageName.equals("android")) { 4548 throw new SecurityException( 4549 "Must be called from an activity that is declared in the android package"); 4550 } 4551 if (sourceRecord.app == null) { 4552 throw new SecurityException("Called without a process attached to activity"); 4553 } 4554 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) { 4555 // This is still okay, as long as this activity is running under the 4556 // uid of the original calling activity. 4557 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 4558 throw new SecurityException( 4559 "Calling activity in uid " + sourceRecord.app.uid 4560 + " must be system uid or original calling uid " 4561 + sourceRecord.launchedFromUid); 4562 } 4563 } 4564 if (ignoreTargetSecurity) { 4565 if (intent.getComponent() == null) { 4566 throw new SecurityException( 4567 "Component must be specified with ignoreTargetSecurity"); 4568 } 4569 if (intent.getSelector() != null) { 4570 throw new SecurityException( 4571 "Selector not allowed with ignoreTargetSecurity"); 4572 } 4573 } 4574 targetUid = sourceRecord.launchedFromUid; 4575 targetPackage = sourceRecord.launchedFromPackage; 4576 } 4577 4578 if (userId == UserHandle.USER_NULL) { 4579 userId = UserHandle.getUserId(sourceRecord.app.uid); 4580 } 4581 4582 // TODO: Switch to user app stacks here. 4583 try { 4584 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent, 4585 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 4586 null, null, bOptions, ignoreTargetSecurity, userId, null, 4587 "startActivityAsCaller"); 4588 return ret; 4589 } catch (SecurityException e) { 4590 // XXX need to figure out how to propagate to original app. 4591 // A SecurityException here is generally actually a fault of the original 4592 // calling activity (such as a fairly granting permissions), so propagate it 4593 // back to them. 4594 /* 4595 StringBuilder msg = new StringBuilder(); 4596 msg.append("While launching"); 4597 msg.append(intent.toString()); 4598 msg.append(": "); 4599 msg.append(e.getMessage()); 4600 */ 4601 throw e; 4602 } 4603 } 4604 4605 @Override 4606 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 4607 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4608 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { 4609 enforceNotIsolatedCaller("startActivityAndWait"); 4610 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4611 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 4612 WaitResult res = new WaitResult(); 4613 // TODO: Switch to user app stacks here. 4614 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 4615 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 4616 bOptions, false, userId, null, "startActivityAndWait"); 4617 return res; 4618 } 4619 4620 @Override 4621 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 4622 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4623 int startFlags, Configuration config, Bundle bOptions, int userId) { 4624 enforceNotIsolatedCaller("startActivityWithConfig"); 4625 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4626 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 4627 // TODO: Switch to user app stacks here. 4628 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, 4629 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 4630 null, null, config, bOptions, false, userId, null, "startActivityWithConfig"); 4631 return ret; 4632 } 4633 4634 @Override 4635 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target, 4636 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo, 4637 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) 4638 throws TransactionTooLargeException { 4639 enforceNotIsolatedCaller("startActivityIntentSender"); 4640 // Refuse possible leaked file descriptors 4641 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 4642 throw new IllegalArgumentException("File descriptors passed in Intent"); 4643 } 4644 4645 if (!(target instanceof PendingIntentRecord)) { 4646 throw new IllegalArgumentException("Bad PendingIntent object"); 4647 } 4648 4649 PendingIntentRecord pir = (PendingIntentRecord)target; 4650 4651 synchronized (this) { 4652 // If this is coming from the currently resumed activity, it is 4653 // effectively saying that app switches are allowed at this point. 4654 final ActivityStack stack = getFocusedStack(); 4655 if (stack.mResumedActivity != null && 4656 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 4657 mAppSwitchesAllowedTime = 0; 4658 } 4659 } 4660 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null, 4661 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions); 4662 return ret; 4663 } 4664 4665 @Override 4666 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 4667 Intent intent, String resolvedType, IVoiceInteractionSession session, 4668 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 4669 Bundle bOptions, int userId) { 4670 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 4671 != PackageManager.PERMISSION_GRANTED) { 4672 String msg = "Permission Denial: startVoiceActivity() from pid=" 4673 + Binder.getCallingPid() 4674 + ", uid=" + Binder.getCallingUid() 4675 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 4676 Slog.w(TAG, msg); 4677 throw new SecurityException(msg); 4678 } 4679 if (session == null || interactor == null) { 4680 throw new NullPointerException("null session or interactor"); 4681 } 4682 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false, 4683 ALLOW_FULL_ONLY, "startVoiceActivity", null); 4684 // TODO: Switch to user app stacks here. 4685 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent, 4686 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 4687 null, bOptions, false, userId, null, "startVoiceActivity"); 4688 } 4689 4690 @Override 4691 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid, 4692 Intent intent, String resolvedType, Bundle bOptions, int userId) { 4693 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 4694 != PackageManager.PERMISSION_GRANTED) { 4695 final String msg = "Permission Denial: startAssistantActivity() from pid=" 4696 + Binder.getCallingPid() 4697 + ", uid=" + Binder.getCallingUid() 4698 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION; 4699 Slog.w(TAG, msg); 4700 throw new SecurityException(msg); 4701 } 4702 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false, 4703 ALLOW_FULL_ONLY, "startAssistantActivity", null); 4704 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent, 4705 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false, 4706 userId, null, "startAssistantActivity"); 4707 } 4708 4709 @Override 4710 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) 4711 throws RemoteException { 4712 Slog.i(TAG, "Activity tried to startVoiceInteraction"); 4713 synchronized (this) { 4714 ActivityRecord activity = getFocusedStack().topActivity(); 4715 if (ActivityRecord.forTokenLocked(callingActivity) != activity) { 4716 throw new SecurityException("Only focused activity can call startVoiceInteraction"); 4717 } 4718 if (mRunningVoice != null || activity.getTask().voiceSession != null 4719 || activity.voiceSession != null) { 4720 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction"); 4721 return; 4722 } 4723 if (activity.pendingVoiceInteractionStart) { 4724 Slog.w(TAG, "Pending start of voice interaction already."); 4725 return; 4726 } 4727 activity.pendingVoiceInteractionStart = true; 4728 } 4729 LocalServices.getService(VoiceInteractionManagerInternal.class) 4730 .startLocalVoiceInteraction(callingActivity, options); 4731 } 4732 4733 @Override 4734 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException { 4735 LocalServices.getService(VoiceInteractionManagerInternal.class) 4736 .stopLocalVoiceInteraction(callingActivity); 4737 } 4738 4739 @Override 4740 public boolean supportsLocalVoiceInteraction() throws RemoteException { 4741 return LocalServices.getService(VoiceInteractionManagerInternal.class) 4742 .supportsLocalVoiceInteraction(); 4743 } 4744 4745 void onLocalVoiceInteractionStartedLocked(IBinder activity, 4746 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { 4747 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity); 4748 if (activityToCallback == null) return; 4749 activityToCallback.setVoiceSessionLocked(voiceSession); 4750 4751 // Inform the activity 4752 try { 4753 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity, 4754 voiceInteractor); 4755 long token = Binder.clearCallingIdentity(); 4756 try { 4757 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid); 4758 } finally { 4759 Binder.restoreCallingIdentity(token); 4760 } 4761 // TODO: VI Should we cache the activity so that it's easier to find later 4762 // rather than scan through all the stacks and activities? 4763 } catch (RemoteException re) { 4764 activityToCallback.clearVoiceSessionLocked(); 4765 // TODO: VI Should this terminate the voice session? 4766 } 4767 } 4768 4769 @Override 4770 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) { 4771 synchronized (this) { 4772 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) { 4773 if (keepAwake) { 4774 mVoiceWakeLock.acquire(); 4775 } else { 4776 mVoiceWakeLock.release(); 4777 } 4778 } 4779 } 4780 } 4781 4782 @Override 4783 public boolean startNextMatchingActivity(IBinder callingActivity, 4784 Intent intent, Bundle bOptions) { 4785 // Refuse possible leaked file descriptors 4786 if (intent != null && intent.hasFileDescriptors() == true) { 4787 throw new IllegalArgumentException("File descriptors passed in Intent"); 4788 } 4789 ActivityOptions options = ActivityOptions.fromBundle(bOptions); 4790 4791 synchronized (this) { 4792 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 4793 if (r == null) { 4794 ActivityOptions.abort(options); 4795 return false; 4796 } 4797 if (r.app == null || r.app.thread == null) { 4798 // The caller is not running... d'oh! 4799 ActivityOptions.abort(options); 4800 return false; 4801 } 4802 intent = new Intent(intent); 4803 // The caller is not allowed to change the data. 4804 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 4805 // And we are resetting to find the next component... 4806 intent.setComponent(null); 4807 4808 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4809 4810 ActivityInfo aInfo = null; 4811 try { 4812 List<ResolveInfo> resolves = 4813 AppGlobals.getPackageManager().queryIntentActivities( 4814 intent, r.resolvedType, 4815 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 4816 UserHandle.getCallingUserId()).getList(); 4817 4818 // Look for the original activity in the list... 4819 final int N = resolves != null ? resolves.size() : 0; 4820 for (int i=0; i<N; i++) { 4821 ResolveInfo rInfo = resolves.get(i); 4822 if (rInfo.activityInfo.packageName.equals(r.packageName) 4823 && rInfo.activityInfo.name.equals(r.info.name)) { 4824 // We found the current one... the next matching is 4825 // after it. 4826 i++; 4827 if (i<N) { 4828 aInfo = resolves.get(i).activityInfo; 4829 } 4830 if (debug) { 4831 Slog.v(TAG, "Next matching activity: found current " + r.packageName 4832 + "/" + r.info.name); 4833 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null) 4834 ? "null" : aInfo.packageName + "/" + aInfo.name)); 4835 } 4836 break; 4837 } 4838 } 4839 } catch (RemoteException e) { 4840 } 4841 4842 if (aInfo == null) { 4843 // Nobody who is next! 4844 ActivityOptions.abort(options); 4845 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 4846 return false; 4847 } 4848 4849 intent.setComponent(new ComponentName( 4850 aInfo.applicationInfo.packageName, aInfo.name)); 4851 intent.setFlags(intent.getFlags()&~( 4852 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 4853 Intent.FLAG_ACTIVITY_CLEAR_TOP| 4854 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 4855 Intent.FLAG_ACTIVITY_NEW_TASK)); 4856 4857 // Okay now we need to start the new activity, replacing the 4858 // currently running activity. This is a little tricky because 4859 // we want to start the new one as if the current one is finished, 4860 // but not finish the current one first so that there is no flicker. 4861 // And thus... 4862 final boolean wasFinishing = r.finishing; 4863 r.finishing = true; 4864 4865 // Propagate reply information over to the new activity. 4866 final ActivityRecord resultTo = r.resultTo; 4867 final String resultWho = r.resultWho; 4868 final int requestCode = r.requestCode; 4869 r.resultTo = null; 4870 if (resultTo != null) { 4871 resultTo.removeResultsLocked(r, resultWho, requestCode); 4872 } 4873 4874 final long origId = Binder.clearCallingIdentity(); 4875 int res = mActivityStarter.startActivityLocked(r.app.thread, intent, 4876 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null, 4877 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1, 4878 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options, 4879 false, false, null, null, "startNextMatchingActivity"); 4880 Binder.restoreCallingIdentity(origId); 4881 4882 r.finishing = wasFinishing; 4883 if (res != ActivityManager.START_SUCCESS) { 4884 return false; 4885 } 4886 return true; 4887 } 4888 } 4889 4890 @Override 4891 public final int startActivityFromRecents(int taskId, Bundle bOptions) { 4892 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 4893 String msg = "Permission Denial: startActivityFromRecents called without " + 4894 START_TASKS_FROM_RECENTS; 4895 Slog.w(TAG, msg); 4896 throw new SecurityException(msg); 4897 } 4898 final long origId = Binder.clearCallingIdentity(); 4899 try { 4900 synchronized (this) { 4901 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions); 4902 } 4903 } finally { 4904 Binder.restoreCallingIdentity(origId); 4905 } 4906 } 4907 4908 final int startActivityInPackage(int uid, String callingPackage, 4909 Intent intent, String resolvedType, IBinder resultTo, 4910 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId, 4911 TaskRecord inTask, String reason) { 4912 4913 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4914 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 4915 4916 // TODO: Switch to user app stacks here. 4917 return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent, 4918 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 4919 null, null, null, bOptions, false, userId, inTask, reason); 4920 } 4921 4922 @Override 4923 public final int startActivities(IApplicationThread caller, String callingPackage, 4924 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions, 4925 int userId) { 4926 final String reason = "startActivities"; 4927 enforceNotIsolatedCaller(reason); 4928 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4929 userId, false, ALLOW_FULL_ONLY, reason, null); 4930 // TODO: Switch to user app stacks here. 4931 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents, 4932 resolvedTypes, resultTo, bOptions, userId, reason); 4933 return ret; 4934 } 4935 4936 final int startActivitiesInPackage(int uid, String callingPackage, 4937 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 4938 Bundle bOptions, int userId) { 4939 4940 final String reason = "startActivityInPackage"; 4941 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4942 userId, false, ALLOW_FULL_ONLY, reason, null); 4943 // TODO: Switch to user app stacks here. 4944 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes, 4945 resultTo, bOptions, userId, reason); 4946 return ret; 4947 } 4948 4949 @Override 4950 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) { 4951 synchronized (this) { 4952 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4953 if (r == null) { 4954 return; 4955 } 4956 r.reportFullyDrawnLocked(restoredFromBundle); 4957 } 4958 } 4959 4960 @Override 4961 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4962 synchronized (this) { 4963 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4964 if (r == null) { 4965 return; 4966 } 4967 final long origId = Binder.clearCallingIdentity(); 4968 try { 4969 r.setRequestedOrientation(requestedOrientation); 4970 } finally { 4971 Binder.restoreCallingIdentity(origId); 4972 } 4973 } 4974 } 4975 4976 @Override 4977 public int getRequestedOrientation(IBinder token) { 4978 synchronized (this) { 4979 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4980 if (r == null) { 4981 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4982 } 4983 return r.getRequestedOrientation(); 4984 } 4985 } 4986 4987 @Override 4988 public final void requestActivityRelaunch(IBinder token) { 4989 synchronized(this) { 4990 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4991 if (r == null) { 4992 return; 4993 } 4994 final long origId = Binder.clearCallingIdentity(); 4995 try { 4996 r.forceNewConfig = true; 4997 r.ensureActivityConfigurationLocked(0 /* globalChanges */, 4998 true /* preserveWindow */); 4999 } finally { 5000 Binder.restoreCallingIdentity(origId); 5001 } 5002 } 5003 } 5004 5005 /** 5006 * This is the internal entry point for handling Activity.finish(). 5007 * 5008 * @param token The Binder token referencing the Activity we want to finish. 5009 * @param resultCode Result code, if any, from this Activity. 5010 * @param resultData Result data (Intent), if any, from this Activity. 5011 * @param finishTask Whether to finish the task associated with this Activity. 5012 * 5013 * @return Returns true if the activity successfully finished, or false if it is still running. 5014 */ 5015 @Override 5016 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 5017 int finishTask) { 5018 // Refuse possible leaked file descriptors 5019 if (resultData != null && resultData.hasFileDescriptors() == true) { 5020 throw new IllegalArgumentException("File descriptors passed in Intent"); 5021 } 5022 5023 synchronized(this) { 5024 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5025 if (r == null) { 5026 return true; 5027 } 5028 // Keep track of the root activity of the task before we finish it 5029 TaskRecord tr = r.getTask(); 5030 ActivityRecord rootR = tr.getRootActivity(); 5031 if (rootR == null) { 5032 Slog.w(TAG, "Finishing task with all activities already finished"); 5033 } 5034 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can 5035 // finish. 5036 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r && 5037 mStackSupervisor.isLastLockedTask(tr)) { 5038 Slog.i(TAG, "Not finishing task in lock task mode"); 5039 mStackSupervisor.showLockTaskToast(); 5040 return false; 5041 } 5042 if (mController != null) { 5043 // Find the first activity that is not finishing. 5044 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0); 5045 if (next != null) { 5046 // ask watcher if this is allowed 5047 boolean resumeOK = true; 5048 try { 5049 resumeOK = mController.activityResuming(next.packageName); 5050 } catch (RemoteException e) { 5051 mController = null; 5052 Watchdog.getInstance().setActivityController(null); 5053 } 5054 5055 if (!resumeOK) { 5056 Slog.i(TAG, "Not finishing activity because controller resumed"); 5057 return false; 5058 } 5059 } 5060 } 5061 final long origId = Binder.clearCallingIdentity(); 5062 try { 5063 boolean res; 5064 final boolean finishWithRootActivity = 5065 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY; 5066 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY 5067 || (finishWithRootActivity && r == rootR)) { 5068 // If requested, remove the task that is associated to this activity only if it 5069 // was the root activity in the task. The result code and data is ignored 5070 // because we don't support returning them across task boundaries. Also, to 5071 // keep backwards compatibility we remove the task from recents when finishing 5072 // task with root activity. 5073 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity); 5074 if (!res) { 5075 Slog.i(TAG, "Removing task failed to finish activity"); 5076 } 5077 } else { 5078 res = tr.getStack().requestFinishActivityLocked(token, resultCode, 5079 resultData, "app-request", true); 5080 if (!res) { 5081 Slog.i(TAG, "Failed to finish by app-request"); 5082 } 5083 } 5084 return res; 5085 } finally { 5086 Binder.restoreCallingIdentity(origId); 5087 } 5088 } 5089 } 5090 5091 @Override 5092 public final void finishHeavyWeightApp() { 5093 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5094 != PackageManager.PERMISSION_GRANTED) { 5095 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 5096 + Binder.getCallingPid() 5097 + ", uid=" + Binder.getCallingUid() 5098 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5099 Slog.w(TAG, msg); 5100 throw new SecurityException(msg); 5101 } 5102 5103 synchronized(this) { 5104 if (mHeavyWeightProcess == null) { 5105 return; 5106 } 5107 5108 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities); 5109 for (int i = 0; i < activities.size(); i++) { 5110 ActivityRecord r = activities.get(i); 5111 if (!r.finishing && r.isInStackLocked()) { 5112 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED, 5113 null, "finish-heavy", true); 5114 } 5115 } 5116 5117 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5118 mHeavyWeightProcess.userId, 0)); 5119 mHeavyWeightProcess = null; 5120 } 5121 } 5122 5123 @Override 5124 public void crashApplication(int uid, int initialPid, String packageName, int userId, 5125 String message) { 5126 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5127 != PackageManager.PERMISSION_GRANTED) { 5128 String msg = "Permission Denial: crashApplication() from pid=" 5129 + Binder.getCallingPid() 5130 + ", uid=" + Binder.getCallingUid() 5131 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5132 Slog.w(TAG, msg); 5133 throw new SecurityException(msg); 5134 } 5135 5136 synchronized(this) { 5137 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message); 5138 } 5139 } 5140 5141 @Override 5142 public final void finishSubActivity(IBinder token, String resultWho, 5143 int requestCode) { 5144 synchronized(this) { 5145 final long origId = Binder.clearCallingIdentity(); 5146 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5147 if (r != null) { 5148 r.getStack().finishSubActivityLocked(r, resultWho, requestCode); 5149 } 5150 Binder.restoreCallingIdentity(origId); 5151 } 5152 } 5153 5154 @Override 5155 public boolean finishActivityAffinity(IBinder token) { 5156 synchronized(this) { 5157 final long origId = Binder.clearCallingIdentity(); 5158 try { 5159 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5160 if (r == null) { 5161 return false; 5162 } 5163 5164 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps 5165 // can finish. 5166 final TaskRecord task = r.getTask(); 5167 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && 5168 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) { 5169 mStackSupervisor.showLockTaskToast(); 5170 return false; 5171 } 5172 return task.getStack().finishActivityAffinityLocked(r); 5173 } finally { 5174 Binder.restoreCallingIdentity(origId); 5175 } 5176 } 5177 } 5178 5179 @Override 5180 public void finishVoiceTask(IVoiceInteractionSession session) { 5181 synchronized (this) { 5182 final long origId = Binder.clearCallingIdentity(); 5183 try { 5184 // TODO: VI Consider treating local voice interactions and voice tasks 5185 // differently here 5186 mStackSupervisor.finishVoiceTask(session); 5187 } finally { 5188 Binder.restoreCallingIdentity(origId); 5189 } 5190 } 5191 5192 } 5193 5194 @Override 5195 public boolean releaseActivityInstance(IBinder token) { 5196 synchronized(this) { 5197 final long origId = Binder.clearCallingIdentity(); 5198 try { 5199 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5200 if (r == null) { 5201 return false; 5202 } 5203 return r.getStack().safelyDestroyActivityLocked(r, "app-req"); 5204 } finally { 5205 Binder.restoreCallingIdentity(origId); 5206 } 5207 } 5208 } 5209 5210 @Override 5211 public void releaseSomeActivities(IApplicationThread appInt) { 5212 synchronized(this) { 5213 final long origId = Binder.clearCallingIdentity(); 5214 try { 5215 ProcessRecord app = getRecordForAppLocked(appInt); 5216 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 5217 } finally { 5218 Binder.restoreCallingIdentity(origId); 5219 } 5220 } 5221 } 5222 5223 @Override 5224 public boolean willActivityBeVisible(IBinder token) { 5225 synchronized(this) { 5226 ActivityStack stack = ActivityRecord.getStackLocked(token); 5227 if (stack != null) { 5228 return stack.willActivityBeVisibleLocked(token); 5229 } 5230 return false; 5231 } 5232 } 5233 5234 @Override 5235 public void overridePendingTransition(IBinder token, String packageName, 5236 int enterAnim, int exitAnim) { 5237 synchronized(this) { 5238 ActivityRecord self = ActivityRecord.isInStackLocked(token); 5239 if (self == null) { 5240 return; 5241 } 5242 5243 final long origId = Binder.clearCallingIdentity(); 5244 5245 if (self.state == ActivityState.RESUMED 5246 || self.state == ActivityState.PAUSING) { 5247 mWindowManager.overridePendingAppTransition(packageName, 5248 enterAnim, exitAnim, null); 5249 } 5250 5251 Binder.restoreCallingIdentity(origId); 5252 } 5253 } 5254 5255 /** 5256 * Main function for removing an existing process from the activity manager 5257 * as a result of that process going away. Clears out all connections 5258 * to the process. 5259 */ 5260 private final void handleAppDiedLocked(ProcessRecord app, 5261 boolean restarting, boolean allowRestart) { 5262 int pid = app.pid; 5263 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1, 5264 false /*replacingPid*/); 5265 if (!kept && !restarting) { 5266 removeLruProcessLocked(app); 5267 if (pid > 0) { 5268 ProcessList.remove(pid); 5269 } 5270 } 5271 5272 if (mProfileProc == app) { 5273 clearProfilerLocked(); 5274 } 5275 5276 // Remove this application's activities from active lists. 5277 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 5278 5279 app.activities.clear(); 5280 5281 if (app.instr != null) { 5282 Slog.w(TAG, "Crash of app " + app.processName 5283 + " running instrumentation " + app.instr.mClass); 5284 Bundle info = new Bundle(); 5285 info.putString("shortMsg", "Process crashed."); 5286 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 5287 } 5288 5289 mWindowManager.deferSurfaceLayout(); 5290 try { 5291 if (!restarting && hasVisibleActivities 5292 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) { 5293 // If there was nothing to resume, and we are not already restarting this process, but 5294 // there is a visible activity that is hosted by the process... then make sure all 5295 // visible activities are running, taking care of restarting this process. 5296 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 5297 } 5298 } finally { 5299 mWindowManager.continueSurfaceLayout(); 5300 } 5301 } 5302 5303 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 5304 final IBinder threadBinder = thread.asBinder(); 5305 // Find the application record. 5306 for (int i=mLruProcesses.size()-1; i>=0; i--) { 5307 final ProcessRecord rec = mLruProcesses.get(i); 5308 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 5309 return i; 5310 } 5311 } 5312 return -1; 5313 } 5314 5315 final ProcessRecord getRecordForAppLocked( 5316 IApplicationThread thread) { 5317 if (thread == null) { 5318 return null; 5319 } 5320 5321 int appIndex = getLRURecordIndexForAppLocked(thread); 5322 if (appIndex >= 0) { 5323 return mLruProcesses.get(appIndex); 5324 } 5325 5326 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's 5327 // double-check that. 5328 final IBinder threadBinder = thread.asBinder(); 5329 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5330 for (int i = pmap.size()-1; i >= 0; i--) { 5331 final SparseArray<ProcessRecord> procs = pmap.valueAt(i); 5332 for (int j = procs.size()-1; j >= 0; j--) { 5333 final ProcessRecord proc = procs.valueAt(j); 5334 if (proc.thread != null && proc.thread.asBinder() == threadBinder) { 5335 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: " 5336 + proc); 5337 return proc; 5338 } 5339 } 5340 } 5341 5342 return null; 5343 } 5344 5345 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 5346 // If there are no longer any background processes running, 5347 // and the app that died was not running instrumentation, 5348 // then tell everyone we are now low on memory. 5349 boolean haveBg = false; 5350 for (int i=mLruProcesses.size()-1; i>=0; i--) { 5351 ProcessRecord rec = mLruProcesses.get(i); 5352 if (rec.thread != null 5353 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 5354 haveBg = true; 5355 break; 5356 } 5357 } 5358 5359 if (!haveBg) { 5360 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 5361 if (doReport) { 5362 long now = SystemClock.uptimeMillis(); 5363 if (now < (mLastMemUsageReportTime+5*60*1000)) { 5364 doReport = false; 5365 } else { 5366 mLastMemUsageReportTime = now; 5367 } 5368 } 5369 final ArrayList<ProcessMemInfo> memInfos 5370 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 5371 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 5372 long now = SystemClock.uptimeMillis(); 5373 for (int i=mLruProcesses.size()-1; i>=0; i--) { 5374 ProcessRecord rec = mLruProcesses.get(i); 5375 if (rec == dyingProc || rec.thread == null) { 5376 continue; 5377 } 5378 if (doReport) { 5379 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 5380 rec.setProcState, rec.adjType, rec.makeAdjReason())); 5381 } 5382 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) { 5383 // The low memory report is overriding any current 5384 // state for a GC request. Make sure to do 5385 // heavy/important/visible/foreground processes first. 5386 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 5387 rec.lastRequestedGc = 0; 5388 } else { 5389 rec.lastRequestedGc = rec.lastLowMemory; 5390 } 5391 rec.reportLowMemory = true; 5392 rec.lastLowMemory = now; 5393 mProcessesToGc.remove(rec); 5394 addProcessToGcListLocked(rec); 5395 } 5396 } 5397 if (doReport) { 5398 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 5399 mHandler.sendMessage(msg); 5400 } 5401 scheduleAppGcsLocked(); 5402 } 5403 } 5404 5405 final void appDiedLocked(ProcessRecord app) { 5406 appDiedLocked(app, app.pid, app.thread, false); 5407 } 5408 5409 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread, 5410 boolean fromBinderDied) { 5411 // First check if this ProcessRecord is actually active for the pid. 5412 synchronized (mPidsSelfLocked) { 5413 ProcessRecord curProc = mPidsSelfLocked.get(pid); 5414 if (curProc != app) { 5415 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 5416 return; 5417 } 5418 } 5419 5420 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 5421 synchronized (stats) { 5422 stats.noteProcessDiedLocked(app.info.uid, pid); 5423 } 5424 5425 if (!app.killed) { 5426 if (!fromBinderDied) { 5427 killProcessQuiet(pid); 5428 } 5429 killProcessGroup(app.uid, pid); 5430 app.killed = true; 5431 } 5432 5433 // Clean up already done if the process has been re-started. 5434 if (app.pid == pid && app.thread != null && 5435 app.thread.asBinder() == thread.asBinder()) { 5436 boolean doLowMem = app.instr == null; 5437 boolean doOomAdj = doLowMem; 5438 if (!app.killedByAm) { 5439 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: " 5440 + ProcessList.makeOomAdjString(app.setAdj) 5441 + ProcessList.makeProcStateString(app.setProcState)); 5442 mAllowLowerMemLevel = true; 5443 } else { 5444 // Note that we always want to do oom adj to update our state with the 5445 // new number of procs. 5446 mAllowLowerMemLevel = false; 5447 doLowMem = false; 5448 } 5449 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName, 5450 app.setAdj, app.setProcState); 5451 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 5452 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder()); 5453 handleAppDiedLocked(app, false, true); 5454 5455 if (doOomAdj) { 5456 updateOomAdjLocked(); 5457 } 5458 if (doLowMem) { 5459 doLowMemReportIfNeededLocked(app); 5460 } 5461 } else if (app.pid != pid) { 5462 // A new process has already been started. 5463 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 5464 + ") has died and restarted (pid " + app.pid + ")."); 5465 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 5466 } else if (DEBUG_PROCESSES) { 5467 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread " 5468 + thread.asBinder()); 5469 } 5470 } 5471 5472 /** 5473 * If a stack trace dump file is configured, dump process stack traces. 5474 * @param clearTraces causes the dump file to be erased prior to the new 5475 * traces being written, if true; when false, the new traces will be 5476 * appended to any existing file content. 5477 * @param firstPids of dalvik VM processes to dump stack traces for first 5478 * @param lastPids of dalvik VM processes to dump stack traces for last 5479 * @param nativePids optional list of native pids to dump stack crawls 5480 */ 5481 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 5482 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, 5483 ArrayList<Integer> nativePids) { 5484 ArrayList<Integer> extraPids = null; 5485 5486 // Measure CPU usage as soon as we're called in order to get a realistic sampling 5487 // of the top users at the time of the request. 5488 if (processCpuTracker != null) { 5489 processCpuTracker.init(); 5490 try { 5491 Thread.sleep(200); 5492 } catch (InterruptedException ignored) { 5493 } 5494 5495 processCpuTracker.update(); 5496 5497 // We'll take the stack crawls of just the top apps using CPU. 5498 final int N = processCpuTracker.countWorkingStats(); 5499 extraPids = new ArrayList<>(); 5500 for (int i = 0; i < N && extraPids.size() < 5; i++) { 5501 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 5502 if (lastPids.indexOfKey(stats.pid) >= 0) { 5503 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid); 5504 5505 extraPids.add(stats.pid); 5506 } else if (DEBUG_ANR) { 5507 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: " 5508 + stats.pid); 5509 } 5510 } 5511 } 5512 5513 boolean useTombstonedForJavaTraces = false; 5514 File tracesFile; 5515 5516 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", ""); 5517 if (tracesDirProp.isEmpty()) { 5518 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace 5519 // dumping scheme. All traces are written to a global trace file (usually 5520 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate 5521 // the file if requested. 5522 // 5523 // This mode of operation will be removed in the near future. 5524 5525 5526 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5527 if (globalTracesPath.isEmpty()) { 5528 Slog.w(TAG, "dumpStackTraces: no trace path configured"); 5529 return null; 5530 } 5531 5532 tracesFile = new File(globalTracesPath); 5533 try { 5534 if (clearTraces && tracesFile.exists()) { 5535 tracesFile.delete(); 5536 } 5537 5538 tracesFile.createNewFile(); 5539 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw- 5540 } catch (IOException e) { 5541 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e); 5542 return null; 5543 } 5544 } else { 5545 File tracesDir = new File(tracesDirProp); 5546 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme. 5547 // Each set of ANR traces is written to a separate file and dumpstate will process 5548 // all such files and add them to a captured bug report if they're recent enough. 5549 maybePruneOldTraces(tracesDir); 5550 5551 // NOTE: We should consider creating the file in native code atomically once we've 5552 // gotten rid of the old scheme of dumping and lot of the code that deals with paths 5553 // can be removed. 5554 tracesFile = createAnrDumpFile(tracesDir); 5555 if (tracesFile == null) { 5556 return null; 5557 } 5558 5559 useTombstonedForJavaTraces = true; 5560 } 5561 5562 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids, 5563 useTombstonedForJavaTraces); 5564 return tracesFile; 5565 } 5566 5567 @GuardedBy("ActivityManagerService.class") 5568 private static SimpleDateFormat sAnrFileDateFormat; 5569 5570 private static synchronized File createAnrDumpFile(File tracesDir) { 5571 if (sAnrFileDateFormat == null) { 5572 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS"); 5573 } 5574 5575 final String formattedDate = sAnrFileDateFormat.format(new Date()); 5576 final File anrFile = new File(tracesDir, "anr_" + formattedDate); 5577 5578 try { 5579 if (anrFile.createNewFile()) { 5580 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw------- 5581 return anrFile; 5582 } else { 5583 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed"); 5584 } 5585 } catch (IOException ioe) { 5586 Slog.w(TAG, "Exception creating ANR dump file:", ioe); 5587 } 5588 5589 return null; 5590 } 5591 5592 /** 5593 * Prune all trace files that are more than a day old. 5594 * 5595 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a 5596 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now 5597 * since it's the system_server that creates trace files for most ANRs. 5598 */ 5599 private static void maybePruneOldTraces(File tracesDir) { 5600 final long now = System.currentTimeMillis(); 5601 final File[] traceFiles = tracesDir.listFiles(); 5602 5603 if (traceFiles != null) { 5604 for (File file : traceFiles) { 5605 if ((now - file.lastModified()) > DAY_IN_MILLIS) { 5606 if (!file.delete()) { 5607 Slog.w(TAG, "Unable to prune stale trace file: " + file); 5608 } 5609 } 5610 } 5611 } 5612 } 5613 5614 /** 5615 * Legacy code, do not use. Existing users will be deleted. 5616 * 5617 * @deprecated 5618 */ 5619 @Deprecated 5620 public static class DumpStackFileObserver extends FileObserver { 5621 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp 5622 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds 5623 5624 private final String mTracesPath; 5625 private boolean mClosed; 5626 5627 public DumpStackFileObserver(String tracesPath) { 5628 super(tracesPath, FileObserver.CLOSE_WRITE); 5629 mTracesPath = tracesPath; 5630 } 5631 5632 @Override 5633 public synchronized void onEvent(int event, String path) { 5634 mClosed = true; 5635 notify(); 5636 } 5637 5638 public long dumpWithTimeout(int pid, long timeout) { 5639 sendSignal(pid, SIGNAL_QUIT); 5640 final long start = SystemClock.elapsedRealtime(); 5641 5642 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS); 5643 synchronized (this) { 5644 try { 5645 wait(waitTime); // Wait for traces file to be closed. 5646 } catch (InterruptedException e) { 5647 Slog.wtf(TAG, e); 5648 } 5649 } 5650 5651 // This avoids a corner case of passing a negative time to the native 5652 // trace in case we've already hit the overall timeout. 5653 final long timeWaited = SystemClock.elapsedRealtime() - start; 5654 if (timeWaited >= timeout) { 5655 return timeWaited; 5656 } 5657 5658 if (!mClosed) { 5659 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid + 5660 ". Attempting native stack collection."); 5661 5662 final long nativeDumpTimeoutMs = Math.min( 5663 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited); 5664 5665 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath, 5666 (int) (nativeDumpTimeoutMs / 1000)); 5667 } 5668 5669 final long end = SystemClock.elapsedRealtime(); 5670 mClosed = false; 5671 5672 return (end - start); 5673 } 5674 } 5675 5676 /** 5677 * Dump java traces for process {@code pid} to the specified file. If java trace dumping 5678 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies 5679 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent 5680 * attempting to obtain native traces in the case of a failure. Returns the total time spent 5681 * capturing traces. 5682 */ 5683 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) { 5684 final long timeStart = SystemClock.elapsedRealtime(); 5685 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) { 5686 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName, 5687 (NATIVE_DUMP_TIMEOUT_MS / 1000)); 5688 } 5689 5690 return SystemClock.elapsedRealtime() - timeStart; 5691 } 5692 5693 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids, 5694 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids, 5695 boolean useTombstonedForJavaTraces) { 5696 5697 // We don't need any sort of inotify based monitoring when we're dumping traces via 5698 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full 5699 // control of all writes to the file in question. 5700 final DumpStackFileObserver observer; 5701 if (useTombstonedForJavaTraces) { 5702 observer = null; 5703 } else { 5704 // Use a FileObserver to detect when traces finish writing. 5705 // The order of traces is considered important to maintain for legibility. 5706 observer = new DumpStackFileObserver(tracesFile); 5707 } 5708 5709 // We must complete all stack dumps within 20 seconds. 5710 long remainingTime = 20 * 1000; 5711 try { 5712 if (observer != null) { 5713 observer.startWatching(); 5714 } 5715 5716 // First collect all of the stacks of the most important pids. 5717 if (firstPids != null) { 5718 int num = firstPids.size(); 5719 for (int i = 0; i < num; i++) { 5720 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid " 5721 + firstPids.get(i)); 5722 final long timeTaken; 5723 if (useTombstonedForJavaTraces) { 5724 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime); 5725 } else { 5726 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime); 5727 } 5728 5729 remainingTime -= timeTaken; 5730 if (remainingTime <= 0) { 5731 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) + 5732 "); deadline exceeded."); 5733 return; 5734 } 5735 5736 if (DEBUG_ANR) { 5737 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms"); 5738 } 5739 } 5740 } 5741 5742 // Next collect the stacks of the native pids 5743 if (nativePids != null) { 5744 for (int pid : nativePids) { 5745 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid); 5746 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime); 5747 5748 final long start = SystemClock.elapsedRealtime(); 5749 Debug.dumpNativeBacktraceToFileTimeout( 5750 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000)); 5751 final long timeTaken = SystemClock.elapsedRealtime() - start; 5752 5753 remainingTime -= timeTaken; 5754 if (remainingTime <= 0) { 5755 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid + 5756 "); deadline exceeded."); 5757 return; 5758 } 5759 5760 if (DEBUG_ANR) { 5761 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms"); 5762 } 5763 } 5764 } 5765 5766 // Lastly, dump stacks for all extra PIDs from the CPU tracker. 5767 if (extraPids != null) { 5768 for (int pid : extraPids) { 5769 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid); 5770 5771 final long timeTaken; 5772 if (useTombstonedForJavaTraces) { 5773 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime); 5774 } else { 5775 timeTaken = observer.dumpWithTimeout(pid, remainingTime); 5776 } 5777 5778 remainingTime -= timeTaken; 5779 if (remainingTime <= 0) { 5780 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid + 5781 "); deadline exceeded."); 5782 return; 5783 } 5784 5785 if (DEBUG_ANR) { 5786 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms"); 5787 } 5788 } 5789 } 5790 } finally { 5791 if (observer != null) { 5792 observer.stopWatching(); 5793 } 5794 } 5795 } 5796 5797 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 5798 if (true || Build.IS_USER) { 5799 return; 5800 } 5801 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5802 if (tracesPath == null || tracesPath.length() == 0) { 5803 return; 5804 } 5805 5806 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 5807 StrictMode.allowThreadDiskWrites(); 5808 try { 5809 final File tracesFile = new File(tracesPath); 5810 final File tracesDir = tracesFile.getParentFile(); 5811 final File tracesTmp = new File(tracesDir, "__tmp__"); 5812 try { 5813 if (tracesFile.exists()) { 5814 tracesTmp.delete(); 5815 tracesFile.renameTo(tracesTmp); 5816 } 5817 StringBuilder sb = new StringBuilder(); 5818 Time tobj = new Time(); 5819 tobj.set(System.currentTimeMillis()); 5820 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5821 sb.append(": "); 5822 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5823 sb.append(" since "); 5824 sb.append(msg); 5825 FileOutputStream fos = new FileOutputStream(tracesFile); 5826 fos.write(sb.toString().getBytes()); 5827 if (app == null) { 5828 fos.write("\n*** No application process!".getBytes()); 5829 } 5830 fos.close(); 5831 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5832 } catch (IOException e) { 5833 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5834 return; 5835 } 5836 5837 if (app != null) { 5838 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5839 firstPids.add(app.pid); 5840 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */); 5841 } 5842 5843 File lastTracesFile = null; 5844 File curTracesFile = null; 5845 for (int i=9; i>=0; i--) { 5846 String name = String.format(Locale.US, "slow%02d.txt", i); 5847 curTracesFile = new File(tracesDir, name); 5848 if (curTracesFile.exists()) { 5849 if (lastTracesFile != null) { 5850 curTracesFile.renameTo(lastTracesFile); 5851 } else { 5852 curTracesFile.delete(); 5853 } 5854 } 5855 lastTracesFile = curTracesFile; 5856 } 5857 tracesFile.renameTo(curTracesFile); 5858 if (tracesTmp.exists()) { 5859 tracesTmp.renameTo(tracesFile); 5860 } 5861 } finally { 5862 StrictMode.setThreadPolicy(oldPolicy); 5863 } 5864 } 5865 5866 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5867 if (!mLaunchWarningShown) { 5868 mLaunchWarningShown = true; 5869 mUiHandler.post(new Runnable() { 5870 @Override 5871 public void run() { 5872 synchronized (ActivityManagerService.this) { 5873 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5874 d.show(); 5875 mUiHandler.postDelayed(new Runnable() { 5876 @Override 5877 public void run() { 5878 synchronized (ActivityManagerService.this) { 5879 d.dismiss(); 5880 mLaunchWarningShown = false; 5881 } 5882 } 5883 }, 4000); 5884 } 5885 } 5886 }); 5887 } 5888 } 5889 5890 @Override 5891 public boolean clearApplicationUserData(final String packageName, 5892 final IPackageDataObserver observer, int userId) { 5893 enforceNotIsolatedCaller("clearApplicationUserData"); 5894 int uid = Binder.getCallingUid(); 5895 int pid = Binder.getCallingPid(); 5896 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false, 5897 ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5898 5899 final ApplicationInfo appInfo; 5900 final boolean isInstantApp; 5901 5902 long callingId = Binder.clearCallingIdentity(); 5903 try { 5904 IPackageManager pm = AppGlobals.getPackageManager(); 5905 synchronized(this) { 5906 // Instant packages are not protected 5907 if (getPackageManagerInternalLocked().isPackageDataProtected( 5908 resolvedUserId, packageName)) { 5909 throw new SecurityException( 5910 "Cannot clear data for a protected package: " + packageName); 5911 } 5912 5913 ApplicationInfo applicationInfo = null; 5914 try { 5915 applicationInfo = pm.getApplicationInfo(packageName, 5916 MATCH_UNINSTALLED_PACKAGES, resolvedUserId); 5917 } catch (RemoteException e) { 5918 /* ignore */ 5919 } 5920 appInfo = applicationInfo; 5921 5922 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid; 5923 5924 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA, 5925 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) { 5926 throw new SecurityException("PID " + pid + " does not have permission " 5927 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5928 + " of package " + packageName); 5929 } 5930 5931 final boolean hasInstantMetadata = getPackageManagerInternalLocked() 5932 .hasInstantApplicationMetadata(packageName, resolvedUserId); 5933 final boolean isUninstalledAppWithoutInstantMetadata = 5934 (appInfo == null && !hasInstantMetadata); 5935 isInstantApp = (appInfo != null && appInfo.isInstantApp()) 5936 || hasInstantMetadata; 5937 final boolean canAccessInstantApps = checkComponentPermission( 5938 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true) 5939 == PackageManager.PERMISSION_GRANTED; 5940 5941 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp 5942 && !canAccessInstantApps)) { 5943 Slog.w(TAG, "Invalid packageName: " + packageName); 5944 if (observer != null) { 5945 try { 5946 observer.onRemoveCompleted(packageName, false); 5947 } catch (RemoteException e) { 5948 Slog.i(TAG, "Observer no longer exists."); 5949 } 5950 } 5951 return false; 5952 } 5953 5954 if (appInfo != null) { 5955 forceStopPackageLocked(packageName, appInfo.uid, "clear data"); 5956 // Remove all tasks match the cleared application package and user 5957 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5958 final TaskRecord tr = mRecentTasks.get(i); 5959 final String taskPackageName = 5960 tr.getBaseIntent().getComponent().getPackageName(); 5961 if (tr.userId != resolvedUserId) continue; 5962 if (!taskPackageName.equals(packageName)) continue; 5963 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, 5964 REMOVE_FROM_RECENTS); 5965 } 5966 } 5967 } 5968 5969 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() { 5970 @Override 5971 public void onRemoveCompleted(String packageName, boolean succeeded) 5972 throws RemoteException { 5973 if (appInfo != null) { 5974 synchronized (ActivityManagerService.this) { 5975 finishForceStopPackageLocked(packageName, appInfo.uid); 5976 } 5977 } 5978 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5979 Uri.fromParts("package", packageName, null)); 5980 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 5981 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1); 5982 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId); 5983 if (isInstantApp) { 5984 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); 5985 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0, 5986 null, null, permission.ACCESS_INSTANT_APPS, null, false, false, 5987 resolvedUserId); 5988 } else { 5989 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0, 5990 null, null, null, null, false, false, resolvedUserId); 5991 } 5992 5993 if (observer != null) { 5994 observer.onRemoveCompleted(packageName, succeeded); 5995 } 5996 } 5997 }; 5998 5999 try { 6000 // Clear application user data 6001 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId); 6002 6003 if (appInfo != null) { 6004 synchronized (this) { 6005 // Remove all permissions granted from/to this package 6006 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true); 6007 } 6008 6009 // Reset notification settings. 6010 INotificationManager inm = NotificationManager.getService(); 6011 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid); 6012 } 6013 } catch (RemoteException e) { 6014 } 6015 } finally { 6016 Binder.restoreCallingIdentity(callingId); 6017 } 6018 return true; 6019 } 6020 6021 @Override 6022 public void killBackgroundProcesses(final String packageName, int userId) { 6023 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 6024 != PackageManager.PERMISSION_GRANTED && 6025 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 6026 != PackageManager.PERMISSION_GRANTED) { 6027 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 6028 + Binder.getCallingPid() 6029 + ", uid=" + Binder.getCallingUid() 6030 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 6031 Slog.w(TAG, msg); 6032 throw new SecurityException(msg); 6033 } 6034 6035 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 6036 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 6037 long callingId = Binder.clearCallingIdentity(); 6038 try { 6039 IPackageManager pm = AppGlobals.getPackageManager(); 6040 synchronized(this) { 6041 int appId = -1; 6042 try { 6043 appId = UserHandle.getAppId( 6044 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId)); 6045 } catch (RemoteException e) { 6046 } 6047 if (appId == -1) { 6048 Slog.w(TAG, "Invalid packageName: " + packageName); 6049 return; 6050 } 6051 killPackageProcessesLocked(packageName, appId, userId, 6052 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 6053 } 6054 } finally { 6055 Binder.restoreCallingIdentity(callingId); 6056 } 6057 } 6058 6059 @Override 6060 public void killAllBackgroundProcesses() { 6061 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 6062 != PackageManager.PERMISSION_GRANTED) { 6063 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 6064 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 6065 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 6066 Slog.w(TAG, msg); 6067 throw new SecurityException(msg); 6068 } 6069 6070 final long callingId = Binder.clearCallingIdentity(); 6071 try { 6072 synchronized (this) { 6073 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 6074 final int NP = mProcessNames.getMap().size(); 6075 for (int ip = 0; ip < NP; ip++) { 6076 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 6077 final int NA = apps.size(); 6078 for (int ia = 0; ia < NA; ia++) { 6079 final ProcessRecord app = apps.valueAt(ia); 6080 if (app.persistent) { 6081 // We don't kill persistent processes. 6082 continue; 6083 } 6084 if (app.removed) { 6085 procs.add(app); 6086 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 6087 app.removed = true; 6088 procs.add(app); 6089 } 6090 } 6091 } 6092 6093 final int N = procs.size(); 6094 for (int i = 0; i < N; i++) { 6095 removeProcessLocked(procs.get(i), false, true, "kill all background"); 6096 } 6097 6098 mAllowLowerMemLevel = true; 6099 6100 updateOomAdjLocked(); 6101 doLowMemReportIfNeededLocked(null); 6102 } 6103 } finally { 6104 Binder.restoreCallingIdentity(callingId); 6105 } 6106 } 6107 6108 /** 6109 * Kills all background processes, except those matching any of the 6110 * specified properties. 6111 * 6112 * @param minTargetSdk the target SDK version at or above which to preserve 6113 * processes, or {@code -1} to ignore the target SDK 6114 * @param maxProcState the process state at or below which to preserve 6115 * processes, or {@code -1} to ignore the process state 6116 */ 6117 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) { 6118 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 6119 != PackageManager.PERMISSION_GRANTED) { 6120 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid=" 6121 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 6122 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 6123 Slog.w(TAG, msg); 6124 throw new SecurityException(msg); 6125 } 6126 6127 final long callingId = Binder.clearCallingIdentity(); 6128 try { 6129 synchronized (this) { 6130 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 6131 final int NP = mProcessNames.getMap().size(); 6132 for (int ip = 0; ip < NP; ip++) { 6133 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 6134 final int NA = apps.size(); 6135 for (int ia = 0; ia < NA; ia++) { 6136 final ProcessRecord app = apps.valueAt(ia); 6137 if (app.removed) { 6138 procs.add(app); 6139 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk) 6140 && (maxProcState < 0 || app.setProcState > maxProcState)) { 6141 app.removed = true; 6142 procs.add(app); 6143 } 6144 } 6145 } 6146 6147 final int N = procs.size(); 6148 for (int i = 0; i < N; i++) { 6149 removeProcessLocked(procs.get(i), false, true, "kill all background except"); 6150 } 6151 } 6152 } finally { 6153 Binder.restoreCallingIdentity(callingId); 6154 } 6155 } 6156 6157 @Override 6158 public void forceStopPackage(final String packageName, int userId) { 6159 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 6160 != PackageManager.PERMISSION_GRANTED) { 6161 String msg = "Permission Denial: forceStopPackage() from pid=" 6162 + Binder.getCallingPid() 6163 + ", uid=" + Binder.getCallingUid() 6164 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 6165 Slog.w(TAG, msg); 6166 throw new SecurityException(msg); 6167 } 6168 final int callingPid = Binder.getCallingPid(); 6169 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(), 6170 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 6171 long callingId = Binder.clearCallingIdentity(); 6172 try { 6173 IPackageManager pm = AppGlobals.getPackageManager(); 6174 synchronized(this) { 6175 int[] users = userId == UserHandle.USER_ALL 6176 ? mUserController.getUsers() : new int[] { userId }; 6177 for (int user : users) { 6178 int pkgUid = -1; 6179 try { 6180 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 6181 user); 6182 } catch (RemoteException e) { 6183 } 6184 if (pkgUid == -1) { 6185 Slog.w(TAG, "Invalid packageName: " + packageName); 6186 continue; 6187 } 6188 try { 6189 pm.setPackageStoppedState(packageName, true, user); 6190 } catch (RemoteException e) { 6191 } catch (IllegalArgumentException e) { 6192 Slog.w(TAG, "Failed trying to unstop package " 6193 + packageName + ": " + e); 6194 } 6195 if (mUserController.isUserRunningLocked(user, 0)) { 6196 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 6197 finishForceStopPackageLocked(packageName, pkgUid); 6198 } 6199 } 6200 } 6201 } finally { 6202 Binder.restoreCallingIdentity(callingId); 6203 } 6204 } 6205 6206 @Override 6207 public void addPackageDependency(String packageName) { 6208 synchronized (this) { 6209 int callingPid = Binder.getCallingPid(); 6210 if (callingPid == myPid()) { 6211 // Yeah, um, no. 6212 return; 6213 } 6214 ProcessRecord proc; 6215 synchronized (mPidsSelfLocked) { 6216 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 6217 } 6218 if (proc != null) { 6219 if (proc.pkgDeps == null) { 6220 proc.pkgDeps = new ArraySet<String>(1); 6221 } 6222 proc.pkgDeps.add(packageName); 6223 } 6224 } 6225 } 6226 6227 /* 6228 * The pkg name and app id have to be specified. 6229 */ 6230 @Override 6231 public void killApplication(String pkg, int appId, int userId, String reason) { 6232 if (pkg == null) { 6233 return; 6234 } 6235 // Make sure the uid is valid. 6236 if (appId < 0) { 6237 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 6238 return; 6239 } 6240 int callerUid = Binder.getCallingUid(); 6241 // Only the system server can kill an application 6242 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) { 6243 // Post an aysnc message to kill the application 6244 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 6245 msg.arg1 = appId; 6246 msg.arg2 = userId; 6247 Bundle bundle = new Bundle(); 6248 bundle.putString("pkg", pkg); 6249 bundle.putString("reason", reason); 6250 msg.obj = bundle; 6251 mHandler.sendMessage(msg); 6252 } else { 6253 throw new SecurityException(callerUid + " cannot kill pkg: " + 6254 pkg); 6255 } 6256 } 6257 6258 @Override 6259 public void closeSystemDialogs(String reason) { 6260 enforceNotIsolatedCaller("closeSystemDialogs"); 6261 6262 final int pid = Binder.getCallingPid(); 6263 final int uid = Binder.getCallingUid(); 6264 final long origId = Binder.clearCallingIdentity(); 6265 try { 6266 synchronized (this) { 6267 // Only allow this from foreground processes, so that background 6268 // applications can't abuse it to prevent system UI from being shown. 6269 if (uid >= FIRST_APPLICATION_UID) { 6270 ProcessRecord proc; 6271 synchronized (mPidsSelfLocked) { 6272 proc = mPidsSelfLocked.get(pid); 6273 } 6274 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 6275 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 6276 + " from background process " + proc); 6277 return; 6278 } 6279 } 6280 closeSystemDialogsLocked(reason); 6281 } 6282 } finally { 6283 Binder.restoreCallingIdentity(origId); 6284 } 6285 } 6286 6287 void closeSystemDialogsLocked(String reason) { 6288 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 6289 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 6290 | Intent.FLAG_RECEIVER_FOREGROUND); 6291 if (reason != null) { 6292 intent.putExtra("reason", reason); 6293 } 6294 mWindowManager.closeSystemDialogs(reason); 6295 6296 mStackSupervisor.closeSystemDialogsLocked(); 6297 6298 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 6299 AppOpsManager.OP_NONE, null, false, false, 6300 -1, SYSTEM_UID, UserHandle.USER_ALL); 6301 } 6302 6303 @Override 6304 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 6305 enforceNotIsolatedCaller("getProcessMemoryInfo"); 6306 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 6307 for (int i=pids.length-1; i>=0; i--) { 6308 ProcessRecord proc; 6309 int oomAdj; 6310 synchronized (this) { 6311 synchronized (mPidsSelfLocked) { 6312 proc = mPidsSelfLocked.get(pids[i]); 6313 oomAdj = proc != null ? proc.setAdj : 0; 6314 } 6315 } 6316 infos[i] = new Debug.MemoryInfo(); 6317 Debug.getMemoryInfo(pids[i], infos[i]); 6318 if (proc != null) { 6319 synchronized (this) { 6320 if (proc.thread != null && proc.setAdj == oomAdj) { 6321 // Record this for posterity if the process has been stable. 6322 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 6323 infos[i].getTotalUss(), false, proc.pkgList); 6324 } 6325 } 6326 } 6327 } 6328 return infos; 6329 } 6330 6331 @Override 6332 public long[] getProcessPss(int[] pids) { 6333 enforceNotIsolatedCaller("getProcessPss"); 6334 long[] pss = new long[pids.length]; 6335 for (int i=pids.length-1; i>=0; i--) { 6336 ProcessRecord proc; 6337 int oomAdj; 6338 synchronized (this) { 6339 synchronized (mPidsSelfLocked) { 6340 proc = mPidsSelfLocked.get(pids[i]); 6341 oomAdj = proc != null ? proc.setAdj : 0; 6342 } 6343 } 6344 long[] tmpUss = new long[1]; 6345 pss[i] = Debug.getPss(pids[i], tmpUss, null); 6346 if (proc != null) { 6347 synchronized (this) { 6348 if (proc.thread != null && proc.setAdj == oomAdj) { 6349 // Record this for posterity if the process has been stable. 6350 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 6351 } 6352 } 6353 } 6354 } 6355 return pss; 6356 } 6357 6358 @Override 6359 public void killApplicationProcess(String processName, int uid) { 6360 if (processName == null) { 6361 return; 6362 } 6363 6364 int callerUid = Binder.getCallingUid(); 6365 // Only the system server can kill an application 6366 if (callerUid == SYSTEM_UID) { 6367 synchronized (this) { 6368 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 6369 if (app != null && app.thread != null) { 6370 try { 6371 app.thread.scheduleSuicide(); 6372 } catch (RemoteException e) { 6373 // If the other end already died, then our work here is done. 6374 } 6375 } else { 6376 Slog.w(TAG, "Process/uid not found attempting kill of " 6377 + processName + " / " + uid); 6378 } 6379 } 6380 } else { 6381 throw new SecurityException(callerUid + " cannot kill app process: " + 6382 processName); 6383 } 6384 } 6385 6386 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 6387 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 6388 false, true, false, false, UserHandle.getUserId(uid), reason); 6389 } 6390 6391 private void finishForceStopPackageLocked(final String packageName, int uid) { 6392 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 6393 Uri.fromParts("package", packageName, null)); 6394 if (!mProcessesReady) { 6395 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 6396 | Intent.FLAG_RECEIVER_FOREGROUND); 6397 } 6398 intent.putExtra(Intent.EXTRA_UID, uid); 6399 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 6400 broadcastIntentLocked(null, null, intent, 6401 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 6402 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid)); 6403 } 6404 6405 6406 private final boolean killPackageProcessesLocked(String packageName, int appId, 6407 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 6408 boolean doit, boolean evenPersistent, String reason) { 6409 ArrayList<ProcessRecord> procs = new ArrayList<>(); 6410 6411 // Remove all processes this package may have touched: all with the 6412 // same UID (except for the system or root user), and all whose name 6413 // matches the package name. 6414 final int NP = mProcessNames.getMap().size(); 6415 for (int ip=0; ip<NP; ip++) { 6416 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 6417 final int NA = apps.size(); 6418 for (int ia=0; ia<NA; ia++) { 6419 ProcessRecord app = apps.valueAt(ia); 6420 if (app.persistent && !evenPersistent) { 6421 // we don't kill persistent processes 6422 continue; 6423 } 6424 if (app.removed) { 6425 if (doit) { 6426 procs.add(app); 6427 } 6428 continue; 6429 } 6430 6431 // Skip process if it doesn't meet our oom adj requirement. 6432 if (app.setAdj < minOomAdj) { 6433 continue; 6434 } 6435 6436 // If no package is specified, we call all processes under the 6437 // give user id. 6438 if (packageName == null) { 6439 if (userId != UserHandle.USER_ALL && app.userId != userId) { 6440 continue; 6441 } 6442 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 6443 continue; 6444 } 6445 // Package has been specified, we want to hit all processes 6446 // that match it. We need to qualify this by the processes 6447 // that are running under the specified app and user ID. 6448 } else { 6449 final boolean isDep = app.pkgDeps != null 6450 && app.pkgDeps.contains(packageName); 6451 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 6452 continue; 6453 } 6454 if (userId != UserHandle.USER_ALL && app.userId != userId) { 6455 continue; 6456 } 6457 if (!app.pkgList.containsKey(packageName) && !isDep) { 6458 continue; 6459 } 6460 } 6461 6462 // Process has passed all conditions, kill it! 6463 if (!doit) { 6464 return true; 6465 } 6466 app.removed = true; 6467 procs.add(app); 6468 } 6469 } 6470 6471 int N = procs.size(); 6472 for (int i=0; i<N; i++) { 6473 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 6474 } 6475 updateOomAdjLocked(); 6476 return N > 0; 6477 } 6478 6479 private void cleanupDisabledPackageComponentsLocked( 6480 String packageName, int userId, boolean killProcess, String[] changedClasses) { 6481 6482 Set<String> disabledClasses = null; 6483 boolean packageDisabled = false; 6484 IPackageManager pm = AppGlobals.getPackageManager(); 6485 6486 if (changedClasses == null) { 6487 // Nothing changed... 6488 return; 6489 } 6490 6491 // Determine enable/disable state of the package and its components. 6492 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 6493 for (int i = changedClasses.length - 1; i >= 0; i--) { 6494 final String changedClass = changedClasses[i]; 6495 6496 if (changedClass.equals(packageName)) { 6497 try { 6498 // Entire package setting changed 6499 enabled = pm.getApplicationEnabledSetting(packageName, 6500 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM); 6501 } catch (Exception e) { 6502 // No such package/component; probably racing with uninstall. In any 6503 // event it means we have nothing further to do here. 6504 return; 6505 } 6506 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED 6507 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 6508 if (packageDisabled) { 6509 // Entire package is disabled. 6510 // No need to continue to check component states. 6511 disabledClasses = null; 6512 break; 6513 } 6514 } else { 6515 try { 6516 enabled = pm.getComponentEnabledSetting( 6517 new ComponentName(packageName, changedClass), 6518 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM); 6519 } catch (Exception e) { 6520 // As above, probably racing with uninstall. 6521 return; 6522 } 6523 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED 6524 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) { 6525 if (disabledClasses == null) { 6526 disabledClasses = new ArraySet<>(changedClasses.length); 6527 } 6528 disabledClasses.add(changedClass); 6529 } 6530 } 6531 } 6532 6533 if (!packageDisabled && disabledClasses == null) { 6534 // Nothing to do here... 6535 return; 6536 } 6537 6538 // Clean-up disabled activities. 6539 if (mStackSupervisor.finishDisabledPackageActivitiesLocked( 6540 packageName, disabledClasses, true, false, userId) && mBooted) { 6541 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 6542 mStackSupervisor.scheduleIdleLocked(); 6543 } 6544 6545 // Clean-up disabled tasks 6546 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId); 6547 6548 // Clean-up disabled services. 6549 mServices.bringDownDisabledPackageServicesLocked( 6550 packageName, disabledClasses, userId, false, killProcess, true); 6551 6552 // Clean-up disabled providers. 6553 ArrayList<ContentProviderRecord> providers = new ArrayList<>(); 6554 mProviderMap.collectPackageProvidersLocked( 6555 packageName, disabledClasses, true, false, userId, providers); 6556 for (int i = providers.size() - 1; i >= 0; i--) { 6557 removeDyingProviderLocked(null, providers.get(i), true); 6558 } 6559 6560 // Clean-up disabled broadcast receivers. 6561 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) { 6562 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked( 6563 packageName, disabledClasses, userId, true); 6564 } 6565 6566 } 6567 6568 final boolean clearBroadcastQueueForUserLocked(int userId) { 6569 boolean didSomething = false; 6570 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) { 6571 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked( 6572 null, null, userId, true); 6573 } 6574 return didSomething; 6575 } 6576 6577 final boolean forceStopPackageLocked(String packageName, int appId, 6578 boolean callerWillRestart, boolean purgeCache, boolean doit, 6579 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 6580 int i; 6581 6582 if (userId == UserHandle.USER_ALL && packageName == null) { 6583 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 6584 } 6585 6586 if (appId < 0 && packageName != null) { 6587 try { 6588 appId = UserHandle.getAppId(AppGlobals.getPackageManager() 6589 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0)); 6590 } catch (RemoteException e) { 6591 } 6592 } 6593 6594 if (doit) { 6595 if (packageName != null) { 6596 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId 6597 + " user=" + userId + ": " + reason); 6598 } else { 6599 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 6600 } 6601 6602 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId); 6603 } 6604 6605 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId, 6606 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent, 6607 packageName == null ? ("stop user " + userId) : ("stop " + packageName)); 6608 6609 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName); 6610 6611 if (mStackSupervisor.finishDisabledPackageActivitiesLocked( 6612 packageName, null, doit, evenPersistent, userId)) { 6613 if (!doit) { 6614 return true; 6615 } 6616 didSomething = true; 6617 } 6618 6619 if (mServices.bringDownDisabledPackageServicesLocked( 6620 packageName, null, userId, evenPersistent, true, doit)) { 6621 if (!doit) { 6622 return true; 6623 } 6624 didSomething = true; 6625 } 6626 6627 if (packageName == null) { 6628 // Remove all sticky broadcasts from this user. 6629 mStickyBroadcasts.remove(userId); 6630 } 6631 6632 ArrayList<ContentProviderRecord> providers = new ArrayList<>(); 6633 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent, 6634 userId, providers)) { 6635 if (!doit) { 6636 return true; 6637 } 6638 didSomething = true; 6639 } 6640 for (i = providers.size() - 1; i >= 0; i--) { 6641 removeDyingProviderLocked(null, providers.get(i), true); 6642 } 6643 6644 // Remove transient permissions granted from/to this package/user 6645 removeUriPermissionsForPackageLocked(packageName, userId, false); 6646 6647 if (doit) { 6648 for (i = mBroadcastQueues.length - 1; i >= 0; i--) { 6649 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked( 6650 packageName, null, userId, doit); 6651 } 6652 } 6653 6654 if (packageName == null || uninstalling) { 6655 // Remove pending intents. For now we only do this when force 6656 // stopping users, because we have some problems when doing this 6657 // for packages -- app widgets are not currently cleaned up for 6658 // such packages, so they can be left with bad pending intents. 6659 if (mIntentSenderRecords.size() > 0) { 6660 Iterator<WeakReference<PendingIntentRecord>> it 6661 = mIntentSenderRecords.values().iterator(); 6662 while (it.hasNext()) { 6663 WeakReference<PendingIntentRecord> wpir = it.next(); 6664 if (wpir == null) { 6665 it.remove(); 6666 continue; 6667 } 6668 PendingIntentRecord pir = wpir.get(); 6669 if (pir == null) { 6670 it.remove(); 6671 continue; 6672 } 6673 if (packageName == null) { 6674 // Stopping user, remove all objects for the user. 6675 if (pir.key.userId != userId) { 6676 // Not the same user, skip it. 6677 continue; 6678 } 6679 } else { 6680 if (UserHandle.getAppId(pir.uid) != appId) { 6681 // Different app id, skip it. 6682 continue; 6683 } 6684 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 6685 // Different user, skip it. 6686 continue; 6687 } 6688 if (!pir.key.packageName.equals(packageName)) { 6689 // Different package, skip it. 6690 continue; 6691 } 6692 } 6693 if (!doit) { 6694 return true; 6695 } 6696 didSomething = true; 6697 it.remove(); 6698 makeIntentSenderCanceledLocked(pir); 6699 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 6700 pir.key.activity.pendingResults.remove(pir.ref); 6701 } 6702 } 6703 } 6704 } 6705 6706 if (doit) { 6707 if (purgeCache && packageName != null) { 6708 AttributeCache ac = AttributeCache.instance(); 6709 if (ac != null) { 6710 ac.removePackage(packageName); 6711 } 6712 } 6713 if (mBooted) { 6714 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 6715 mStackSupervisor.scheduleIdleLocked(); 6716 } 6717 } 6718 6719 return didSomething; 6720 } 6721 6722 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) { 6723 return removeProcessNameLocked(name, uid, null); 6724 } 6725 6726 private final ProcessRecord removeProcessNameLocked(final String name, final int uid, 6727 final ProcessRecord expecting) { 6728 ProcessRecord old = mProcessNames.get(name, uid); 6729 // Only actually remove when the currently recorded value matches the 6730 // record that we expected; if it doesn't match then we raced with a 6731 // newly created process and we don't want to destroy the new one. 6732 if ((expecting == null) || (old == expecting)) { 6733 mProcessNames.remove(name, uid); 6734 } 6735 if (old != null && old.uidRecord != null) { 6736 old.uidRecord.numProcs--; 6737 if (old.uidRecord.numProcs == 0) { 6738 // No more processes using this uid, tell clients it is gone. 6739 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 6740 "No more processes in " + old.uidRecord); 6741 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE); 6742 EventLogTags.writeAmUidStopped(uid); 6743 mActiveUids.remove(uid); 6744 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT); 6745 } 6746 old.uidRecord = null; 6747 } 6748 mIsolatedProcesses.remove(uid); 6749 return old; 6750 } 6751 6752 private final void addProcessNameLocked(ProcessRecord proc) { 6753 // We shouldn't already have a process under this name, but just in case we 6754 // need to clean up whatever may be there now. 6755 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid); 6756 if (old == proc && proc.persistent) { 6757 // We are re-adding a persistent process. Whatevs! Just leave it there. 6758 Slog.w(TAG, "Re-adding persistent process " + proc); 6759 } else if (old != null) { 6760 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc); 6761 } 6762 UidRecord uidRec = mActiveUids.get(proc.uid); 6763 if (uidRec == null) { 6764 uidRec = new UidRecord(proc.uid); 6765 // This is the first appearance of the uid, report it now! 6766 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 6767 "Creating new process uid: " + uidRec); 6768 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0 6769 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) { 6770 uidRec.setWhitelist = uidRec.curWhitelist = true; 6771 } 6772 uidRec.updateHasInternetPermission(); 6773 mActiveUids.put(proc.uid, uidRec); 6774 EventLogTags.writeAmUidRunning(uidRec.uid); 6775 noteUidProcessState(uidRec.uid, uidRec.curProcState); 6776 } 6777 proc.uidRecord = uidRec; 6778 6779 // Reset render thread tid if it was already set, so new process can set it again. 6780 proc.renderThreadTid = 0; 6781 uidRec.numProcs++; 6782 mProcessNames.put(proc.processName, proc.uid, proc); 6783 if (proc.isolated) { 6784 mIsolatedProcesses.put(proc.uid, proc); 6785 } 6786 } 6787 6788 boolean removeProcessLocked(ProcessRecord app, 6789 boolean callerWillRestart, boolean allowRestart, String reason) { 6790 final String name = app.processName; 6791 final int uid = app.uid; 6792 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES, 6793 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")"); 6794 6795 ProcessRecord old = mProcessNames.get(name, uid); 6796 if (old != app) { 6797 // This process is no longer active, so nothing to do. 6798 Slog.w(TAG, "Ignoring remove of inactive process: " + app); 6799 return false; 6800 } 6801 removeProcessNameLocked(name, uid); 6802 if (mHeavyWeightProcess == app) { 6803 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 6804 mHeavyWeightProcess.userId, 0)); 6805 mHeavyWeightProcess = null; 6806 } 6807 boolean needRestart = false; 6808 if (app.pid > 0 && app.pid != MY_PID) { 6809 int pid = app.pid; 6810 synchronized (mPidsSelfLocked) { 6811 mPidsSelfLocked.remove(pid); 6812 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6813 } 6814 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6815 boolean willRestart = false; 6816 if (app.persistent && !app.isolated) { 6817 if (!callerWillRestart) { 6818 willRestart = true; 6819 } else { 6820 needRestart = true; 6821 } 6822 } 6823 app.kill(reason, true); 6824 if (app.isolated) { 6825 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6826 getPackageManagerInternalLocked().removeIsolatedUid(app.uid); 6827 } 6828 handleAppDiedLocked(app, willRestart, allowRestart); 6829 if (willRestart) { 6830 removeLruProcessLocked(app); 6831 addAppLocked(app.info, null, false, null /* ABI override */); 6832 } 6833 } else { 6834 mRemovedProcesses.add(app); 6835 } 6836 6837 return needRestart; 6838 } 6839 6840 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) { 6841 cleanupAppInLaunchingProvidersLocked(app, true); 6842 removeProcessLocked(app, false, true, "timeout publishing content providers"); 6843 } 6844 6845 private final void processStartTimedOutLocked(ProcessRecord app) { 6846 final int pid = app.pid; 6847 boolean gone = false; 6848 synchronized (mPidsSelfLocked) { 6849 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 6850 if (knownApp != null && knownApp.thread == null) { 6851 mPidsSelfLocked.remove(pid); 6852 gone = true; 6853 } 6854 } 6855 6856 if (gone) { 6857 Slog.w(TAG, "Process " + app + " failed to attach"); 6858 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 6859 pid, app.uid, app.processName); 6860 removeProcessNameLocked(app.processName, app.uid); 6861 if (mHeavyWeightProcess == app) { 6862 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 6863 mHeavyWeightProcess.userId, 0)); 6864 mHeavyWeightProcess = null; 6865 } 6866 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6867 // Take care of any launching providers waiting for this process. 6868 cleanupAppInLaunchingProvidersLocked(app, true); 6869 // Take care of any services that are waiting for the process. 6870 mServices.processStartTimedOutLocked(app); 6871 app.kill("start timeout", true); 6872 if (app.isolated) { 6873 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6874 } 6875 removeLruProcessLocked(app); 6876 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 6877 Slog.w(TAG, "Unattached app died before backup, skipping"); 6878 mHandler.post(new Runnable() { 6879 @Override 6880 public void run(){ 6881 try { 6882 IBackupManager bm = IBackupManager.Stub.asInterface( 6883 ServiceManager.getService(Context.BACKUP_SERVICE)); 6884 bm.agentDisconnected(app.info.packageName); 6885 } catch (RemoteException e) { 6886 // Can't happen; the backup manager is local 6887 } 6888 } 6889 }); 6890 } 6891 if (isPendingBroadcastProcessLocked(pid)) { 6892 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 6893 skipPendingBroadcastLocked(pid); 6894 } 6895 } else { 6896 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 6897 } 6898 } 6899 6900 private final boolean attachApplicationLocked(IApplicationThread thread, 6901 int pid) { 6902 6903 // Find the application record that is being attached... either via 6904 // the pid if we are running in multiple processes, or just pull the 6905 // next app record if we are emulating process with anonymous threads. 6906 ProcessRecord app; 6907 long startTime = SystemClock.uptimeMillis(); 6908 if (pid != MY_PID && pid >= 0) { 6909 synchronized (mPidsSelfLocked) { 6910 app = mPidsSelfLocked.get(pid); 6911 } 6912 } else { 6913 app = null; 6914 } 6915 6916 if (app == null) { 6917 Slog.w(TAG, "No pending application record for pid " + pid 6918 + " (IApplicationThread " + thread + "); dropping process"); 6919 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6920 if (pid > 0 && pid != MY_PID) { 6921 killProcessQuiet(pid); 6922 //TODO: killProcessGroup(app.info.uid, pid); 6923 } else { 6924 try { 6925 thread.scheduleExit(); 6926 } catch (Exception e) { 6927 // Ignore exceptions. 6928 } 6929 } 6930 return false; 6931 } 6932 6933 // If this application record is still attached to a previous 6934 // process, clean it up now. 6935 if (app.thread != null) { 6936 handleAppDiedLocked(app, true, true); 6937 } 6938 6939 // Tell the process all about itself. 6940 6941 if (DEBUG_ALL) Slog.v( 6942 TAG, "Binding process pid " + pid + " to record " + app); 6943 6944 final String processName = app.processName; 6945 try { 6946 AppDeathRecipient adr = new AppDeathRecipient( 6947 app, pid, thread); 6948 thread.asBinder().linkToDeath(adr, 0); 6949 app.deathRecipient = adr; 6950 } catch (RemoteException e) { 6951 app.resetPackageList(mProcessStats); 6952 startProcessLocked(app, "link fail", processName); 6953 return false; 6954 } 6955 6956 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6957 6958 app.makeActive(thread, mProcessStats); 6959 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ; 6960 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; 6961 app.forcingToImportant = null; 6962 updateProcessForegroundLocked(app, false, false); 6963 app.hasShownUi = false; 6964 app.debugging = false; 6965 app.cached = false; 6966 app.killedByAm = false; 6967 app.killed = false; 6968 6969 6970 // We carefully use the same state that PackageManager uses for 6971 // filtering, since we use this flag to decide if we need to install 6972 // providers when user is unlocked later 6973 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId); 6974 6975 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6976 6977 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6978 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6979 6980 if (providers != null && checkAppInLaunchingProvidersLocked(app)) { 6981 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG); 6982 msg.obj = app; 6983 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT); 6984 } 6985 6986 checkTime(startTime, "attachApplicationLocked: before bindApplication"); 6987 6988 if (!normalMode) { 6989 Slog.i(TAG, "Launching preboot mode app: " + app); 6990 } 6991 6992 if (DEBUG_ALL) Slog.v( 6993 TAG, "New app record " + app 6994 + " thread=" + thread.asBinder() + " pid=" + pid); 6995 try { 6996 int testMode = ApplicationThreadConstants.DEBUG_OFF; 6997 if (mDebugApp != null && mDebugApp.equals(processName)) { 6998 testMode = mWaitForDebugger 6999 ? ApplicationThreadConstants.DEBUG_WAIT 7000 : ApplicationThreadConstants.DEBUG_ON; 7001 app.debugging = true; 7002 if (mDebugTransient) { 7003 mDebugApp = mOrigDebugApp; 7004 mWaitForDebugger = mOrigWaitForDebugger; 7005 } 7006 } 7007 7008 ProfilerInfo profilerInfo = null; 7009 String agent = null; 7010 if (mProfileApp != null && mProfileApp.equals(processName)) { 7011 mProfileProc = app; 7012 profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ? 7013 new ProfilerInfo(mProfilerInfo) : null; 7014 agent = mProfilerInfo != null ? mProfilerInfo.agent : null; 7015 } else if (app.instr != null && app.instr.mProfileFile != null) { 7016 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false, 7017 null); 7018 } 7019 7020 boolean enableTrackAllocation = false; 7021 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) { 7022 enableTrackAllocation = true; 7023 mTrackAllocationApp = null; 7024 } 7025 7026 // If the app is being launched for restore or full backup, set it up specially 7027 boolean isRestrictedBackupMode = false; 7028 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 7029 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID 7030 && ((mBackupTarget.backupMode == BackupRecord.RESTORE) 7031 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 7032 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL)); 7033 } 7034 7035 if (app.instr != null) { 7036 notifyPackageUse(app.instr.mClass.getPackageName(), 7037 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION); 7038 } 7039 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc " 7040 + processName + " with config " + getGlobalConfiguration()); 7041 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info; 7042 app.compat = compatibilityInfoForPackageLocked(appInfo); 7043 7044 if (profilerInfo != null && profilerInfo.profileFd != null) { 7045 profilerInfo.profileFd = profilerInfo.profileFd.dup(); 7046 } 7047 7048 // We deprecated Build.SERIAL and it is not accessible to 7049 // apps that target the v2 security sandbox. Since access to 7050 // the serial is now behind a permission we push down the value. 7051 String buildSerial = appInfo.targetSandboxVersion < 2 7052 ? sTheRealBuildSerial : Build.UNKNOWN; 7053 7054 // Check if this is a secondary process that should be incorporated into some 7055 // currently active instrumentation. (Note we do this AFTER all of the profiling 7056 // stuff above because profiling can currently happen only in the primary 7057 // instrumentation process.) 7058 if (mActiveInstrumentation.size() > 0 && app.instr == null) { 7059 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) { 7060 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i); 7061 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) { 7062 if (aInstr.mTargetProcesses.length == 0) { 7063 // This is the wildcard mode, where every process brought up for 7064 // the target instrumentation should be included. 7065 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) { 7066 app.instr = aInstr; 7067 aInstr.mRunningProcesses.add(app); 7068 } 7069 } else { 7070 for (String proc : aInstr.mTargetProcesses) { 7071 if (proc.equals(app.processName)) { 7072 app.instr = aInstr; 7073 aInstr.mRunningProcesses.add(app); 7074 break; 7075 } 7076 } 7077 } 7078 } 7079 } 7080 } 7081 7082 // If we were asked to attach an agent on startup, do so now, before we're binding 7083 // application code. 7084 if (agent != null) { 7085 thread.attachAgent(agent); 7086 } 7087 7088 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication"); 7089 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app); 7090 if (app.instr != null) { 7091 thread.bindApplication(processName, appInfo, providers, 7092 app.instr.mClass, 7093 profilerInfo, app.instr.mArguments, 7094 app.instr.mWatcher, 7095 app.instr.mUiAutomationConnection, testMode, 7096 mBinderTransactionTrackingEnabled, enableTrackAllocation, 7097 isRestrictedBackupMode || !normalMode, app.persistent, 7098 new Configuration(getGlobalConfiguration()), app.compat, 7099 getCommonServicesLocked(app.isolated), 7100 mCoreSettingsObserver.getCoreSettingsLocked(), 7101 buildSerial); 7102 } else { 7103 thread.bindApplication(processName, appInfo, providers, null, profilerInfo, 7104 null, null, null, testMode, 7105 mBinderTransactionTrackingEnabled, enableTrackAllocation, 7106 isRestrictedBackupMode || !normalMode, app.persistent, 7107 new Configuration(getGlobalConfiguration()), app.compat, 7108 getCommonServicesLocked(app.isolated), 7109 mCoreSettingsObserver.getCoreSettingsLocked(), 7110 buildSerial); 7111 } 7112 7113 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication"); 7114 updateLruProcessLocked(app, false, null); 7115 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked"); 7116 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 7117 } catch (Exception e) { 7118 // todo: Yikes! What should we do? For now we will try to 7119 // start another process, but that could easily get us in 7120 // an infinite loop of restarting processes... 7121 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 7122 7123 app.resetPackageList(mProcessStats); 7124 app.unlinkDeathRecipient(); 7125 startProcessLocked(app, "bind fail", processName); 7126 return false; 7127 } 7128 7129 // Remove this record from the list of starting applications. 7130 mPersistentStartingProcesses.remove(app); 7131 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES, 7132 "Attach application locked removing on hold: " + app); 7133 mProcessesOnHold.remove(app); 7134 7135 boolean badApp = false; 7136 boolean didSomething = false; 7137 7138 // See if the top visible activity is waiting to run in this process... 7139 if (normalMode) { 7140 try { 7141 if (mStackSupervisor.attachApplicationLocked(app)) { 7142 didSomething = true; 7143 } 7144 } catch (Exception e) { 7145 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 7146 badApp = true; 7147 } 7148 } 7149 7150 // Find any services that should be running in this process... 7151 if (!badApp) { 7152 try { 7153 didSomething |= mServices.attachApplicationLocked(app, processName); 7154 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked"); 7155 } catch (Exception e) { 7156 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 7157 badApp = true; 7158 } 7159 } 7160 7161 // Check if a next-broadcast receiver is in this process... 7162 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 7163 try { 7164 didSomething |= sendPendingBroadcastsLocked(app); 7165 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked"); 7166 } catch (Exception e) { 7167 // If the app died trying to launch the receiver we declare it 'bad' 7168 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 7169 badApp = true; 7170 } 7171 } 7172 7173 // Check whether the next backup agent is in this process... 7174 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) { 7175 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, 7176 "New app is backup target, launching agent for " + app); 7177 notifyPackageUse(mBackupTarget.appInfo.packageName, 7178 PackageManager.NOTIFY_PACKAGE_USE_BACKUP); 7179 try { 7180 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 7181 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 7182 mBackupTarget.backupMode); 7183 } catch (Exception e) { 7184 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 7185 badApp = true; 7186 } 7187 } 7188 7189 if (badApp) { 7190 app.kill("error during init", true); 7191 handleAppDiedLocked(app, false, true); 7192 return false; 7193 } 7194 7195 if (!didSomething) { 7196 updateOomAdjLocked(); 7197 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked"); 7198 } 7199 7200 return true; 7201 } 7202 7203 @Override 7204 public final void attachApplication(IApplicationThread thread) { 7205 synchronized (this) { 7206 int callingPid = Binder.getCallingPid(); 7207 final long origId = Binder.clearCallingIdentity(); 7208 attachApplicationLocked(thread, callingPid); 7209 Binder.restoreCallingIdentity(origId); 7210 } 7211 } 7212 7213 @Override 7214 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 7215 final long origId = Binder.clearCallingIdentity(); 7216 synchronized (this) { 7217 ActivityStack stack = ActivityRecord.getStackLocked(token); 7218 if (stack != null) { 7219 ActivityRecord r = 7220 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */, 7221 false /* processPausingActivities */, config); 7222 if (stopProfiling) { 7223 if ((mProfileProc == r.app) && mProfilerInfo != null) { 7224 clearProfilerLocked(); 7225 } 7226 } 7227 } 7228 } 7229 Binder.restoreCallingIdentity(origId); 7230 } 7231 7232 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 7233 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 7234 finishBooting ? 1 : 0, enableScreen ? 1 : 0)); 7235 } 7236 7237 void enableScreenAfterBoot() { 7238 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 7239 SystemClock.uptimeMillis()); 7240 mWindowManager.enableScreenAfterBoot(); 7241 7242 synchronized (this) { 7243 updateEventDispatchingLocked(); 7244 } 7245 } 7246 7247 @Override 7248 public void showBootMessage(final CharSequence msg, final boolean always) { 7249 if (Binder.getCallingUid() != myUid()) { 7250 throw new SecurityException(); 7251 } 7252 mWindowManager.showBootMessage(msg, always); 7253 } 7254 7255 @Override 7256 public void keyguardGoingAway(int flags) { 7257 enforceNotIsolatedCaller("keyguardGoingAway"); 7258 final long token = Binder.clearCallingIdentity(); 7259 try { 7260 synchronized (this) { 7261 mKeyguardController.keyguardGoingAway(flags); 7262 } 7263 } finally { 7264 Binder.restoreCallingIdentity(token); 7265 } 7266 } 7267 7268 /** 7269 * @return whther the keyguard is currently locked. 7270 */ 7271 boolean isKeyguardLocked() { 7272 return mKeyguardController.isKeyguardLocked(); 7273 } 7274 7275 final void finishBooting() { 7276 synchronized (this) { 7277 if (!mBootAnimationComplete) { 7278 mCallFinishBooting = true; 7279 return; 7280 } 7281 mCallFinishBooting = false; 7282 } 7283 7284 ArraySet<String> completedIsas = new ArraySet<String>(); 7285 for (String abi : Build.SUPPORTED_ABIS) { 7286 zygoteProcess.establishZygoteConnectionForAbi(abi); 7287 final String instructionSet = VMRuntime.getInstructionSet(abi); 7288 if (!completedIsas.contains(instructionSet)) { 7289 try { 7290 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)); 7291 } catch (InstallerException e) { 7292 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" + 7293 e.getMessage() +")"); 7294 } 7295 completedIsas.add(instructionSet); 7296 } 7297 } 7298 7299 IntentFilter pkgFilter = new IntentFilter(); 7300 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 7301 pkgFilter.addDataScheme("package"); 7302 mContext.registerReceiver(new BroadcastReceiver() { 7303 @Override 7304 public void onReceive(Context context, Intent intent) { 7305 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 7306 if (pkgs != null) { 7307 for (String pkg : pkgs) { 7308 synchronized (ActivityManagerService.this) { 7309 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 7310 0, "query restart")) { 7311 setResultCode(Activity.RESULT_OK); 7312 return; 7313 } 7314 } 7315 } 7316 } 7317 } 7318 }, pkgFilter); 7319 7320 IntentFilter dumpheapFilter = new IntentFilter(); 7321 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP); 7322 mContext.registerReceiver(new BroadcastReceiver() { 7323 @Override 7324 public void onReceive(Context context, Intent intent) { 7325 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) { 7326 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000); 7327 } else { 7328 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG); 7329 } 7330 } 7331 }, dumpheapFilter); 7332 7333 // Let system services know. 7334 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 7335 7336 synchronized (this) { 7337 // Ensure that any processes we had put on hold are now started 7338 // up. 7339 final int NP = mProcessesOnHold.size(); 7340 if (NP > 0) { 7341 ArrayList<ProcessRecord> procs = 7342 new ArrayList<ProcessRecord>(mProcessesOnHold); 7343 for (int ip=0; ip<NP; ip++) { 7344 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: " 7345 + procs.get(ip)); 7346 startProcessLocked(procs.get(ip), "on-hold", null); 7347 } 7348 } 7349 7350 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 7351 // Start looking for apps that are abusing wake locks. 7352 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG); 7353 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL); 7354 // Tell anyone interested that we are done booting! 7355 SystemProperties.set("sys.boot_completed", "1"); 7356 7357 // And trigger dev.bootcomplete if we are not showing encryption progress 7358 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 7359 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 7360 SystemProperties.set("dev.bootcomplete", "1"); 7361 } 7362 mUserController.sendBootCompletedLocked( 7363 new IIntentReceiver.Stub() { 7364 @Override 7365 public void performReceive(Intent intent, int resultCode, 7366 String data, Bundle extras, boolean ordered, 7367 boolean sticky, int sendingUser) { 7368 synchronized (ActivityManagerService.this) { 7369 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 7370 true, false); 7371 } 7372 } 7373 }); 7374 scheduleStartProfilesLocked(); 7375 } 7376 } 7377 } 7378 7379 @Override 7380 public void bootAnimationComplete() { 7381 final boolean callFinishBooting; 7382 synchronized (this) { 7383 callFinishBooting = mCallFinishBooting; 7384 mBootAnimationComplete = true; 7385 } 7386 if (callFinishBooting) { 7387 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); 7388 finishBooting(); 7389 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 7390 } 7391 } 7392 7393 final void ensureBootCompleted() { 7394 boolean booting; 7395 boolean enableScreen; 7396 synchronized (this) { 7397 booting = mBooting; 7398 mBooting = false; 7399 enableScreen = !mBooted; 7400 mBooted = true; 7401 } 7402 7403 if (booting) { 7404 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); 7405 finishBooting(); 7406 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 7407 } 7408 7409 if (enableScreen) { 7410 enableScreenAfterBoot(); 7411 } 7412 } 7413 7414 @Override 7415 public final void activityResumed(IBinder token) { 7416 final long origId = Binder.clearCallingIdentity(); 7417 synchronized(this) { 7418 ActivityRecord.activityResumedLocked(token); 7419 mWindowManager.notifyAppResumedFinished(token); 7420 } 7421 Binder.restoreCallingIdentity(origId); 7422 } 7423 7424 @Override 7425 public final void activityPaused(IBinder token) { 7426 final long origId = Binder.clearCallingIdentity(); 7427 synchronized(this) { 7428 ActivityStack stack = ActivityRecord.getStackLocked(token); 7429 if (stack != null) { 7430 stack.activityPausedLocked(token, false); 7431 } 7432 } 7433 Binder.restoreCallingIdentity(origId); 7434 } 7435 7436 @Override 7437 public final void activityStopped(IBinder token, Bundle icicle, 7438 PersistableBundle persistentState, CharSequence description) { 7439 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token); 7440 7441 // Refuse possible leaked file descriptors 7442 if (icicle != null && icicle.hasFileDescriptors()) { 7443 throw new IllegalArgumentException("File descriptors passed in Bundle"); 7444 } 7445 7446 final long origId = Binder.clearCallingIdentity(); 7447 7448 synchronized (this) { 7449 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 7450 if (r != null) { 7451 r.activityStoppedLocked(icicle, persistentState, description); 7452 } 7453 } 7454 7455 trimApplications(); 7456 7457 Binder.restoreCallingIdentity(origId); 7458 } 7459 7460 @Override 7461 public final void activityDestroyed(IBinder token) { 7462 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token); 7463 synchronized (this) { 7464 ActivityStack stack = ActivityRecord.getStackLocked(token); 7465 if (stack != null) { 7466 stack.activityDestroyedLocked(token, "activityDestroyed"); 7467 } 7468 } 7469 } 7470 7471 @Override 7472 public final void activityRelaunched(IBinder token) { 7473 final long origId = Binder.clearCallingIdentity(); 7474 synchronized (this) { 7475 mStackSupervisor.activityRelaunchedLocked(token); 7476 } 7477 Binder.restoreCallingIdentity(origId); 7478 } 7479 7480 @Override 7481 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration, 7482 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) { 7483 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " " 7484 + horizontalSizeConfiguration + " " + verticalSizeConfigurations); 7485 synchronized (this) { 7486 ActivityRecord record = ActivityRecord.isInStackLocked(token); 7487 if (record == null) { 7488 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not " 7489 + "found for: " + token); 7490 } 7491 record.setSizeConfigurations(horizontalSizeConfiguration, 7492 verticalSizeConfigurations, smallestSizeConfigurations); 7493 } 7494 } 7495 7496 @Override 7497 public final void notifyLaunchTaskBehindComplete(IBinder token) { 7498 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 7499 } 7500 7501 @Override 7502 public final void notifyEnterAnimationComplete(IBinder token) { 7503 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 7504 } 7505 7506 @Override 7507 public String getCallingPackage(IBinder token) { 7508 synchronized (this) { 7509 ActivityRecord r = getCallingRecordLocked(token); 7510 return r != null ? r.info.packageName : null; 7511 } 7512 } 7513 7514 @Override 7515 public ComponentName getCallingActivity(IBinder token) { 7516 synchronized (this) { 7517 ActivityRecord r = getCallingRecordLocked(token); 7518 return r != null ? r.intent.getComponent() : null; 7519 } 7520 } 7521 7522 private ActivityRecord getCallingRecordLocked(IBinder token) { 7523 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7524 if (r == null) { 7525 return null; 7526 } 7527 return r.resultTo; 7528 } 7529 7530 @Override 7531 public ComponentName getActivityClassForToken(IBinder token) { 7532 synchronized(this) { 7533 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7534 if (r == null) { 7535 return null; 7536 } 7537 return r.intent.getComponent(); 7538 } 7539 } 7540 7541 @Override 7542 public String getPackageForToken(IBinder token) { 7543 synchronized(this) { 7544 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7545 if (r == null) { 7546 return null; 7547 } 7548 return r.packageName; 7549 } 7550 } 7551 7552 @Override 7553 public boolean isRootVoiceInteraction(IBinder token) { 7554 synchronized(this) { 7555 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7556 if (r == null) { 7557 return false; 7558 } 7559 return r.rootVoiceInteraction; 7560 } 7561 } 7562 7563 @Override 7564 public IIntentSender getIntentSender(int type, 7565 String packageName, IBinder token, String resultWho, 7566 int requestCode, Intent[] intents, String[] resolvedTypes, 7567 int flags, Bundle bOptions, int userId) { 7568 enforceNotIsolatedCaller("getIntentSender"); 7569 // Refuse possible leaked file descriptors 7570 if (intents != null) { 7571 if (intents.length < 1) { 7572 throw new IllegalArgumentException("Intents array length must be >= 1"); 7573 } 7574 for (int i=0; i<intents.length; i++) { 7575 Intent intent = intents[i]; 7576 if (intent != null) { 7577 if (intent.hasFileDescriptors()) { 7578 throw new IllegalArgumentException("File descriptors passed in Intent"); 7579 } 7580 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 7581 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 7582 throw new IllegalArgumentException( 7583 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 7584 } 7585 intents[i] = new Intent(intent); 7586 } 7587 } 7588 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 7589 throw new IllegalArgumentException( 7590 "Intent array length does not match resolvedTypes length"); 7591 } 7592 } 7593 if (bOptions != null) { 7594 if (bOptions.hasFileDescriptors()) { 7595 throw new IllegalArgumentException("File descriptors passed in options"); 7596 } 7597 } 7598 7599 synchronized(this) { 7600 int callingUid = Binder.getCallingUid(); 7601 int origUserId = userId; 7602 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7603 type == ActivityManager.INTENT_SENDER_BROADCAST, 7604 ALLOW_NON_FULL, "getIntentSender", null); 7605 if (origUserId == UserHandle.USER_CURRENT) { 7606 // We don't want to evaluate this until the pending intent is 7607 // actually executed. However, we do want to always do the 7608 // security checking for it above. 7609 userId = UserHandle.USER_CURRENT; 7610 } 7611 try { 7612 if (callingUid != 0 && callingUid != SYSTEM_UID) { 7613 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName, 7614 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid)); 7615 if (!UserHandle.isSameApp(callingUid, uid)) { 7616 String msg = "Permission Denial: getIntentSender() from pid=" 7617 + Binder.getCallingPid() 7618 + ", uid=" + Binder.getCallingUid() 7619 + ", (need uid=" + uid + ")" 7620 + " is not allowed to send as package " + packageName; 7621 Slog.w(TAG, msg); 7622 throw new SecurityException(msg); 7623 } 7624 } 7625 7626 return getIntentSenderLocked(type, packageName, callingUid, userId, 7627 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions); 7628 7629 } catch (RemoteException e) { 7630 throw new SecurityException(e); 7631 } 7632 } 7633 } 7634 7635 IIntentSender getIntentSenderLocked(int type, String packageName, 7636 int callingUid, int userId, IBinder token, String resultWho, 7637 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 7638 Bundle bOptions) { 7639 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 7640 ActivityRecord activity = null; 7641 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 7642 activity = ActivityRecord.isInStackLocked(token); 7643 if (activity == null) { 7644 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack"); 7645 return null; 7646 } 7647 if (activity.finishing) { 7648 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing"); 7649 return null; 7650 } 7651 } 7652 7653 // We're going to be splicing together extras before sending, so we're 7654 // okay poking into any contained extras. 7655 if (intents != null) { 7656 for (int i = 0; i < intents.length; i++) { 7657 intents[i].setDefusable(true); 7658 } 7659 } 7660 Bundle.setDefusable(bOptions, true); 7661 7662 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 7663 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 7664 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 7665 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 7666 |PendingIntent.FLAG_UPDATE_CURRENT); 7667 7668 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 7669 type, packageName, activity, resultWho, 7670 requestCode, intents, resolvedTypes, flags, bOptions, userId); 7671 WeakReference<PendingIntentRecord> ref; 7672 ref = mIntentSenderRecords.get(key); 7673 PendingIntentRecord rec = ref != null ? ref.get() : null; 7674 if (rec != null) { 7675 if (!cancelCurrent) { 7676 if (updateCurrent) { 7677 if (rec.key.requestIntent != null) { 7678 rec.key.requestIntent.replaceExtras(intents != null ? 7679 intents[intents.length - 1] : null); 7680 } 7681 if (intents != null) { 7682 intents[intents.length-1] = rec.key.requestIntent; 7683 rec.key.allIntents = intents; 7684 rec.key.allResolvedTypes = resolvedTypes; 7685 } else { 7686 rec.key.allIntents = null; 7687 rec.key.allResolvedTypes = null; 7688 } 7689 } 7690 return rec; 7691 } 7692 makeIntentSenderCanceledLocked(rec); 7693 mIntentSenderRecords.remove(key); 7694 } 7695 if (noCreate) { 7696 return rec; 7697 } 7698 rec = new PendingIntentRecord(this, key, callingUid); 7699 mIntentSenderRecords.put(key, rec.ref); 7700 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 7701 if (activity.pendingResults == null) { 7702 activity.pendingResults 7703 = new HashSet<WeakReference<PendingIntentRecord>>(); 7704 } 7705 activity.pendingResults.add(rec.ref); 7706 } 7707 return rec; 7708 } 7709 7710 @Override 7711 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code, 7712 Intent intent, String resolvedType, 7713 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 7714 if (target instanceof PendingIntentRecord) { 7715 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType, 7716 whitelistToken, finishedReceiver, requiredPermission, options); 7717 } else { 7718 if (intent == null) { 7719 // Weird case: someone has given us their own custom IIntentSender, and now 7720 // they have someone else trying to send to it but of course this isn't 7721 // really a PendingIntent, so there is no base Intent, and the caller isn't 7722 // supplying an Intent... but we never want to dispatch a null Intent to 7723 // a receiver, so um... let's make something up. 7724 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call"); 7725 intent = new Intent(Intent.ACTION_MAIN); 7726 } 7727 try { 7728 target.send(code, intent, resolvedType, whitelistToken, null, 7729 requiredPermission, options); 7730 } catch (RemoteException e) { 7731 } 7732 // Platform code can rely on getting a result back when the send is done, but if 7733 // this intent sender is from outside of the system we can't rely on it doing that. 7734 // So instead we don't give it the result receiver, and instead just directly 7735 // report the finish immediately. 7736 if (finishedReceiver != null) { 7737 try { 7738 finishedReceiver.performReceive(intent, 0, 7739 null, null, false, false, UserHandle.getCallingUserId()); 7740 } catch (RemoteException e) { 7741 } 7742 } 7743 return 0; 7744 } 7745 } 7746 7747 @Override 7748 public void cancelIntentSender(IIntentSender sender) { 7749 if (!(sender instanceof PendingIntentRecord)) { 7750 return; 7751 } 7752 synchronized(this) { 7753 PendingIntentRecord rec = (PendingIntentRecord)sender; 7754 try { 7755 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName, 7756 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId()); 7757 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 7758 String msg = "Permission Denial: cancelIntentSender() from pid=" 7759 + Binder.getCallingPid() 7760 + ", uid=" + Binder.getCallingUid() 7761 + " is not allowed to cancel package " 7762 + rec.key.packageName; 7763 Slog.w(TAG, msg); 7764 throw new SecurityException(msg); 7765 } 7766 } catch (RemoteException e) { 7767 throw new SecurityException(e); 7768 } 7769 cancelIntentSenderLocked(rec, true); 7770 } 7771 } 7772 7773 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 7774 makeIntentSenderCanceledLocked(rec); 7775 mIntentSenderRecords.remove(rec.key); 7776 if (cleanActivity && rec.key.activity != null) { 7777 rec.key.activity.pendingResults.remove(rec.ref); 7778 } 7779 } 7780 7781 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) { 7782 rec.canceled = true; 7783 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked(); 7784 if (callbacks != null) { 7785 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget(); 7786 } 7787 } 7788 7789 @Override 7790 public String getPackageForIntentSender(IIntentSender pendingResult) { 7791 if (!(pendingResult instanceof PendingIntentRecord)) { 7792 return null; 7793 } 7794 try { 7795 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7796 return res.key.packageName; 7797 } catch (ClassCastException e) { 7798 } 7799 return null; 7800 } 7801 7802 @Override 7803 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) { 7804 if (!(sender instanceof PendingIntentRecord)) { 7805 return; 7806 } 7807 synchronized(this) { 7808 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver); 7809 } 7810 } 7811 7812 @Override 7813 public void unregisterIntentSenderCancelListener(IIntentSender sender, 7814 IResultReceiver receiver) { 7815 if (!(sender instanceof PendingIntentRecord)) { 7816 return; 7817 } 7818 synchronized(this) { 7819 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver); 7820 } 7821 } 7822 7823 @Override 7824 public int getUidForIntentSender(IIntentSender sender) { 7825 if (sender instanceof PendingIntentRecord) { 7826 try { 7827 PendingIntentRecord res = (PendingIntentRecord)sender; 7828 return res.uid; 7829 } catch (ClassCastException e) { 7830 } 7831 } 7832 return -1; 7833 } 7834 7835 @Override 7836 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 7837 if (!(pendingResult instanceof PendingIntentRecord)) { 7838 return false; 7839 } 7840 try { 7841 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7842 if (res.key.allIntents == null) { 7843 return false; 7844 } 7845 for (int i=0; i<res.key.allIntents.length; i++) { 7846 Intent intent = res.key.allIntents[i]; 7847 if (intent.getPackage() != null && intent.getComponent() != null) { 7848 return false; 7849 } 7850 } 7851 return true; 7852 } catch (ClassCastException e) { 7853 } 7854 return false; 7855 } 7856 7857 @Override 7858 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 7859 if (!(pendingResult instanceof PendingIntentRecord)) { 7860 return false; 7861 } 7862 try { 7863 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7864 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 7865 return true; 7866 } 7867 return false; 7868 } catch (ClassCastException e) { 7869 } 7870 return false; 7871 } 7872 7873 @Override 7874 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 7875 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT, 7876 "getIntentForIntentSender()"); 7877 if (!(pendingResult instanceof PendingIntentRecord)) { 7878 return null; 7879 } 7880 try { 7881 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7882 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 7883 } catch (ClassCastException e) { 7884 } 7885 return null; 7886 } 7887 7888 @Override 7889 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 7890 if (!(pendingResult instanceof PendingIntentRecord)) { 7891 return null; 7892 } 7893 try { 7894 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7895 synchronized (this) { 7896 return getTagForIntentSenderLocked(res, prefix); 7897 } 7898 } catch (ClassCastException e) { 7899 } 7900 return null; 7901 } 7902 7903 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) { 7904 final Intent intent = res.key.requestIntent; 7905 if (intent != null) { 7906 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 7907 || res.lastTagPrefix.equals(prefix))) { 7908 return res.lastTag; 7909 } 7910 res.lastTagPrefix = prefix; 7911 final StringBuilder sb = new StringBuilder(128); 7912 if (prefix != null) { 7913 sb.append(prefix); 7914 } 7915 if (intent.getAction() != null) { 7916 sb.append(intent.getAction()); 7917 } else if (intent.getComponent() != null) { 7918 intent.getComponent().appendShortString(sb); 7919 } else { 7920 sb.append("?"); 7921 } 7922 return res.lastTag = sb.toString(); 7923 } 7924 return null; 7925 } 7926 7927 @Override 7928 public void setProcessLimit(int max) { 7929 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 7930 "setProcessLimit()"); 7931 synchronized (this) { 7932 mConstants.setOverrideMaxCachedProcesses(max); 7933 } 7934 trimApplications(); 7935 } 7936 7937 @Override 7938 public int getProcessLimit() { 7939 synchronized (this) { 7940 return mConstants.getOverrideMaxCachedProcesses(); 7941 } 7942 } 7943 7944 void importanceTokenDied(ImportanceToken token) { 7945 synchronized (ActivityManagerService.this) { 7946 synchronized (mPidsSelfLocked) { 7947 ImportanceToken cur 7948 = mImportantProcesses.get(token.pid); 7949 if (cur != token) { 7950 return; 7951 } 7952 mImportantProcesses.remove(token.pid); 7953 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 7954 if (pr == null) { 7955 return; 7956 } 7957 pr.forcingToImportant = null; 7958 updateProcessForegroundLocked(pr, false, false); 7959 } 7960 updateOomAdjLocked(); 7961 } 7962 } 7963 7964 @Override 7965 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) { 7966 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 7967 "setProcessImportant()"); 7968 synchronized(this) { 7969 boolean changed = false; 7970 7971 synchronized (mPidsSelfLocked) { 7972 ProcessRecord pr = mPidsSelfLocked.get(pid); 7973 if (pr == null && isForeground) { 7974 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 7975 return; 7976 } 7977 ImportanceToken oldToken = mImportantProcesses.get(pid); 7978 if (oldToken != null) { 7979 oldToken.token.unlinkToDeath(oldToken, 0); 7980 mImportantProcesses.remove(pid); 7981 if (pr != null) { 7982 pr.forcingToImportant = null; 7983 } 7984 changed = true; 7985 } 7986 if (isForeground && token != null) { 7987 ImportanceToken newToken = new ImportanceToken(pid, token, reason) { 7988 @Override 7989 public void binderDied() { 7990 importanceTokenDied(this); 7991 } 7992 }; 7993 try { 7994 token.linkToDeath(newToken, 0); 7995 mImportantProcesses.put(pid, newToken); 7996 pr.forcingToImportant = newToken; 7997 changed = true; 7998 } catch (RemoteException e) { 7999 // If the process died while doing this, we will later 8000 // do the cleanup with the process death link. 8001 } 8002 } 8003 } 8004 8005 if (changed) { 8006 updateOomAdjLocked(); 8007 } 8008 } 8009 } 8010 8011 @Override 8012 public boolean isAppForeground(int uid) throws RemoteException { 8013 synchronized (this) { 8014 UidRecord uidRec = mActiveUids.get(uid); 8015 if (uidRec == null || uidRec.idle) { 8016 return false; 8017 } 8018 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 8019 } 8020 } 8021 8022 // NOTE: this is an internal method used by the OnShellCommand implementation only and should 8023 // be guarded by permission checking. 8024 int getUidState(int uid) { 8025 synchronized (this) { 8026 return getUidStateLocked(uid); 8027 } 8028 } 8029 8030 int getUidStateLocked(int uid) { 8031 UidRecord uidRec = mActiveUids.get(uid); 8032 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState; 8033 } 8034 8035 @Override 8036 public boolean isInMultiWindowMode(IBinder token) { 8037 final long origId = Binder.clearCallingIdentity(); 8038 try { 8039 synchronized(this) { 8040 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8041 if (r == null) { 8042 return false; 8043 } 8044 // An activity is consider to be in multi-window mode if its task isn't fullscreen. 8045 return !r.getTask().mFullscreen; 8046 } 8047 } finally { 8048 Binder.restoreCallingIdentity(origId); 8049 } 8050 } 8051 8052 @Override 8053 public boolean isInPictureInPictureMode(IBinder token) { 8054 final long origId = Binder.clearCallingIdentity(); 8055 try { 8056 synchronized(this) { 8057 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token)); 8058 } 8059 } finally { 8060 Binder.restoreCallingIdentity(origId); 8061 } 8062 } 8063 8064 private boolean isInPictureInPictureMode(ActivityRecord r) { 8065 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() || 8066 r.getStack().isInStackLocked(r) == null) { 8067 return false; 8068 } 8069 8070 // If we are animating to fullscreen then we have already dispatched the PIP mode 8071 // changed, so we should reflect that check here as well. 8072 final PinnedActivityStack stack = r.getStack(); 8073 final PinnedStackWindowController windowController = stack.getWindowContainerController(); 8074 return !windowController.isAnimatingBoundsToFullscreen(); 8075 } 8076 8077 @Override 8078 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) { 8079 final long origId = Binder.clearCallingIdentity(); 8080 try { 8081 synchronized(this) { 8082 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked( 8083 "enterPictureInPictureMode", token, params); 8084 8085 // If the activity is already in picture in picture mode, then just return early 8086 if (isInPictureInPictureMode(r)) { 8087 return true; 8088 } 8089 8090 // Activity supports picture-in-picture, now check that we can enter PiP at this 8091 // point, if it is 8092 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode", 8093 false /* beforeStopping */)) { 8094 return false; 8095 } 8096 8097 final Runnable enterPipRunnable = () -> { 8098 // Only update the saved args from the args that are set 8099 r.pictureInPictureArgs.copyOnlySet(params); 8100 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio(); 8101 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions(); 8102 // Adjust the source bounds by the insets for the transition down 8103 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint()); 8104 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio, 8105 true /* moveHomeStackToFront */, "enterPictureInPictureMode"); 8106 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID); 8107 stack.setPictureInPictureAspectRatio(aspectRatio); 8108 stack.setPictureInPictureActions(actions); 8109 8110 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED, 8111 r.supportsEnterPipOnTaskSwitch); 8112 logPictureInPictureArgs(params); 8113 }; 8114 8115 if (isKeyguardLocked()) { 8116 // If the keyguard is showing or occluded, then try and dismiss it before 8117 // entering picture-in-picture (this will prompt the user to authenticate if the 8118 // device is currently locked). 8119 try { 8120 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() { 8121 @Override 8122 public void onDismissError() throws RemoteException { 8123 // Do nothing 8124 } 8125 8126 @Override 8127 public void onDismissSucceeded() throws RemoteException { 8128 mHandler.post(enterPipRunnable); 8129 } 8130 8131 @Override 8132 public void onDismissCancelled() throws RemoteException { 8133 // Do nothing 8134 } 8135 }); 8136 } catch (RemoteException e) { 8137 // Local call 8138 } 8139 } else { 8140 // Enter picture in picture immediately otherwise 8141 enterPipRunnable.run(); 8142 } 8143 return true; 8144 } 8145 } finally { 8146 Binder.restoreCallingIdentity(origId); 8147 } 8148 } 8149 8150 @Override 8151 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) { 8152 final long origId = Binder.clearCallingIdentity(); 8153 try { 8154 synchronized(this) { 8155 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked( 8156 "setPictureInPictureParams", token, params); 8157 8158 // Only update the saved args from the args that are set 8159 r.pictureInPictureArgs.copyOnlySet(params); 8160 if (r.getStack().getStackId() == PINNED_STACK_ID) { 8161 // If the activity is already in picture-in-picture, update the pinned stack now 8162 // if it is not already expanding to fullscreen. Otherwise, the arguments will 8163 // be used the next time the activity enters PiP 8164 final PinnedActivityStack stack = r.getStack(); 8165 if (!stack.isAnimatingBoundsToFullscreen()) { 8166 stack.setPictureInPictureAspectRatio( 8167 r.pictureInPictureArgs.getAspectRatio()); 8168 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions()); 8169 } 8170 } 8171 logPictureInPictureArgs(params); 8172 } 8173 } finally { 8174 Binder.restoreCallingIdentity(origId); 8175 } 8176 } 8177 8178 @Override 8179 public int getMaxNumPictureInPictureActions(IBinder token) { 8180 // Currently, this is a static constant, but later, we may change this to be dependent on 8181 // the context of the activity 8182 return 3; 8183 } 8184 8185 private void logPictureInPictureArgs(PictureInPictureParams params) { 8186 if (params.hasSetActions()) { 8187 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count", 8188 params.getActions().size()); 8189 } 8190 if (params.hasSetAspectRatio()) { 8191 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED); 8192 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio()); 8193 MetricsLogger.action(lm); 8194 } 8195 } 8196 8197 /** 8198 * Checks the state of the system and the activity associated with the given {@param token} to 8199 * verify that picture-in-picture is supported for that activity. 8200 * 8201 * @return the activity record for the given {@param token} if all the checks pass. 8202 */ 8203 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller, 8204 IBinder token, PictureInPictureParams params) { 8205 if (!mSupportsPictureInPicture) { 8206 throw new IllegalStateException(caller 8207 + ": Device doesn't support picture-in-picture mode."); 8208 } 8209 8210 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 8211 if (r == null) { 8212 throw new IllegalStateException(caller 8213 + ": Can't find activity for token=" + token); 8214 } 8215 8216 if (!r.supportsPictureInPicture()) { 8217 throw new IllegalStateException(caller 8218 + ": Current activity does not support picture-in-picture."); 8219 } 8220 8221 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) { 8222 throw new IllegalStateException(caller 8223 + ": Activities on the home, assistant, or recents stack not supported"); 8224 } 8225 8226 if (params.hasSetAspectRatio() 8227 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId, 8228 params.getAspectRatio())) { 8229 final float minAspectRatio = mContext.getResources().getFloat( 8230 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio); 8231 final float maxAspectRatio = mContext.getResources().getFloat( 8232 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio); 8233 throw new IllegalArgumentException(String.format(caller 8234 + ": Aspect ratio is too extreme (must be between %f and %f).", 8235 minAspectRatio, maxAspectRatio)); 8236 } 8237 8238 // Truncate the number of actions if necessary 8239 params.truncateActions(getMaxNumPictureInPictureActions(token)); 8240 8241 return r; 8242 } 8243 8244 // ========================================================= 8245 // PROCESS INFO 8246 // ========================================================= 8247 8248 static class ProcessInfoService extends IProcessInfoService.Stub { 8249 final ActivityManagerService mActivityManagerService; 8250 ProcessInfoService(ActivityManagerService activityManagerService) { 8251 mActivityManagerService = activityManagerService; 8252 } 8253 8254 @Override 8255 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) { 8256 mActivityManagerService.getProcessStatesAndOomScoresForPIDs( 8257 /*in*/ pids, /*out*/ states, null); 8258 } 8259 8260 @Override 8261 public void getProcessStatesAndOomScoresFromPids( 8262 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) { 8263 mActivityManagerService.getProcessStatesAndOomScoresForPIDs( 8264 /*in*/ pids, /*out*/ states, /*out*/ scores); 8265 } 8266 } 8267 8268 /** 8269 * For each PID in the given input array, write the current process state 8270 * for that process into the states array, or -1 to indicate that no 8271 * process with the given PID exists. If scores array is provided, write 8272 * the oom score for the process into the scores array, with INVALID_ADJ 8273 * indicating the PID doesn't exist. 8274 */ 8275 public void getProcessStatesAndOomScoresForPIDs( 8276 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) { 8277 if (scores != null) { 8278 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE, 8279 "getProcessStatesAndOomScoresForPIDs()"); 8280 } 8281 8282 if (pids == null) { 8283 throw new NullPointerException("pids"); 8284 } else if (states == null) { 8285 throw new NullPointerException("states"); 8286 } else if (pids.length != states.length) { 8287 throw new IllegalArgumentException("pids and states arrays have different lengths!"); 8288 } else if (scores != null && pids.length != scores.length) { 8289 throw new IllegalArgumentException("pids and scores arrays have different lengths!"); 8290 } 8291 8292 synchronized (mPidsSelfLocked) { 8293 for (int i = 0; i < pids.length; i++) { 8294 ProcessRecord pr = mPidsSelfLocked.get(pids[i]); 8295 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT : 8296 pr.curProcState; 8297 if (scores != null) { 8298 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj; 8299 } 8300 } 8301 } 8302 } 8303 8304 // ========================================================= 8305 // PERMISSIONS 8306 // ========================================================= 8307 8308 static class PermissionController extends IPermissionController.Stub { 8309 ActivityManagerService mActivityManagerService; 8310 PermissionController(ActivityManagerService activityManagerService) { 8311 mActivityManagerService = activityManagerService; 8312 } 8313 8314 @Override 8315 public boolean checkPermission(String permission, int pid, int uid) { 8316 return mActivityManagerService.checkPermission(permission, pid, 8317 uid) == PackageManager.PERMISSION_GRANTED; 8318 } 8319 8320 @Override 8321 public String[] getPackagesForUid(int uid) { 8322 return mActivityManagerService.mContext.getPackageManager() 8323 .getPackagesForUid(uid); 8324 } 8325 8326 @Override 8327 public boolean isRuntimePermission(String permission) { 8328 try { 8329 PermissionInfo info = mActivityManagerService.mContext.getPackageManager() 8330 .getPermissionInfo(permission, 0); 8331 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) 8332 == PermissionInfo.PROTECTION_DANGEROUS; 8333 } catch (NameNotFoundException nnfe) { 8334 Slog.e(TAG, "No such permission: "+ permission, nnfe); 8335 } 8336 return false; 8337 } 8338 } 8339 8340 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 8341 @Override 8342 public int checkComponentPermission(String permission, int pid, int uid, 8343 int owningUid, boolean exported) { 8344 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 8345 owningUid, exported); 8346 } 8347 8348 @Override 8349 public Object getAMSLock() { 8350 return ActivityManagerService.this; 8351 } 8352 } 8353 8354 /** 8355 * This can be called with or without the global lock held. 8356 */ 8357 int checkComponentPermission(String permission, int pid, int uid, 8358 int owningUid, boolean exported) { 8359 if (pid == MY_PID) { 8360 return PackageManager.PERMISSION_GRANTED; 8361 } 8362 return ActivityManager.checkComponentPermission(permission, uid, 8363 owningUid, exported); 8364 } 8365 8366 /** 8367 * As the only public entry point for permissions checking, this method 8368 * can enforce the semantic that requesting a check on a null global 8369 * permission is automatically denied. (Internally a null permission 8370 * string is used when calling {@link #checkComponentPermission} in cases 8371 * when only uid-based security is needed.) 8372 * 8373 * This can be called with or without the global lock held. 8374 */ 8375 @Override 8376 public int checkPermission(String permission, int pid, int uid) { 8377 if (permission == null) { 8378 return PackageManager.PERMISSION_DENIED; 8379 } 8380 return checkComponentPermission(permission, pid, uid, -1, true); 8381 } 8382 8383 @Override 8384 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 8385 if (permission == null) { 8386 return PackageManager.PERMISSION_DENIED; 8387 } 8388 8389 // We might be performing an operation on behalf of an indirect binder 8390 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 8391 // client identity accordingly before proceeding. 8392 Identity tlsIdentity = sCallerIdentity.get(); 8393 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 8394 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 8395 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 8396 uid = tlsIdentity.uid; 8397 pid = tlsIdentity.pid; 8398 } 8399 8400 return checkComponentPermission(permission, pid, uid, -1, true); 8401 } 8402 8403 /** 8404 * Binder IPC calls go through the public entry point. 8405 * This can be called with or without the global lock held. 8406 */ 8407 int checkCallingPermission(String permission) { 8408 return checkPermission(permission, 8409 Binder.getCallingPid(), 8410 UserHandle.getAppId(Binder.getCallingUid())); 8411 } 8412 8413 /** 8414 * This can be called with or without the global lock held. 8415 */ 8416 void enforceCallingPermission(String permission, String func) { 8417 if (checkCallingPermission(permission) 8418 == PackageManager.PERMISSION_GRANTED) { 8419 return; 8420 } 8421 8422 String msg = "Permission Denial: " + func + " from pid=" 8423 + Binder.getCallingPid() 8424 + ", uid=" + Binder.getCallingUid() 8425 + " requires " + permission; 8426 Slog.w(TAG, msg); 8427 throw new SecurityException(msg); 8428 } 8429 8430 /** 8431 * Determine if UID is holding permissions required to access {@link Uri} in 8432 * the given {@link ProviderInfo}. Final permission checking is always done 8433 * in {@link ContentProvider}. 8434 */ 8435 private final boolean checkHoldingPermissionsLocked( 8436 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 8437 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8438 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 8439 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 8440 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 8441 != PERMISSION_GRANTED) { 8442 return false; 8443 } 8444 } 8445 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 8446 } 8447 8448 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 8449 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 8450 if (pi.applicationInfo.uid == uid) { 8451 return true; 8452 } else if (!pi.exported) { 8453 return false; 8454 } 8455 8456 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 8457 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 8458 try { 8459 // check if target holds top-level <provider> permissions 8460 if (!readMet && pi.readPermission != null && considerUidPermissions 8461 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 8462 readMet = true; 8463 } 8464 if (!writeMet && pi.writePermission != null && considerUidPermissions 8465 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 8466 writeMet = true; 8467 } 8468 8469 // track if unprotected read/write is allowed; any denied 8470 // <path-permission> below removes this ability 8471 boolean allowDefaultRead = pi.readPermission == null; 8472 boolean allowDefaultWrite = pi.writePermission == null; 8473 8474 // check if target holds any <path-permission> that match uri 8475 final PathPermission[] pps = pi.pathPermissions; 8476 if (pps != null) { 8477 final String path = grantUri.uri.getPath(); 8478 int i = pps.length; 8479 while (i > 0 && (!readMet || !writeMet)) { 8480 i--; 8481 PathPermission pp = pps[i]; 8482 if (pp.match(path)) { 8483 if (!readMet) { 8484 final String pprperm = pp.getReadPermission(); 8485 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8486 "Checking read perm for " + pprperm + " for " + pp.getPath() 8487 + ": match=" + pp.match(path) 8488 + " check=" + pm.checkUidPermission(pprperm, uid)); 8489 if (pprperm != null) { 8490 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 8491 == PERMISSION_GRANTED) { 8492 readMet = true; 8493 } else { 8494 allowDefaultRead = false; 8495 } 8496 } 8497 } 8498 if (!writeMet) { 8499 final String ppwperm = pp.getWritePermission(); 8500 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8501 "Checking write perm " + ppwperm + " for " + pp.getPath() 8502 + ": match=" + pp.match(path) 8503 + " check=" + pm.checkUidPermission(ppwperm, uid)); 8504 if (ppwperm != null) { 8505 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 8506 == PERMISSION_GRANTED) { 8507 writeMet = true; 8508 } else { 8509 allowDefaultWrite = false; 8510 } 8511 } 8512 } 8513 } 8514 } 8515 } 8516 8517 // grant unprotected <provider> read/write, if not blocked by 8518 // <path-permission> above 8519 if (allowDefaultRead) readMet = true; 8520 if (allowDefaultWrite) writeMet = true; 8521 8522 } catch (RemoteException e) { 8523 return false; 8524 } 8525 8526 return readMet && writeMet; 8527 } 8528 8529 public boolean isAppStartModeDisabled(int uid, String packageName) { 8530 synchronized (this) { 8531 return getAppStartModeLocked(uid, packageName, 0, -1, false, true) 8532 == ActivityManager.APP_START_MODE_DISABLED; 8533 } 8534 } 8535 8536 // Unified app-op and target sdk check 8537 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) { 8538 // Apps that target O+ are always subject to background check 8539 if (packageTargetSdk >= Build.VERSION_CODES.O) { 8540 if (DEBUG_BACKGROUND_CHECK) { 8541 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted"); 8542 } 8543 return ActivityManager.APP_START_MODE_DELAYED_RIGID; 8544 } 8545 // ...and legacy apps get an AppOp check 8546 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, 8547 uid, packageName); 8548 if (DEBUG_BACKGROUND_CHECK) { 8549 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop); 8550 } 8551 switch (appop) { 8552 case AppOpsManager.MODE_ALLOWED: 8553 return ActivityManager.APP_START_MODE_NORMAL; 8554 case AppOpsManager.MODE_IGNORED: 8555 return ActivityManager.APP_START_MODE_DELAYED; 8556 default: 8557 return ActivityManager.APP_START_MODE_DELAYED_RIGID; 8558 } 8559 } 8560 8561 // Service launch is available to apps with run-in-background exemptions but 8562 // some other background operations are not. If we're doing a check 8563 // of service-launch policy, allow those callers to proceed unrestricted. 8564 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) { 8565 // Persistent app? 8566 if (mPackageManagerInt.isPackagePersistent(packageName)) { 8567 if (DEBUG_BACKGROUND_CHECK) { 8568 Slog.i(TAG, "App " + uid + "/" + packageName 8569 + " is persistent; not restricted in background"); 8570 } 8571 return ActivityManager.APP_START_MODE_NORMAL; 8572 } 8573 8574 // Non-persistent but background whitelisted? 8575 if (uidOnBackgroundWhitelist(uid)) { 8576 if (DEBUG_BACKGROUND_CHECK) { 8577 Slog.i(TAG, "App " + uid + "/" + packageName 8578 + " on background whitelist; not restricted in background"); 8579 } 8580 return ActivityManager.APP_START_MODE_NORMAL; 8581 } 8582 8583 // Is this app on the battery whitelist? 8584 if (isOnDeviceIdleWhitelistLocked(uid)) { 8585 if (DEBUG_BACKGROUND_CHECK) { 8586 Slog.i(TAG, "App " + uid + "/" + packageName 8587 + " on idle whitelist; not restricted in background"); 8588 } 8589 return ActivityManager.APP_START_MODE_NORMAL; 8590 } 8591 8592 // None of the service-policy criteria apply, so we apply the common criteria 8593 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk); 8594 } 8595 8596 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk, 8597 int callingPid, boolean alwaysRestrict, boolean disabledOnly) { 8598 UidRecord uidRec = mActiveUids.get(uid); 8599 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg=" 8600 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle=" 8601 + (uidRec != null ? uidRec.idle : false)); 8602 if (uidRec == null || alwaysRestrict || uidRec.idle) { 8603 boolean ephemeral; 8604 if (uidRec == null) { 8605 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral( 8606 UserHandle.getUserId(uid), packageName); 8607 } else { 8608 ephemeral = uidRec.ephemeral; 8609 } 8610 8611 if (ephemeral) { 8612 // We are hard-core about ephemeral apps not running in the background. 8613 return ActivityManager.APP_START_MODE_DISABLED; 8614 } else { 8615 if (disabledOnly) { 8616 // The caller is only interested in whether app starts are completely 8617 // disabled for the given package (that is, it is an instant app). So 8618 // we don't need to go further, which is all just seeing if we should 8619 // apply a "delayed" mode for a regular app. 8620 return ActivityManager.APP_START_MODE_NORMAL; 8621 } 8622 final int startMode = (alwaysRestrict) 8623 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk) 8624 : appServicesRestrictedInBackgroundLocked(uid, packageName, 8625 packageTargetSdk); 8626 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid 8627 + " pkg=" + packageName + " startMode=" + startMode 8628 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid)); 8629 if (startMode == ActivityManager.APP_START_MODE_DELAYED) { 8630 // This is an old app that has been forced into a "compatible as possible" 8631 // mode of background check. To increase compatibility, we will allow other 8632 // foreground apps to cause its services to start. 8633 if (callingPid >= 0) { 8634 ProcessRecord proc; 8635 synchronized (mPidsSelfLocked) { 8636 proc = mPidsSelfLocked.get(callingPid); 8637 } 8638 if (proc != null && 8639 !ActivityManager.isProcStateBackground(proc.curProcState)) { 8640 // Whoever is instigating this is in the foreground, so we will allow it 8641 // to go through. 8642 return ActivityManager.APP_START_MODE_NORMAL; 8643 } 8644 } 8645 } 8646 return startMode; 8647 } 8648 } 8649 return ActivityManager.APP_START_MODE_NORMAL; 8650 } 8651 8652 boolean isOnDeviceIdleWhitelistLocked(int uid) { 8653 final int appId = UserHandle.getAppId(uid); 8654 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0 8655 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0 8656 || mPendingTempWhitelist.indexOfKey(uid) >= 0; 8657 } 8658 8659 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) { 8660 ProviderInfo pi = null; 8661 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 8662 if (cpr != null) { 8663 pi = cpr.info; 8664 } else { 8665 try { 8666 pi = AppGlobals.getPackageManager().resolveContentProvider( 8667 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags, 8668 userHandle); 8669 } catch (RemoteException ex) { 8670 } 8671 } 8672 return pi; 8673 } 8674 8675 void grantEphemeralAccessLocked(int userId, Intent intent, 8676 int targetAppId, int ephemeralAppId) { 8677 getPackageManagerInternalLocked(). 8678 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId); 8679 } 8680 8681 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 8682 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 8683 if (targetUris != null) { 8684 return targetUris.get(grantUri); 8685 } 8686 return null; 8687 } 8688 8689 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 8690 String targetPkg, int targetUid, GrantUri grantUri) { 8691 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 8692 if (targetUris == null) { 8693 targetUris = Maps.newArrayMap(); 8694 mGrantedUriPermissions.put(targetUid, targetUris); 8695 } 8696 8697 UriPermission perm = targetUris.get(grantUri); 8698 if (perm == null) { 8699 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 8700 targetUris.put(grantUri, perm); 8701 } 8702 8703 return perm; 8704 } 8705 8706 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 8707 final int modeFlags) { 8708 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 8709 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 8710 : UriPermission.STRENGTH_OWNED; 8711 8712 // Root gets to do everything. 8713 if (uid == 0) { 8714 return true; 8715 } 8716 8717 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 8718 if (perms == null) return false; 8719 8720 // First look for exact match 8721 final UriPermission exactPerm = perms.get(grantUri); 8722 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 8723 return true; 8724 } 8725 8726 // No exact match, look for prefixes 8727 final int N = perms.size(); 8728 for (int i = 0; i < N; i++) { 8729 final UriPermission perm = perms.valueAt(i); 8730 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 8731 && perm.getStrength(modeFlags) >= minStrength) { 8732 return true; 8733 } 8734 } 8735 8736 return false; 8737 } 8738 8739 /** 8740 * @param uri This uri must NOT contain an embedded userId. 8741 * @param userId The userId in which the uri is to be resolved. 8742 */ 8743 @Override 8744 public int checkUriPermission(Uri uri, int pid, int uid, 8745 final int modeFlags, int userId, IBinder callerToken) { 8746 enforceNotIsolatedCaller("checkUriPermission"); 8747 8748 // Another redirected-binder-call permissions check as in 8749 // {@link checkPermissionWithToken}. 8750 Identity tlsIdentity = sCallerIdentity.get(); 8751 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 8752 uid = tlsIdentity.uid; 8753 pid = tlsIdentity.pid; 8754 } 8755 8756 // Our own process gets to do everything. 8757 if (pid == MY_PID) { 8758 return PackageManager.PERMISSION_GRANTED; 8759 } 8760 synchronized (this) { 8761 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 8762 ? PackageManager.PERMISSION_GRANTED 8763 : PackageManager.PERMISSION_DENIED; 8764 } 8765 } 8766 8767 /** 8768 * Check if the targetPkg can be granted permission to access uri by 8769 * the callingUid using the given modeFlags. Throws a security exception 8770 * if callingUid is not allowed to do this. Returns the uid of the target 8771 * if the URI permission grant should be performed; returns -1 if it is not 8772 * needed (for example targetPkg already has permission to access the URI). 8773 * If you already know the uid of the target, you can supply it in 8774 * lastTargetUid else set that to -1. 8775 */ 8776 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 8777 final int modeFlags, int lastTargetUid) { 8778 if (!Intent.isAccessUriMode(modeFlags)) { 8779 return -1; 8780 } 8781 8782 if (targetPkg != null) { 8783 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8784 "Checking grant " + targetPkg + " permission to " + grantUri); 8785 } 8786 8787 final IPackageManager pm = AppGlobals.getPackageManager(); 8788 8789 // If this is not a content: uri, we can't do anything with it. 8790 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 8791 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8792 "Can't grant URI permission for non-content URI: " + grantUri); 8793 return -1; 8794 } 8795 8796 // Bail early if system is trying to hand out permissions directly; it 8797 // must always grant permissions on behalf of someone explicit. 8798 final int callingAppId = UserHandle.getAppId(callingUid); 8799 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) { 8800 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) { 8801 // Exempted authority for cropping user photos in Settings app 8802 } else { 8803 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission" 8804 + " grant to " + grantUri + "; use startActivityAsCaller() instead"); 8805 return -1; 8806 } 8807 } 8808 8809 final String authority = grantUri.uri.getAuthority(); 8810 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId, 8811 MATCH_DEBUG_TRIAGED_MISSING); 8812 if (pi == null) { 8813 Slog.w(TAG, "No content provider found for permission check: " + 8814 grantUri.uri.toSafeString()); 8815 return -1; 8816 } 8817 8818 int targetUid = lastTargetUid; 8819 if (targetUid < 0 && targetPkg != null) { 8820 try { 8821 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, 8822 UserHandle.getUserId(callingUid)); 8823 if (targetUid < 0) { 8824 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8825 "Can't grant URI permission no uid for: " + targetPkg); 8826 return -1; 8827 } 8828 } catch (RemoteException ex) { 8829 return -1; 8830 } 8831 } 8832 8833 // If we're extending a persistable grant, then we always need to create 8834 // the grant data structure so that take/release APIs work 8835 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) { 8836 return targetUid; 8837 } 8838 8839 if (targetUid >= 0) { 8840 // First... does the target actually need this permission? 8841 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 8842 // No need to grant the target this permission. 8843 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8844 "Target " + targetPkg + " already has full permission to " + grantUri); 8845 return -1; 8846 } 8847 } else { 8848 // First... there is no target package, so can anyone access it? 8849 boolean allowed = pi.exported; 8850 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 8851 if (pi.readPermission != null) { 8852 allowed = false; 8853 } 8854 } 8855 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 8856 if (pi.writePermission != null) { 8857 allowed = false; 8858 } 8859 } 8860 if (allowed) { 8861 return -1; 8862 } 8863 } 8864 8865 /* There is a special cross user grant if: 8866 * - The target is on another user. 8867 * - Apps on the current user can access the uri without any uid permissions. 8868 * In this case, we grant a uri permission, even if the ContentProvider does not normally 8869 * grant uri permissions. 8870 */ 8871 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 8872 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 8873 modeFlags, false /*without considering the uid permissions*/); 8874 8875 // Second... is the provider allowing granting of URI permissions? 8876 if (!specialCrossUserGrant) { 8877 if (!pi.grantUriPermissions) { 8878 throw new SecurityException("Provider " + pi.packageName 8879 + "/" + pi.name 8880 + " does not allow granting of Uri permissions (uri " 8881 + grantUri + ")"); 8882 } 8883 if (pi.uriPermissionPatterns != null) { 8884 final int N = pi.uriPermissionPatterns.length; 8885 boolean allowed = false; 8886 for (int i=0; i<N; i++) { 8887 if (pi.uriPermissionPatterns[i] != null 8888 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 8889 allowed = true; 8890 break; 8891 } 8892 } 8893 if (!allowed) { 8894 throw new SecurityException("Provider " + pi.packageName 8895 + "/" + pi.name 8896 + " does not allow granting of permission to path of Uri " 8897 + grantUri); 8898 } 8899 } 8900 } 8901 8902 // Third... does the caller itself have permission to access 8903 // this uri? 8904 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 8905 // Require they hold a strong enough Uri permission 8906 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 8907 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) { 8908 throw new SecurityException( 8909 "UID " + callingUid + " does not have permission to " + grantUri 8910 + "; you could obtain access using ACTION_OPEN_DOCUMENT " 8911 + "or related APIs"); 8912 } else { 8913 throw new SecurityException( 8914 "UID " + callingUid + " does not have permission to " + grantUri); 8915 } 8916 } 8917 } 8918 return targetUid; 8919 } 8920 8921 /** 8922 * @param uri This uri must NOT contain an embedded userId. 8923 * @param userId The userId in which the uri is to be resolved. 8924 */ 8925 @Override 8926 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 8927 final int modeFlags, int userId) { 8928 enforceNotIsolatedCaller("checkGrantUriPermission"); 8929 synchronized(this) { 8930 return checkGrantUriPermissionLocked(callingUid, targetPkg, 8931 new GrantUri(userId, uri, false), modeFlags, -1); 8932 } 8933 } 8934 8935 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 8936 final int modeFlags, UriPermissionOwner owner) { 8937 if (!Intent.isAccessUriMode(modeFlags)) { 8938 return; 8939 } 8940 8941 // So here we are: the caller has the assumed permission 8942 // to the uri, and the target doesn't. Let's now give this to 8943 // the target. 8944 8945 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8946 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 8947 8948 final String authority = grantUri.uri.getAuthority(); 8949 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId, 8950 MATCH_DEBUG_TRIAGED_MISSING); 8951 if (pi == null) { 8952 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 8953 return; 8954 } 8955 8956 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 8957 grantUri.prefix = true; 8958 } 8959 final UriPermission perm = findOrCreateUriPermissionLocked( 8960 pi.packageName, targetPkg, targetUid, grantUri); 8961 perm.grantModes(modeFlags, owner); 8962 } 8963 8964 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 8965 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 8966 if (targetPkg == null) { 8967 throw new NullPointerException("targetPkg"); 8968 } 8969 int targetUid; 8970 final IPackageManager pm = AppGlobals.getPackageManager(); 8971 try { 8972 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId); 8973 } catch (RemoteException ex) { 8974 return; 8975 } 8976 8977 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 8978 targetUid); 8979 if (targetUid < 0) { 8980 return; 8981 } 8982 8983 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 8984 owner); 8985 } 8986 8987 static class NeededUriGrants extends ArrayList<GrantUri> { 8988 final String targetPkg; 8989 final int targetUid; 8990 final int flags; 8991 8992 NeededUriGrants(String targetPkg, int targetUid, int flags) { 8993 this.targetPkg = targetPkg; 8994 this.targetUid = targetUid; 8995 this.flags = flags; 8996 } 8997 } 8998 8999 /** 9000 * Like checkGrantUriPermissionLocked, but takes an Intent. 9001 */ 9002 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 9003 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 9004 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9005 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 9006 + " clip=" + (intent != null ? intent.getClipData() : null) 9007 + " from " + intent + "; flags=0x" 9008 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 9009 9010 if (targetPkg == null) { 9011 throw new NullPointerException("targetPkg"); 9012 } 9013 9014 if (intent == null) { 9015 return null; 9016 } 9017 Uri data = intent.getData(); 9018 ClipData clip = intent.getClipData(); 9019 if (data == null && clip == null) { 9020 return null; 9021 } 9022 // Default userId for uris in the intent (if they don't specify it themselves) 9023 int contentUserHint = intent.getContentUserHint(); 9024 if (contentUserHint == UserHandle.USER_CURRENT) { 9025 contentUserHint = UserHandle.getUserId(callingUid); 9026 } 9027 final IPackageManager pm = AppGlobals.getPackageManager(); 9028 int targetUid; 9029 if (needed != null) { 9030 targetUid = needed.targetUid; 9031 } else { 9032 try { 9033 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, 9034 targetUserId); 9035 } catch (RemoteException ex) { 9036 return null; 9037 } 9038 if (targetUid < 0) { 9039 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9040 "Can't grant URI permission no uid for: " + targetPkg 9041 + " on user " + targetUserId); 9042 return null; 9043 } 9044 } 9045 if (data != null) { 9046 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 9047 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 9048 targetUid); 9049 if (targetUid > 0) { 9050 if (needed == null) { 9051 needed = new NeededUriGrants(targetPkg, targetUid, mode); 9052 } 9053 needed.add(grantUri); 9054 } 9055 } 9056 if (clip != null) { 9057 for (int i=0; i<clip.getItemCount(); i++) { 9058 Uri uri = clip.getItemAt(i).getUri(); 9059 if (uri != null) { 9060 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 9061 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 9062 targetUid); 9063 if (targetUid > 0) { 9064 if (needed == null) { 9065 needed = new NeededUriGrants(targetPkg, targetUid, mode); 9066 } 9067 needed.add(grantUri); 9068 } 9069 } else { 9070 Intent clipIntent = clip.getItemAt(i).getIntent(); 9071 if (clipIntent != null) { 9072 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 9073 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 9074 if (newNeeded != null) { 9075 needed = newNeeded; 9076 } 9077 } 9078 } 9079 } 9080 } 9081 9082 return needed; 9083 } 9084 9085 /** 9086 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 9087 */ 9088 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 9089 UriPermissionOwner owner) { 9090 if (needed != null) { 9091 for (int i=0; i<needed.size(); i++) { 9092 GrantUri grantUri = needed.get(i); 9093 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 9094 grantUri, needed.flags, owner); 9095 } 9096 } 9097 } 9098 9099 void grantUriPermissionFromIntentLocked(int callingUid, 9100 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 9101 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 9102 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 9103 if (needed == null) { 9104 return; 9105 } 9106 9107 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 9108 } 9109 9110 /** 9111 * @param uri This uri must NOT contain an embedded userId. 9112 * @param userId The userId in which the uri is to be resolved. 9113 */ 9114 @Override 9115 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 9116 final int modeFlags, int userId) { 9117 enforceNotIsolatedCaller("grantUriPermission"); 9118 GrantUri grantUri = new GrantUri(userId, uri, false); 9119 synchronized(this) { 9120 final ProcessRecord r = getRecordForAppLocked(caller); 9121 if (r == null) { 9122 throw new SecurityException("Unable to find app for caller " 9123 + caller 9124 + " when granting permission to uri " + grantUri); 9125 } 9126 if (targetPkg == null) { 9127 throw new IllegalArgumentException("null target"); 9128 } 9129 if (grantUri == null) { 9130 throw new IllegalArgumentException("null uri"); 9131 } 9132 9133 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 9134 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 9135 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 9136 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 9137 9138 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 9139 UserHandle.getUserId(r.uid)); 9140 } 9141 } 9142 9143 void removeUriPermissionIfNeededLocked(UriPermission perm) { 9144 if (perm.modeFlags == 0) { 9145 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 9146 perm.targetUid); 9147 if (perms != null) { 9148 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9149 "Removing " + perm.targetUid + " permission to " + perm.uri); 9150 9151 perms.remove(perm.uri); 9152 if (perms.isEmpty()) { 9153 mGrantedUriPermissions.remove(perm.targetUid); 9154 } 9155 } 9156 } 9157 } 9158 9159 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri, 9160 final int modeFlags) { 9161 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9162 "Revoking all granted permissions to " + grantUri); 9163 9164 final IPackageManager pm = AppGlobals.getPackageManager(); 9165 final String authority = grantUri.uri.getAuthority(); 9166 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId, 9167 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE); 9168 if (pi == null) { 9169 Slog.w(TAG, "No content provider found for permission revoke: " 9170 + grantUri.toSafeString()); 9171 return; 9172 } 9173 9174 // Does the caller have this permission on the URI? 9175 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 9176 // If they don't have direct access to the URI, then revoke any 9177 // ownerless URI permissions that have been granted to them. 9178 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9179 if (perms != null) { 9180 boolean persistChanged = false; 9181 for (int i = perms.size()-1; i >= 0; i--) { 9182 final UriPermission perm = perms.valueAt(i); 9183 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) { 9184 continue; 9185 } 9186 if (perm.uri.sourceUserId == grantUri.sourceUserId 9187 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 9188 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9189 "Revoking non-owned " + perm.targetUid 9190 + " permission to " + perm.uri); 9191 persistChanged |= perm.revokeModes( 9192 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 9193 if (perm.modeFlags == 0) { 9194 perms.removeAt(i); 9195 } 9196 } 9197 } 9198 if (perms.isEmpty()) { 9199 mGrantedUriPermissions.remove(callingUid); 9200 } 9201 if (persistChanged) { 9202 schedulePersistUriGrants(); 9203 } 9204 } 9205 return; 9206 } 9207 9208 boolean persistChanged = false; 9209 9210 // Go through all of the permissions and remove any that match. 9211 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) { 9212 final int targetUid = mGrantedUriPermissions.keyAt(i); 9213 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 9214 9215 for (int j = perms.size()-1; j >= 0; j--) { 9216 final UriPermission perm = perms.valueAt(j); 9217 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) { 9218 continue; 9219 } 9220 if (perm.uri.sourceUserId == grantUri.sourceUserId 9221 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 9222 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9223 "Revoking " + perm.targetUid + " permission to " + perm.uri); 9224 persistChanged |= perm.revokeModes( 9225 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, 9226 targetPackage == null); 9227 if (perm.modeFlags == 0) { 9228 perms.removeAt(j); 9229 } 9230 } 9231 } 9232 9233 if (perms.isEmpty()) { 9234 mGrantedUriPermissions.removeAt(i); 9235 } 9236 } 9237 9238 if (persistChanged) { 9239 schedulePersistUriGrants(); 9240 } 9241 } 9242 9243 /** 9244 * @param uri This uri must NOT contain an embedded userId. 9245 * @param userId The userId in which the uri is to be resolved. 9246 */ 9247 @Override 9248 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri, 9249 final int modeFlags, int userId) { 9250 enforceNotIsolatedCaller("revokeUriPermission"); 9251 synchronized(this) { 9252 final ProcessRecord r = getRecordForAppLocked(caller); 9253 if (r == null) { 9254 throw new SecurityException("Unable to find app for caller " 9255 + caller 9256 + " when revoking permission to uri " + uri); 9257 } 9258 if (uri == null) { 9259 Slog.w(TAG, "revokeUriPermission: null uri"); 9260 return; 9261 } 9262 9263 if (!Intent.isAccessUriMode(modeFlags)) { 9264 return; 9265 } 9266 9267 final String authority = uri.getAuthority(); 9268 final ProviderInfo pi = getProviderInfoLocked(authority, userId, 9269 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE); 9270 if (pi == null) { 9271 Slog.w(TAG, "No content provider found for permission revoke: " 9272 + uri.toSafeString()); 9273 return; 9274 } 9275 9276 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false), 9277 modeFlags); 9278 } 9279 } 9280 9281 /** 9282 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 9283 * given package. 9284 * 9285 * @param packageName Package name to match, or {@code null} to apply to all 9286 * packages. 9287 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 9288 * to all users. 9289 * @param persistable If persistable grants should be removed. 9290 */ 9291 private void removeUriPermissionsForPackageLocked( 9292 String packageName, int userHandle, boolean persistable) { 9293 if (userHandle == UserHandle.USER_ALL && packageName == null) { 9294 throw new IllegalArgumentException("Must narrow by either package or user"); 9295 } 9296 9297 boolean persistChanged = false; 9298 9299 int N = mGrantedUriPermissions.size(); 9300 for (int i = 0; i < N; i++) { 9301 final int targetUid = mGrantedUriPermissions.keyAt(i); 9302 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 9303 9304 // Only inspect grants matching user 9305 if (userHandle == UserHandle.USER_ALL 9306 || userHandle == UserHandle.getUserId(targetUid)) { 9307 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 9308 final UriPermission perm = it.next(); 9309 9310 // Only inspect grants matching package 9311 if (packageName == null || perm.sourcePkg.equals(packageName) 9312 || perm.targetPkg.equals(packageName)) { 9313 // Hacky solution as part of fixing a security bug; ignore 9314 // grants associated with DownloadManager so we don't have 9315 // to immediately launch it to regrant the permissions 9316 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority()) 9317 && !persistable) continue; 9318 9319 persistChanged |= perm.revokeModes(persistable 9320 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 9321 9322 // Only remove when no modes remain; any persisted grants 9323 // will keep this alive. 9324 if (perm.modeFlags == 0) { 9325 it.remove(); 9326 } 9327 } 9328 } 9329 9330 if (perms.isEmpty()) { 9331 mGrantedUriPermissions.remove(targetUid); 9332 N--; 9333 i--; 9334 } 9335 } 9336 } 9337 9338 if (persistChanged) { 9339 schedulePersistUriGrants(); 9340 } 9341 } 9342 9343 @Override 9344 public IBinder newUriPermissionOwner(String name) { 9345 enforceNotIsolatedCaller("newUriPermissionOwner"); 9346 synchronized(this) { 9347 UriPermissionOwner owner = new UriPermissionOwner(this, name); 9348 return owner.getExternalTokenLocked(); 9349 } 9350 } 9351 9352 @Override 9353 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) { 9354 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity"); 9355 synchronized(this) { 9356 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 9357 if (r == null) { 9358 throw new IllegalArgumentException("Activity does not exist; token=" 9359 + activityToken); 9360 } 9361 return r.getUriPermissionsLocked().getExternalTokenLocked(); 9362 } 9363 } 9364 /** 9365 * @param uri This uri must NOT contain an embedded userId. 9366 * @param sourceUserId The userId in which the uri is to be resolved. 9367 * @param targetUserId The userId of the app that receives the grant. 9368 */ 9369 @Override 9370 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 9371 final int modeFlags, int sourceUserId, int targetUserId) { 9372 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(), 9373 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY, 9374 "grantUriPermissionFromOwner", null); 9375 synchronized(this) { 9376 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 9377 if (owner == null) { 9378 throw new IllegalArgumentException("Unknown owner: " + token); 9379 } 9380 if (fromUid != Binder.getCallingUid()) { 9381 if (Binder.getCallingUid() != myUid()) { 9382 // Only system code can grant URI permissions on behalf 9383 // of other users. 9384 throw new SecurityException("nice try"); 9385 } 9386 } 9387 if (targetPkg == null) { 9388 throw new IllegalArgumentException("null target"); 9389 } 9390 if (uri == null) { 9391 throw new IllegalArgumentException("null uri"); 9392 } 9393 9394 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 9395 modeFlags, owner, targetUserId); 9396 } 9397 } 9398 9399 /** 9400 * @param uri This uri must NOT contain an embedded userId. 9401 * @param userId The userId in which the uri is to be resolved. 9402 */ 9403 @Override 9404 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 9405 synchronized(this) { 9406 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 9407 if (owner == null) { 9408 throw new IllegalArgumentException("Unknown owner: " + token); 9409 } 9410 9411 if (uri == null) { 9412 owner.removeUriPermissionsLocked(mode); 9413 } else { 9414 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 9415 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode); 9416 } 9417 } 9418 } 9419 9420 private void schedulePersistUriGrants() { 9421 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 9422 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 9423 10 * DateUtils.SECOND_IN_MILLIS); 9424 } 9425 } 9426 9427 private void writeGrantedUriPermissions() { 9428 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()"); 9429 9430 // Snapshot permissions so we can persist without lock 9431 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 9432 synchronized (this) { 9433 final int size = mGrantedUriPermissions.size(); 9434 for (int i = 0; i < size; i++) { 9435 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 9436 for (UriPermission perm : perms.values()) { 9437 if (perm.persistedModeFlags != 0) { 9438 persist.add(perm.snapshot()); 9439 } 9440 } 9441 } 9442 } 9443 9444 FileOutputStream fos = null; 9445 try { 9446 fos = mGrantFile.startWrite(); 9447 9448 XmlSerializer out = new FastXmlSerializer(); 9449 out.setOutput(fos, StandardCharsets.UTF_8.name()); 9450 out.startDocument(null, true); 9451 out.startTag(null, TAG_URI_GRANTS); 9452 for (UriPermission.Snapshot perm : persist) { 9453 out.startTag(null, TAG_URI_GRANT); 9454 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 9455 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 9456 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 9457 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 9458 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 9459 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 9460 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 9461 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 9462 out.endTag(null, TAG_URI_GRANT); 9463 } 9464 out.endTag(null, TAG_URI_GRANTS); 9465 out.endDocument(); 9466 9467 mGrantFile.finishWrite(fos); 9468 } catch (IOException e) { 9469 if (fos != null) { 9470 mGrantFile.failWrite(fos); 9471 } 9472 } 9473 } 9474 9475 private void readGrantedUriPermissionsLocked() { 9476 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()"); 9477 9478 final long now = System.currentTimeMillis(); 9479 9480 FileInputStream fis = null; 9481 try { 9482 fis = mGrantFile.openRead(); 9483 final XmlPullParser in = Xml.newPullParser(); 9484 in.setInput(fis, StandardCharsets.UTF_8.name()); 9485 9486 int type; 9487 while ((type = in.next()) != END_DOCUMENT) { 9488 final String tag = in.getName(); 9489 if (type == START_TAG) { 9490 if (TAG_URI_GRANT.equals(tag)) { 9491 final int sourceUserId; 9492 final int targetUserId; 9493 final int userHandle = readIntAttribute(in, 9494 ATTR_USER_HANDLE, UserHandle.USER_NULL); 9495 if (userHandle != UserHandle.USER_NULL) { 9496 // For backwards compatibility. 9497 sourceUserId = userHandle; 9498 targetUserId = userHandle; 9499 } else { 9500 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 9501 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 9502 } 9503 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 9504 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 9505 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 9506 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 9507 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 9508 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 9509 9510 // Sanity check that provider still belongs to source package 9511 // Both direct boot aware and unaware packages are fine as we 9512 // will do filtering at query time to avoid multiple parsing. 9513 final ProviderInfo pi = getProviderInfoLocked( 9514 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE 9515 | MATCH_DIRECT_BOOT_UNAWARE); 9516 if (pi != null && sourcePkg.equals(pi.packageName)) { 9517 int targetUid = -1; 9518 try { 9519 targetUid = AppGlobals.getPackageManager().getPackageUid( 9520 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId); 9521 } catch (RemoteException e) { 9522 } 9523 if (targetUid != -1) { 9524 final UriPermission perm = findOrCreateUriPermissionLocked( 9525 sourcePkg, targetPkg, targetUid, 9526 new GrantUri(sourceUserId, uri, prefix)); 9527 perm.initPersistedModes(modeFlags, createdTime); 9528 } 9529 } else { 9530 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 9531 + " but instead found " + pi); 9532 } 9533 } 9534 } 9535 } 9536 } catch (FileNotFoundException e) { 9537 // Missing grants is okay 9538 } catch (IOException e) { 9539 Slog.wtf(TAG, "Failed reading Uri grants", e); 9540 } catch (XmlPullParserException e) { 9541 Slog.wtf(TAG, "Failed reading Uri grants", e); 9542 } finally { 9543 IoUtils.closeQuietly(fis); 9544 } 9545 } 9546 9547 /** 9548 * @param uri This uri must NOT contain an embedded userId. 9549 * @param userId The userId in which the uri is to be resolved. 9550 */ 9551 @Override 9552 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 9553 enforceNotIsolatedCaller("takePersistableUriPermission"); 9554 9555 Preconditions.checkFlagsArgument(modeFlags, 9556 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 9557 9558 synchronized (this) { 9559 final int callingUid = Binder.getCallingUid(); 9560 boolean persistChanged = false; 9561 GrantUri grantUri = new GrantUri(userId, uri, false); 9562 9563 UriPermission exactPerm = findUriPermissionLocked(callingUid, 9564 new GrantUri(userId, uri, false)); 9565 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 9566 new GrantUri(userId, uri, true)); 9567 9568 final boolean exactValid = (exactPerm != null) 9569 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 9570 final boolean prefixValid = (prefixPerm != null) 9571 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 9572 9573 if (!(exactValid || prefixValid)) { 9574 throw new SecurityException("No persistable permission grants found for UID " 9575 + callingUid + " and Uri " + grantUri.toSafeString()); 9576 } 9577 9578 if (exactValid) { 9579 persistChanged |= exactPerm.takePersistableModes(modeFlags); 9580 } 9581 if (prefixValid) { 9582 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 9583 } 9584 9585 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 9586 9587 if (persistChanged) { 9588 schedulePersistUriGrants(); 9589 } 9590 } 9591 } 9592 9593 /** 9594 * @param uri This uri must NOT contain an embedded userId. 9595 * @param userId The userId in which the uri is to be resolved. 9596 */ 9597 @Override 9598 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 9599 enforceNotIsolatedCaller("releasePersistableUriPermission"); 9600 9601 Preconditions.checkFlagsArgument(modeFlags, 9602 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 9603 9604 synchronized (this) { 9605 final int callingUid = Binder.getCallingUid(); 9606 boolean persistChanged = false; 9607 9608 UriPermission exactPerm = findUriPermissionLocked(callingUid, 9609 new GrantUri(userId, uri, false)); 9610 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 9611 new GrantUri(userId, uri, true)); 9612 if (exactPerm == null && prefixPerm == null) { 9613 throw new SecurityException("No permission grants found for UID " + callingUid 9614 + " and Uri " + uri.toSafeString()); 9615 } 9616 9617 if (exactPerm != null) { 9618 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 9619 removeUriPermissionIfNeededLocked(exactPerm); 9620 } 9621 if (prefixPerm != null) { 9622 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 9623 removeUriPermissionIfNeededLocked(prefixPerm); 9624 } 9625 9626 if (persistChanged) { 9627 schedulePersistUriGrants(); 9628 } 9629 } 9630 } 9631 9632 /** 9633 * Prune any older {@link UriPermission} for the given UID until outstanding 9634 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 9635 * 9636 * @return if any mutations occured that require persisting. 9637 */ 9638 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 9639 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 9640 if (perms == null) return false; 9641 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 9642 9643 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 9644 for (UriPermission perm : perms.values()) { 9645 if (perm.persistedModeFlags != 0) { 9646 persisted.add(perm); 9647 } 9648 } 9649 9650 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 9651 if (trimCount <= 0) return false; 9652 9653 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 9654 for (int i = 0; i < trimCount; i++) { 9655 final UriPermission perm = persisted.get(i); 9656 9657 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9658 "Trimming grant created at " + perm.persistedCreateTime); 9659 9660 perm.releasePersistableModes(~0); 9661 removeUriPermissionIfNeededLocked(perm); 9662 } 9663 9664 return true; 9665 } 9666 9667 @Override 9668 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 9669 String packageName, boolean incoming) { 9670 enforceNotIsolatedCaller("getPersistedUriPermissions"); 9671 Preconditions.checkNotNull(packageName, "packageName"); 9672 9673 final int callingUid = Binder.getCallingUid(); 9674 final int callingUserId = UserHandle.getUserId(callingUid); 9675 final IPackageManager pm = AppGlobals.getPackageManager(); 9676 try { 9677 final int packageUid = pm.getPackageUid(packageName, 9678 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId); 9679 if (packageUid != callingUid) { 9680 throw new SecurityException( 9681 "Package " + packageName + " does not belong to calling UID " + callingUid); 9682 } 9683 } catch (RemoteException e) { 9684 throw new SecurityException("Failed to verify package name ownership"); 9685 } 9686 9687 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 9688 synchronized (this) { 9689 if (incoming) { 9690 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 9691 callingUid); 9692 if (perms == null) { 9693 Slog.w(TAG, "No permission grants found for " + packageName); 9694 } else { 9695 for (UriPermission perm : perms.values()) { 9696 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 9697 result.add(perm.buildPersistedPublicApiObject()); 9698 } 9699 } 9700 } 9701 } else { 9702 final int size = mGrantedUriPermissions.size(); 9703 for (int i = 0; i < size; i++) { 9704 final ArrayMap<GrantUri, UriPermission> perms = 9705 mGrantedUriPermissions.valueAt(i); 9706 for (UriPermission perm : perms.values()) { 9707 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 9708 result.add(perm.buildPersistedPublicApiObject()); 9709 } 9710 } 9711 } 9712 } 9713 } 9714 return new ParceledListSlice<android.content.UriPermission>(result); 9715 } 9716 9717 @Override 9718 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions( 9719 String packageName, int userId) { 9720 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS, 9721 "getGrantedUriPermissions"); 9722 9723 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 9724 synchronized (this) { 9725 final int size = mGrantedUriPermissions.size(); 9726 for (int i = 0; i < size; i++) { 9727 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 9728 for (UriPermission perm : perms.values()) { 9729 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId 9730 && perm.persistedModeFlags != 0) { 9731 result.add(perm.buildPersistedPublicApiObject()); 9732 } 9733 } 9734 } 9735 } 9736 return new ParceledListSlice<android.content.UriPermission>(result); 9737 } 9738 9739 @Override 9740 public void clearGrantedUriPermissions(String packageName, int userId) { 9741 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS, 9742 "clearGrantedUriPermissions"); 9743 removeUriPermissionsForPackageLocked(packageName, userId, true); 9744 } 9745 9746 @Override 9747 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 9748 synchronized (this) { 9749 ProcessRecord app = 9750 who != null ? getRecordForAppLocked(who) : null; 9751 if (app == null) return; 9752 9753 Message msg = Message.obtain(); 9754 msg.what = WAIT_FOR_DEBUGGER_UI_MSG; 9755 msg.obj = app; 9756 msg.arg1 = waiting ? 1 : 0; 9757 mUiHandler.sendMessage(msg); 9758 } 9759 } 9760 9761 @Override 9762 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 9763 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 9764 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 9765 outInfo.availMem = getFreeMemory(); 9766 outInfo.totalMem = getTotalMemory(); 9767 outInfo.threshold = homeAppMem; 9768 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 9769 outInfo.hiddenAppThreshold = cachedAppMem; 9770 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 9771 ProcessList.SERVICE_ADJ); 9772 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 9773 ProcessList.VISIBLE_APP_ADJ); 9774 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 9775 ProcessList.FOREGROUND_APP_ADJ); 9776 } 9777 9778 // ========================================================= 9779 // TASK MANAGEMENT 9780 // ========================================================= 9781 9782 @Override 9783 public List<IBinder> getAppTasks(String callingPackage) { 9784 int callingUid = Binder.getCallingUid(); 9785 long ident = Binder.clearCallingIdentity(); 9786 9787 synchronized(this) { 9788 ArrayList<IBinder> list = new ArrayList<IBinder>(); 9789 try { 9790 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks"); 9791 9792 final int N = mRecentTasks.size(); 9793 for (int i = 0; i < N; i++) { 9794 TaskRecord tr = mRecentTasks.get(i); 9795 // Skip tasks that do not match the caller. We don't need to verify 9796 // callingPackage, because we are also limiting to callingUid and know 9797 // that will limit to the correct security sandbox. 9798 if (tr.effectiveUid != callingUid) { 9799 continue; 9800 } 9801 Intent intent = tr.getBaseIntent(); 9802 if (intent == null || 9803 !callingPackage.equals(intent.getComponent().getPackageName())) { 9804 continue; 9805 } 9806 ActivityManager.RecentTaskInfo taskInfo = 9807 createRecentTaskInfoFromTaskRecord(tr); 9808 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 9809 list.add(taskImpl.asBinder()); 9810 } 9811 } finally { 9812 Binder.restoreCallingIdentity(ident); 9813 } 9814 return list; 9815 } 9816 } 9817 9818 @Override 9819 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 9820 final int callingUid = Binder.getCallingUid(); 9821 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 9822 9823 synchronized(this) { 9824 if (DEBUG_ALL) Slog.v( 9825 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 9826 9827 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 9828 callingUid); 9829 9830 // TODO: Improve with MRU list from all ActivityStacks. 9831 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 9832 } 9833 9834 return list; 9835 } 9836 9837 /** 9838 * Creates a new RecentTaskInfo from a TaskRecord. 9839 */ 9840 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 9841 // Update the task description to reflect any changes in the task stack 9842 tr.updateTaskDescription(); 9843 9844 // Compose the recent task info 9845 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 9846 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 9847 rti.persistentId = tr.taskId; 9848 rti.baseIntent = new Intent(tr.getBaseIntent()); 9849 rti.origActivity = tr.origActivity; 9850 rti.realActivity = tr.realActivity; 9851 rti.description = tr.lastDescription; 9852 rti.stackId = tr.getStackId(); 9853 rti.userId = tr.userId; 9854 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 9855 rti.firstActiveTime = tr.firstActiveTime; 9856 rti.lastActiveTime = tr.lastActiveTime; 9857 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 9858 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 9859 rti.numActivities = 0; 9860 if (tr.mBounds != null) { 9861 rti.bounds = new Rect(tr.mBounds); 9862 } 9863 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen(); 9864 rti.resizeMode = tr.mResizeMode; 9865 9866 ActivityRecord base = null; 9867 ActivityRecord top = null; 9868 ActivityRecord tmp; 9869 9870 for (int i = tr.mActivities.size() - 1; i >= 0; --i) { 9871 tmp = tr.mActivities.get(i); 9872 if (tmp.finishing) { 9873 continue; 9874 } 9875 base = tmp; 9876 if (top == null || (top.state == ActivityState.INITIALIZING)) { 9877 top = base; 9878 } 9879 rti.numActivities++; 9880 } 9881 9882 rti.baseActivity = (base != null) ? base.intent.getComponent() : null; 9883 rti.topActivity = (top != null) ? top.intent.getComponent() : null; 9884 9885 return rti; 9886 } 9887 9888 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 9889 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 9890 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 9891 if (!allowed) { 9892 if (checkPermission(android.Manifest.permission.GET_TASKS, 9893 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 9894 // Temporary compatibility: some existing apps on the system image may 9895 // still be requesting the old permission and not switched to the new 9896 // one; if so, we'll still allow them full access. This means we need 9897 // to see if they are holding the old permission and are a system app. 9898 try { 9899 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 9900 allowed = true; 9901 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid 9902 + " is using old GET_TASKS but privileged; allowing"); 9903 } 9904 } catch (RemoteException e) { 9905 } 9906 } 9907 } 9908 if (!allowed) { 9909 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid 9910 + " does not hold REAL_GET_TASKS; limiting output"); 9911 } 9912 return allowed; 9913 } 9914 9915 @Override 9916 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, 9917 int userId) { 9918 final int callingUid = Binder.getCallingUid(); 9919 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 9920 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 9921 9922 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 9923 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 9924 synchronized (this) { 9925 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 9926 callingUid); 9927 final boolean detailed = checkCallingPermission( 9928 android.Manifest.permission.GET_DETAILED_TASKS) 9929 == PackageManager.PERMISSION_GRANTED; 9930 9931 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) { 9932 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents"); 9933 return ParceledListSlice.emptyList(); 9934 } 9935 mRecentTasks.loadUserRecentsLocked(userId); 9936 9937 final int recentsCount = mRecentTasks.size(); 9938 ArrayList<ActivityManager.RecentTaskInfo> res = 9939 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount); 9940 9941 final Set<Integer> includedUsers; 9942 if (includeProfiles) { 9943 includedUsers = mUserController.getProfileIds(userId); 9944 } else { 9945 includedUsers = new HashSet<>(); 9946 } 9947 includedUsers.add(Integer.valueOf(userId)); 9948 9949 for (int i = 0; i < recentsCount && maxNum > 0; i++) { 9950 TaskRecord tr = mRecentTasks.get(i); 9951 // Only add calling user or related users recent tasks 9952 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 9953 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr); 9954 continue; 9955 } 9956 9957 if (tr.realActivitySuspended) { 9958 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr); 9959 continue; 9960 } 9961 9962 // Return the entry if desired by the caller. We always return 9963 // the first entry, because callers always expect this to be the 9964 // foreground app. We may filter others if the caller has 9965 // not supplied RECENT_WITH_EXCLUDED and there is some reason 9966 // we should exclude the entry. 9967 9968 if (i == 0 9969 || withExcluded 9970 || (tr.intent == null) 9971 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 9972 == 0)) { 9973 if (!allowed) { 9974 // If the caller doesn't have the GET_TASKS permission, then only 9975 // allow them to see a small subset of tasks -- their own and home. 9976 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 9977 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr); 9978 continue; 9979 } 9980 } 9981 final ActivityStack stack = tr.getStack(); 9982 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) { 9983 if (stack != null && stack.isHomeOrRecentsStack()) { 9984 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 9985 "Skipping, home or recents stack task: " + tr); 9986 continue; 9987 } 9988 } 9989 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) { 9990 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) { 9991 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 9992 "Skipping, top task in docked stack: " + tr); 9993 continue; 9994 } 9995 } 9996 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) { 9997 if (stack != null && stack.isPinnedStack()) { 9998 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 9999 "Skipping, pinned stack task: " + tr); 10000 continue; 10001 } 10002 } 10003 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 10004 // Don't include auto remove tasks that are finished or finishing. 10005 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 10006 "Skipping, auto-remove without activity: " + tr); 10007 continue; 10008 } 10009 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 10010 && !tr.isAvailable) { 10011 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 10012 "Skipping, unavail real act: " + tr); 10013 continue; 10014 } 10015 10016 if (!tr.mUserSetupComplete) { 10017 // Don't include task launched while user is not done setting-up. 10018 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 10019 "Skipping, user setup not complete: " + tr); 10020 continue; 10021 } 10022 10023 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 10024 if (!detailed) { 10025 rti.baseIntent.replaceExtras((Bundle)null); 10026 } 10027 10028 res.add(rti); 10029 maxNum--; 10030 } 10031 } 10032 return new ParceledListSlice<>(res); 10033 } 10034 } 10035 10036 @Override 10037 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 10038 synchronized (this) { 10039 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 10040 "getTaskThumbnail()"); 10041 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked( 10042 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); 10043 if (tr != null) { 10044 return tr.getTaskThumbnailLocked(); 10045 } 10046 } 10047 return null; 10048 } 10049 10050 @Override 10051 public ActivityManager.TaskDescription getTaskDescription(int id) { 10052 synchronized (this) { 10053 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 10054 "getTaskDescription()"); 10055 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, 10056 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); 10057 if (tr != null) { 10058 return tr.lastTaskDescription; 10059 } 10060 } 10061 return null; 10062 } 10063 10064 @Override 10065 public int addAppTask(IBinder activityToken, Intent intent, 10066 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 10067 final int callingUid = Binder.getCallingUid(); 10068 final long callingIdent = Binder.clearCallingIdentity(); 10069 10070 try { 10071 synchronized (this) { 10072 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 10073 if (r == null) { 10074 throw new IllegalArgumentException("Activity does not exist; token=" 10075 + activityToken); 10076 } 10077 ComponentName comp = intent.getComponent(); 10078 if (comp == null) { 10079 throw new IllegalArgumentException("Intent " + intent 10080 + " must specify explicit component"); 10081 } 10082 if (thumbnail.getWidth() != mThumbnailWidth 10083 || thumbnail.getHeight() != mThumbnailHeight) { 10084 throw new IllegalArgumentException("Bad thumbnail size: got " 10085 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 10086 + mThumbnailWidth + "x" + mThumbnailHeight); 10087 } 10088 if (intent.getSelector() != null) { 10089 intent.setSelector(null); 10090 } 10091 if (intent.getSourceBounds() != null) { 10092 intent.setSourceBounds(null); 10093 } 10094 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 10095 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 10096 // The caller has added this as an auto-remove task... that makes no 10097 // sense, so turn off auto-remove. 10098 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 10099 } 10100 } 10101 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 10102 mLastAddedTaskActivity = null; 10103 } 10104 ActivityInfo ainfo = mLastAddedTaskActivity; 10105 if (ainfo == null) { 10106 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 10107 comp, 0, UserHandle.getUserId(callingUid)); 10108 if (ainfo.applicationInfo.uid != callingUid) { 10109 throw new SecurityException( 10110 "Can't add task for another application: target uid=" 10111 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 10112 } 10113 } 10114 10115 TaskRecord task = new TaskRecord(this, 10116 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), 10117 ainfo, intent, description, new TaskThumbnailInfo()); 10118 10119 int trimIdx = mRecentTasks.trimForTaskLocked(task, false); 10120 if (trimIdx >= 0) { 10121 // If this would have caused a trim, then we'll abort because that 10122 // means it would be added at the end of the list but then just removed. 10123 return INVALID_TASK_ID; 10124 } 10125 10126 final int N = mRecentTasks.size(); 10127 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 10128 final TaskRecord tr = mRecentTasks.remove(N - 1); 10129 tr.removedFromRecents(); 10130 } 10131 10132 task.inRecents = true; 10133 mRecentTasks.add(task); 10134 r.getStack().addTask(task, false, "addAppTask"); 10135 10136 task.setLastThumbnailLocked(thumbnail); 10137 task.freeLastThumbnail(); 10138 return task.taskId; 10139 } 10140 } finally { 10141 Binder.restoreCallingIdentity(callingIdent); 10142 } 10143 } 10144 10145 @Override 10146 public Point getAppTaskThumbnailSize() { 10147 synchronized (this) { 10148 return new Point(mThumbnailWidth, mThumbnailHeight); 10149 } 10150 } 10151 10152 @Override 10153 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 10154 synchronized (this) { 10155 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10156 if (r != null) { 10157 r.setTaskDescription(td); 10158 final TaskRecord task = r.getTask(); 10159 task.updateTaskDescription(); 10160 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td); 10161 } 10162 } 10163 } 10164 10165 @Override 10166 public void setTaskResizeable(int taskId, int resizeableMode) { 10167 synchronized (this) { 10168 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked( 10169 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); 10170 if (task == null) { 10171 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found"); 10172 return; 10173 } 10174 task.setResizeMode(resizeableMode); 10175 } 10176 } 10177 10178 @Override 10179 public void resizeTask(int taskId, Rect bounds, int resizeMode) { 10180 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()"); 10181 long ident = Binder.clearCallingIdentity(); 10182 try { 10183 synchronized (this) { 10184 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10185 if (task == null) { 10186 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found"); 10187 return; 10188 } 10189 // Place the task in the right stack if it isn't there already based on 10190 // the requested bounds. 10191 // The stack transition logic is: 10192 // - a null bounds on a freeform task moves that task to fullscreen 10193 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves 10194 // that task to freeform 10195 // - otherwise the task is not moved 10196 int stackId = task.getStackId(); 10197 if (!StackId.isTaskResizeAllowed(stackId)) { 10198 throw new IllegalArgumentException("resizeTask not allowed on task=" + task); 10199 } 10200 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) { 10201 stackId = FULLSCREEN_WORKSPACE_STACK_ID; 10202 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) { 10203 stackId = FREEFORM_WORKSPACE_STACK_ID; 10204 } 10205 10206 // Reparent the task to the right stack if necessary 10207 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0; 10208 if (stackId != task.getStackId()) { 10209 // Defer resume until the task is resized below 10210 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, 10211 DEFER_RESUME, "resizeTask"); 10212 preserveWindow = false; 10213 } 10214 10215 // After reparenting (which only resizes the task to the stack bounds), resize the 10216 // task to the actual bounds provided 10217 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME); 10218 } 10219 } finally { 10220 Binder.restoreCallingIdentity(ident); 10221 } 10222 } 10223 10224 @Override 10225 public Rect getTaskBounds(int taskId) { 10226 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()"); 10227 long ident = Binder.clearCallingIdentity(); 10228 Rect rect = new Rect(); 10229 try { 10230 synchronized (this) { 10231 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, 10232 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); 10233 if (task == null) { 10234 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found"); 10235 return rect; 10236 } 10237 if (task.getStack() != null) { 10238 // Return the bounds from window manager since it will be adjusted for various 10239 // things like the presense of a docked stack for tasks that aren't resizeable. 10240 task.getWindowContainerBounds(rect); 10241 } else { 10242 // Task isn't in window manager yet since it isn't associated with a stack. 10243 // Return the persist value from activity manager 10244 if (task.mBounds != null) { 10245 rect.set(task.mBounds); 10246 } else if (task.mLastNonFullscreenBounds != null) { 10247 rect.set(task.mLastNonFullscreenBounds); 10248 } 10249 } 10250 } 10251 } finally { 10252 Binder.restoreCallingIdentity(ident); 10253 } 10254 return rect; 10255 } 10256 10257 @Override 10258 public void cancelTaskWindowTransition(int taskId) { 10259 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()"); 10260 final long ident = Binder.clearCallingIdentity(); 10261 try { 10262 synchronized (this) { 10263 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, 10264 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID); 10265 if (task == null) { 10266 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found"); 10267 return; 10268 } 10269 task.cancelWindowTransition(); 10270 } 10271 } finally { 10272 Binder.restoreCallingIdentity(ident); 10273 } 10274 } 10275 10276 @Override 10277 public void cancelTaskThumbnailTransition(int taskId) { 10278 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()"); 10279 final long ident = Binder.clearCallingIdentity(); 10280 try { 10281 synchronized (this) { 10282 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, 10283 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID); 10284 if (task == null) { 10285 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found"); 10286 return; 10287 } 10288 task.cancelThumbnailTransition(); 10289 } 10290 } finally { 10291 Binder.restoreCallingIdentity(ident); 10292 } 10293 } 10294 10295 @Override 10296 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) { 10297 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()"); 10298 final long ident = Binder.clearCallingIdentity(); 10299 try { 10300 final TaskRecord task; 10301 synchronized (this) { 10302 task = mStackSupervisor.anyTaskForIdLocked(taskId, 10303 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); 10304 if (task == null) { 10305 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found"); 10306 return null; 10307 } 10308 } 10309 // Don't call this while holding the lock as this operation might hit the disk. 10310 return task.getSnapshot(reducedResolution); 10311 } finally { 10312 Binder.restoreCallingIdentity(ident); 10313 } 10314 } 10315 10316 @Override 10317 public Bitmap getTaskDescriptionIcon(String filePath, int userId) { 10318 if (userId != UserHandle.getCallingUserId()) { 10319 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10320 "getTaskDescriptionIcon"); 10321 } 10322 final File passedIconFile = new File(filePath); 10323 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId), 10324 passedIconFile.getName()); 10325 if (!legitIconFile.getPath().equals(filePath) 10326 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 10327 throw new IllegalArgumentException("Bad file path: " + filePath 10328 + " passed for userId " + userId); 10329 } 10330 return mRecentTasks.getTaskDescriptionIcon(filePath); 10331 } 10332 10333 @Override 10334 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) 10335 throws RemoteException { 10336 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts); 10337 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 10338 activityOptions.getCustomInPlaceResId() == 0) { 10339 throw new IllegalArgumentException("Expected in-place ActivityOption " + 10340 "with valid animation"); 10341 } 10342 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false); 10343 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(), 10344 activityOptions.getCustomInPlaceResId()); 10345 mWindowManager.executeAppTransition(); 10346 } 10347 10348 private void removeTasksByPackageNameLocked(String packageName, int userId) { 10349 // Remove all tasks with activities in the specified package from the list of recent tasks 10350 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 10351 TaskRecord tr = mRecentTasks.get(i); 10352 if (tr.userId != userId) continue; 10353 10354 ComponentName cn = tr.intent.getComponent(); 10355 if (cn != null && cn.getPackageName().equals(packageName)) { 10356 // If the package name matches, remove the task. 10357 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS); 10358 } 10359 } 10360 } 10361 10362 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses, 10363 int userId) { 10364 10365 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 10366 TaskRecord tr = mRecentTasks.get(i); 10367 if (userId != UserHandle.USER_ALL && tr.userId != userId) { 10368 continue; 10369 } 10370 10371 ComponentName cn = tr.intent.getComponent(); 10372 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName) 10373 && (filterByClasses == null || filterByClasses.contains(cn.getClassName())); 10374 if (sameComponent) { 10375 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS); 10376 } 10377 } 10378 } 10379 10380 @Override 10381 public void removeStack(int stackId) { 10382 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()"); 10383 if (StackId.isHomeOrRecentsStack(stackId)) { 10384 throw new IllegalArgumentException("Removing home or recents stack is not allowed."); 10385 } 10386 10387 synchronized (this) { 10388 final long ident = Binder.clearCallingIdentity(); 10389 try { 10390 mStackSupervisor.removeStackLocked(stackId); 10391 } finally { 10392 Binder.restoreCallingIdentity(ident); 10393 } 10394 } 10395 } 10396 10397 @Override 10398 public void moveStackToDisplay(int stackId, int displayId) { 10399 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()"); 10400 10401 synchronized (this) { 10402 final long ident = Binder.clearCallingIdentity(); 10403 try { 10404 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId 10405 + " to displayId=" + displayId); 10406 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP); 10407 } finally { 10408 Binder.restoreCallingIdentity(ident); 10409 } 10410 } 10411 } 10412 10413 @Override 10414 public boolean removeTask(int taskId) { 10415 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()"); 10416 synchronized (this) { 10417 final long ident = Binder.clearCallingIdentity(); 10418 try { 10419 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS); 10420 } finally { 10421 Binder.restoreCallingIdentity(ident); 10422 } 10423 } 10424 } 10425 10426 /** 10427 * TODO: Add mController hook 10428 */ 10429 @Override 10430 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) { 10431 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()"); 10432 10433 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId); 10434 synchronized(this) { 10435 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */); 10436 } 10437 } 10438 10439 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) { 10440 ActivityOptions options = ActivityOptions.fromBundle(bOptions); 10441 10442 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 10443 Binder.getCallingUid(), -1, -1, "Task to front")) { 10444 ActivityOptions.abort(options); 10445 return; 10446 } 10447 final long origId = Binder.clearCallingIdentity(); 10448 try { 10449 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10450 if (task == null) { 10451 Slog.d(TAG, "Could not find task for id: "+ taskId); 10452 return; 10453 } 10454 if (mStackSupervisor.isLockTaskModeViolation(task)) { 10455 mStackSupervisor.showLockTaskToast(); 10456 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 10457 return; 10458 } 10459 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 10460 if (prev != null) { 10461 task.setTaskToReturnTo(prev); 10462 } 10463 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront", 10464 false /* forceNonResizable */); 10465 10466 final ActivityRecord topActivity = task.getTopActivity(); 10467 if (topActivity != null) { 10468 10469 // We are reshowing a task, use a starting window to hide the initial draw delay 10470 // so the transition can start earlier. 10471 topActivity.showStartingWindow(null /* prev */, false /* newTask */, 10472 true /* taskSwitch */, fromRecents); 10473 } 10474 } finally { 10475 Binder.restoreCallingIdentity(origId); 10476 } 10477 ActivityOptions.abort(options); 10478 } 10479 10480 /** 10481 * Attempts to move a task backwards in z-order (the order of activities within the task is 10482 * unchanged). 10483 * 10484 * There are several possible results of this call: 10485 * - if the task is locked, then we will show the lock toast 10486 * - if there is a task behind the provided task, then that task is made visible and resumed as 10487 * this task is moved to the back 10488 * - otherwise, if there are no other tasks in the stack: 10489 * - if this task is in the pinned stack, then we remove the stack completely, which will 10490 * have the effect of moving the task to the top or bottom of the fullscreen stack 10491 * (depending on whether it is visible) 10492 * - otherwise, we simply return home and hide this task 10493 * 10494 * @param token A reference to the activity we wish to move 10495 * @param nonRoot If false then this only works if the activity is the root 10496 * of a task; if true it will work for any activity in a task. 10497 * @return Returns true if the move completed, false if not. 10498 */ 10499 @Override 10500 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 10501 enforceNotIsolatedCaller("moveActivityTaskToBack"); 10502 synchronized(this) { 10503 final long origId = Binder.clearCallingIdentity(); 10504 try { 10505 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 10506 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10507 if (task != null) { 10508 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId); 10509 } 10510 } finally { 10511 Binder.restoreCallingIdentity(origId); 10512 } 10513 } 10514 return false; 10515 } 10516 10517 @Override 10518 public void moveTaskBackwards(int task) { 10519 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 10520 "moveTaskBackwards()"); 10521 10522 synchronized(this) { 10523 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 10524 Binder.getCallingUid(), -1, -1, "Task backwards")) { 10525 return; 10526 } 10527 final long origId = Binder.clearCallingIdentity(); 10528 moveTaskBackwardsLocked(task); 10529 Binder.restoreCallingIdentity(origId); 10530 } 10531 } 10532 10533 private final void moveTaskBackwardsLocked(int task) { 10534 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 10535 } 10536 10537 @Override 10538 public int createStackOnDisplay(int displayId) throws RemoteException { 10539 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()"); 10540 synchronized (this) { 10541 final int stackId = mStackSupervisor.getNextStackId(); 10542 final ActivityStack stack = 10543 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/); 10544 if (stack == null) { 10545 return INVALID_STACK_ID; 10546 } 10547 return stack.mStackId; 10548 } 10549 } 10550 10551 @Override 10552 public int getActivityDisplayId(IBinder activityToken) throws RemoteException { 10553 synchronized (this) { 10554 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 10555 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) { 10556 return stack.mDisplayId; 10557 } 10558 return DEFAULT_DISPLAY; 10559 } 10560 } 10561 10562 @Override 10563 public int getActivityStackId(IBinder token) throws RemoteException { 10564 synchronized (this) { 10565 ActivityStack stack = ActivityRecord.getStackLocked(token); 10566 if (stack == null) { 10567 return INVALID_STACK_ID; 10568 } 10569 return stack.mStackId; 10570 } 10571 } 10572 10573 @Override 10574 public void exitFreeformMode(IBinder token) throws RemoteException { 10575 synchronized (this) { 10576 long ident = Binder.clearCallingIdentity(); 10577 try { 10578 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 10579 if (r == null) { 10580 throw new IllegalArgumentException( 10581 "exitFreeformMode: No activity record matching token=" + token); 10582 } 10583 10584 final ActivityStack stack = r.getStack(); 10585 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) { 10586 throw new IllegalStateException( 10587 "exitFreeformMode: You can only go fullscreen from freeform."); 10588 } 10589 10590 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r); 10591 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, 10592 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode"); 10593 } finally { 10594 Binder.restoreCallingIdentity(ident); 10595 } 10596 } 10597 } 10598 10599 @Override 10600 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 10601 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()"); 10602 if (StackId.isHomeOrRecentsStack(stackId)) { 10603 throw new IllegalArgumentException( 10604 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId); 10605 } 10606 synchronized (this) { 10607 long ident = Binder.clearCallingIdentity(); 10608 try { 10609 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10610 if (task == null) { 10611 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId); 10612 return; 10613 } 10614 10615 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId 10616 + " to stackId=" + stackId + " toTop=" + toTop); 10617 if (stackId == DOCKED_STACK_ID) { 10618 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, 10619 null /* initialBounds */); 10620 } 10621 task.reparent(stackId, toTop, 10622 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack"); 10623 } finally { 10624 Binder.restoreCallingIdentity(ident); 10625 } 10626 } 10627 } 10628 10629 @Override 10630 public void swapDockedAndFullscreenStack() throws RemoteException { 10631 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()"); 10632 synchronized (this) { 10633 long ident = Binder.clearCallingIdentity(); 10634 try { 10635 final ActivityStack fullscreenStack = mStackSupervisor.getStack( 10636 FULLSCREEN_WORKSPACE_STACK_ID); 10637 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask() 10638 : null; 10639 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID); 10640 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks() 10641 : null; 10642 if (topTask == null || tasks == null || tasks.size() == 0) { 10643 Slog.w(TAG, 10644 "Unable to swap tasks, either docked or fullscreen stack is empty."); 10645 return; 10646 } 10647 10648 // TODO: App transition 10649 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false); 10650 10651 // Defer the resume until we move all the docked tasks to the fullscreen stack below 10652 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, 10653 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK"); 10654 final int size = tasks.size(); 10655 for (int i = 0; i < size; i++) { 10656 final int id = tasks.get(i).taskId; 10657 if (id == topTask.taskId) { 10658 continue; 10659 } 10660 10661 // Defer the resume until after all the tasks have been moved 10662 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, 10663 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME, 10664 "swapDockedAndFullscreenStack - FULLSCREEN_STACK"); 10665 } 10666 10667 // Because we deferred the resume to avoid conflicts with stack switches while 10668 // resuming, we need to do it after all the tasks are moved. 10669 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 10670 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 10671 10672 mWindowManager.executeAppTransition(); 10673 } finally { 10674 Binder.restoreCallingIdentity(ident); 10675 } 10676 } 10677 } 10678 10679 /** 10680 * Moves the input task to the docked stack. 10681 * 10682 * @param taskId Id of task to move. 10683 * @param createMode The mode the docked stack should be created in if it doesn't exist 10684 * already. See 10685 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT} 10686 * and 10687 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT} 10688 * @param toTop If the task and stack should be moved to the top. 10689 * @param animate Whether we should play an animation for the moving the task 10690 * @param initialBounds If the docked stack gets created, it will use these bounds for the 10691 * docked stack. Pass {@code null} to use default bounds. 10692 */ 10693 @Override 10694 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate, 10695 Rect initialBounds) { 10696 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()"); 10697 synchronized (this) { 10698 long ident = Binder.clearCallingIdentity(); 10699 try { 10700 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10701 if (task == null) { 10702 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId); 10703 return false; 10704 } 10705 10706 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId 10707 + " to createMode=" + createMode + " toTop=" + toTop); 10708 mWindowManager.setDockedStackCreateState(createMode, initialBounds); 10709 10710 // Defer resuming until we move the home stack to the front below 10711 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop, 10712 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME, 10713 "moveTaskToDockedStack"); 10714 if (moved) { 10715 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 10716 } 10717 return moved; 10718 } finally { 10719 Binder.restoreCallingIdentity(ident); 10720 } 10721 } 10722 } 10723 10724 /** 10725 * Moves the top activity in the input stackId to the pinned stack. 10726 * 10727 * @param stackId Id of stack to move the top activity to pinned stack. 10728 * @param bounds Bounds to use for pinned stack. 10729 * 10730 * @return True if the top activity of the input stack was successfully moved to the pinned 10731 * stack. 10732 */ 10733 @Override 10734 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) { 10735 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()"); 10736 synchronized (this) { 10737 if (!mSupportsPictureInPicture) { 10738 throw new IllegalStateException("moveTopActivityToPinnedStack:" 10739 + "Device doesn't support picture-in-picture mode"); 10740 } 10741 10742 long ident = Binder.clearCallingIdentity(); 10743 try { 10744 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds); 10745 } finally { 10746 Binder.restoreCallingIdentity(ident); 10747 } 10748 } 10749 } 10750 10751 @Override 10752 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode, 10753 boolean preserveWindows, boolean animate, int animationDuration) { 10754 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); 10755 long ident = Binder.clearCallingIdentity(); 10756 try { 10757 synchronized (this) { 10758 if (animate) { 10759 if (stackId == PINNED_STACK_ID) { 10760 final PinnedActivityStack pinnedStack = 10761 mStackSupervisor.getStack(PINNED_STACK_ID); 10762 if (pinnedStack != null) { 10763 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */, 10764 destBounds, animationDuration, false /* fromFullscreen */); 10765 } 10766 } else { 10767 throw new IllegalArgumentException("Stack: " + stackId 10768 + " doesn't support animated resize."); 10769 } 10770 } else { 10771 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */, 10772 null /* tempTaskInsetBounds */, preserveWindows, 10773 allowResizeInDockedMode, !DEFER_RESUME); 10774 } 10775 } 10776 } finally { 10777 Binder.restoreCallingIdentity(ident); 10778 } 10779 } 10780 10781 @Override 10782 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds, 10783 Rect tempDockedTaskInsetBounds, 10784 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) { 10785 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 10786 "resizeDockedStack()"); 10787 long ident = Binder.clearCallingIdentity(); 10788 try { 10789 synchronized (this) { 10790 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds, 10791 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds, 10792 PRESERVE_WINDOWS); 10793 } 10794 } finally { 10795 Binder.restoreCallingIdentity(ident); 10796 } 10797 } 10798 10799 @Override 10800 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) { 10801 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 10802 "resizePinnedStack()"); 10803 final long ident = Binder.clearCallingIdentity(); 10804 try { 10805 synchronized (this) { 10806 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds); 10807 } 10808 } finally { 10809 Binder.restoreCallingIdentity(ident); 10810 } 10811 } 10812 10813 /** 10814 * Try to place task to provided position. The final position might be different depending on 10815 * current user and stacks state. The task will be moved to target stack if it's currently in 10816 * different stack. 10817 */ 10818 @Override 10819 public void positionTaskInStack(int taskId, int stackId, int position) { 10820 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()"); 10821 if (StackId.isHomeOrRecentsStack(stackId)) { 10822 throw new IllegalArgumentException( 10823 "positionTaskInStack: Attempt to change the position of task " 10824 + taskId + " in/to home/recents stack"); 10825 } 10826 synchronized (this) { 10827 long ident = Binder.clearCallingIdentity(); 10828 try { 10829 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task=" 10830 + taskId + " in stackId=" + stackId + " at position=" + position); 10831 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10832 if (task == null) { 10833 throw new IllegalArgumentException("positionTaskInStack: no task for id=" 10834 + taskId); 10835 } 10836 10837 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED, 10838 !ON_TOP); 10839 10840 // TODO: Have the callers of this API call a separate reparent method if that is 10841 // what they intended to do vs. having this method also do reparenting. 10842 if (task.getStack() == stack) { 10843 // Change position in current stack. 10844 stack.positionChildAt(task, position); 10845 } else { 10846 // Reparent to new stack. 10847 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE, 10848 !ANIMATE, !DEFER_RESUME, "positionTaskInStack"); 10849 } 10850 } finally { 10851 Binder.restoreCallingIdentity(ident); 10852 } 10853 } 10854 } 10855 10856 @Override 10857 public List<StackInfo> getAllStackInfos() { 10858 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()"); 10859 long ident = Binder.clearCallingIdentity(); 10860 try { 10861 synchronized (this) { 10862 return mStackSupervisor.getAllStackInfosLocked(); 10863 } 10864 } finally { 10865 Binder.restoreCallingIdentity(ident); 10866 } 10867 } 10868 10869 @Override 10870 public StackInfo getStackInfo(int stackId) { 10871 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); 10872 long ident = Binder.clearCallingIdentity(); 10873 try { 10874 synchronized (this) { 10875 return mStackSupervisor.getStackInfoLocked(stackId); 10876 } 10877 } finally { 10878 Binder.restoreCallingIdentity(ident); 10879 } 10880 } 10881 10882 @Override 10883 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 10884 synchronized(this) { 10885 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 10886 } 10887 } 10888 10889 @Override 10890 public void updateDeviceOwner(String packageName) { 10891 final int callingUid = Binder.getCallingUid(); 10892 if (callingUid != 0 && callingUid != SYSTEM_UID) { 10893 throw new SecurityException("updateDeviceOwner called from non-system process"); 10894 } 10895 synchronized (this) { 10896 mDeviceOwnerName = packageName; 10897 } 10898 } 10899 10900 @Override 10901 public void updateLockTaskPackages(int userId, String[] packages) { 10902 final int callingUid = Binder.getCallingUid(); 10903 if (callingUid != 0 && callingUid != SYSTEM_UID) { 10904 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES, 10905 "updateLockTaskPackages()"); 10906 } 10907 synchronized (this) { 10908 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + 10909 Arrays.toString(packages)); 10910 mLockTaskPackages.put(userId, packages); 10911 mStackSupervisor.onLockTaskPackagesUpdatedLocked(); 10912 } 10913 } 10914 10915 10916 void startLockTaskModeLocked(TaskRecord task) { 10917 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task); 10918 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 10919 return; 10920 } 10921 10922 // When a task is locked, dismiss the pinned stack if it exists 10923 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack( 10924 PINNED_STACK_ID); 10925 if (pinnedStack != null) { 10926 mStackSupervisor.removeStackLocked(PINNED_STACK_ID); 10927 } 10928 10929 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode 10930 // is initiated by system after the pinning request was shown and locked mode is initiated 10931 // by an authorized app directly 10932 final int callingUid = Binder.getCallingUid(); 10933 boolean isSystemInitiated = callingUid == SYSTEM_UID; 10934 long ident = Binder.clearCallingIdentity(); 10935 try { 10936 if (!isSystemInitiated) { 10937 task.mLockTaskUid = callingUid; 10938 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) { 10939 // startLockTask() called by app and task mode is lockTaskModeDefault. 10940 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user"); 10941 StatusBarManagerInternal statusBarManager = 10942 LocalServices.getService(StatusBarManagerInternal.class); 10943 if (statusBarManager != null) { 10944 statusBarManager.showScreenPinningRequest(task.taskId); 10945 } 10946 return; 10947 } 10948 10949 final ActivityStack stack = mStackSupervisor.getFocusedStack(); 10950 if (stack == null || task != stack.topTask()) { 10951 throw new IllegalArgumentException("Invalid task, not in foreground"); 10952 } 10953 } 10954 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" : 10955 "Locking fully"); 10956 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ? 10957 ActivityManager.LOCK_TASK_MODE_PINNED : 10958 ActivityManager.LOCK_TASK_MODE_LOCKED, 10959 "startLockTask", true); 10960 } finally { 10961 Binder.restoreCallingIdentity(ident); 10962 } 10963 } 10964 10965 @Override 10966 public void startLockTaskModeById(int taskId) { 10967 synchronized (this) { 10968 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10969 if (task != null) { 10970 startLockTaskModeLocked(task); 10971 } 10972 } 10973 } 10974 10975 @Override 10976 public void startLockTaskModeByToken(IBinder token) { 10977 synchronized (this) { 10978 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 10979 if (r == null) { 10980 return; 10981 } 10982 final TaskRecord task = r.getTask(); 10983 if (task != null) { 10984 startLockTaskModeLocked(task); 10985 } 10986 } 10987 } 10988 10989 @Override 10990 public void startSystemLockTaskMode(int taskId) throws RemoteException { 10991 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode"); 10992 // This makes inner call to look as if it was initiated by system. 10993 long ident = Binder.clearCallingIdentity(); 10994 try { 10995 synchronized (this) { 10996 startLockTaskModeById(taskId); 10997 } 10998 } finally { 10999 Binder.restoreCallingIdentity(ident); 11000 } 11001 } 11002 11003 @Override 11004 public void stopLockTaskMode() { 11005 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked(); 11006 if (lockTask == null) { 11007 // Our work here is done. 11008 return; 11009 } 11010 11011 final int callingUid = Binder.getCallingUid(); 11012 final int lockTaskUid = lockTask.mLockTaskUid; 11013 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState(); 11014 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) { 11015 // Done. 11016 return; 11017 } else { 11018 // Ensure the same caller for startLockTaskMode and stopLockTaskMode. 11019 // It is possible lockTaskMode was started by the system process because 11020 // android:lockTaskMode is set to a locking value in the application manifest 11021 // instead of the app calling startLockTaskMode. In this case 11022 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the 11023 // {@link TaskRecord.effectiveUid} instead. Also caller with 11024 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task. 11025 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED 11026 && callingUid != lockTaskUid 11027 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) { 11028 throw new SecurityException("Invalid uid, expected " + lockTaskUid 11029 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid); 11030 } 11031 } 11032 long ident = Binder.clearCallingIdentity(); 11033 try { 11034 Log.d(TAG, "stopLockTaskMode"); 11035 // Stop lock task 11036 synchronized (this) { 11037 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE, 11038 "stopLockTask", true); 11039 } 11040 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 11041 if (tm != null) { 11042 tm.showInCallScreen(false); 11043 } 11044 } finally { 11045 Binder.restoreCallingIdentity(ident); 11046 } 11047 } 11048 11049 /** 11050 * This API should be called by SystemUI only when user perform certain action to dismiss 11051 * lock task mode. We should only dismiss pinned lock task mode in this case. 11052 */ 11053 @Override 11054 public void stopSystemLockTaskMode() throws RemoteException { 11055 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) { 11056 stopLockTaskMode(); 11057 } else { 11058 mStackSupervisor.showLockTaskToast(); 11059 } 11060 } 11061 11062 @Override 11063 public boolean isInLockTaskMode() { 11064 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE; 11065 } 11066 11067 @Override 11068 public int getLockTaskModeState() { 11069 synchronized (this) { 11070 return mStackSupervisor.getLockTaskModeState(); 11071 } 11072 } 11073 11074 @Override 11075 public void showLockTaskEscapeMessage(IBinder token) { 11076 synchronized (this) { 11077 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 11078 if (r == null) { 11079 return; 11080 } 11081 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask()); 11082 } 11083 } 11084 11085 @Override 11086 public void setDisablePreviewScreenshots(IBinder token, boolean disable) 11087 throws RemoteException { 11088 synchronized (this) { 11089 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 11090 if (r == null) { 11091 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token=" 11092 + token); 11093 return; 11094 } 11095 final long origId = Binder.clearCallingIdentity(); 11096 try { 11097 r.setDisablePreviewScreenshots(disable); 11098 } finally { 11099 Binder.restoreCallingIdentity(origId); 11100 } 11101 } 11102 } 11103 11104 // ========================================================= 11105 // CONTENT PROVIDERS 11106 // ========================================================= 11107 11108 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 11109 List<ProviderInfo> providers = null; 11110 try { 11111 providers = AppGlobals.getPackageManager() 11112 .queryContentProviders(app.processName, app.uid, 11113 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS 11114 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null) 11115 .getList(); 11116 } catch (RemoteException ex) { 11117 } 11118 if (DEBUG_MU) Slog.v(TAG_MU, 11119 "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 11120 int userId = app.userId; 11121 if (providers != null) { 11122 int N = providers.size(); 11123 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 11124 for (int i=0; i<N; i++) { 11125 // TODO: keep logic in sync with installEncryptionUnawareProviders 11126 ProviderInfo cpi = 11127 (ProviderInfo)providers.get(i); 11128 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 11129 cpi.name, cpi.flags); 11130 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) { 11131 // This is a singleton provider, but a user besides the 11132 // default user is asking to initialize a process it runs 11133 // in... well, no, it doesn't actually run in this process, 11134 // it runs in the process of the default user. Get rid of it. 11135 providers.remove(i); 11136 N--; 11137 i--; 11138 continue; 11139 } 11140 11141 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 11142 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 11143 if (cpr == null) { 11144 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 11145 mProviderMap.putProviderByClass(comp, cpr); 11146 } 11147 if (DEBUG_MU) Slog.v(TAG_MU, 11148 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 11149 app.pubProviders.put(cpi.name, cpr); 11150 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 11151 // Don't add this if it is a platform component that is marked 11152 // to run in multiple processes, because this is actually 11153 // part of the framework so doesn't make sense to track as a 11154 // separate apk in the process. 11155 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 11156 mProcessStats); 11157 } 11158 notifyPackageUse(cpi.applicationInfo.packageName, 11159 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER); 11160 } 11161 } 11162 return providers; 11163 } 11164 11165 /** 11166 * Check if the calling UID has a possible chance at accessing the provider 11167 * at the given authority and user. 11168 */ 11169 public String checkContentProviderAccess(String authority, int userId) { 11170 if (userId == UserHandle.USER_ALL) { 11171 mContext.enforceCallingOrSelfPermission( 11172 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG); 11173 userId = UserHandle.getCallingUserId(); 11174 } 11175 11176 ProviderInfo cpi = null; 11177 try { 11178 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority, 11179 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS 11180 | PackageManager.MATCH_DISABLED_COMPONENTS 11181 | PackageManager.MATCH_DIRECT_BOOT_AWARE 11182 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 11183 userId); 11184 } catch (RemoteException ignored) { 11185 } 11186 if (cpi == null) { 11187 return "Failed to find provider " + authority + " for user " + userId 11188 + "; expected to find a valid ContentProvider for this authority"; 11189 } 11190 11191 ProcessRecord r = null; 11192 synchronized (mPidsSelfLocked) { 11193 r = mPidsSelfLocked.get(Binder.getCallingPid()); 11194 } 11195 if (r == null) { 11196 return "Failed to find PID " + Binder.getCallingPid(); 11197 } 11198 11199 synchronized (this) { 11200 return checkContentProviderPermissionLocked(cpi, r, userId, true); 11201 } 11202 } 11203 11204 /** 11205 * Check if {@link ProcessRecord} has a possible chance at accessing the 11206 * given {@link ProviderInfo}. Final permission checking is always done 11207 * in {@link ContentProvider}. 11208 */ 11209 private final String checkContentProviderPermissionLocked( 11210 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 11211 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 11212 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 11213 boolean checkedGrants = false; 11214 if (checkUser) { 11215 // Looking for cross-user grants before enforcing the typical cross-users permissions 11216 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId); 11217 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 11218 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 11219 return null; 11220 } 11221 checkedGrants = true; 11222 } 11223 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false, 11224 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null); 11225 if (userId != tmpTargetUserId) { 11226 // When we actually went to determine the final targer user ID, this ended 11227 // up different than our initial check for the authority. This is because 11228 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 11229 // SELF. So we need to re-check the grants again. 11230 checkedGrants = false; 11231 } 11232 } 11233 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 11234 cpi.applicationInfo.uid, cpi.exported) 11235 == PackageManager.PERMISSION_GRANTED) { 11236 return null; 11237 } 11238 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 11239 cpi.applicationInfo.uid, cpi.exported) 11240 == PackageManager.PERMISSION_GRANTED) { 11241 return null; 11242 } 11243 11244 PathPermission[] pps = cpi.pathPermissions; 11245 if (pps != null) { 11246 int i = pps.length; 11247 while (i > 0) { 11248 i--; 11249 PathPermission pp = pps[i]; 11250 String pprperm = pp.getReadPermission(); 11251 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 11252 cpi.applicationInfo.uid, cpi.exported) 11253 == PackageManager.PERMISSION_GRANTED) { 11254 return null; 11255 } 11256 String ppwperm = pp.getWritePermission(); 11257 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 11258 cpi.applicationInfo.uid, cpi.exported) 11259 == PackageManager.PERMISSION_GRANTED) { 11260 return null; 11261 } 11262 } 11263 } 11264 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 11265 return null; 11266 } 11267 11268 final String suffix; 11269 if (!cpi.exported) { 11270 suffix = " that is not exported from UID " + cpi.applicationInfo.uid; 11271 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) { 11272 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs"; 11273 } else { 11274 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission; 11275 } 11276 final String msg = "Permission Denial: opening provider " + cpi.name 11277 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 11278 + ", uid=" + callingUid + ")" + suffix; 11279 Slog.w(TAG, msg); 11280 return msg; 11281 } 11282 11283 /** 11284 * Returns if the ContentProvider has granted a uri to callingUid 11285 */ 11286 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 11287 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 11288 if (perms != null) { 11289 for (int i=perms.size()-1; i>=0; i--) { 11290 GrantUri grantUri = perms.keyAt(i); 11291 if (grantUri.sourceUserId == userId || !checkUser) { 11292 if (matchesProvider(grantUri.uri, cpi)) { 11293 return true; 11294 } 11295 } 11296 } 11297 } 11298 return false; 11299 } 11300 11301 /** 11302 * Returns true if the uri authority is one of the authorities specified in the provider. 11303 */ 11304 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 11305 String uriAuth = uri.getAuthority(); 11306 String cpiAuth = cpi.authority; 11307 if (cpiAuth.indexOf(';') == -1) { 11308 return cpiAuth.equals(uriAuth); 11309 } 11310 String[] cpiAuths = cpiAuth.split(";"); 11311 int length = cpiAuths.length; 11312 for (int i = 0; i < length; i++) { 11313 if (cpiAuths[i].equals(uriAuth)) return true; 11314 } 11315 return false; 11316 } 11317 11318 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 11319 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 11320 if (r != null) { 11321 for (int i=0; i<r.conProviders.size(); i++) { 11322 ContentProviderConnection conn = r.conProviders.get(i); 11323 if (conn.provider == cpr) { 11324 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER, 11325 "Adding provider requested by " 11326 + r.processName + " from process " 11327 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 11328 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 11329 if (stable) { 11330 conn.stableCount++; 11331 conn.numStableIncs++; 11332 } else { 11333 conn.unstableCount++; 11334 conn.numUnstableIncs++; 11335 } 11336 return conn; 11337 } 11338 } 11339 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 11340 if (stable) { 11341 conn.stableCount = 1; 11342 conn.numStableIncs = 1; 11343 } else { 11344 conn.unstableCount = 1; 11345 conn.numUnstableIncs = 1; 11346 } 11347 cpr.connections.add(conn); 11348 r.conProviders.add(conn); 11349 startAssociationLocked(r.uid, r.processName, r.curProcState, 11350 cpr.uid, cpr.name, cpr.info.processName); 11351 return conn; 11352 } 11353 cpr.addExternalProcessHandleLocked(externalProcessToken); 11354 return null; 11355 } 11356 11357 boolean decProviderCountLocked(ContentProviderConnection conn, 11358 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 11359 if (conn != null) { 11360 cpr = conn.provider; 11361 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER, 11362 "Removing provider requested by " 11363 + conn.client.processName + " from process " 11364 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 11365 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 11366 if (stable) { 11367 conn.stableCount--; 11368 } else { 11369 conn.unstableCount--; 11370 } 11371 if (conn.stableCount == 0 && conn.unstableCount == 0) { 11372 cpr.connections.remove(conn); 11373 conn.client.conProviders.remove(conn); 11374 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 11375 // The client is more important than last activity -- note the time this 11376 // is happening, so we keep the old provider process around a bit as last 11377 // activity to avoid thrashing it. 11378 if (cpr.proc != null) { 11379 cpr.proc.lastProviderTime = SystemClock.uptimeMillis(); 11380 } 11381 } 11382 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 11383 return true; 11384 } 11385 return false; 11386 } 11387 cpr.removeExternalProcessHandleLocked(externalProcessToken); 11388 return false; 11389 } 11390 11391 private void checkTime(long startTime, String where) { 11392 long now = SystemClock.uptimeMillis(); 11393 if ((now-startTime) > 50) { 11394 // If we are taking more than 50ms, log about it. 11395 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 11396 } 11397 } 11398 11399 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] { 11400 PROC_SPACE_TERM, 11401 PROC_SPACE_TERM|PROC_PARENS, 11402 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state 11403 }; 11404 11405 private final long[] mProcessStateStatsLongs = new long[1]; 11406 11407 boolean isProcessAliveLocked(ProcessRecord proc) { 11408 if (proc.procStatFile == null) { 11409 proc.procStatFile = "/proc/" + proc.pid + "/stat"; 11410 } 11411 mProcessStateStatsLongs[0] = 0; 11412 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null, 11413 mProcessStateStatsLongs, null)) { 11414 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile); 11415 return false; 11416 } 11417 final long state = mProcessStateStatsLongs[0]; 11418 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": " 11419 + (char)state); 11420 return state != 'Z' && state != 'X' && state != 'x' && state != 'K'; 11421 } 11422 11423 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 11424 String name, IBinder token, boolean stable, int userId) { 11425 ContentProviderRecord cpr; 11426 ContentProviderConnection conn = null; 11427 ProviderInfo cpi = null; 11428 11429 synchronized(this) { 11430 long startTime = SystemClock.uptimeMillis(); 11431 11432 ProcessRecord r = null; 11433 if (caller != null) { 11434 r = getRecordForAppLocked(caller); 11435 if (r == null) { 11436 throw new SecurityException( 11437 "Unable to find app for caller " + caller 11438 + " (pid=" + Binder.getCallingPid() 11439 + ") when getting content provider " + name); 11440 } 11441 } 11442 11443 boolean checkCrossUser = true; 11444 11445 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 11446 11447 // First check if this content provider has been published... 11448 cpr = mProviderMap.getProviderByName(name, userId); 11449 // If that didn't work, check if it exists for user 0 and then 11450 // verify that it's a singleton provider before using it. 11451 if (cpr == null && userId != UserHandle.USER_SYSTEM) { 11452 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM); 11453 if (cpr != null) { 11454 cpi = cpr.info; 11455 if (isSingleton(cpi.processName, cpi.applicationInfo, 11456 cpi.name, cpi.flags) 11457 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 11458 userId = UserHandle.USER_SYSTEM; 11459 checkCrossUser = false; 11460 } else { 11461 cpr = null; 11462 cpi = null; 11463 } 11464 } 11465 } 11466 11467 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed; 11468 if (providerRunning) { 11469 cpi = cpr.info; 11470 String msg; 11471 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 11472 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 11473 != null) { 11474 throw new SecurityException(msg); 11475 } 11476 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 11477 11478 if (r != null && cpr.canRunHere(r)) { 11479 // This provider has been published or is in the process 11480 // of being published... but it is also allowed to run 11481 // in the caller's process, so don't make a connection 11482 // and just let the caller instantiate its own instance. 11483 ContentProviderHolder holder = cpr.newHolder(null); 11484 // don't give caller the provider object, it needs 11485 // to make its own. 11486 holder.provider = null; 11487 return holder; 11488 } 11489 // Don't expose providers between normal apps and instant apps 11490 try { 11491 if (AppGlobals.getPackageManager() 11492 .resolveContentProvider(name, 0 /*flags*/, userId) == null) { 11493 return null; 11494 } 11495 } catch (RemoteException e) { 11496 } 11497 11498 final long origId = Binder.clearCallingIdentity(); 11499 11500 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 11501 11502 // In this case the provider instance already exists, so we can 11503 // return it right away. 11504 conn = incProviderCountLocked(r, cpr, token, stable); 11505 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 11506 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 11507 // If this is a perceptible app accessing the provider, 11508 // make sure to count it as being accessed and thus 11509 // back up on the LRU list. This is good because 11510 // content providers are often expensive to start. 11511 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 11512 updateLruProcessLocked(cpr.proc, false, null); 11513 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 11514 } 11515 } 11516 11517 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 11518 final int verifiedAdj = cpr.proc.verifiedAdj; 11519 boolean success = updateOomAdjLocked(cpr.proc, true); 11520 // XXX things have changed so updateOomAdjLocked doesn't actually tell us 11521 // if the process has been successfully adjusted. So to reduce races with 11522 // it, we will check whether the process still exists. Note that this doesn't 11523 // completely get rid of races with LMK killing the process, but should make 11524 // them much smaller. 11525 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) { 11526 success = false; 11527 } 11528 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name); 11529 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 11530 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success); 11531 // NOTE: there is still a race here where a signal could be 11532 // pending on the process even though we managed to update its 11533 // adj level. Not sure what to do about this, but at least 11534 // the race is now smaller. 11535 if (!success) { 11536 // Uh oh... it looks like the provider's process 11537 // has been killed on us. We need to wait for a new 11538 // process to be started, and make sure its death 11539 // doesn't kill our process. 11540 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString() 11541 + " is crashing; detaching " + r); 11542 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 11543 checkTime(startTime, "getContentProviderImpl: before appDied"); 11544 appDiedLocked(cpr.proc); 11545 checkTime(startTime, "getContentProviderImpl: after appDied"); 11546 if (!lastRef) { 11547 // This wasn't the last ref our process had on 11548 // the provider... we have now been killed, bail. 11549 return null; 11550 } 11551 providerRunning = false; 11552 conn = null; 11553 } else { 11554 cpr.proc.verifiedAdj = cpr.proc.setAdj; 11555 } 11556 11557 Binder.restoreCallingIdentity(origId); 11558 } 11559 11560 if (!providerRunning) { 11561 try { 11562 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 11563 cpi = AppGlobals.getPackageManager(). 11564 resolveContentProvider(name, 11565 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 11566 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 11567 } catch (RemoteException ex) { 11568 } 11569 if (cpi == null) { 11570 return null; 11571 } 11572 // If the provider is a singleton AND 11573 // (it's a call within the same user || the provider is a 11574 // privileged app) 11575 // Then allow connecting to the singleton provider 11576 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 11577 cpi.name, cpi.flags) 11578 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 11579 if (singleton) { 11580 userId = UserHandle.USER_SYSTEM; 11581 } 11582 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 11583 checkTime(startTime, "getContentProviderImpl: got app info for user"); 11584 11585 String msg; 11586 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 11587 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 11588 != null) { 11589 throw new SecurityException(msg); 11590 } 11591 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 11592 11593 if (!mProcessesReady 11594 && !cpi.processName.equals("system")) { 11595 // If this content provider does not run in the system 11596 // process, and the system is not yet ready to run other 11597 // processes, then fail fast instead of hanging. 11598 throw new IllegalArgumentException( 11599 "Attempt to launch content provider before system ready"); 11600 } 11601 11602 // Make sure that the user who owns this provider is running. If not, 11603 // we don't want to allow it to run. 11604 if (!mUserController.isUserRunningLocked(userId, 0)) { 11605 Slog.w(TAG, "Unable to launch app " 11606 + cpi.applicationInfo.packageName + "/" 11607 + cpi.applicationInfo.uid + " for provider " 11608 + name + ": user " + userId + " is stopped"); 11609 return null; 11610 } 11611 11612 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 11613 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 11614 cpr = mProviderMap.getProviderByClass(comp, userId); 11615 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 11616 final boolean firstClass = cpr == null; 11617 if (firstClass) { 11618 final long ident = Binder.clearCallingIdentity(); 11619 11620 // If permissions need a review before any of the app components can run, 11621 // we return no provider and launch a review activity if the calling app 11622 // is in the foreground. 11623 if (mPermissionReviewRequired) { 11624 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) { 11625 return null; 11626 } 11627 } 11628 11629 try { 11630 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 11631 ApplicationInfo ai = 11632 AppGlobals.getPackageManager(). 11633 getApplicationInfo( 11634 cpi.applicationInfo.packageName, 11635 STOCK_PM_FLAGS, userId); 11636 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 11637 if (ai == null) { 11638 Slog.w(TAG, "No package info for content provider " 11639 + cpi.name); 11640 return null; 11641 } 11642 ai = getAppInfoForUser(ai, userId); 11643 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 11644 } catch (RemoteException ex) { 11645 // pm is in same process, this will never happen. 11646 } finally { 11647 Binder.restoreCallingIdentity(ident); 11648 } 11649 } 11650 11651 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 11652 11653 if (r != null && cpr.canRunHere(r)) { 11654 // If this is a multiprocess provider, then just return its 11655 // info and allow the caller to instantiate it. Only do 11656 // this if the provider is the same user as the caller's 11657 // process, or can run as root (so can be in any process). 11658 return cpr.newHolder(null); 11659 } 11660 11661 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid " 11662 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): " 11663 + cpr.info.name + " callers=" + Debug.getCallers(6)); 11664 11665 // This is single process, and our app is now connecting to it. 11666 // See if we are already in the process of launching this 11667 // provider. 11668 final int N = mLaunchingProviders.size(); 11669 int i; 11670 for (i = 0; i < N; i++) { 11671 if (mLaunchingProviders.get(i) == cpr) { 11672 break; 11673 } 11674 } 11675 11676 // If the provider is not already being launched, then get it 11677 // started. 11678 if (i >= N) { 11679 final long origId = Binder.clearCallingIdentity(); 11680 11681 try { 11682 // Content provider is now in use, its package can't be stopped. 11683 try { 11684 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 11685 AppGlobals.getPackageManager().setPackageStoppedState( 11686 cpr.appInfo.packageName, false, userId); 11687 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 11688 } catch (RemoteException e) { 11689 } catch (IllegalArgumentException e) { 11690 Slog.w(TAG, "Failed trying to unstop package " 11691 + cpr.appInfo.packageName + ": " + e); 11692 } 11693 11694 // Use existing process if already started 11695 checkTime(startTime, "getContentProviderImpl: looking for process record"); 11696 ProcessRecord proc = getProcessRecordLocked( 11697 cpi.processName, cpr.appInfo.uid, false); 11698 if (proc != null && proc.thread != null && !proc.killed) { 11699 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER, 11700 "Installing in existing process " + proc); 11701 if (!proc.pubProviders.containsKey(cpi.name)) { 11702 checkTime(startTime, "getContentProviderImpl: scheduling install"); 11703 proc.pubProviders.put(cpi.name, cpr); 11704 try { 11705 proc.thread.scheduleInstallProvider(cpi); 11706 } catch (RemoteException e) { 11707 } 11708 } 11709 } else { 11710 checkTime(startTime, "getContentProviderImpl: before start process"); 11711 proc = startProcessLocked(cpi.processName, 11712 cpr.appInfo, false, 0, "content provider", 11713 new ComponentName(cpi.applicationInfo.packageName, 11714 cpi.name), false, false, false); 11715 checkTime(startTime, "getContentProviderImpl: after start process"); 11716 if (proc == null) { 11717 Slog.w(TAG, "Unable to launch app " 11718 + cpi.applicationInfo.packageName + "/" 11719 + cpi.applicationInfo.uid + " for provider " 11720 + name + ": process is bad"); 11721 return null; 11722 } 11723 } 11724 cpr.launchingApp = proc; 11725 mLaunchingProviders.add(cpr); 11726 } finally { 11727 Binder.restoreCallingIdentity(origId); 11728 } 11729 } 11730 11731 checkTime(startTime, "getContentProviderImpl: updating data structures"); 11732 11733 // Make sure the provider is published (the same provider class 11734 // may be published under multiple names). 11735 if (firstClass) { 11736 mProviderMap.putProviderByClass(comp, cpr); 11737 } 11738 11739 mProviderMap.putProviderByName(name, cpr); 11740 conn = incProviderCountLocked(r, cpr, token, stable); 11741 if (conn != null) { 11742 conn.waiting = true; 11743 } 11744 } 11745 checkTime(startTime, "getContentProviderImpl: done!"); 11746 11747 grantEphemeralAccessLocked(userId, null /*intent*/, 11748 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid())); 11749 } 11750 11751 // Wait for the provider to be published... 11752 synchronized (cpr) { 11753 while (cpr.provider == null) { 11754 if (cpr.launchingApp == null) { 11755 Slog.w(TAG, "Unable to launch app " 11756 + cpi.applicationInfo.packageName + "/" 11757 + cpi.applicationInfo.uid + " for provider " 11758 + name + ": launching app became null"); 11759 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 11760 UserHandle.getUserId(cpi.applicationInfo.uid), 11761 cpi.applicationInfo.packageName, 11762 cpi.applicationInfo.uid, name); 11763 return null; 11764 } 11765 try { 11766 if (DEBUG_MU) Slog.v(TAG_MU, 11767 "Waiting to start provider " + cpr 11768 + " launchingApp=" + cpr.launchingApp); 11769 if (conn != null) { 11770 conn.waiting = true; 11771 } 11772 cpr.wait(); 11773 } catch (InterruptedException ex) { 11774 } finally { 11775 if (conn != null) { 11776 conn.waiting = false; 11777 } 11778 } 11779 } 11780 } 11781 return cpr != null ? cpr.newHolder(conn) : null; 11782 } 11783 11784 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi, 11785 ProcessRecord r, final int userId) { 11786 if (getPackageManagerInternalLocked().isPermissionsReviewRequired( 11787 cpi.packageName, userId)) { 11788 11789 final boolean callerForeground = r == null || r.setSchedGroup 11790 != ProcessList.SCHED_GROUP_BACKGROUND; 11791 11792 // Show a permission review UI only for starting from a foreground app 11793 if (!callerForeground) { 11794 Slog.w(TAG, "u" + userId + " Instantiating a provider in package" 11795 + cpi.packageName + " requires a permissions review"); 11796 return false; 11797 } 11798 11799 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS); 11800 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 11801 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 11802 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName); 11803 11804 if (DEBUG_PERMISSIONS_REVIEW) { 11805 Slog.i(TAG, "u" + userId + " Launching permission review " 11806 + "for package " + cpi.packageName); 11807 } 11808 11809 final UserHandle userHandle = new UserHandle(userId); 11810 mHandler.post(new Runnable() { 11811 @Override 11812 public void run() { 11813 mContext.startActivityAsUser(intent, userHandle); 11814 } 11815 }); 11816 11817 return false; 11818 } 11819 11820 return true; 11821 } 11822 11823 PackageManagerInternal getPackageManagerInternalLocked() { 11824 if (mPackageManagerInt == null) { 11825 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class); 11826 } 11827 return mPackageManagerInt; 11828 } 11829 11830 @Override 11831 public final ContentProviderHolder getContentProvider( 11832 IApplicationThread caller, String name, int userId, boolean stable) { 11833 enforceNotIsolatedCaller("getContentProvider"); 11834 if (caller == null) { 11835 String msg = "null IApplicationThread when getting content provider " 11836 + name; 11837 Slog.w(TAG, msg); 11838 throw new SecurityException(msg); 11839 } 11840 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 11841 // with cross-user grant. 11842 return getContentProviderImpl(caller, name, null, stable, userId); 11843 } 11844 11845 public ContentProviderHolder getContentProviderExternal( 11846 String name, int userId, IBinder token) { 11847 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 11848 "Do not have permission in call getContentProviderExternal()"); 11849 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 11850 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null); 11851 return getContentProviderExternalUnchecked(name, token, userId); 11852 } 11853 11854 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 11855 IBinder token, int userId) { 11856 return getContentProviderImpl(null, name, token, true, userId); 11857 } 11858 11859 /** 11860 * Drop a content provider from a ProcessRecord's bookkeeping 11861 */ 11862 public void removeContentProvider(IBinder connection, boolean stable) { 11863 enforceNotIsolatedCaller("removeContentProvider"); 11864 long ident = Binder.clearCallingIdentity(); 11865 try { 11866 synchronized (this) { 11867 ContentProviderConnection conn; 11868 try { 11869 conn = (ContentProviderConnection)connection; 11870 } catch (ClassCastException e) { 11871 String msg ="removeContentProvider: " + connection 11872 + " not a ContentProviderConnection"; 11873 Slog.w(TAG, msg); 11874 throw new IllegalArgumentException(msg); 11875 } 11876 if (conn == null) { 11877 throw new NullPointerException("connection is null"); 11878 } 11879 if (decProviderCountLocked(conn, null, null, stable)) { 11880 updateOomAdjLocked(); 11881 } 11882 } 11883 } finally { 11884 Binder.restoreCallingIdentity(ident); 11885 } 11886 } 11887 11888 public void removeContentProviderExternal(String name, IBinder token) { 11889 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 11890 "Do not have permission in call removeContentProviderExternal()"); 11891 int userId = UserHandle.getCallingUserId(); 11892 long ident = Binder.clearCallingIdentity(); 11893 try { 11894 removeContentProviderExternalUnchecked(name, token, userId); 11895 } finally { 11896 Binder.restoreCallingIdentity(ident); 11897 } 11898 } 11899 11900 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 11901 synchronized (this) { 11902 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 11903 if(cpr == null) { 11904 //remove from mProvidersByClass 11905 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list"); 11906 return; 11907 } 11908 11909 //update content provider record entry info 11910 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 11911 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 11912 if (localCpr.hasExternalProcessHandles()) { 11913 if (localCpr.removeExternalProcessHandleLocked(token)) { 11914 updateOomAdjLocked(); 11915 } else { 11916 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 11917 + " with no external reference for token: " 11918 + token + "."); 11919 } 11920 } else { 11921 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 11922 + " with no external references."); 11923 } 11924 } 11925 } 11926 11927 public final void publishContentProviders(IApplicationThread caller, 11928 List<ContentProviderHolder> providers) { 11929 if (providers == null) { 11930 return; 11931 } 11932 11933 enforceNotIsolatedCaller("publishContentProviders"); 11934 synchronized (this) { 11935 final ProcessRecord r = getRecordForAppLocked(caller); 11936 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 11937 if (r == null) { 11938 throw new SecurityException( 11939 "Unable to find app for caller " + caller 11940 + " (pid=" + Binder.getCallingPid() 11941 + ") when publishing content providers"); 11942 } 11943 11944 final long origId = Binder.clearCallingIdentity(); 11945 11946 final int N = providers.size(); 11947 for (int i = 0; i < N; i++) { 11948 ContentProviderHolder src = providers.get(i); 11949 if (src == null || src.info == null || src.provider == null) { 11950 continue; 11951 } 11952 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 11953 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 11954 if (dst != null) { 11955 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 11956 mProviderMap.putProviderByClass(comp, dst); 11957 String names[] = dst.info.authority.split(";"); 11958 for (int j = 0; j < names.length; j++) { 11959 mProviderMap.putProviderByName(names[j], dst); 11960 } 11961 11962 int launchingCount = mLaunchingProviders.size(); 11963 int j; 11964 boolean wasInLaunchingProviders = false; 11965 for (j = 0; j < launchingCount; j++) { 11966 if (mLaunchingProviders.get(j) == dst) { 11967 mLaunchingProviders.remove(j); 11968 wasInLaunchingProviders = true; 11969 j--; 11970 launchingCount--; 11971 } 11972 } 11973 if (wasInLaunchingProviders) { 11974 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r); 11975 } 11976 synchronized (dst) { 11977 dst.provider = src.provider; 11978 dst.proc = r; 11979 dst.notifyAll(); 11980 } 11981 updateOomAdjLocked(r, true); 11982 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName, 11983 src.info.authority); 11984 } 11985 } 11986 11987 Binder.restoreCallingIdentity(origId); 11988 } 11989 } 11990 11991 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 11992 ContentProviderConnection conn; 11993 try { 11994 conn = (ContentProviderConnection)connection; 11995 } catch (ClassCastException e) { 11996 String msg ="refContentProvider: " + connection 11997 + " not a ContentProviderConnection"; 11998 Slog.w(TAG, msg); 11999 throw new IllegalArgumentException(msg); 12000 } 12001 if (conn == null) { 12002 throw new NullPointerException("connection is null"); 12003 } 12004 12005 synchronized (this) { 12006 if (stable > 0) { 12007 conn.numStableIncs += stable; 12008 } 12009 stable = conn.stableCount + stable; 12010 if (stable < 0) { 12011 throw new IllegalStateException("stableCount < 0: " + stable); 12012 } 12013 12014 if (unstable > 0) { 12015 conn.numUnstableIncs += unstable; 12016 } 12017 unstable = conn.unstableCount + unstable; 12018 if (unstable < 0) { 12019 throw new IllegalStateException("unstableCount < 0: " + unstable); 12020 } 12021 12022 if ((stable+unstable) <= 0) { 12023 throw new IllegalStateException("ref counts can't go to zero here: stable=" 12024 + stable + " unstable=" + unstable); 12025 } 12026 conn.stableCount = stable; 12027 conn.unstableCount = unstable; 12028 return !conn.dead; 12029 } 12030 } 12031 12032 public void unstableProviderDied(IBinder connection) { 12033 ContentProviderConnection conn; 12034 try { 12035 conn = (ContentProviderConnection)connection; 12036 } catch (ClassCastException e) { 12037 String msg ="refContentProvider: " + connection 12038 + " not a ContentProviderConnection"; 12039 Slog.w(TAG, msg); 12040 throw new IllegalArgumentException(msg); 12041 } 12042 if (conn == null) { 12043 throw new NullPointerException("connection is null"); 12044 } 12045 12046 // Safely retrieve the content provider associated with the connection. 12047 IContentProvider provider; 12048 synchronized (this) { 12049 provider = conn.provider.provider; 12050 } 12051 12052 if (provider == null) { 12053 // Um, yeah, we're way ahead of you. 12054 return; 12055 } 12056 12057 // Make sure the caller is being honest with us. 12058 if (provider.asBinder().pingBinder()) { 12059 // Er, no, still looks good to us. 12060 synchronized (this) { 12061 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 12062 + " says " + conn + " died, but we don't agree"); 12063 return; 12064 } 12065 } 12066 12067 // Well look at that! It's dead! 12068 synchronized (this) { 12069 if (conn.provider.provider != provider) { 12070 // But something changed... good enough. 12071 return; 12072 } 12073 12074 ProcessRecord proc = conn.provider.proc; 12075 if (proc == null || proc.thread == null) { 12076 // Seems like the process is already cleaned up. 12077 return; 12078 } 12079 12080 // As far as we're concerned, this is just like receiving a 12081 // death notification... just a bit prematurely. 12082 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 12083 + ") early provider death"); 12084 final long ident = Binder.clearCallingIdentity(); 12085 try { 12086 appDiedLocked(proc); 12087 } finally { 12088 Binder.restoreCallingIdentity(ident); 12089 } 12090 } 12091 } 12092 12093 @Override 12094 public void appNotRespondingViaProvider(IBinder connection) { 12095 enforceCallingPermission( 12096 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 12097 12098 final ContentProviderConnection conn = (ContentProviderConnection) connection; 12099 if (conn == null) { 12100 Slog.w(TAG, "ContentProviderConnection is null"); 12101 return; 12102 } 12103 12104 final ProcessRecord host = conn.provider.proc; 12105 if (host == null) { 12106 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 12107 return; 12108 } 12109 12110 mHandler.post(new Runnable() { 12111 @Override 12112 public void run() { 12113 mAppErrors.appNotResponding(host, null, null, false, 12114 "ContentProvider not responding"); 12115 } 12116 }); 12117 } 12118 12119 public final void installSystemProviders() { 12120 List<ProviderInfo> providers; 12121 synchronized (this) { 12122 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID); 12123 providers = generateApplicationProvidersLocked(app); 12124 if (providers != null) { 12125 for (int i=providers.size()-1; i>=0; i--) { 12126 ProviderInfo pi = (ProviderInfo)providers.get(i); 12127 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 12128 Slog.w(TAG, "Not installing system proc provider " + pi.name 12129 + ": not system .apk"); 12130 providers.remove(i); 12131 } 12132 } 12133 } 12134 } 12135 if (providers != null) { 12136 mSystemThread.installSystemProviders(providers); 12137 } 12138 12139 mConstants.start(mContext.getContentResolver()); 12140 mCoreSettingsObserver = new CoreSettingsObserver(this); 12141 mFontScaleSettingObserver = new FontScaleSettingObserver(); 12142 12143 // Now that the settings provider is published we can consider sending 12144 // in a rescue party. 12145 RescueParty.onSettingsProviderPublished(mContext); 12146 12147 //mUsageStatsService.monitorPackages(); 12148 } 12149 12150 private void startPersistentApps(int matchFlags) { 12151 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return; 12152 12153 synchronized (this) { 12154 try { 12155 final List<ApplicationInfo> apps = AppGlobals.getPackageManager() 12156 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList(); 12157 for (ApplicationInfo app : apps) { 12158 if (!"android".equals(app.packageName)) { 12159 addAppLocked(app, null, false, null /* ABI override */); 12160 } 12161 } 12162 } catch (RemoteException ex) { 12163 } 12164 } 12165 } 12166 12167 /** 12168 * When a user is unlocked, we need to install encryption-unaware providers 12169 * belonging to any running apps. 12170 */ 12171 private void installEncryptionUnawareProviders(int userId) { 12172 // We're only interested in providers that are encryption unaware, and 12173 // we don't care about uninstalled apps, since there's no way they're 12174 // running at this point. 12175 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE; 12176 12177 synchronized (this) { 12178 final int NP = mProcessNames.getMap().size(); 12179 for (int ip = 0; ip < NP; ip++) { 12180 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 12181 final int NA = apps.size(); 12182 for (int ia = 0; ia < NA; ia++) { 12183 final ProcessRecord app = apps.valueAt(ia); 12184 if (app.userId != userId || app.thread == null || app.unlocked) continue; 12185 12186 final int NG = app.pkgList.size(); 12187 for (int ig = 0; ig < NG; ig++) { 12188 try { 12189 final String pkgName = app.pkgList.keyAt(ig); 12190 final PackageInfo pkgInfo = AppGlobals.getPackageManager() 12191 .getPackageInfo(pkgName, matchFlags, userId); 12192 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) { 12193 for (ProviderInfo pi : pkgInfo.providers) { 12194 // TODO: keep in sync with generateApplicationProvidersLocked 12195 final boolean processMatch = Objects.equals(pi.processName, 12196 app.processName) || pi.multiprocess; 12197 final boolean userMatch = isSingleton(pi.processName, 12198 pi.applicationInfo, pi.name, pi.flags) 12199 ? (app.userId == UserHandle.USER_SYSTEM) : true; 12200 if (processMatch && userMatch) { 12201 Log.v(TAG, "Installing " + pi); 12202 app.thread.scheduleInstallProvider(pi); 12203 } else { 12204 Log.v(TAG, "Skipping " + pi); 12205 } 12206 } 12207 } 12208 } catch (RemoteException ignored) { 12209 } 12210 } 12211 } 12212 } 12213 } 12214 } 12215 12216 /** 12217 * Allows apps to retrieve the MIME type of a URI. 12218 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 12219 * users, then it does not need permission to access the ContentProvider. 12220 * Either, it needs cross-user uri grants. 12221 * 12222 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 12223 * 12224 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 12225 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 12226 */ 12227 public String getProviderMimeType(Uri uri, int userId) { 12228 enforceNotIsolatedCaller("getProviderMimeType"); 12229 final String name = uri.getAuthority(); 12230 int callingUid = Binder.getCallingUid(); 12231 int callingPid = Binder.getCallingPid(); 12232 long ident = 0; 12233 boolean clearedIdentity = false; 12234 synchronized (this) { 12235 userId = mUserController.unsafeConvertIncomingUserLocked(userId); 12236 } 12237 if (canClearIdentity(callingPid, callingUid, userId)) { 12238 clearedIdentity = true; 12239 ident = Binder.clearCallingIdentity(); 12240 } 12241 ContentProviderHolder holder = null; 12242 try { 12243 holder = getContentProviderExternalUnchecked(name, null, userId); 12244 if (holder != null) { 12245 return holder.provider.getType(uri); 12246 } 12247 } catch (RemoteException e) { 12248 Log.w(TAG, "Content provider dead retrieving " + uri, e); 12249 return null; 12250 } catch (Exception e) { 12251 Log.w(TAG, "Exception while determining type of " + uri, e); 12252 return null; 12253 } finally { 12254 // We need to clear the identity to call removeContentProviderExternalUnchecked 12255 if (!clearedIdentity) { 12256 ident = Binder.clearCallingIdentity(); 12257 } 12258 try { 12259 if (holder != null) { 12260 removeContentProviderExternalUnchecked(name, null, userId); 12261 } 12262 } finally { 12263 Binder.restoreCallingIdentity(ident); 12264 } 12265 } 12266 12267 return null; 12268 } 12269 12270 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 12271 if (UserHandle.getUserId(callingUid) == userId) { 12272 return true; 12273 } 12274 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 12275 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 12276 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 12277 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 12278 return true; 12279 } 12280 return false; 12281 } 12282 12283 // ========================================================= 12284 // GLOBAL MANAGEMENT 12285 // ========================================================= 12286 12287 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 12288 boolean isolated, int isolatedUid) { 12289 String proc = customProcess != null ? customProcess : info.processName; 12290 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12291 final int userId = UserHandle.getUserId(info.uid); 12292 int uid = info.uid; 12293 if (isolated) { 12294 if (isolatedUid == 0) { 12295 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1; 12296 while (true) { 12297 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID 12298 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) { 12299 mNextIsolatedProcessUid = FIRST_ISOLATED_UID; 12300 } 12301 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 12302 mNextIsolatedProcessUid++; 12303 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 12304 // No process for this uid, use it. 12305 break; 12306 } 12307 stepsLeft--; 12308 if (stepsLeft <= 0) { 12309 return null; 12310 } 12311 } 12312 } else { 12313 // Special case for startIsolatedProcess (internal only), where 12314 // the uid of the isolated process is specified by the caller. 12315 uid = isolatedUid; 12316 } 12317 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid); 12318 12319 // Register the isolated UID with this application so BatteryStats knows to 12320 // attribute resource usage to the application. 12321 // 12322 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats 12323 // about the process state of the isolated UID *before* it is registered with the 12324 // owning application. 12325 mBatteryStatsService.addIsolatedUid(uid, info.uid); 12326 } 12327 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid); 12328 if (!mBooted && !mBooting 12329 && userId == UserHandle.USER_SYSTEM 12330 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { 12331 r.persistent = true; 12332 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 12333 } 12334 addProcessNameLocked(r); 12335 return r; 12336 } 12337 12338 private boolean uidOnBackgroundWhitelist(final int uid) { 12339 final int appId = UserHandle.getAppId(uid); 12340 final int[] whitelist = mBackgroundAppIdWhitelist; 12341 final int N = whitelist.length; 12342 for (int i = 0; i < N; i++) { 12343 if (appId == whitelist[i]) { 12344 return true; 12345 } 12346 } 12347 return false; 12348 } 12349 12350 @Override 12351 public void backgroundWhitelistUid(final int uid) { 12352 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 12353 throw new SecurityException("Only the OS may call backgroundWhitelistUid()"); 12354 } 12355 12356 if (DEBUG_BACKGROUND_CHECK) { 12357 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist"); 12358 } 12359 synchronized (this) { 12360 final int N = mBackgroundAppIdWhitelist.length; 12361 int[] newList = new int[N+1]; 12362 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N); 12363 newList[N] = UserHandle.getAppId(uid); 12364 mBackgroundAppIdWhitelist = newList; 12365 } 12366 } 12367 12368 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated, 12369 String abiOverride) { 12370 ProcessRecord app; 12371 if (!isolated) { 12372 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName, 12373 info.uid, true); 12374 } else { 12375 app = null; 12376 } 12377 12378 if (app == null) { 12379 app = newProcessRecordLocked(info, customProcess, isolated, 0); 12380 updateLruProcessLocked(app, false, null); 12381 updateOomAdjLocked(); 12382 } 12383 12384 // This package really, really can not be stopped. 12385 try { 12386 AppGlobals.getPackageManager().setPackageStoppedState( 12387 info.packageName, false, UserHandle.getUserId(app.uid)); 12388 } catch (RemoteException e) { 12389 } catch (IllegalArgumentException e) { 12390 Slog.w(TAG, "Failed trying to unstop package " 12391 + info.packageName + ": " + e); 12392 } 12393 12394 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { 12395 app.persistent = true; 12396 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 12397 } 12398 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 12399 mPersistentStartingProcesses.add(app); 12400 startProcessLocked(app, "added application", 12401 customProcess != null ? customProcess : app.processName, abiOverride, 12402 null /* entryPoint */, null /* entryPointArgs */); 12403 } 12404 12405 return app; 12406 } 12407 12408 public void unhandledBack() { 12409 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 12410 "unhandledBack()"); 12411 12412 synchronized(this) { 12413 final long origId = Binder.clearCallingIdentity(); 12414 try { 12415 getFocusedStack().unhandledBackLocked(); 12416 } finally { 12417 Binder.restoreCallingIdentity(origId); 12418 } 12419 } 12420 } 12421 12422 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException { 12423 enforceNotIsolatedCaller("openContentUri"); 12424 final int userId = UserHandle.getCallingUserId(); 12425 final Uri uri = Uri.parse(uriString); 12426 String name = uri.getAuthority(); 12427 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 12428 ParcelFileDescriptor pfd = null; 12429 if (cph != null) { 12430 // We record the binder invoker's uid in thread-local storage before 12431 // going to the content provider to open the file. Later, in the code 12432 // that handles all permissions checks, we look for this uid and use 12433 // that rather than the Activity Manager's own uid. The effect is that 12434 // we do the check against the caller's permissions even though it looks 12435 // to the content provider like the Activity Manager itself is making 12436 // the request. 12437 Binder token = new Binder(); 12438 sCallerIdentity.set(new Identity( 12439 token, Binder.getCallingPid(), Binder.getCallingUid())); 12440 try { 12441 pfd = cph.provider.openFile(null, uri, "r", null, token); 12442 } catch (FileNotFoundException e) { 12443 // do nothing; pfd will be returned null 12444 } finally { 12445 // Ensure that whatever happens, we clean up the identity state 12446 sCallerIdentity.remove(); 12447 // Ensure we're done with the provider. 12448 removeContentProviderExternalUnchecked(name, null, userId); 12449 } 12450 } else { 12451 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 12452 } 12453 return pfd; 12454 } 12455 12456 // Actually is sleeping or shutting down or whatever else in the future 12457 // is an inactive state. 12458 boolean isSleepingOrShuttingDownLocked() { 12459 return isSleepingLocked() || mShuttingDown; 12460 } 12461 12462 boolean isShuttingDownLocked() { 12463 return mShuttingDown; 12464 } 12465 12466 boolean isSleepingLocked() { 12467 return mSleeping; 12468 } 12469 12470 void onWakefulnessChanged(int wakefulness) { 12471 synchronized(this) { 12472 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE; 12473 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE; 12474 mWakefulness = wakefulness; 12475 12476 if (wasAwake != isAwake) { 12477 // Also update state in a special way for running foreground services UI. 12478 mServices.updateScreenStateLocked(isAwake); 12479 sendNotifyVrManagerOfSleepState(!isAwake); 12480 } 12481 } 12482 } 12483 12484 void finishRunningVoiceLocked() { 12485 if (mRunningVoice != null) { 12486 mRunningVoice = null; 12487 mVoiceWakeLock.release(); 12488 updateSleepIfNeededLocked(); 12489 } 12490 } 12491 12492 void startTimeTrackingFocusedActivityLocked() { 12493 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked(); 12494 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) { 12495 mCurAppTimeTracker.start(resumedActivity.packageName); 12496 } 12497 } 12498 12499 void updateSleepIfNeededLocked() { 12500 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay(); 12501 final boolean wasSleeping = mSleeping; 12502 12503 if (!shouldSleep) { 12504 // If wasSleeping is true, we need to wake up activity manager state from when 12505 // we started sleeping. In either case, we need to apply the sleep tokens, which 12506 // will wake up stacks or put them to sleep as appropriate. 12507 if (wasSleeping) { 12508 mSleeping = false; 12509 startTimeTrackingFocusedActivityLocked(); 12510 mTopProcessState = ActivityManager.PROCESS_STATE_TOP; 12511 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 12512 } 12513 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */); 12514 if (wasSleeping) { 12515 updateOomAdjLocked(); 12516 } 12517 } else if (!mSleeping && shouldSleep) { 12518 mSleeping = true; 12519 if (mCurAppTimeTracker != null) { 12520 mCurAppTimeTracker.stop(); 12521 } 12522 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING; 12523 mStackSupervisor.goingToSleepLocked(); 12524 updateOomAdjLocked(); 12525 } 12526 } 12527 12528 /** Pokes the task persister. */ 12529 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 12530 mRecentTasks.notifyTaskPersisterLocked(task, flush); 12531 } 12532 12533 /** 12534 * Notifies all listeners when the pinned stack animation starts. 12535 */ 12536 @Override 12537 public void notifyPinnedStackAnimationStarted() { 12538 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted(); 12539 } 12540 12541 /** 12542 * Notifies all listeners when the pinned stack animation ends. 12543 */ 12544 @Override 12545 public void notifyPinnedStackAnimationEnded() { 12546 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded(); 12547 } 12548 12549 @Override 12550 public void notifyCleartextNetwork(int uid, byte[] firstPacket) { 12551 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget(); 12552 } 12553 12554 @Override 12555 public boolean shutdown(int timeout) { 12556 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 12557 != PackageManager.PERMISSION_GRANTED) { 12558 throw new SecurityException("Requires permission " 12559 + android.Manifest.permission.SHUTDOWN); 12560 } 12561 12562 boolean timedout = false; 12563 12564 synchronized(this) { 12565 mShuttingDown = true; 12566 mStackSupervisor.prepareForShutdownLocked(); 12567 updateEventDispatchingLocked(); 12568 timedout = mStackSupervisor.shutdownLocked(timeout); 12569 } 12570 12571 mAppOpsService.shutdown(); 12572 if (mUsageStatsService != null) { 12573 mUsageStatsService.prepareShutdown(); 12574 } 12575 mBatteryStatsService.shutdown(); 12576 synchronized (this) { 12577 mProcessStats.shutdownLocked(); 12578 notifyTaskPersisterLocked(null, true); 12579 } 12580 12581 return timedout; 12582 } 12583 12584 public final void activitySlept(IBinder token) { 12585 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token); 12586 12587 final long origId = Binder.clearCallingIdentity(); 12588 12589 synchronized (this) { 12590 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 12591 if (r != null) { 12592 mStackSupervisor.activitySleptLocked(r); 12593 } 12594 } 12595 12596 Binder.restoreCallingIdentity(origId); 12597 } 12598 12599 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) { 12600 Slog.d(TAG, "<<< startRunningVoiceLocked()"); 12601 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid)); 12602 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) { 12603 boolean wasRunningVoice = mRunningVoice != null; 12604 mRunningVoice = session; 12605 if (!wasRunningVoice) { 12606 mVoiceWakeLock.acquire(); 12607 updateSleepIfNeededLocked(); 12608 } 12609 } 12610 } 12611 12612 private void updateEventDispatchingLocked() { 12613 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 12614 } 12615 12616 @Override 12617 public void setLockScreenShown(boolean showing) { 12618 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 12619 != PackageManager.PERMISSION_GRANTED) { 12620 throw new SecurityException("Requires permission " 12621 + android.Manifest.permission.DEVICE_POWER); 12622 } 12623 12624 synchronized(this) { 12625 long ident = Binder.clearCallingIdentity(); 12626 try { 12627 mKeyguardController.setKeyguardShown(showing); 12628 } finally { 12629 Binder.restoreCallingIdentity(ident); 12630 } 12631 } 12632 } 12633 12634 @Override 12635 public void notifyLockedProfile(@UserIdInt int userId) { 12636 try { 12637 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) { 12638 throw new SecurityException("Only privileged app can call notifyLockedProfile"); 12639 } 12640 } catch (RemoteException ex) { 12641 throw new SecurityException("Fail to check is caller a privileged app", ex); 12642 } 12643 12644 synchronized (this) { 12645 final long ident = Binder.clearCallingIdentity(); 12646 try { 12647 if (mUserController.shouldConfirmCredentials(userId)) { 12648 if (mKeyguardController.isKeyguardLocked()) { 12649 // Showing launcher to avoid user entering credential twice. 12650 final int currentUserId = mUserController.getCurrentUserIdLocked(); 12651 startHomeActivityLocked(currentUserId, "notifyLockedProfile"); 12652 } 12653 mStackSupervisor.lockAllProfileTasks(userId); 12654 } 12655 } finally { 12656 Binder.restoreCallingIdentity(ident); 12657 } 12658 } 12659 } 12660 12661 @Override 12662 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) { 12663 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent"); 12664 synchronized (this) { 12665 final long ident = Binder.clearCallingIdentity(); 12666 try { 12667 mActivityStarter.startConfirmCredentialIntent(intent, options); 12668 } finally { 12669 Binder.restoreCallingIdentity(ident); 12670 } 12671 } 12672 } 12673 12674 @Override 12675 public void stopAppSwitches() { 12676 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 12677 != PackageManager.PERMISSION_GRANTED) { 12678 throw new SecurityException("viewquires permission " 12679 + android.Manifest.permission.STOP_APP_SWITCHES); 12680 } 12681 12682 synchronized(this) { 12683 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 12684 + APP_SWITCH_DELAY_TIME; 12685 mDidAppSwitch = false; 12686 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 12687 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 12688 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 12689 } 12690 } 12691 12692 public void resumeAppSwitches() { 12693 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 12694 != PackageManager.PERMISSION_GRANTED) { 12695 throw new SecurityException("Requires permission " 12696 + android.Manifest.permission.STOP_APP_SWITCHES); 12697 } 12698 12699 synchronized(this) { 12700 // Note that we don't execute any pending app switches... we will 12701 // let those wait until either the timeout, or the next start 12702 // activity request. 12703 mAppSwitchesAllowedTime = 0; 12704 } 12705 } 12706 12707 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 12708 int callingPid, int callingUid, String name) { 12709 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 12710 return true; 12711 } 12712 12713 int perm = checkComponentPermission( 12714 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 12715 sourceUid, -1, true); 12716 if (perm == PackageManager.PERMISSION_GRANTED) { 12717 return true; 12718 } 12719 12720 // If the actual IPC caller is different from the logical source, then 12721 // also see if they are allowed to control app switches. 12722 if (callingUid != -1 && callingUid != sourceUid) { 12723 perm = checkComponentPermission( 12724 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 12725 callingUid, -1, true); 12726 if (perm == PackageManager.PERMISSION_GRANTED) { 12727 return true; 12728 } 12729 } 12730 12731 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 12732 return false; 12733 } 12734 12735 public void setDebugApp(String packageName, boolean waitForDebugger, 12736 boolean persistent) { 12737 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 12738 "setDebugApp()"); 12739 12740 long ident = Binder.clearCallingIdentity(); 12741 try { 12742 // Note that this is not really thread safe if there are multiple 12743 // callers into it at the same time, but that's not a situation we 12744 // care about. 12745 if (persistent) { 12746 final ContentResolver resolver = mContext.getContentResolver(); 12747 Settings.Global.putString( 12748 resolver, Settings.Global.DEBUG_APP, 12749 packageName); 12750 Settings.Global.putInt( 12751 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 12752 waitForDebugger ? 1 : 0); 12753 } 12754 12755 synchronized (this) { 12756 if (!persistent) { 12757 mOrigDebugApp = mDebugApp; 12758 mOrigWaitForDebugger = mWaitForDebugger; 12759 } 12760 mDebugApp = packageName; 12761 mWaitForDebugger = waitForDebugger; 12762 mDebugTransient = !persistent; 12763 if (packageName != null) { 12764 forceStopPackageLocked(packageName, -1, false, false, true, true, 12765 false, UserHandle.USER_ALL, "set debug app"); 12766 } 12767 } 12768 } finally { 12769 Binder.restoreCallingIdentity(ident); 12770 } 12771 } 12772 12773 void setTrackAllocationApp(ApplicationInfo app, String processName) { 12774 synchronized (this) { 12775 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 12776 if (!isDebuggable) { 12777 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 12778 throw new SecurityException("Process not debuggable: " + app.packageName); 12779 } 12780 } 12781 12782 mTrackAllocationApp = processName; 12783 } 12784 } 12785 12786 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 12787 synchronized (this) { 12788 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 12789 if (!isDebuggable) { 12790 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 12791 throw new SecurityException("Process not debuggable: " + app.packageName); 12792 } 12793 } 12794 mProfileApp = processName; 12795 12796 if (mProfilerInfo != null) { 12797 if (mProfilerInfo.profileFd != null) { 12798 try { 12799 mProfilerInfo.profileFd.close(); 12800 } catch (IOException e) { 12801 } 12802 } 12803 } 12804 mProfilerInfo = new ProfilerInfo(profilerInfo); 12805 mProfileType = 0; 12806 } 12807 } 12808 12809 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) { 12810 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 12811 if (!isDebuggable) { 12812 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 12813 throw new SecurityException("Process not debuggable: " + app.packageName); 12814 } 12815 } 12816 mNativeDebuggingApp = processName; 12817 } 12818 12819 @Override 12820 public void setAlwaysFinish(boolean enabled) { 12821 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 12822 "setAlwaysFinish()"); 12823 12824 long ident = Binder.clearCallingIdentity(); 12825 try { 12826 Settings.Global.putInt( 12827 mContext.getContentResolver(), 12828 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 12829 12830 synchronized (this) { 12831 mAlwaysFinishActivities = enabled; 12832 } 12833 } finally { 12834 Binder.restoreCallingIdentity(ident); 12835 } 12836 } 12837 12838 @Override 12839 public void setActivityController(IActivityController controller, boolean imAMonkey) { 12840 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 12841 "setActivityController()"); 12842 synchronized (this) { 12843 mController = controller; 12844 mControllerIsAMonkey = imAMonkey; 12845 Watchdog.getInstance().setActivityController(controller); 12846 } 12847 } 12848 12849 @Override 12850 public void setUserIsMonkey(boolean userIsMonkey) { 12851 synchronized (this) { 12852 synchronized (mPidsSelfLocked) { 12853 final int callingPid = Binder.getCallingPid(); 12854 ProcessRecord proc = mPidsSelfLocked.get(callingPid); 12855 if (proc == null) { 12856 throw new SecurityException("Unknown process: " + callingPid); 12857 } 12858 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) { 12859 throw new SecurityException("Only an instrumentation process " 12860 + "with a UiAutomation can call setUserIsMonkey"); 12861 } 12862 } 12863 mUserIsMonkey = userIsMonkey; 12864 } 12865 } 12866 12867 @Override 12868 public boolean isUserAMonkey() { 12869 synchronized (this) { 12870 // If there is a controller also implies the user is a monkey. 12871 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey)); 12872 } 12873 } 12874 12875 /** 12876 * @deprecated This method is only used by a few internal components and it will soon be 12877 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps). 12878 * No new code should be calling it. 12879 */ 12880 @Deprecated 12881 @Override 12882 public void requestBugReport(int bugreportType) { 12883 String extraOptions = null; 12884 switch (bugreportType) { 12885 case ActivityManager.BUGREPORT_OPTION_FULL: 12886 // Default options. 12887 break; 12888 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE: 12889 extraOptions = "bugreportplus"; 12890 break; 12891 case ActivityManager.BUGREPORT_OPTION_REMOTE: 12892 extraOptions = "bugreportremote"; 12893 break; 12894 case ActivityManager.BUGREPORT_OPTION_WEAR: 12895 extraOptions = "bugreportwear"; 12896 break; 12897 case ActivityManager.BUGREPORT_OPTION_TELEPHONY: 12898 extraOptions = "bugreporttelephony"; 12899 break; 12900 default: 12901 throw new IllegalArgumentException("Provided bugreport type is not correct, value: " 12902 + bugreportType); 12903 } 12904 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 12905 if (extraOptions != null) { 12906 SystemProperties.set("dumpstate.options", extraOptions); 12907 } 12908 SystemProperties.set("ctl.start", "bugreport"); 12909 } 12910 12911 /** 12912 * @deprecated This method is only used by a few internal components and it will soon be 12913 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps). 12914 * No new code should be calling it. 12915 */ 12916 @Deprecated 12917 @Override 12918 public void requestTelephonyBugReport(String shareTitle, String shareDescription) { 12919 12920 if (!TextUtils.isEmpty(shareTitle)) { 12921 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) { 12922 String errorStr = "shareTitle should be less than " + 12923 MAX_BUGREPORT_TITLE_SIZE + " characters"; 12924 throw new IllegalArgumentException(errorStr); 12925 } else { 12926 if (!TextUtils.isEmpty(shareDescription)) { 12927 int length; 12928 try { 12929 length = shareDescription.getBytes("UTF-8").length; 12930 } catch (UnsupportedEncodingException e) { 12931 String errorStr = "shareDescription: UnsupportedEncodingException"; 12932 throw new IllegalArgumentException(errorStr); 12933 } 12934 if (length > SystemProperties.PROP_VALUE_MAX) { 12935 String errorStr = "shareTitle should be less than " + 12936 SystemProperties.PROP_VALUE_MAX + " bytes"; 12937 throw new IllegalArgumentException(errorStr); 12938 } else { 12939 SystemProperties.set("dumpstate.options.description", shareDescription); 12940 } 12941 } 12942 SystemProperties.set("dumpstate.options.title", shareTitle); 12943 } 12944 } 12945 12946 Slog.d(TAG, "Bugreport notification title " + shareTitle 12947 + " description " + shareDescription); 12948 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY); 12949 } 12950 12951 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 12952 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 12953 } 12954 12955 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 12956 if (r != null && (r.instr != null || r.usingWrapper)) { 12957 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 12958 } 12959 return KEY_DISPATCHING_TIMEOUT; 12960 } 12961 12962 @Override 12963 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 12964 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 12965 != PackageManager.PERMISSION_GRANTED) { 12966 throw new SecurityException("Requires permission " 12967 + android.Manifest.permission.FILTER_EVENTS); 12968 } 12969 ProcessRecord proc; 12970 long timeout; 12971 synchronized (this) { 12972 synchronized (mPidsSelfLocked) { 12973 proc = mPidsSelfLocked.get(pid); 12974 } 12975 timeout = getInputDispatchingTimeoutLocked(proc); 12976 } 12977 12978 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 12979 return -1; 12980 } 12981 12982 return timeout; 12983 } 12984 12985 /** 12986 * Handle input dispatching timeouts. 12987 * Returns whether input dispatching should be aborted or not. 12988 */ 12989 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 12990 final ActivityRecord activity, final ActivityRecord parent, 12991 final boolean aboveSystem, String reason) { 12992 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 12993 != PackageManager.PERMISSION_GRANTED) { 12994 throw new SecurityException("Requires permission " 12995 + android.Manifest.permission.FILTER_EVENTS); 12996 } 12997 12998 final String annotation; 12999 if (reason == null) { 13000 annotation = "Input dispatching timed out"; 13001 } else { 13002 annotation = "Input dispatching timed out (" + reason + ")"; 13003 } 13004 13005 if (proc != null) { 13006 synchronized (this) { 13007 if (proc.debugging) { 13008 return false; 13009 } 13010 13011 if (proc.instr != null) { 13012 Bundle info = new Bundle(); 13013 info.putString("shortMsg", "keyDispatchingTimedOut"); 13014 info.putString("longMsg", annotation); 13015 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 13016 return true; 13017 } 13018 } 13019 mHandler.post(new Runnable() { 13020 @Override 13021 public void run() { 13022 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation); 13023 } 13024 }); 13025 } 13026 13027 return true; 13028 } 13029 13030 @Override 13031 public Bundle getAssistContextExtras(int requestType) { 13032 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null, 13033 null, null, true /* focused */, true /* newSessionId */, 13034 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0); 13035 if (pae == null) { 13036 return null; 13037 } 13038 synchronized (pae) { 13039 while (!pae.haveResult) { 13040 try { 13041 pae.wait(); 13042 } catch (InterruptedException e) { 13043 } 13044 } 13045 } 13046 synchronized (this) { 13047 buildAssistBundleLocked(pae, pae.result); 13048 mPendingAssistExtras.remove(pae); 13049 mUiHandler.removeCallbacks(pae); 13050 } 13051 return pae.extras; 13052 } 13053 13054 @Override 13055 public boolean isAssistDataAllowedOnCurrentActivity() { 13056 int userId; 13057 synchronized (this) { 13058 final ActivityStack focusedStack = getFocusedStack(); 13059 if (focusedStack == null || focusedStack.isAssistantStack()) { 13060 return false; 13061 } 13062 13063 final ActivityRecord activity = focusedStack.topActivity(); 13064 if (activity == null) { 13065 return false; 13066 } 13067 userId = activity.userId; 13068 } 13069 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( 13070 Context.DEVICE_POLICY_SERVICE); 13071 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId)); 13072 } 13073 13074 @Override 13075 public boolean showAssistFromActivity(IBinder token, Bundle args) { 13076 long ident = Binder.clearCallingIdentity(); 13077 try { 13078 synchronized (this) { 13079 ActivityRecord caller = ActivityRecord.forTokenLocked(token); 13080 ActivityRecord top = getFocusedStack().topActivity(); 13081 if (top != caller) { 13082 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller 13083 + " is not current top " + top); 13084 return false; 13085 } 13086 if (!top.nowVisible) { 13087 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller 13088 + " is not visible"); 13089 return false; 13090 } 13091 } 13092 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null, 13093 token); 13094 } finally { 13095 Binder.restoreCallingIdentity(ident); 13096 } 13097 } 13098 13099 @Override 13100 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver, 13101 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) { 13102 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras, 13103 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null, 13104 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null; 13105 } 13106 13107 @Override 13108 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras, 13109 IBinder activityToken, int flags) { 13110 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null, 13111 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(), 13112 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null; 13113 } 13114 13115 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 13116 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, 13117 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout, 13118 int flags) { 13119 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 13120 "enqueueAssistContext()"); 13121 13122 synchronized (this) { 13123 ActivityRecord activity = getFocusedStack().topActivity(); 13124 if (activity == null) { 13125 Slog.w(TAG, "getAssistContextExtras failed: no top activity"); 13126 return null; 13127 } 13128 if (activity.app == null || activity.app.thread == null) { 13129 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 13130 return null; 13131 } 13132 if (focused) { 13133 if (activityToken != null) { 13134 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken); 13135 if (activity != caller) { 13136 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller 13137 + " is not current top " + activity); 13138 return null; 13139 } 13140 } 13141 } else { 13142 activity = ActivityRecord.forTokenLocked(activityToken); 13143 if (activity == null) { 13144 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken 13145 + " couldn't be found"); 13146 return null; 13147 } 13148 if (activity.app == null || activity.app.thread == null) { 13149 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity); 13150 return null; 13151 } 13152 } 13153 13154 PendingAssistExtras pae; 13155 Bundle extras = new Bundle(); 13156 if (args != null) { 13157 extras.putAll(args); 13158 } 13159 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 13160 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid); 13161 13162 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras, 13163 userHandle); 13164 pae.isHome = activity.isHomeActivity(); 13165 13166 // Increment the sessionId if necessary 13167 if (newSessionId) { 13168 mViSessionId++; 13169 } 13170 try { 13171 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType, 13172 mViSessionId, flags); 13173 mPendingAssistExtras.add(pae); 13174 mUiHandler.postDelayed(pae, timeout); 13175 } catch (RemoteException e) { 13176 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 13177 return null; 13178 } 13179 return pae; 13180 } 13181 } 13182 13183 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) { 13184 IResultReceiver receiver; 13185 synchronized (this) { 13186 mPendingAssistExtras.remove(pae); 13187 receiver = pae.receiver; 13188 } 13189 if (receiver != null) { 13190 // Caller wants result sent back to them. 13191 Bundle sendBundle = new Bundle(); 13192 // At least return the receiver extras 13193 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS, 13194 pae.receiverExtras); 13195 try { 13196 pae.receiver.send(0, sendBundle); 13197 } catch (RemoteException e) { 13198 } 13199 } 13200 } 13201 13202 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) { 13203 if (result != null) { 13204 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result); 13205 } 13206 if (pae.hint != null) { 13207 pae.extras.putBoolean(pae.hint, true); 13208 } 13209 } 13210 13211 /** Called from an app when assist data is ready. */ 13212 @Override 13213 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure, 13214 AssistContent content, Uri referrer) { 13215 PendingAssistExtras pae = (PendingAssistExtras)token; 13216 synchronized (pae) { 13217 pae.result = extras; 13218 pae.structure = structure; 13219 pae.content = content; 13220 if (referrer != null) { 13221 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer); 13222 } 13223 if (structure != null) { 13224 structure.setHomeActivity(pae.isHome); 13225 } 13226 pae.haveResult = true; 13227 pae.notifyAll(); 13228 if (pae.intent == null && pae.receiver == null) { 13229 // Caller is just waiting for the result. 13230 return; 13231 } 13232 } 13233 // We are now ready to launch the assist activity. 13234 IResultReceiver sendReceiver = null; 13235 Bundle sendBundle = null; 13236 synchronized (this) { 13237 buildAssistBundleLocked(pae, extras); 13238 boolean exists = mPendingAssistExtras.remove(pae); 13239 mUiHandler.removeCallbacks(pae); 13240 if (!exists) { 13241 // Timed out. 13242 return; 13243 } 13244 if ((sendReceiver=pae.receiver) != null) { 13245 // Caller wants result sent back to them. 13246 sendBundle = new Bundle(); 13247 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras); 13248 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure); 13249 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content); 13250 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS, 13251 pae.receiverExtras); 13252 } 13253 } 13254 if (sendReceiver != null) { 13255 try { 13256 sendReceiver.send(0, sendBundle); 13257 } catch (RemoteException e) { 13258 } 13259 return; 13260 } 13261 13262 final long ident = Binder.clearCallingIdentity(); 13263 try { 13264 if (TextUtils.equals(pae.intent.getAction(), 13265 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) { 13266 pae.intent.putExtras(pae.extras); 13267 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle)); 13268 } else { 13269 pae.intent.replaceExtras(pae.extras); 13270 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 13271 | Intent.FLAG_ACTIVITY_SINGLE_TOP 13272 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 13273 closeSystemDialogs("assist"); 13274 13275 try { 13276 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 13277 } catch (ActivityNotFoundException e) { 13278 Slog.w(TAG, "No activity to handle assist action.", e); 13279 } 13280 } 13281 } finally { 13282 Binder.restoreCallingIdentity(ident); 13283 } 13284 } 13285 13286 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle, 13287 Bundle args) { 13288 return enqueueAssistContext(requestType, intent, hint, null, null, null, 13289 true /* focused */, true /* newSessionId */, userHandle, args, 13290 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null; 13291 } 13292 13293 public void registerProcessObserver(IProcessObserver observer) { 13294 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 13295 "registerProcessObserver()"); 13296 synchronized (this) { 13297 mProcessObservers.register(observer); 13298 } 13299 } 13300 13301 @Override 13302 public void unregisterProcessObserver(IProcessObserver observer) { 13303 synchronized (this) { 13304 mProcessObservers.unregister(observer); 13305 } 13306 } 13307 13308 @Override 13309 public int getUidProcessState(int uid, String callingPackage) { 13310 if (!hasUsageStatsPermission(callingPackage)) { 13311 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, 13312 "getUidProcessState"); 13313 } 13314 13315 synchronized (this) { 13316 UidRecord uidRec = mActiveUids.get(uid); 13317 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT; 13318 } 13319 } 13320 13321 @Override 13322 public void registerUidObserver(IUidObserver observer, int which, int cutpoint, 13323 String callingPackage) { 13324 if (!hasUsageStatsPermission(callingPackage)) { 13325 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, 13326 "registerUidObserver"); 13327 } 13328 synchronized (this) { 13329 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(), 13330 callingPackage, which, cutpoint)); 13331 } 13332 } 13333 13334 @Override 13335 public void unregisterUidObserver(IUidObserver observer) { 13336 synchronized (this) { 13337 mUidObservers.unregister(observer); 13338 } 13339 } 13340 13341 @Override 13342 public boolean convertFromTranslucent(IBinder token) { 13343 final long origId = Binder.clearCallingIdentity(); 13344 try { 13345 synchronized (this) { 13346 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 13347 if (r == null) { 13348 return false; 13349 } 13350 final boolean translucentChanged = r.changeWindowTranslucency(true); 13351 if (translucentChanged) { 13352 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 13353 } 13354 mWindowManager.setAppFullscreen(token, true); 13355 return translucentChanged; 13356 } 13357 } finally { 13358 Binder.restoreCallingIdentity(origId); 13359 } 13360 } 13361 13362 @Override 13363 public boolean convertToTranslucent(IBinder token, Bundle options) { 13364 final long origId = Binder.clearCallingIdentity(); 13365 try { 13366 synchronized (this) { 13367 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 13368 if (r == null) { 13369 return false; 13370 } 13371 final TaskRecord task = r.getTask(); 13372 int index = task.mActivities.lastIndexOf(r); 13373 if (index > 0) { 13374 ActivityRecord under = task.mActivities.get(index - 1); 13375 under.returningOptions = ActivityOptions.fromBundle(options); 13376 } 13377 final boolean translucentChanged = r.changeWindowTranslucency(false); 13378 if (translucentChanged) { 13379 r.getStack().convertActivityToTranslucent(r); 13380 } 13381 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 13382 mWindowManager.setAppFullscreen(token, false); 13383 return translucentChanged; 13384 } 13385 } finally { 13386 Binder.restoreCallingIdentity(origId); 13387 } 13388 } 13389 13390 @Override 13391 public Bundle getActivityOptions(IBinder token) { 13392 final long origId = Binder.clearCallingIdentity(); 13393 try { 13394 synchronized (this) { 13395 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 13396 if (r != null) { 13397 final ActivityOptions activityOptions = r.takeOptionsLocked(); 13398 return activityOptions == null ? null : activityOptions.toBundle(); 13399 } 13400 return null; 13401 } 13402 } finally { 13403 Binder.restoreCallingIdentity(origId); 13404 } 13405 } 13406 13407 @Override 13408 public void setImmersive(IBinder token, boolean immersive) { 13409 synchronized(this) { 13410 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 13411 if (r == null) { 13412 throw new IllegalArgumentException(); 13413 } 13414 r.immersive = immersive; 13415 13416 // update associated state if we're frontmost 13417 if (r == mStackSupervisor.getResumedActivityLocked()) { 13418 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r); 13419 applyUpdateLockStateLocked(r); 13420 } 13421 } 13422 } 13423 13424 @Override 13425 public boolean isImmersive(IBinder token) { 13426 synchronized (this) { 13427 ActivityRecord r = ActivityRecord.isInStackLocked(token); 13428 if (r == null) { 13429 throw new IllegalArgumentException(); 13430 } 13431 return r.immersive; 13432 } 13433 } 13434 13435 @Override 13436 public void setVrThread(int tid) { 13437 enforceSystemHasVrFeature(); 13438 synchronized (this) { 13439 synchronized (mPidsSelfLocked) { 13440 final int pid = Binder.getCallingPid(); 13441 final ProcessRecord proc = mPidsSelfLocked.get(pid); 13442 mVrController.setVrThreadLocked(tid, pid, proc); 13443 } 13444 } 13445 } 13446 13447 @Override 13448 public void setPersistentVrThread(int tid) { 13449 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) { 13450 final String msg = "Permission Denial: setPersistentVrThread() from pid=" 13451 + Binder.getCallingPid() 13452 + ", uid=" + Binder.getCallingUid() 13453 + " requires " + permission.RESTRICTED_VR_ACCESS; 13454 Slog.w(TAG, msg); 13455 throw new SecurityException(msg); 13456 } 13457 enforceSystemHasVrFeature(); 13458 synchronized (this) { 13459 synchronized (mPidsSelfLocked) { 13460 final int pid = Binder.getCallingPid(); 13461 final ProcessRecord proc = mPidsSelfLocked.get(pid); 13462 mVrController.setPersistentVrThreadLocked(tid, pid, proc); 13463 } 13464 } 13465 } 13466 13467 /** 13468 * Schedule the given thread a normal scheduling priority. 13469 * 13470 * @param tid the tid of the thread to adjust the scheduling of. 13471 * @param suppressLogs {@code true} if any error logging should be disabled. 13472 * 13473 * @return {@code true} if this succeeded. 13474 */ 13475 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) { 13476 try { 13477 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0); 13478 return true; 13479 } catch (IllegalArgumentException e) { 13480 if (!suppressLogs) { 13481 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e); 13482 } 13483 } catch (SecurityException e) { 13484 if (!suppressLogs) { 13485 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e); 13486 } 13487 } 13488 return false; 13489 } 13490 13491 /** 13492 * Schedule the given thread an FIFO scheduling priority. 13493 * 13494 * @param tid the tid of the thread to adjust the scheduling of. 13495 * @param suppressLogs {@code true} if any error logging should be disabled. 13496 * 13497 * @return {@code true} if this succeeded. 13498 */ 13499 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) { 13500 try { 13501 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1); 13502 return true; 13503 } catch (IllegalArgumentException e) { 13504 if (!suppressLogs) { 13505 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e); 13506 } 13507 } catch (SecurityException e) { 13508 if (!suppressLogs) { 13509 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e); 13510 } 13511 } 13512 return false; 13513 } 13514 13515 /** 13516 * Check that we have the features required for VR-related API calls, and throw an exception if 13517 * not. 13518 */ 13519 private void enforceSystemHasVrFeature() { 13520 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { 13521 throw new UnsupportedOperationException("VR mode not supported on this device!"); 13522 } 13523 } 13524 13525 @Override 13526 public void setRenderThread(int tid) { 13527 synchronized (this) { 13528 ProcessRecord proc; 13529 int pid = Binder.getCallingPid(); 13530 if (pid == Process.myPid()) { 13531 demoteSystemServerRenderThread(tid); 13532 return; 13533 } 13534 synchronized (mPidsSelfLocked) { 13535 proc = mPidsSelfLocked.get(pid); 13536 if (proc != null && proc.renderThreadTid == 0 && tid > 0) { 13537 // ensure the tid belongs to the process 13538 if (!isThreadInProcess(pid, tid)) { 13539 throw new IllegalArgumentException( 13540 "Render thread does not belong to process"); 13541 } 13542 proc.renderThreadTid = tid; 13543 if (DEBUG_OOM_ADJ) { 13544 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid); 13545 } 13546 // promote to FIFO now 13547 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { 13548 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band"); 13549 if (mUseFifoUiScheduling) { 13550 setThreadScheduler(proc.renderThreadTid, 13551 SCHED_FIFO | SCHED_RESET_ON_FORK, 1); 13552 } else { 13553 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST); 13554 } 13555 } 13556 } else { 13557 if (DEBUG_OOM_ADJ) { 13558 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " + 13559 "PID: " + pid + ", TID: " + tid + " FIFO: " + 13560 mUseFifoUiScheduling); 13561 } 13562 } 13563 } 13564 } 13565 } 13566 13567 /** 13568 * We only use RenderThread in system_server to store task snapshots to the disk, which should 13569 * happen in the background. Thus, demote render thread from system_server to a lower priority. 13570 * 13571 * @param tid the tid of the RenderThread 13572 */ 13573 private void demoteSystemServerRenderThread(int tid) { 13574 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND); 13575 } 13576 13577 @Override 13578 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) { 13579 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { 13580 throw new UnsupportedOperationException("VR mode not supported on this device!"); 13581 } 13582 13583 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 13584 13585 ActivityRecord r; 13586 synchronized (this) { 13587 r = ActivityRecord.isInStackLocked(token); 13588 } 13589 13590 if (r == null) { 13591 throw new IllegalArgumentException(); 13592 } 13593 13594 int err; 13595 if ((err = vrService.hasVrPackage(packageName, r.userId)) != 13596 VrManagerInternal.NO_ERROR) { 13597 return err; 13598 } 13599 13600 synchronized(this) { 13601 r.requestedVrComponent = (enabled) ? packageName : null; 13602 13603 // Update associated state if this activity is currently focused 13604 if (r == mStackSupervisor.getResumedActivityLocked()) { 13605 applyUpdateVrModeLocked(r); 13606 } 13607 return 0; 13608 } 13609 } 13610 13611 @Override 13612 public boolean isVrModePackageEnabled(ComponentName packageName) { 13613 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { 13614 throw new UnsupportedOperationException("VR mode not supported on this device!"); 13615 } 13616 13617 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 13618 13619 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) == 13620 VrManagerInternal.NO_ERROR; 13621 } 13622 13623 public boolean isTopActivityImmersive() { 13624 enforceNotIsolatedCaller("startActivity"); 13625 synchronized (this) { 13626 ActivityRecord r = getFocusedStack().topRunningActivityLocked(); 13627 return (r != null) ? r.immersive : false; 13628 } 13629 } 13630 13631 /** 13632 * @return whether the system should disable UI modes incompatible with VR mode. 13633 */ 13634 boolean shouldDisableNonVrUiLocked() { 13635 return mVrController.shouldDisableNonVrUiLocked(); 13636 } 13637 13638 @Override 13639 public boolean isTopOfTask(IBinder token) { 13640 synchronized (this) { 13641 ActivityRecord r = ActivityRecord.isInStackLocked(token); 13642 if (r == null) { 13643 throw new IllegalArgumentException(); 13644 } 13645 return r.getTask().getTopActivity() == r; 13646 } 13647 } 13648 13649 @Override 13650 public void setHasTopUi(boolean hasTopUi) throws RemoteException { 13651 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) { 13652 String msg = "Permission Denial: setHasTopUi() from pid=" 13653 + Binder.getCallingPid() 13654 + ", uid=" + Binder.getCallingUid() 13655 + " requires " + permission.INTERNAL_SYSTEM_WINDOW; 13656 Slog.w(TAG, msg); 13657 throw new SecurityException(msg); 13658 } 13659 final int pid = Binder.getCallingPid(); 13660 final long origId = Binder.clearCallingIdentity(); 13661 try { 13662 synchronized (this) { 13663 boolean changed = false; 13664 ProcessRecord pr; 13665 synchronized (mPidsSelfLocked) { 13666 pr = mPidsSelfLocked.get(pid); 13667 if (pr == null) { 13668 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid); 13669 return; 13670 } 13671 if (pr.hasTopUi != hasTopUi) { 13672 if (DEBUG_OOM_ADJ) { 13673 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid); 13674 } 13675 pr.hasTopUi = hasTopUi; 13676 changed = true; 13677 } 13678 } 13679 if (changed) { 13680 updateOomAdjLocked(pr, true); 13681 } 13682 } 13683 } finally { 13684 Binder.restoreCallingIdentity(origId); 13685 } 13686 } 13687 13688 public final void enterSafeMode() { 13689 synchronized(this) { 13690 // It only makes sense to do this before the system is ready 13691 // and started launching other packages. 13692 if (!mSystemReady) { 13693 try { 13694 AppGlobals.getPackageManager().enterSafeMode(); 13695 } catch (RemoteException e) { 13696 } 13697 } 13698 13699 mSafeMode = true; 13700 } 13701 } 13702 13703 public final void showSafeModeOverlay() { 13704 View v = LayoutInflater.from(mContext).inflate( 13705 com.android.internal.R.layout.safe_mode, null); 13706 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 13707 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 13708 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 13709 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 13710 lp.gravity = Gravity.BOTTOM | Gravity.START; 13711 lp.format = v.getBackground().getOpacity(); 13712 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 13713 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 13714 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 13715 ((WindowManager)mContext.getSystemService( 13716 Context.WINDOW_SERVICE)).addView(v, lp); 13717 } 13718 13719 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) { 13720 if (sender != null && !(sender instanceof PendingIntentRecord)) { 13721 return; 13722 } 13723 final PendingIntentRecord rec = (PendingIntentRecord)sender; 13724 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13725 synchronized (stats) { 13726 if (mBatteryStatsService.isOnBattery()) { 13727 mBatteryStatsService.enforceCallingPermission(); 13728 int MY_UID = Binder.getCallingUid(); 13729 final int uid; 13730 if (sender == null) { 13731 uid = sourceUid; 13732 } else { 13733 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid; 13734 } 13735 BatteryStatsImpl.Uid.Pkg pkg = 13736 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 13737 sourcePkg != null ? sourcePkg : rec.key.packageName); 13738 pkg.noteWakeupAlarmLocked(tag); 13739 } 13740 } 13741 } 13742 13743 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) { 13744 if (sender != null && !(sender instanceof PendingIntentRecord)) { 13745 return; 13746 } 13747 final PendingIntentRecord rec = (PendingIntentRecord)sender; 13748 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13749 synchronized (stats) { 13750 mBatteryStatsService.enforceCallingPermission(); 13751 int MY_UID = Binder.getCallingUid(); 13752 final int uid; 13753 if (sender == null) { 13754 uid = sourceUid; 13755 } else { 13756 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid; 13757 } 13758 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid); 13759 } 13760 } 13761 13762 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) { 13763 if (sender != null && !(sender instanceof PendingIntentRecord)) { 13764 return; 13765 } 13766 final PendingIntentRecord rec = (PendingIntentRecord)sender; 13767 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13768 synchronized (stats) { 13769 mBatteryStatsService.enforceCallingPermission(); 13770 int MY_UID = Binder.getCallingUid(); 13771 final int uid; 13772 if (sender == null) { 13773 uid = sourceUid; 13774 } else { 13775 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid; 13776 } 13777 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid); 13778 } 13779 } 13780 13781 public boolean killPids(int[] pids, String pReason, boolean secure) { 13782 if (Binder.getCallingUid() != SYSTEM_UID) { 13783 throw new SecurityException("killPids only available to the system"); 13784 } 13785 String reason = (pReason == null) ? "Unknown" : pReason; 13786 // XXX Note: don't acquire main activity lock here, because the window 13787 // manager calls in with its locks held. 13788 13789 boolean killed = false; 13790 synchronized (mPidsSelfLocked) { 13791 int worstType = 0; 13792 for (int i=0; i<pids.length; i++) { 13793 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 13794 if (proc != null) { 13795 int type = proc.setAdj; 13796 if (type > worstType) { 13797 worstType = type; 13798 } 13799 } 13800 } 13801 13802 // If the worst oom_adj is somewhere in the cached proc LRU range, 13803 // then constrain it so we will kill all cached procs. 13804 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 13805 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 13806 worstType = ProcessList.CACHED_APP_MIN_ADJ; 13807 } 13808 13809 // If this is not a secure call, don't let it kill processes that 13810 // are important. 13811 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 13812 worstType = ProcessList.SERVICE_ADJ; 13813 } 13814 13815 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 13816 for (int i=0; i<pids.length; i++) { 13817 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 13818 if (proc == null) { 13819 continue; 13820 } 13821 int adj = proc.setAdj; 13822 if (adj >= worstType && !proc.killedByAm) { 13823 proc.kill(reason, true); 13824 killed = true; 13825 } 13826 } 13827 } 13828 return killed; 13829 } 13830 13831 @Override 13832 public void killUid(int appId, int userId, String reason) { 13833 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid"); 13834 synchronized (this) { 13835 final long identity = Binder.clearCallingIdentity(); 13836 try { 13837 killPackageProcessesLocked(null, appId, userId, 13838 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true, 13839 reason != null ? reason : "kill uid"); 13840 } finally { 13841 Binder.restoreCallingIdentity(identity); 13842 } 13843 } 13844 } 13845 13846 @Override 13847 public boolean killProcessesBelowForeground(String reason) { 13848 if (Binder.getCallingUid() != SYSTEM_UID) { 13849 throw new SecurityException("killProcessesBelowForeground() only available to system"); 13850 } 13851 13852 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 13853 } 13854 13855 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 13856 if (Binder.getCallingUid() != SYSTEM_UID) { 13857 throw new SecurityException("killProcessesBelowAdj() only available to system"); 13858 } 13859 13860 boolean killed = false; 13861 synchronized (mPidsSelfLocked) { 13862 final int size = mPidsSelfLocked.size(); 13863 for (int i = 0; i < size; i++) { 13864 final int pid = mPidsSelfLocked.keyAt(i); 13865 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 13866 if (proc == null) continue; 13867 13868 final int adj = proc.setAdj; 13869 if (adj > belowAdj && !proc.killedByAm) { 13870 proc.kill(reason, true); 13871 killed = true; 13872 } 13873 } 13874 } 13875 return killed; 13876 } 13877 13878 @Override 13879 public void hang(final IBinder who, boolean allowRestart) { 13880 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13881 != PackageManager.PERMISSION_GRANTED) { 13882 throw new SecurityException("Requires permission " 13883 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13884 } 13885 13886 final IBinder.DeathRecipient death = new DeathRecipient() { 13887 @Override 13888 public void binderDied() { 13889 synchronized (this) { 13890 notifyAll(); 13891 } 13892 } 13893 }; 13894 13895 try { 13896 who.linkToDeath(death, 0); 13897 } catch (RemoteException e) { 13898 Slog.w(TAG, "hang: given caller IBinder is already dead."); 13899 return; 13900 } 13901 13902 synchronized (this) { 13903 Watchdog.getInstance().setAllowRestart(allowRestart); 13904 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 13905 synchronized (death) { 13906 while (who.isBinderAlive()) { 13907 try { 13908 death.wait(); 13909 } catch (InterruptedException e) { 13910 } 13911 } 13912 } 13913 Watchdog.getInstance().setAllowRestart(true); 13914 } 13915 } 13916 13917 @Override 13918 public void restart() { 13919 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13920 != PackageManager.PERMISSION_GRANTED) { 13921 throw new SecurityException("Requires permission " 13922 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13923 } 13924 13925 Log.i(TAG, "Sending shutdown broadcast..."); 13926 13927 BroadcastReceiver br = new BroadcastReceiver() { 13928 @Override public void onReceive(Context context, Intent intent) { 13929 // Now the broadcast is done, finish up the low-level shutdown. 13930 Log.i(TAG, "Shutting down activity manager..."); 13931 shutdown(10000); 13932 Log.i(TAG, "Shutdown complete, restarting!"); 13933 killProcess(myPid()); 13934 System.exit(10); 13935 } 13936 }; 13937 13938 // First send the high-level shut down broadcast. 13939 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 13940 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 13941 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 13942 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 13943 mContext.sendOrderedBroadcastAsUser(intent, 13944 UserHandle.ALL, null, br, mHandler, 0, null, null); 13945 */ 13946 br.onReceive(mContext, intent); 13947 } 13948 13949 private long getLowRamTimeSinceIdle(long now) { 13950 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 13951 } 13952 13953 @Override 13954 public void performIdleMaintenance() { 13955 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13956 != PackageManager.PERMISSION_GRANTED) { 13957 throw new SecurityException("Requires permission " 13958 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13959 } 13960 13961 synchronized (this) { 13962 final long now = SystemClock.uptimeMillis(); 13963 final long timeSinceLastIdle = now - mLastIdleTime; 13964 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 13965 mLastIdleTime = now; 13966 mLowRamTimeSinceLastIdle = 0; 13967 if (mLowRamStartTime != 0) { 13968 mLowRamStartTime = now; 13969 } 13970 13971 StringBuilder sb = new StringBuilder(128); 13972 sb.append("Idle maintenance over "); 13973 TimeUtils.formatDuration(timeSinceLastIdle, sb); 13974 sb.append(" low RAM for "); 13975 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 13976 Slog.i(TAG, sb.toString()); 13977 13978 // If at least 1/3 of our time since the last idle period has been spent 13979 // with RAM low, then we want to kill processes. 13980 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 13981 13982 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13983 ProcessRecord proc = mLruProcesses.get(i); 13984 if (proc.notCachedSinceIdle) { 13985 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING 13986 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 13987 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 13988 if (doKilling && proc.initialIdlePss != 0 13989 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 13990 sb = new StringBuilder(128); 13991 sb.append("Kill"); 13992 sb.append(proc.processName); 13993 sb.append(" in idle maint: pss="); 13994 sb.append(proc.lastPss); 13995 sb.append(", swapPss="); 13996 sb.append(proc.lastSwapPss); 13997 sb.append(", initialPss="); 13998 sb.append(proc.initialIdlePss); 13999 sb.append(", period="); 14000 TimeUtils.formatDuration(timeSinceLastIdle, sb); 14001 sb.append(", lowRamPeriod="); 14002 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 14003 Slog.wtfQuiet(TAG, sb.toString()); 14004 proc.kill("idle maint (pss " + proc.lastPss 14005 + " from " + proc.initialIdlePss + ")", true); 14006 } 14007 } 14008 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME 14009 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) { 14010 proc.notCachedSinceIdle = true; 14011 proc.initialIdlePss = 0; 14012 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true, 14013 mTestPssMode, isSleepingLocked(), now); 14014 } 14015 } 14016 14017 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 14018 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 14019 } 14020 } 14021 14022 @Override 14023 public void sendIdleJobTrigger() { 14024 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14025 != PackageManager.PERMISSION_GRANTED) { 14026 throw new SecurityException("Requires permission " 14027 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14028 } 14029 14030 final long ident = Binder.clearCallingIdentity(); 14031 try { 14032 Intent intent = new Intent(ACTION_TRIGGER_IDLE) 14033 .setPackage("android") 14034 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14035 broadcastIntent(null, intent, null, null, 0, null, null, null, 14036 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL); 14037 } finally { 14038 Binder.restoreCallingIdentity(ident); 14039 } 14040 } 14041 14042 private void retrieveSettings() { 14043 final ContentResolver resolver = mContext.getContentResolver(); 14044 final boolean freeformWindowManagement = 14045 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT) 14046 || Settings.Global.getInt( 14047 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0; 14048 14049 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext); 14050 final boolean supportsPictureInPicture = supportsMultiWindow && 14051 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); 14052 final boolean supportsSplitScreenMultiWindow = 14053 ActivityManager.supportsSplitScreenMultiWindow(mContext); 14054 final boolean supportsMultiDisplay = mContext.getPackageManager() 14055 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS); 14056 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP); 14057 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0; 14058 final boolean alwaysFinishActivities = 14059 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0; 14060 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0; 14061 final boolean forceResizable = Settings.Global.getInt( 14062 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0; 14063 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver, 14064 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS); 14065 final boolean supportsLeanbackOnly = 14066 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY); 14067 14068 // Transfer any global setting for forcing RTL layout, into a System Property 14069 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 14070 14071 final Configuration configuration = new Configuration(); 14072 Settings.System.getConfiguration(resolver, configuration); 14073 if (forceRtl) { 14074 // This will take care of setting the correct layout direction flags 14075 configuration.setLayoutDirection(configuration.locale); 14076 } 14077 14078 synchronized (this) { 14079 mDebugApp = mOrigDebugApp = debugApp; 14080 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 14081 mAlwaysFinishActivities = alwaysFinishActivities; 14082 mSupportsLeanbackOnly = supportsLeanbackOnly; 14083 mForceResizableActivities = forceResizable; 14084 final boolean multiWindowFormEnabled = freeformWindowManagement 14085 || supportsSplitScreenMultiWindow 14086 || supportsPictureInPicture 14087 || supportsMultiDisplay; 14088 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) { 14089 mSupportsMultiWindow = true; 14090 mSupportsFreeformWindowManagement = freeformWindowManagement; 14091 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow; 14092 mSupportsPictureInPicture = supportsPictureInPicture; 14093 mSupportsMultiDisplay = supportsMultiDisplay; 14094 } else { 14095 mSupportsMultiWindow = false; 14096 mSupportsFreeformWindowManagement = false; 14097 mSupportsSplitScreenMultiWindow = false; 14098 mSupportsPictureInPicture = false; 14099 mSupportsMultiDisplay = false; 14100 } 14101 mWindowManager.setForceResizableTasks(mForceResizableActivities); 14102 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture); 14103 // This happens before any activities are started, so we can change global configuration 14104 // in-place. 14105 updateConfigurationLocked(configuration, null, true); 14106 final Configuration globalConfig = getGlobalConfiguration(); 14107 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig); 14108 14109 // Load resources only after the current configuration has been set. 14110 final Resources res = mContext.getResources(); 14111 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 14112 mThumbnailWidth = res.getDimensionPixelSize( 14113 com.android.internal.R.dimen.thumbnail_width); 14114 mThumbnailHeight = res.getDimensionPixelSize( 14115 com.android.internal.R.dimen.thumbnail_height); 14116 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString( 14117 com.android.internal.R.string.config_appsNotReportingCrashes)); 14118 mUserController.mUserSwitchUiEnabled = !res.getBoolean( 14119 com.android.internal.R.bool.config_customUserSwitchUi); 14120 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) { 14121 mFullscreenThumbnailScale = (float) res 14122 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) / 14123 (float) globalConfig.screenWidthDp; 14124 } else { 14125 mFullscreenThumbnailScale = res.getFraction( 14126 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1); 14127 } 14128 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs; 14129 } 14130 } 14131 14132 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { 14133 traceLog.traceBegin("PhaseActivityManagerReady"); 14134 synchronized(this) { 14135 if (mSystemReady) { 14136 // If we're done calling all the receivers, run the next "boot phase" passed in 14137 // by the SystemServer 14138 if (goingCallback != null) { 14139 goingCallback.run(); 14140 } 14141 return; 14142 } 14143 14144 mLocalDeviceIdleController 14145 = LocalServices.getService(DeviceIdleController.LocalService.class); 14146 mAssistUtils = new AssistUtils(mContext); 14147 mVrController.onSystemReady(); 14148 // Make sure we have the current profile info, since it is needed for security checks. 14149 mUserController.onSystemReady(); 14150 mRecentTasks.onSystemReadyLocked(); 14151 mAppOpsService.systemReady(); 14152 mSystemReady = true; 14153 } 14154 14155 try { 14156 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface( 14157 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE)) 14158 .getSerial(); 14159 } catch (RemoteException e) {} 14160 14161 ArrayList<ProcessRecord> procsToKill = null; 14162 synchronized(mPidsSelfLocked) { 14163 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 14164 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 14165 if (!isAllowedWhileBooting(proc.info)){ 14166 if (procsToKill == null) { 14167 procsToKill = new ArrayList<ProcessRecord>(); 14168 } 14169 procsToKill.add(proc); 14170 } 14171 } 14172 } 14173 14174 synchronized(this) { 14175 if (procsToKill != null) { 14176 for (int i=procsToKill.size()-1; i>=0; i--) { 14177 ProcessRecord proc = procsToKill.get(i); 14178 Slog.i(TAG, "Removing system update proc: " + proc); 14179 removeProcessLocked(proc, true, false, "system update done"); 14180 } 14181 } 14182 14183 // Now that we have cleaned up any update processes, we 14184 // are ready to start launching real processes and know that 14185 // we won't trample on them any more. 14186 mProcessesReady = true; 14187 } 14188 14189 Slog.i(TAG, "System now ready"); 14190 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 14191 SystemClock.uptimeMillis()); 14192 14193 synchronized(this) { 14194 // Make sure we have no pre-ready processes sitting around. 14195 14196 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 14197 ResolveInfo ri = mContext.getPackageManager() 14198 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 14199 STOCK_PM_FLAGS); 14200 CharSequence errorMsg = null; 14201 if (ri != null) { 14202 ActivityInfo ai = ri.activityInfo; 14203 ApplicationInfo app = ai.applicationInfo; 14204 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 14205 mTopAction = Intent.ACTION_FACTORY_TEST; 14206 mTopData = null; 14207 mTopComponent = new ComponentName(app.packageName, 14208 ai.name); 14209 } else { 14210 errorMsg = mContext.getResources().getText( 14211 com.android.internal.R.string.factorytest_not_system); 14212 } 14213 } else { 14214 errorMsg = mContext.getResources().getText( 14215 com.android.internal.R.string.factorytest_no_action); 14216 } 14217 if (errorMsg != null) { 14218 mTopAction = null; 14219 mTopData = null; 14220 mTopComponent = null; 14221 Message msg = Message.obtain(); 14222 msg.what = SHOW_FACTORY_ERROR_UI_MSG; 14223 msg.getData().putCharSequence("msg", errorMsg); 14224 mUiHandler.sendMessage(msg); 14225 } 14226 } 14227 } 14228 14229 retrieveSettings(); 14230 final int currentUserId; 14231 synchronized (this) { 14232 currentUserId = mUserController.getCurrentUserIdLocked(); 14233 readGrantedUriPermissionsLocked(); 14234 } 14235 14236 if (goingCallback != null) goingCallback.run(); 14237 traceLog.traceBegin("ActivityManagerStartApps"); 14238 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 14239 Integer.toString(currentUserId), currentUserId); 14240 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 14241 Integer.toString(currentUserId), currentUserId); 14242 mSystemServiceManager.startUser(currentUserId); 14243 14244 synchronized (this) { 14245 // Only start up encryption-aware persistent apps; once user is 14246 // unlocked we'll come back around and start unaware apps 14247 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); 14248 14249 // Start up initial activity. 14250 mBooting = true; 14251 // Enable home activity for system user, so that the system can always boot. We don't 14252 // do this when the system user is not setup since the setup wizard should be the one 14253 // to handle home activity in this case. 14254 if (UserManager.isSplitSystemUser() && 14255 Settings.Secure.getInt(mContext.getContentResolver(), 14256 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) { 14257 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class); 14258 try { 14259 AppGlobals.getPackageManager().setComponentEnabledSetting(cName, 14260 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, 14261 UserHandle.USER_SYSTEM); 14262 } catch (RemoteException e) { 14263 throw e.rethrowAsRuntimeException(); 14264 } 14265 } 14266 startHomeActivityLocked(currentUserId, "systemReady"); 14267 14268 try { 14269 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 14270 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 14271 + " data partition or your device will be unstable."); 14272 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget(); 14273 } 14274 } catch (RemoteException e) { 14275 } 14276 14277 if (!Build.isBuildConsistent()) { 14278 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 14279 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget(); 14280 } 14281 14282 long ident = Binder.clearCallingIdentity(); 14283 try { 14284 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14285 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14286 | Intent.FLAG_RECEIVER_FOREGROUND); 14287 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); 14288 broadcastIntentLocked(null, null, intent, 14289 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14290 null, false, false, MY_PID, SYSTEM_UID, 14291 currentUserId); 14292 intent = new Intent(Intent.ACTION_USER_STARTING); 14293 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14294 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); 14295 broadcastIntentLocked(null, null, intent, 14296 null, new IIntentReceiver.Stub() { 14297 @Override 14298 public void performReceive(Intent intent, int resultCode, String data, 14299 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 14300 throws RemoteException { 14301 } 14302 }, 0, null, null, 14303 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE, 14304 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL); 14305 } catch (Throwable t) { 14306 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 14307 } finally { 14308 Binder.restoreCallingIdentity(ident); 14309 } 14310 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 14311 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId); 14312 traceLog.traceEnd(); // ActivityManagerStartApps 14313 traceLog.traceEnd(); // PhaseActivityManagerReady 14314 } 14315 } 14316 14317 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 14318 synchronized (this) { 14319 mAppErrors.killAppAtUserRequestLocked(app, fromDialog); 14320 } 14321 } 14322 14323 void skipCurrentReceiverLocked(ProcessRecord app) { 14324 for (BroadcastQueue queue : mBroadcastQueues) { 14325 queue.skipCurrentReceiverLocked(app); 14326 } 14327 } 14328 14329 /** 14330 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 14331 * The application process will exit immediately after this call returns. 14332 * @param app object of the crashing app, null for the system server 14333 * @param crashInfo describing the exception 14334 */ 14335 public void handleApplicationCrash(IBinder app, 14336 ApplicationErrorReport.ParcelableCrashInfo crashInfo) { 14337 ProcessRecord r = findAppProcess(app, "Crash"); 14338 final String processName = app == null ? "system_server" 14339 : (r == null ? "unknown" : r.processName); 14340 14341 handleApplicationCrashInner("crash", r, processName, crashInfo); 14342 } 14343 14344 /* Native crash reporting uses this inner version because it needs to be somewhat 14345 * decoupled from the AM-managed cleanup lifecycle 14346 */ 14347 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 14348 ApplicationErrorReport.CrashInfo crashInfo) { 14349 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 14350 UserHandle.getUserId(Binder.getCallingUid()), processName, 14351 r == null ? -1 : r.info.flags, 14352 crashInfo.exceptionClassName, 14353 crashInfo.exceptionMessage, 14354 crashInfo.throwFileName, 14355 crashInfo.throwLineNumber); 14356 14357 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 14358 14359 mAppErrors.crashApplication(r, crashInfo); 14360 } 14361 14362 public void handleApplicationStrictModeViolation( 14363 IBinder app, 14364 int violationMask, 14365 StrictMode.ViolationInfo info) { 14366 ProcessRecord r = findAppProcess(app, "StrictMode"); 14367 if (r == null) { 14368 return; 14369 } 14370 14371 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 14372 Integer stackFingerprint = info.hashCode(); 14373 boolean logIt = true; 14374 synchronized (mAlreadyLoggedViolatedStacks) { 14375 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 14376 logIt = false; 14377 // TODO: sub-sample into EventLog for these, with 14378 // the info.durationMillis? Then we'd get 14379 // the relative pain numbers, without logging all 14380 // the stack traces repeatedly. We'd want to do 14381 // likewise in the client code, which also does 14382 // dup suppression, before the Binder call. 14383 } else { 14384 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 14385 mAlreadyLoggedViolatedStacks.clear(); 14386 } 14387 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 14388 } 14389 } 14390 if (logIt) { 14391 logStrictModeViolationToDropBox(r, info); 14392 } 14393 } 14394 14395 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 14396 AppErrorResult result = new AppErrorResult(); 14397 synchronized (this) { 14398 final long origId = Binder.clearCallingIdentity(); 14399 14400 Message msg = Message.obtain(); 14401 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG; 14402 HashMap<String, Object> data = new HashMap<String, Object>(); 14403 data.put("result", result); 14404 data.put("app", r); 14405 data.put("violationMask", violationMask); 14406 data.put("info", info); 14407 msg.obj = data; 14408 mUiHandler.sendMessage(msg); 14409 14410 Binder.restoreCallingIdentity(origId); 14411 } 14412 int res = result.get(); 14413 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 14414 } 14415 } 14416 14417 // Depending on the policy in effect, there could be a bunch of 14418 // these in quick succession so we try to batch these together to 14419 // minimize disk writes, number of dropbox entries, and maximize 14420 // compression, by having more fewer, larger records. 14421 private void logStrictModeViolationToDropBox( 14422 ProcessRecord process, 14423 StrictMode.ViolationInfo info) { 14424 if (info == null) { 14425 return; 14426 } 14427 final boolean isSystemApp = process == null || 14428 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 14429 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 14430 final String processName = process == null ? "unknown" : process.processName; 14431 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 14432 final DropBoxManager dbox = (DropBoxManager) 14433 mContext.getSystemService(Context.DROPBOX_SERVICE); 14434 14435 // Exit early if the dropbox isn't configured to accept this report type. 14436 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 14437 14438 boolean bufferWasEmpty; 14439 boolean needsFlush; 14440 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 14441 synchronized (sb) { 14442 bufferWasEmpty = sb.length() == 0; 14443 appendDropBoxProcessHeaders(process, processName, sb); 14444 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 14445 sb.append("System-App: ").append(isSystemApp).append("\n"); 14446 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 14447 if (info.violationNumThisLoop != 0) { 14448 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 14449 } 14450 if (info.numAnimationsRunning != 0) { 14451 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 14452 } 14453 if (info.broadcastIntentAction != null) { 14454 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 14455 } 14456 if (info.durationMillis != -1) { 14457 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 14458 } 14459 if (info.numInstances != -1) { 14460 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 14461 } 14462 if (info.tags != null) { 14463 for (String tag : info.tags) { 14464 sb.append("Span-Tag: ").append(tag).append("\n"); 14465 } 14466 } 14467 sb.append("\n"); 14468 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 14469 sb.append(info.crashInfo.stackTrace); 14470 sb.append("\n"); 14471 } 14472 if (info.message != null) { 14473 sb.append(info.message); 14474 sb.append("\n"); 14475 } 14476 14477 // Only buffer up to ~64k. Various logging bits truncate 14478 // things at 128k. 14479 needsFlush = (sb.length() > 64 * 1024); 14480 } 14481 14482 // Flush immediately if the buffer's grown too large, or this 14483 // is a non-system app. Non-system apps are isolated with a 14484 // different tag & policy and not batched. 14485 // 14486 // Batching is useful during internal testing with 14487 // StrictMode settings turned up high. Without batching, 14488 // thousands of separate files could be created on boot. 14489 if (!isSystemApp || needsFlush) { 14490 new Thread("Error dump: " + dropboxTag) { 14491 @Override 14492 public void run() { 14493 String report; 14494 synchronized (sb) { 14495 report = sb.toString(); 14496 sb.delete(0, sb.length()); 14497 sb.trimToSize(); 14498 } 14499 if (report.length() != 0) { 14500 dbox.addText(dropboxTag, report); 14501 } 14502 } 14503 }.start(); 14504 return; 14505 } 14506 14507 // System app batching: 14508 if (!bufferWasEmpty) { 14509 // An existing dropbox-writing thread is outstanding, so 14510 // we don't need to start it up. The existing thread will 14511 // catch the buffer appends we just did. 14512 return; 14513 } 14514 14515 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 14516 // (After this point, we shouldn't access AMS internal data structures.) 14517 new Thread("Error dump: " + dropboxTag) { 14518 @Override 14519 public void run() { 14520 // 5 second sleep to let stacks arrive and be batched together 14521 try { 14522 Thread.sleep(5000); // 5 seconds 14523 } catch (InterruptedException e) {} 14524 14525 String errorReport; 14526 synchronized (mStrictModeBuffer) { 14527 errorReport = mStrictModeBuffer.toString(); 14528 if (errorReport.length() == 0) { 14529 return; 14530 } 14531 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 14532 mStrictModeBuffer.trimToSize(); 14533 } 14534 dbox.addText(dropboxTag, errorReport); 14535 } 14536 }.start(); 14537 } 14538 14539 /** 14540 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 14541 * @param app object of the crashing app, null for the system server 14542 * @param tag reported by the caller 14543 * @param system whether this wtf is coming from the system 14544 * @param crashInfo describing the context of the error 14545 * @return true if the process should exit immediately (WTF is fatal) 14546 */ 14547 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 14548 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) { 14549 final int callingUid = Binder.getCallingUid(); 14550 final int callingPid = Binder.getCallingPid(); 14551 14552 if (system) { 14553 // If this is coming from the system, we could very well have low-level 14554 // system locks held, so we want to do this all asynchronously. And we 14555 // never want this to become fatal, so there is that too. 14556 mHandler.post(new Runnable() { 14557 @Override public void run() { 14558 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 14559 } 14560 }); 14561 return false; 14562 } 14563 14564 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 14565 crashInfo); 14566 14567 final boolean isFatal = Build.IS_ENG || Settings.Global 14568 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0; 14569 final boolean isSystem = (r == null) || r.persistent; 14570 14571 if (isFatal && !isSystem) { 14572 mAppErrors.crashApplication(r, crashInfo); 14573 return true; 14574 } else { 14575 return false; 14576 } 14577 } 14578 14579 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 14580 final ApplicationErrorReport.CrashInfo crashInfo) { 14581 final ProcessRecord r = findAppProcess(app, "WTF"); 14582 final String processName = app == null ? "system_server" 14583 : (r == null ? "unknown" : r.processName); 14584 14585 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 14586 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 14587 14588 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 14589 14590 return r; 14591 } 14592 14593 /** 14594 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 14595 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 14596 */ 14597 private ProcessRecord findAppProcess(IBinder app, String reason) { 14598 if (app == null) { 14599 return null; 14600 } 14601 14602 synchronized (this) { 14603 final int NP = mProcessNames.getMap().size(); 14604 for (int ip=0; ip<NP; ip++) { 14605 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 14606 final int NA = apps.size(); 14607 for (int ia=0; ia<NA; ia++) { 14608 ProcessRecord p = apps.valueAt(ia); 14609 if (p.thread != null && p.thread.asBinder() == app) { 14610 return p; 14611 } 14612 } 14613 } 14614 14615 Slog.w(TAG, "Can't find mystery application for " + reason 14616 + " from pid=" + Binder.getCallingPid() 14617 + " uid=" + Binder.getCallingUid() + ": " + app); 14618 return null; 14619 } 14620 } 14621 14622 /** 14623 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 14624 * to append various headers to the dropbox log text. 14625 */ 14626 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 14627 StringBuilder sb) { 14628 // Watchdog thread ends up invoking this function (with 14629 // a null ProcessRecord) to add the stack file to dropbox. 14630 // Do not acquire a lock on this (am) in such cases, as it 14631 // could cause a potential deadlock, if and when watchdog 14632 // is invoked due to unavailability of lock on am and it 14633 // would prevent watchdog from killing system_server. 14634 if (process == null) { 14635 sb.append("Process: ").append(processName).append("\n"); 14636 return; 14637 } 14638 // Note: ProcessRecord 'process' is guarded by the service 14639 // instance. (notably process.pkgList, which could otherwise change 14640 // concurrently during execution of this method) 14641 synchronized (this) { 14642 sb.append("Process: ").append(processName).append("\n"); 14643 sb.append("PID: ").append(process.pid).append("\n"); 14644 int flags = process.info.flags; 14645 IPackageManager pm = AppGlobals.getPackageManager(); 14646 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n"); 14647 for (int ip=0; ip<process.pkgList.size(); ip++) { 14648 String pkg = process.pkgList.keyAt(ip); 14649 sb.append("Package: ").append(pkg); 14650 try { 14651 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 14652 if (pi != null) { 14653 sb.append(" v").append(pi.versionCode); 14654 if (pi.versionName != null) { 14655 sb.append(" (").append(pi.versionName).append(")"); 14656 } 14657 } 14658 } catch (RemoteException e) { 14659 Slog.e(TAG, "Error getting package info: " + pkg, e); 14660 } 14661 sb.append("\n"); 14662 } 14663 } 14664 } 14665 14666 private static String processClass(ProcessRecord process) { 14667 if (process == null || process.pid == MY_PID) { 14668 return "system_server"; 14669 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 14670 return "system_app"; 14671 } else { 14672 return "data_app"; 14673 } 14674 } 14675 14676 private volatile long mWtfClusterStart; 14677 private volatile int mWtfClusterCount; 14678 14679 /** 14680 * Write a description of an error (crash, WTF, ANR) to the drop box. 14681 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 14682 * @param process which caused the error, null means the system server 14683 * @param activity which triggered the error, null if unknown 14684 * @param parent activity related to the error, null if unknown 14685 * @param subject line related to the error, null if absent 14686 * @param report in long form describing the error, null if absent 14687 * @param dataFile text file to include in the report, null if none 14688 * @param crashInfo giving an application stack trace, null if absent 14689 */ 14690 public void addErrorToDropBox(String eventType, 14691 ProcessRecord process, String processName, ActivityRecord activity, 14692 ActivityRecord parent, String subject, 14693 final String report, final File dataFile, 14694 final ApplicationErrorReport.CrashInfo crashInfo) { 14695 // NOTE -- this must never acquire the ActivityManagerService lock, 14696 // otherwise the watchdog may be prevented from resetting the system. 14697 14698 // Bail early if not published yet 14699 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return; 14700 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class); 14701 14702 // Exit early if the dropbox isn't configured to accept this report type. 14703 final String dropboxTag = processClass(process) + "_" + eventType; 14704 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 14705 14706 // Rate-limit how often we're willing to do the heavy lifting below to 14707 // collect and record logs; currently 5 logs per 10 second period. 14708 final long now = SystemClock.elapsedRealtime(); 14709 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) { 14710 mWtfClusterStart = now; 14711 mWtfClusterCount = 1; 14712 } else { 14713 if (mWtfClusterCount++ >= 5) return; 14714 } 14715 14716 final StringBuilder sb = new StringBuilder(1024); 14717 appendDropBoxProcessHeaders(process, processName, sb); 14718 if (process != null) { 14719 sb.append("Foreground: ") 14720 .append(process.isInterestingToUserLocked() ? "Yes" : "No") 14721 .append("\n"); 14722 } 14723 if (activity != null) { 14724 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 14725 } 14726 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 14727 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 14728 } 14729 if (parent != null && parent != activity) { 14730 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 14731 } 14732 if (subject != null) { 14733 sb.append("Subject: ").append(subject).append("\n"); 14734 } 14735 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 14736 if (Debug.isDebuggerConnected()) { 14737 sb.append("Debugger: Connected\n"); 14738 } 14739 sb.append("\n"); 14740 14741 // Do the rest in a worker thread to avoid blocking the caller on I/O 14742 // (After this point, we shouldn't access AMS internal data structures.) 14743 Thread worker = new Thread("Error dump: " + dropboxTag) { 14744 @Override 14745 public void run() { 14746 if (report != null) { 14747 sb.append(report); 14748 } 14749 14750 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 14751 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 14752 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length() 14753 - lines * RESERVED_BYTES_PER_LOGCAT_LINE; 14754 14755 if (dataFile != null && maxDataFileSize > 0) { 14756 try { 14757 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize, 14758 "\n\n[[TRUNCATED]]")); 14759 } catch (IOException e) { 14760 Slog.e(TAG, "Error reading " + dataFile, e); 14761 } 14762 } 14763 if (crashInfo != null && crashInfo.stackTrace != null) { 14764 sb.append(crashInfo.stackTrace); 14765 } 14766 14767 if (lines > 0) { 14768 sb.append("\n"); 14769 14770 // Merge several logcat streams, and take the last N lines 14771 InputStreamReader input = null; 14772 try { 14773 java.lang.Process logcat = new ProcessBuilder( 14774 "/system/bin/timeout", "-k", "15s", "10s", 14775 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system", 14776 "-b", "main", "-b", "crash", "-t", String.valueOf(lines)) 14777 .redirectErrorStream(true).start(); 14778 14779 try { logcat.getOutputStream().close(); } catch (IOException e) {} 14780 try { logcat.getErrorStream().close(); } catch (IOException e) {} 14781 input = new InputStreamReader(logcat.getInputStream()); 14782 14783 int num; 14784 char[] buf = new char[8192]; 14785 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 14786 } catch (IOException e) { 14787 Slog.e(TAG, "Error running logcat", e); 14788 } finally { 14789 if (input != null) try { input.close(); } catch (IOException e) {} 14790 } 14791 } 14792 14793 dbox.addText(dropboxTag, sb.toString()); 14794 } 14795 }; 14796 14797 if (process == null) { 14798 // If process is null, we are being called from some internal code 14799 // and may be about to die -- run this synchronously. 14800 worker.run(); 14801 } else { 14802 worker.start(); 14803 } 14804 } 14805 14806 @Override 14807 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 14808 enforceNotIsolatedCaller("getProcessesInErrorState"); 14809 // assume our apps are happy - lazy create the list 14810 List<ActivityManager.ProcessErrorStateInfo> errList = null; 14811 14812 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 14813 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 14814 int userId = UserHandle.getUserId(Binder.getCallingUid()); 14815 14816 synchronized (this) { 14817 14818 // iterate across all processes 14819 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14820 ProcessRecord app = mLruProcesses.get(i); 14821 if (!allUsers && app.userId != userId) { 14822 continue; 14823 } 14824 if ((app.thread != null) && (app.crashing || app.notResponding)) { 14825 // This one's in trouble, so we'll generate a report for it 14826 // crashes are higher priority (in case there's a crash *and* an anr) 14827 ActivityManager.ProcessErrorStateInfo report = null; 14828 if (app.crashing) { 14829 report = app.crashingReport; 14830 } else if (app.notResponding) { 14831 report = app.notRespondingReport; 14832 } 14833 14834 if (report != null) { 14835 if (errList == null) { 14836 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 14837 } 14838 errList.add(report); 14839 } else { 14840 Slog.w(TAG, "Missing app error report, app = " + app.processName + 14841 " crashing = " + app.crashing + 14842 " notResponding = " + app.notResponding); 14843 } 14844 } 14845 } 14846 } 14847 14848 return errList; 14849 } 14850 14851 static int procStateToImportance(int procState, int memAdj, 14852 ActivityManager.RunningAppProcessInfo currApp, 14853 int clientTargetSdk) { 14854 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk( 14855 procState, clientTargetSdk); 14856 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 14857 currApp.lru = memAdj; 14858 } else { 14859 currApp.lru = 0; 14860 } 14861 return imp; 14862 } 14863 14864 private void fillInProcMemInfo(ProcessRecord app, 14865 ActivityManager.RunningAppProcessInfo outInfo, 14866 int clientTargetSdk) { 14867 outInfo.pid = app.pid; 14868 outInfo.uid = app.info.uid; 14869 if (mHeavyWeightProcess == app) { 14870 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 14871 } 14872 if (app.persistent) { 14873 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 14874 } 14875 if (app.activities.size() > 0) { 14876 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 14877 } 14878 outInfo.lastTrimLevel = app.trimMemoryLevel; 14879 int adj = app.curAdj; 14880 int procState = app.curProcState; 14881 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk); 14882 outInfo.importanceReasonCode = app.adjTypeCode; 14883 outInfo.processState = app.curProcState; 14884 } 14885 14886 @Override 14887 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 14888 enforceNotIsolatedCaller("getRunningAppProcesses"); 14889 14890 final int callingUid = Binder.getCallingUid(); 14891 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid); 14892 14893 // Lazy instantiation of list 14894 List<ActivityManager.RunningAppProcessInfo> runList = null; 14895 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 14896 callingUid) == PackageManager.PERMISSION_GRANTED; 14897 final int userId = UserHandle.getUserId(callingUid); 14898 final boolean allUids = isGetTasksAllowed( 14899 "getRunningAppProcesses", Binder.getCallingPid(), callingUid); 14900 14901 synchronized (this) { 14902 // Iterate across all processes 14903 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14904 ProcessRecord app = mLruProcesses.get(i); 14905 if ((!allUsers && app.userId != userId) 14906 || (!allUids && app.uid != callingUid)) { 14907 continue; 14908 } 14909 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 14910 // Generate process state info for running application 14911 ActivityManager.RunningAppProcessInfo currApp = 14912 new ActivityManager.RunningAppProcessInfo(app.processName, 14913 app.pid, app.getPackageList()); 14914 fillInProcMemInfo(app, currApp, clientTargetSdk); 14915 if (app.adjSource instanceof ProcessRecord) { 14916 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 14917 currApp.importanceReasonImportance = 14918 ActivityManager.RunningAppProcessInfo.procStateToImportance( 14919 app.adjSourceProcState); 14920 } else if (app.adjSource instanceof ActivityRecord) { 14921 ActivityRecord r = (ActivityRecord)app.adjSource; 14922 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 14923 } 14924 if (app.adjTarget instanceof ComponentName) { 14925 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 14926 } 14927 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 14928 // + " lru=" + currApp.lru); 14929 if (runList == null) { 14930 runList = new ArrayList<>(); 14931 } 14932 runList.add(currApp); 14933 } 14934 } 14935 } 14936 return runList; 14937 } 14938 14939 @Override 14940 public List<ApplicationInfo> getRunningExternalApplications() { 14941 enforceNotIsolatedCaller("getRunningExternalApplications"); 14942 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 14943 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 14944 if (runningApps != null && runningApps.size() > 0) { 14945 Set<String> extList = new HashSet<String>(); 14946 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 14947 if (app.pkgList != null) { 14948 for (String pkg : app.pkgList) { 14949 extList.add(pkg); 14950 } 14951 } 14952 } 14953 IPackageManager pm = AppGlobals.getPackageManager(); 14954 for (String pkg : extList) { 14955 try { 14956 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 14957 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 14958 retList.add(info); 14959 } 14960 } catch (RemoteException e) { 14961 } 14962 } 14963 } 14964 return retList; 14965 } 14966 14967 @Override 14968 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 14969 enforceNotIsolatedCaller("getMyMemoryState"); 14970 14971 final int callingUid = Binder.getCallingUid(); 14972 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid); 14973 14974 synchronized (this) { 14975 ProcessRecord proc; 14976 synchronized (mPidsSelfLocked) { 14977 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 14978 } 14979 fillInProcMemInfo(proc, outInfo, clientTargetSdk); 14980 } 14981 } 14982 14983 @Override 14984 public int getMemoryTrimLevel() { 14985 enforceNotIsolatedCaller("getMyMemoryState"); 14986 synchronized (this) { 14987 return mLastMemoryLevel; 14988 } 14989 } 14990 14991 @Override 14992 public void onShellCommand(FileDescriptor in, FileDescriptor out, 14993 FileDescriptor err, String[] args, ShellCallback callback, 14994 ResultReceiver resultReceiver) { 14995 (new ActivityManagerShellCommand(this, false)).exec( 14996 this, in, out, err, args, callback, resultReceiver); 14997 } 14998 14999 SleepToken acquireSleepToken(String tag, int displayId) { 15000 synchronized (this) { 15001 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId); 15002 updateSleepIfNeededLocked(); 15003 return token; 15004 } 15005 } 15006 15007 @Override 15008 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 15009 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; 15010 15011 boolean dumpAll = false; 15012 boolean dumpClient = false; 15013 boolean dumpCheckin = false; 15014 boolean dumpCheckinFormat = false; 15015 boolean dumpVisibleStacksOnly = false; 15016 boolean dumpFocusedStackOnly = false; 15017 String dumpPackage = null; 15018 15019 int opti = 0; 15020 while (opti < args.length) { 15021 String opt = args[opti]; 15022 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 15023 break; 15024 } 15025 opti++; 15026 if ("-a".equals(opt)) { 15027 dumpAll = true; 15028 } else if ("-c".equals(opt)) { 15029 dumpClient = true; 15030 } else if ("-v".equals(opt)) { 15031 dumpVisibleStacksOnly = true; 15032 } else if ("-f".equals(opt)) { 15033 dumpFocusedStackOnly = true; 15034 } else if ("-p".equals(opt)) { 15035 if (opti < args.length) { 15036 dumpPackage = args[opti]; 15037 opti++; 15038 } else { 15039 pw.println("Error: -p option requires package argument"); 15040 return; 15041 } 15042 dumpClient = true; 15043 } else if ("--checkin".equals(opt)) { 15044 dumpCheckin = dumpCheckinFormat = true; 15045 } else if ("-C".equals(opt)) { 15046 dumpCheckinFormat = true; 15047 } else if ("-h".equals(opt)) { 15048 ActivityManagerShellCommand.dumpHelp(pw, true); 15049 return; 15050 } else { 15051 pw.println("Unknown argument: " + opt + "; use -h for help"); 15052 } 15053 } 15054 15055 long origId = Binder.clearCallingIdentity(); 15056 boolean more = false; 15057 // Is the caller requesting to dump a particular piece of data? 15058 if (opti < args.length) { 15059 String cmd = args[opti]; 15060 opti++; 15061 if ("activities".equals(cmd) || "a".equals(cmd)) { 15062 synchronized (this) { 15063 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 15064 } 15065 } else if ("lastanr".equals(cmd)) { 15066 synchronized (this) { 15067 dumpLastANRLocked(pw); 15068 } 15069 } else if ("starter".equals(cmd)) { 15070 synchronized (this) { 15071 dumpActivityStarterLocked(pw, dumpPackage); 15072 } 15073 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 15074 synchronized (this) { 15075 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 15076 } 15077 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 15078 String[] newArgs; 15079 String name; 15080 if (opti >= args.length) { 15081 name = null; 15082 newArgs = EMPTY_STRING_ARRAY; 15083 } else { 15084 dumpPackage = args[opti]; 15085 opti++; 15086 newArgs = new String[args.length - opti]; 15087 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15088 args.length - opti); 15089 } 15090 synchronized (this) { 15091 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 15092 } 15093 } else if ("broadcast-stats".equals(cmd)) { 15094 String[] newArgs; 15095 String name; 15096 if (opti >= args.length) { 15097 name = null; 15098 newArgs = EMPTY_STRING_ARRAY; 15099 } else { 15100 dumpPackage = args[opti]; 15101 opti++; 15102 newArgs = new String[args.length - opti]; 15103 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15104 args.length - opti); 15105 } 15106 synchronized (this) { 15107 if (dumpCheckinFormat) { 15108 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, 15109 dumpPackage); 15110 } else { 15111 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage); 15112 } 15113 } 15114 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 15115 String[] newArgs; 15116 String name; 15117 if (opti >= args.length) { 15118 name = null; 15119 newArgs = EMPTY_STRING_ARRAY; 15120 } else { 15121 dumpPackage = args[opti]; 15122 opti++; 15123 newArgs = new String[args.length - opti]; 15124 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15125 args.length - opti); 15126 } 15127 synchronized (this) { 15128 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 15129 } 15130 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 15131 String[] newArgs; 15132 String name; 15133 if (opti >= args.length) { 15134 name = null; 15135 newArgs = EMPTY_STRING_ARRAY; 15136 } else { 15137 dumpPackage = args[opti]; 15138 opti++; 15139 newArgs = new String[args.length - opti]; 15140 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15141 args.length - opti); 15142 } 15143 synchronized (this) { 15144 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 15145 } 15146 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 15147 synchronized (this) { 15148 dumpOomLocked(fd, pw, args, opti, true); 15149 } 15150 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) { 15151 synchronized (this) { 15152 dumpPermissionsLocked(fd, pw, args, opti, true, null); 15153 } 15154 } else if ("provider".equals(cmd)) { 15155 String[] newArgs; 15156 String name; 15157 if (opti >= args.length) { 15158 name = null; 15159 newArgs = EMPTY_STRING_ARRAY; 15160 } else { 15161 name = args[opti]; 15162 opti++; 15163 newArgs = new String[args.length - opti]; 15164 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 15165 } 15166 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 15167 pw.println("No providers match: " + name); 15168 pw.println("Use -h for help."); 15169 } 15170 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 15171 synchronized (this) { 15172 dumpProvidersLocked(fd, pw, args, opti, true, null); 15173 } 15174 } else if ("service".equals(cmd)) { 15175 String[] newArgs; 15176 String name; 15177 if (opti >= args.length) { 15178 name = null; 15179 newArgs = EMPTY_STRING_ARRAY; 15180 } else { 15181 name = args[opti]; 15182 opti++; 15183 newArgs = new String[args.length - opti]; 15184 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15185 args.length - opti); 15186 } 15187 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 15188 pw.println("No services match: " + name); 15189 pw.println("Use -h for help."); 15190 } 15191 } else if ("package".equals(cmd)) { 15192 String[] newArgs; 15193 if (opti >= args.length) { 15194 pw.println("package: no package name specified"); 15195 pw.println("Use -h for help."); 15196 } else { 15197 dumpPackage = args[opti]; 15198 opti++; 15199 newArgs = new String[args.length - opti]; 15200 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15201 args.length - opti); 15202 args = newArgs; 15203 opti = 0; 15204 more = true; 15205 } 15206 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 15207 synchronized (this) { 15208 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 15209 } 15210 } else if ("settings".equals(cmd)) { 15211 synchronized (this) { 15212 mConstants.dump(pw); 15213 } 15214 } else if ("services".equals(cmd) || "s".equals(cmd)) { 15215 if (dumpClient) { 15216 ActiveServices.ServiceDumper dumper; 15217 synchronized (this) { 15218 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true, 15219 dumpPackage); 15220 } 15221 dumper.dumpWithClient(); 15222 } else { 15223 synchronized (this) { 15224 mServices.newServiceDumperLocked(fd, pw, args, opti, true, 15225 dumpPackage).dumpLocked(); 15226 } 15227 } 15228 } else if ("locks".equals(cmd)) { 15229 LockGuard.dump(fd, pw, args); 15230 } else { 15231 // Dumping a single activity? 15232 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly, 15233 dumpFocusedStackOnly)) { 15234 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true); 15235 int res = shell.exec(this, null, fd, null, args, null, 15236 new ResultReceiver(null)); 15237 if (res < 0) { 15238 pw.println("Bad activity command, or no activities match: " + cmd); 15239 pw.println("Use -h for help."); 15240 } 15241 } 15242 } 15243 if (!more) { 15244 Binder.restoreCallingIdentity(origId); 15245 return; 15246 } 15247 } 15248 15249 // No piece of data specified, dump everything. 15250 if (dumpCheckinFormat) { 15251 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage); 15252 } else if (dumpClient) { 15253 ActiveServices.ServiceDumper sdumper; 15254 synchronized (this) { 15255 mConstants.dump(pw); 15256 pw.println(); 15257 if (dumpAll) { 15258 pw.println("-------------------------------------------------------------------------------"); 15259 } 15260 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15261 pw.println(); 15262 if (dumpAll) { 15263 pw.println("-------------------------------------------------------------------------------"); 15264 } 15265 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15266 pw.println(); 15267 if (dumpAll) { 15268 pw.println("-------------------------------------------------------------------------------"); 15269 } 15270 if (dumpAll || dumpPackage != null) { 15271 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15272 pw.println(); 15273 if (dumpAll) { 15274 pw.println("-------------------------------------------------------------------------------"); 15275 } 15276 } 15277 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15278 pw.println(); 15279 if (dumpAll) { 15280 pw.println("-------------------------------------------------------------------------------"); 15281 } 15282 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15283 pw.println(); 15284 if (dumpAll) { 15285 pw.println("-------------------------------------------------------------------------------"); 15286 } 15287 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, 15288 dumpPackage); 15289 } 15290 sdumper.dumpWithClient(); 15291 pw.println(); 15292 synchronized (this) { 15293 if (dumpAll) { 15294 pw.println("-------------------------------------------------------------------------------"); 15295 } 15296 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15297 pw.println(); 15298 if (dumpAll) { 15299 pw.println("-------------------------------------------------------------------------------"); 15300 } 15301 dumpLastANRLocked(pw); 15302 pw.println(); 15303 if (dumpAll) { 15304 pw.println("-------------------------------------------------------------------------------"); 15305 } 15306 dumpActivityStarterLocked(pw, dumpPackage); 15307 pw.println(); 15308 if (dumpAll) { 15309 pw.println("-------------------------------------------------------------------------------"); 15310 } 15311 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 15312 if (mAssociations.size() > 0) { 15313 pw.println(); 15314 if (dumpAll) { 15315 pw.println("-------------------------------------------------------------------------------"); 15316 } 15317 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 15318 } 15319 pw.println(); 15320 if (dumpAll) { 15321 pw.println("-------------------------------------------------------------------------------"); 15322 } 15323 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15324 } 15325 15326 } else { 15327 synchronized (this) { 15328 mConstants.dump(pw); 15329 pw.println(); 15330 if (dumpAll) { 15331 pw.println("-------------------------------------------------------------------------------"); 15332 } 15333 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15334 pw.println(); 15335 if (dumpAll) { 15336 pw.println("-------------------------------------------------------------------------------"); 15337 } 15338 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15339 pw.println(); 15340 if (dumpAll) { 15341 pw.println("-------------------------------------------------------------------------------"); 15342 } 15343 if (dumpAll || dumpPackage != null) { 15344 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15345 pw.println(); 15346 if (dumpAll) { 15347 pw.println("-------------------------------------------------------------------------------"); 15348 } 15349 } 15350 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15351 pw.println(); 15352 if (dumpAll) { 15353 pw.println("-------------------------------------------------------------------------------"); 15354 } 15355 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15356 pw.println(); 15357 if (dumpAll) { 15358 pw.println("-------------------------------------------------------------------------------"); 15359 } 15360 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage) 15361 .dumpLocked(); 15362 pw.println(); 15363 if (dumpAll) { 15364 pw.println("-------------------------------------------------------------------------------"); 15365 } 15366 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15367 pw.println(); 15368 if (dumpAll) { 15369 pw.println("-------------------------------------------------------------------------------"); 15370 } 15371 dumpLastANRLocked(pw); 15372 pw.println(); 15373 if (dumpAll) { 15374 pw.println("-------------------------------------------------------------------------------"); 15375 } 15376 dumpActivityStarterLocked(pw, dumpPackage); 15377 pw.println(); 15378 if (dumpAll) { 15379 pw.println("-------------------------------------------------------------------------------"); 15380 } 15381 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 15382 if (mAssociations.size() > 0) { 15383 pw.println(); 15384 if (dumpAll) { 15385 pw.println("-------------------------------------------------------------------------------"); 15386 } 15387 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 15388 } 15389 pw.println(); 15390 if (dumpAll) { 15391 pw.println("-------------------------------------------------------------------------------"); 15392 } 15393 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15394 } 15395 } 15396 Binder.restoreCallingIdentity(origId); 15397 } 15398 15399 private void dumpLastANRLocked(PrintWriter pw) { 15400 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)"); 15401 if (mLastANRState == null) { 15402 pw.println(" <no ANR has occurred since boot>"); 15403 } else { 15404 pw.println(mLastANRState); 15405 } 15406 } 15407 15408 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) { 15409 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)"); 15410 mActivityStarter.dump(pw, "", dumpPackage); 15411 } 15412 15413 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15414 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 15415 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage, 15416 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 15417 } 15418 15419 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15420 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) { 15421 pw.println(header); 15422 15423 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 15424 dumpPackage); 15425 boolean needSep = printedAnything; 15426 15427 boolean printed = ActivityStackSupervisor.printThisActivity(pw, 15428 mStackSupervisor.getResumedActivityLocked(), 15429 dumpPackage, needSep, " ResumedActivity: "); 15430 if (printed) { 15431 printedAnything = true; 15432 needSep = false; 15433 } 15434 15435 if (dumpPackage == null) { 15436 if (needSep) { 15437 pw.println(); 15438 } 15439 printedAnything = true; 15440 mStackSupervisor.dump(pw, " "); 15441 } 15442 15443 if (!printedAnything) { 15444 pw.println(" (nothing)"); 15445 } 15446 } 15447 15448 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15449 int opti, boolean dumpAll, String dumpPackage) { 15450 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 15451 15452 boolean printedAnything = false; 15453 15454 if (mRecentTasks != null && mRecentTasks.size() > 0) { 15455 boolean printedHeader = false; 15456 15457 final int N = mRecentTasks.size(); 15458 for (int i=0; i<N; i++) { 15459 TaskRecord tr = mRecentTasks.get(i); 15460 if (dumpPackage != null) { 15461 if (tr.realActivity == null || 15462 !dumpPackage.equals(tr.realActivity.getPackageName())) { 15463 continue; 15464 } 15465 } 15466 if (!printedHeader) { 15467 pw.println(" Recent tasks:"); 15468 printedHeader = true; 15469 printedAnything = true; 15470 } 15471 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 15472 pw.println(tr); 15473 if (dumpAll) { 15474 mRecentTasks.get(i).dump(pw, " "); 15475 } 15476 } 15477 } 15478 15479 if (!printedAnything) { 15480 pw.println(" (nothing)"); 15481 } 15482 } 15483 15484 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15485 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 15486 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 15487 15488 int dumpUid = 0; 15489 if (dumpPackage != null) { 15490 IPackageManager pm = AppGlobals.getPackageManager(); 15491 try { 15492 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0); 15493 } catch (RemoteException e) { 15494 } 15495 } 15496 15497 boolean printedAnything = false; 15498 15499 final long now = SystemClock.uptimeMillis(); 15500 15501 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 15502 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 15503 = mAssociations.valueAt(i1); 15504 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 15505 SparseArray<ArrayMap<String, Association>> sourceUids 15506 = targetComponents.valueAt(i2); 15507 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 15508 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 15509 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 15510 Association ass = sourceProcesses.valueAt(i4); 15511 if (dumpPackage != null) { 15512 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 15513 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 15514 continue; 15515 } 15516 } 15517 printedAnything = true; 15518 pw.print(" "); 15519 pw.print(ass.mTargetProcess); 15520 pw.print("/"); 15521 UserHandle.formatUid(pw, ass.mTargetUid); 15522 pw.print(" <- "); 15523 pw.print(ass.mSourceProcess); 15524 pw.print("/"); 15525 UserHandle.formatUid(pw, ass.mSourceUid); 15526 pw.println(); 15527 pw.print(" via "); 15528 pw.print(ass.mTargetComponent.flattenToShortString()); 15529 pw.println(); 15530 pw.print(" "); 15531 long dur = ass.mTime; 15532 if (ass.mNesting > 0) { 15533 dur += now - ass.mStartTime; 15534 } 15535 TimeUtils.formatDuration(dur, pw); 15536 pw.print(" ("); 15537 pw.print(ass.mCount); 15538 pw.print(" times)"); 15539 pw.print(" "); 15540 for (int i=0; i<ass.mStateTimes.length; i++) { 15541 long amt = ass.mStateTimes[i]; 15542 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) { 15543 amt += now - ass.mLastStateUptime; 15544 } 15545 if (amt != 0) { 15546 pw.print(" "); 15547 pw.print(ProcessList.makeProcStateString( 15548 i + ActivityManager.MIN_PROCESS_STATE)); 15549 pw.print("="); 15550 TimeUtils.formatDuration(amt, pw); 15551 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) { 15552 pw.print("*"); 15553 } 15554 } 15555 } 15556 pw.println(); 15557 if (ass.mNesting > 0) { 15558 pw.print(" Currently active: "); 15559 TimeUtils.formatDuration(now - ass.mStartTime, pw); 15560 pw.println(); 15561 } 15562 } 15563 } 15564 } 15565 15566 } 15567 15568 if (!printedAnything) { 15569 pw.println(" (nothing)"); 15570 } 15571 } 15572 15573 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids, 15574 String header, boolean needSep) { 15575 boolean printed = false; 15576 int whichAppId = -1; 15577 if (dumpPackage != null) { 15578 try { 15579 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 15580 dumpPackage, 0); 15581 whichAppId = UserHandle.getAppId(info.uid); 15582 } catch (NameNotFoundException e) { 15583 e.printStackTrace(); 15584 } 15585 } 15586 for (int i=0; i<uids.size(); i++) { 15587 UidRecord uidRec = uids.valueAt(i); 15588 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) { 15589 continue; 15590 } 15591 if (!printed) { 15592 printed = true; 15593 if (needSep) { 15594 pw.println(); 15595 } 15596 pw.print(" "); 15597 pw.println(header); 15598 needSep = true; 15599 } 15600 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid); 15601 pw.print(": "); pw.println(uidRec); 15602 } 15603 return printed; 15604 } 15605 15606 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15607 int opti, boolean dumpAll, String dumpPackage) { 15608 boolean needSep = false; 15609 boolean printedAnything = false; 15610 int numPers = 0; 15611 15612 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 15613 15614 if (dumpAll) { 15615 final int NP = mProcessNames.getMap().size(); 15616 for (int ip=0; ip<NP; ip++) { 15617 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 15618 final int NA = procs.size(); 15619 for (int ia=0; ia<NA; ia++) { 15620 ProcessRecord r = procs.valueAt(ia); 15621 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 15622 continue; 15623 } 15624 if (!needSep) { 15625 pw.println(" All known processes:"); 15626 needSep = true; 15627 printedAnything = true; 15628 } 15629 pw.print(r.persistent ? " *PERS*" : " *APP*"); 15630 pw.print(" UID "); pw.print(procs.keyAt(ia)); 15631 pw.print(" "); pw.println(r); 15632 r.dump(pw, " "); 15633 if (r.persistent) { 15634 numPers++; 15635 } 15636 } 15637 } 15638 } 15639 15640 if (mIsolatedProcesses.size() > 0) { 15641 boolean printed = false; 15642 for (int i=0; i<mIsolatedProcesses.size(); i++) { 15643 ProcessRecord r = mIsolatedProcesses.valueAt(i); 15644 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 15645 continue; 15646 } 15647 if (!printed) { 15648 if (needSep) { 15649 pw.println(); 15650 } 15651 pw.println(" Isolated process list (sorted by uid):"); 15652 printedAnything = true; 15653 printed = true; 15654 needSep = true; 15655 } 15656 pw.print(" Isolated #"); pw.print(i); pw.print(": "); 15657 pw.println(r); 15658 } 15659 } 15660 15661 if (mActiveInstrumentation.size() > 0) { 15662 boolean printed = false; 15663 for (int i=0; i<mActiveInstrumentation.size(); i++) { 15664 ActiveInstrumentation ai = mActiveInstrumentation.get(i); 15665 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage) 15666 && !ai.mTargetInfo.packageName.equals(dumpPackage)) { 15667 continue; 15668 } 15669 if (!printed) { 15670 if (needSep) { 15671 pw.println(); 15672 } 15673 pw.println(" Active instrumentation:"); 15674 printedAnything = true; 15675 printed = true; 15676 needSep = true; 15677 } 15678 pw.print(" Instrumentation #"); pw.print(i); pw.print(": "); 15679 pw.println(ai); 15680 ai.dump(pw, " "); 15681 } 15682 } 15683 15684 if (mActiveUids.size() > 0) { 15685 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) { 15686 printedAnything = needSep = true; 15687 } 15688 } 15689 if (dumpAll) { 15690 if (mValidateUids.size() > 0) { 15691 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) { 15692 printedAnything = needSep = true; 15693 } 15694 } 15695 } 15696 15697 if (mLruProcesses.size() > 0) { 15698 if (needSep) { 15699 pw.println(); 15700 } 15701 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 15702 pw.print(" total, non-act at "); 15703 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 15704 pw.print(", non-svc at "); 15705 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 15706 pw.println("):"); 15707 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 15708 needSep = true; 15709 printedAnything = true; 15710 } 15711 15712 if (dumpAll || dumpPackage != null) { 15713 synchronized (mPidsSelfLocked) { 15714 boolean printed = false; 15715 for (int i=0; i<mPidsSelfLocked.size(); i++) { 15716 ProcessRecord r = mPidsSelfLocked.valueAt(i); 15717 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 15718 continue; 15719 } 15720 if (!printed) { 15721 if (needSep) pw.println(); 15722 needSep = true; 15723 pw.println(" PID mappings:"); 15724 printed = true; 15725 printedAnything = true; 15726 } 15727 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 15728 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 15729 } 15730 } 15731 } 15732 15733 if (mImportantProcesses.size() > 0) { 15734 synchronized (mPidsSelfLocked) { 15735 boolean printed = false; 15736 for (int i = 0; i< mImportantProcesses.size(); i++) { 15737 ProcessRecord r = mPidsSelfLocked.get( 15738 mImportantProcesses.valueAt(i).pid); 15739 if (dumpPackage != null && (r == null 15740 || !r.pkgList.containsKey(dumpPackage))) { 15741 continue; 15742 } 15743 if (!printed) { 15744 if (needSep) pw.println(); 15745 needSep = true; 15746 pw.println(" Foreground Processes:"); 15747 printed = true; 15748 printedAnything = true; 15749 } 15750 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i)); 15751 pw.print(": "); pw.println(mImportantProcesses.valueAt(i)); 15752 } 15753 } 15754 } 15755 15756 if (mPersistentStartingProcesses.size() > 0) { 15757 if (needSep) pw.println(); 15758 needSep = true; 15759 printedAnything = true; 15760 pw.println(" Persisent processes that are starting:"); 15761 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 15762 "Starting Norm", "Restarting PERS", dumpPackage); 15763 } 15764 15765 if (mRemovedProcesses.size() > 0) { 15766 if (needSep) pw.println(); 15767 needSep = true; 15768 printedAnything = true; 15769 pw.println(" Processes that are being removed:"); 15770 dumpProcessList(pw, this, mRemovedProcesses, " ", 15771 "Removed Norm", "Removed PERS", dumpPackage); 15772 } 15773 15774 if (mProcessesOnHold.size() > 0) { 15775 if (needSep) pw.println(); 15776 needSep = true; 15777 printedAnything = true; 15778 pw.println(" Processes that are on old until the system is ready:"); 15779 dumpProcessList(pw, this, mProcessesOnHold, " ", 15780 "OnHold Norm", "OnHold PERS", dumpPackage); 15781 } 15782 15783 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 15784 15785 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage); 15786 if (needSep) { 15787 printedAnything = true; 15788 } 15789 15790 if (dumpPackage == null) { 15791 pw.println(); 15792 needSep = false; 15793 mUserController.dump(pw, dumpAll); 15794 } 15795 if (mHomeProcess != null && (dumpPackage == null 15796 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 15797 if (needSep) { 15798 pw.println(); 15799 needSep = false; 15800 } 15801 pw.println(" mHomeProcess: " + mHomeProcess); 15802 } 15803 if (mPreviousProcess != null && (dumpPackage == null 15804 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 15805 if (needSep) { 15806 pw.println(); 15807 needSep = false; 15808 } 15809 pw.println(" mPreviousProcess: " + mPreviousProcess); 15810 } 15811 if (dumpAll) { 15812 StringBuilder sb = new StringBuilder(128); 15813 sb.append(" mPreviousProcessVisibleTime: "); 15814 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 15815 pw.println(sb); 15816 } 15817 if (mHeavyWeightProcess != null && (dumpPackage == null 15818 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 15819 if (needSep) { 15820 pw.println(); 15821 needSep = false; 15822 } 15823 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 15824 } 15825 if (dumpPackage == null) { 15826 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration()); 15827 mStackSupervisor.dumpDisplayConfigs(pw, " "); 15828 } 15829 if (dumpAll) { 15830 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 15831 if (mCompatModePackages.getPackages().size() > 0) { 15832 boolean printed = false; 15833 for (Map.Entry<String, Integer> entry 15834 : mCompatModePackages.getPackages().entrySet()) { 15835 String pkg = entry.getKey(); 15836 int mode = entry.getValue(); 15837 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 15838 continue; 15839 } 15840 if (!printed) { 15841 pw.println(" mScreenCompatPackages:"); 15842 printed = true; 15843 } 15844 pw.print(" "); pw.print(pkg); pw.print(": "); 15845 pw.print(mode); pw.println(); 15846 } 15847 } 15848 final int NI = mUidObservers.getRegisteredCallbackCount(); 15849 boolean printed = false; 15850 for (int i=0; i<NI; i++) { 15851 final UidObserverRegistration reg = (UidObserverRegistration) 15852 mUidObservers.getRegisteredCallbackCookie(i); 15853 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) { 15854 if (!printed) { 15855 pw.println(" mUidObservers:"); 15856 printed = true; 15857 } 15858 pw.print(" "); UserHandle.formatUid(pw, reg.uid); 15859 pw.print(" "); pw.print(reg.pkg); pw.print(":"); 15860 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) { 15861 pw.print(" IDLE"); 15862 } 15863 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) { 15864 pw.print(" ACT" ); 15865 } 15866 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) { 15867 pw.print(" GONE"); 15868 } 15869 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { 15870 pw.print(" STATE"); 15871 pw.print(" (cut="); pw.print(reg.cutpoint); 15872 pw.print(")"); 15873 } 15874 pw.println(); 15875 if (reg.lastProcStates != null) { 15876 final int NJ = reg.lastProcStates.size(); 15877 for (int j=0; j<NJ; j++) { 15878 pw.print(" Last "); 15879 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j)); 15880 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j)); 15881 } 15882 } 15883 } 15884 } 15885 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist)); 15886 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist)); 15887 if (mPendingTempWhitelist.size() > 0) { 15888 pw.println(" mPendingTempWhitelist:"); 15889 for (int i = 0; i < mPendingTempWhitelist.size(); i++) { 15890 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i); 15891 pw.print(" "); 15892 UserHandle.formatUid(pw, ptw.targetUid); 15893 pw.print(": "); 15894 TimeUtils.formatDuration(ptw.duration, pw); 15895 pw.print(" "); 15896 pw.println(ptw.tag); 15897 } 15898 } 15899 } 15900 if (dumpPackage == null) { 15901 pw.println(" mWakefulness=" 15902 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 15903 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens); 15904 pw.println(" mSleeping=" + mSleeping); 15905 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode); 15906 if (mRunningVoice != null) { 15907 pw.println(" mRunningVoice=" + mRunningVoice); 15908 pw.println(" mVoiceWakeLock" + mVoiceWakeLock); 15909 } 15910 } 15911 pw.println(" mVrController=" + mVrController); 15912 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 15913 || mOrigWaitForDebugger) { 15914 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 15915 || dumpPackage.equals(mOrigDebugApp)) { 15916 if (needSep) { 15917 pw.println(); 15918 needSep = false; 15919 } 15920 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 15921 + " mDebugTransient=" + mDebugTransient 15922 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 15923 } 15924 } 15925 if (mCurAppTimeTracker != null) { 15926 mCurAppTimeTracker.dumpWithHeader(pw, " ", true); 15927 } 15928 if (mMemWatchProcesses.getMap().size() > 0) { 15929 pw.println(" Mem watch processes:"); 15930 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs 15931 = mMemWatchProcesses.getMap(); 15932 for (int i=0; i<procs.size(); i++) { 15933 final String proc = procs.keyAt(i); 15934 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i); 15935 for (int j=0; j<uids.size(); j++) { 15936 if (needSep) { 15937 pw.println(); 15938 needSep = false; 15939 } 15940 StringBuilder sb = new StringBuilder(); 15941 sb.append(" ").append(proc).append('/'); 15942 UserHandle.formatUid(sb, uids.keyAt(j)); 15943 Pair<Long, String> val = uids.valueAt(j); 15944 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb); 15945 if (val.second != null) { 15946 sb.append(", report to ").append(val.second); 15947 } 15948 pw.println(sb.toString()); 15949 } 15950 } 15951 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName); 15952 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile); 15953 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid); 15954 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid); 15955 } 15956 if (mTrackAllocationApp != null) { 15957 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) { 15958 if (needSep) { 15959 pw.println(); 15960 needSep = false; 15961 } 15962 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp); 15963 } 15964 } 15965 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null && 15966 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) { 15967 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 15968 if (needSep) { 15969 pw.println(); 15970 needSep = false; 15971 } 15972 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 15973 if (mProfilerInfo != null) { 15974 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" + 15975 mProfilerInfo.profileFd); 15976 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval + 15977 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler + 15978 " mStreamingOutput=" + mProfilerInfo.streamingOutput); 15979 pw.println(" mProfileType=" + mProfileType); 15980 } 15981 } 15982 } 15983 if (mNativeDebuggingApp != null) { 15984 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) { 15985 if (needSep) { 15986 pw.println(); 15987 needSep = false; 15988 } 15989 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp); 15990 } 15991 } 15992 if (dumpPackage == null) { 15993 if (mAlwaysFinishActivities) { 15994 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities); 15995 } 15996 if (mController != null) { 15997 pw.println(" mController=" + mController 15998 + " mControllerIsAMonkey=" + mControllerIsAMonkey); 15999 } 16000 if (dumpAll) { 16001 pw.println(" Total persistent processes: " + numPers); 16002 pw.println(" mProcessesReady=" + mProcessesReady 16003 + " mSystemReady=" + mSystemReady 16004 + " mBooted=" + mBooted 16005 + " mFactoryTest=" + mFactoryTest); 16006 pw.println(" mBooting=" + mBooting 16007 + " mCallFinishBooting=" + mCallFinishBooting 16008 + " mBootAnimationComplete=" + mBootAnimationComplete); 16009 pw.print(" mLastPowerCheckUptime="); 16010 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 16011 pw.println(""); 16012 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 16013 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 16014 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 16015 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 16016 + " (" + mLruProcesses.size() + " total)" 16017 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 16018 + " mNumServiceProcs=" + mNumServiceProcs 16019 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 16020 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 16021 + " mLastMemoryLevel=" + mLastMemoryLevel 16022 + " mLastNumProcesses=" + mLastNumProcesses); 16023 long now = SystemClock.uptimeMillis(); 16024 pw.print(" mLastIdleTime="); 16025 TimeUtils.formatDuration(now, mLastIdleTime, pw); 16026 pw.print(" mLowRamSinceLastIdle="); 16027 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 16028 pw.println(); 16029 } 16030 } 16031 16032 if (!printedAnything) { 16033 pw.println(" (nothing)"); 16034 } 16035 } 16036 16037 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 16038 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 16039 if (mProcessesToGc.size() > 0) { 16040 boolean printed = false; 16041 long now = SystemClock.uptimeMillis(); 16042 for (int i=0; i<mProcessesToGc.size(); i++) { 16043 ProcessRecord proc = mProcessesToGc.get(i); 16044 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 16045 continue; 16046 } 16047 if (!printed) { 16048 if (needSep) pw.println(); 16049 needSep = true; 16050 pw.println(" Processes that are waiting to GC:"); 16051 printed = true; 16052 } 16053 pw.print(" Process "); pw.println(proc); 16054 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 16055 pw.print(", last gced="); 16056 pw.print(now-proc.lastRequestedGc); 16057 pw.print(" ms ago, last lowMem="); 16058 pw.print(now-proc.lastLowMemory); 16059 pw.println(" ms ago"); 16060 16061 } 16062 } 16063 return needSep; 16064 } 16065 16066 void printOomLevel(PrintWriter pw, String name, int adj) { 16067 pw.print(" "); 16068 if (adj >= 0) { 16069 pw.print(' '); 16070 if (adj < 10) pw.print(' '); 16071 } else { 16072 if (adj > -10) pw.print(' '); 16073 } 16074 pw.print(adj); 16075 pw.print(": "); 16076 pw.print(name); 16077 pw.print(" ("); 16078 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024)); 16079 pw.println(")"); 16080 } 16081 16082 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16083 int opti, boolean dumpAll) { 16084 boolean needSep = false; 16085 16086 if (mLruProcesses.size() > 0) { 16087 if (needSep) pw.println(); 16088 needSep = true; 16089 pw.println(" OOM levels:"); 16090 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 16091 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 16092 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 16093 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 16094 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 16095 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 16096 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 16097 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 16098 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 16099 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 16100 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 16101 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 16102 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 16103 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 16104 16105 if (needSep) pw.println(); 16106 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 16107 pw.print(" total, non-act at "); 16108 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 16109 pw.print(", non-svc at "); 16110 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 16111 pw.println("):"); 16112 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 16113 needSep = true; 16114 } 16115 16116 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 16117 16118 pw.println(); 16119 pw.println(" mHomeProcess: " + mHomeProcess); 16120 pw.println(" mPreviousProcess: " + mPreviousProcess); 16121 if (mHeavyWeightProcess != null) { 16122 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 16123 } 16124 16125 return true; 16126 } 16127 16128 /** 16129 * There are three ways to call this: 16130 * - no provider specified: dump all the providers 16131 * - a flattened component name that matched an existing provider was specified as the 16132 * first arg: dump that one provider 16133 * - the first arg isn't the flattened component name of an existing provider: 16134 * dump all providers whose component contains the first arg as a substring 16135 */ 16136 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 16137 int opti, boolean dumpAll) { 16138 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 16139 } 16140 16141 static class ItemMatcher { 16142 ArrayList<ComponentName> components; 16143 ArrayList<String> strings; 16144 ArrayList<Integer> objects; 16145 boolean all; 16146 16147 ItemMatcher() { 16148 all = true; 16149 } 16150 16151 void build(String name) { 16152 ComponentName componentName = ComponentName.unflattenFromString(name); 16153 if (componentName != null) { 16154 if (components == null) { 16155 components = new ArrayList<ComponentName>(); 16156 } 16157 components.add(componentName); 16158 all = false; 16159 } else { 16160 int objectId = 0; 16161 // Not a '/' separated full component name; maybe an object ID? 16162 try { 16163 objectId = Integer.parseInt(name, 16); 16164 if (objects == null) { 16165 objects = new ArrayList<Integer>(); 16166 } 16167 objects.add(objectId); 16168 all = false; 16169 } catch (RuntimeException e) { 16170 // Not an integer; just do string match. 16171 if (strings == null) { 16172 strings = new ArrayList<String>(); 16173 } 16174 strings.add(name); 16175 all = false; 16176 } 16177 } 16178 } 16179 16180 int build(String[] args, int opti) { 16181 for (; opti<args.length; opti++) { 16182 String name = args[opti]; 16183 if ("--".equals(name)) { 16184 return opti+1; 16185 } 16186 build(name); 16187 } 16188 return opti; 16189 } 16190 16191 boolean match(Object object, ComponentName comp) { 16192 if (all) { 16193 return true; 16194 } 16195 if (components != null) { 16196 for (int i=0; i<components.size(); i++) { 16197 if (components.get(i).equals(comp)) { 16198 return true; 16199 } 16200 } 16201 } 16202 if (objects != null) { 16203 for (int i=0; i<objects.size(); i++) { 16204 if (System.identityHashCode(object) == objects.get(i)) { 16205 return true; 16206 } 16207 } 16208 } 16209 if (strings != null) { 16210 String flat = comp.flattenToString(); 16211 for (int i=0; i<strings.size(); i++) { 16212 if (flat.contains(strings.get(i))) { 16213 return true; 16214 } 16215 } 16216 } 16217 return false; 16218 } 16219 } 16220 16221 /** 16222 * There are three things that cmd can be: 16223 * - a flattened component name that matches an existing activity 16224 * - the cmd arg isn't the flattened component name of an existing activity: 16225 * dump all activity whose component contains the cmd as a substring 16226 * - A hex number of the ActivityRecord object instance. 16227 * 16228 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack 16229 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack 16230 */ 16231 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 16232 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) { 16233 ArrayList<ActivityRecord> activities; 16234 16235 synchronized (this) { 16236 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly, 16237 dumpFocusedStackOnly); 16238 } 16239 16240 if (activities.size() <= 0) { 16241 return false; 16242 } 16243 16244 String[] newArgs = new String[args.length - opti]; 16245 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 16246 16247 TaskRecord lastTask = null; 16248 boolean needSep = false; 16249 for (int i=activities.size()-1; i>=0; i--) { 16250 ActivityRecord r = activities.get(i); 16251 if (needSep) { 16252 pw.println(); 16253 } 16254 needSep = true; 16255 synchronized (this) { 16256 final TaskRecord task = r.getTask(); 16257 if (lastTask != task) { 16258 lastTask = task; 16259 pw.print("TASK "); pw.print(lastTask.affinity); 16260 pw.print(" id="); pw.print(lastTask.taskId); 16261 pw.print(" userId="); pw.println(lastTask.userId); 16262 if (dumpAll) { 16263 lastTask.dump(pw, " "); 16264 } 16265 } 16266 } 16267 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 16268 } 16269 return true; 16270 } 16271 16272 /** 16273 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 16274 * there is a thread associated with the activity. 16275 */ 16276 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 16277 final ActivityRecord r, String[] args, boolean dumpAll) { 16278 String innerPrefix = prefix + " "; 16279 synchronized (this) { 16280 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 16281 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 16282 pw.print(" pid="); 16283 if (r.app != null) pw.println(r.app.pid); 16284 else pw.println("(not running)"); 16285 if (dumpAll) { 16286 r.dump(pw, innerPrefix); 16287 } 16288 } 16289 if (r.app != null && r.app.thread != null) { 16290 // flush anything that is already in the PrintWriter since the thread is going 16291 // to write to the file descriptor directly 16292 pw.flush(); 16293 try { 16294 TransferPipe tp = new TransferPipe(); 16295 try { 16296 r.app.thread.dumpActivity(tp.getWriteFd(), 16297 r.appToken, innerPrefix, args); 16298 tp.go(fd); 16299 } finally { 16300 tp.kill(); 16301 } 16302 } catch (IOException e) { 16303 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 16304 } catch (RemoteException e) { 16305 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 16306 } 16307 } 16308 } 16309 16310 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16311 int opti, boolean dumpAll, String dumpPackage) { 16312 boolean needSep = false; 16313 boolean onlyHistory = false; 16314 boolean printedAnything = false; 16315 16316 if ("history".equals(dumpPackage)) { 16317 if (opti < args.length && "-s".equals(args[opti])) { 16318 dumpAll = false; 16319 } 16320 onlyHistory = true; 16321 dumpPackage = null; 16322 } 16323 16324 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 16325 if (!onlyHistory && dumpAll) { 16326 if (mRegisteredReceivers.size() > 0) { 16327 boolean printed = false; 16328 Iterator it = mRegisteredReceivers.values().iterator(); 16329 while (it.hasNext()) { 16330 ReceiverList r = (ReceiverList)it.next(); 16331 if (dumpPackage != null && (r.app == null || 16332 !dumpPackage.equals(r.app.info.packageName))) { 16333 continue; 16334 } 16335 if (!printed) { 16336 pw.println(" Registered Receivers:"); 16337 needSep = true; 16338 printed = true; 16339 printedAnything = true; 16340 } 16341 pw.print(" * "); pw.println(r); 16342 r.dump(pw, " "); 16343 } 16344 } 16345 16346 if (mReceiverResolver.dump(pw, needSep ? 16347 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 16348 " ", dumpPackage, false, false)) { 16349 needSep = true; 16350 printedAnything = true; 16351 } 16352 } 16353 16354 for (BroadcastQueue q : mBroadcastQueues) { 16355 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 16356 printedAnything |= needSep; 16357 } 16358 16359 needSep = true; 16360 16361 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 16362 for (int user=0; user<mStickyBroadcasts.size(); user++) { 16363 if (needSep) { 16364 pw.println(); 16365 } 16366 needSep = true; 16367 printedAnything = true; 16368 pw.print(" Sticky broadcasts for user "); 16369 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 16370 StringBuilder sb = new StringBuilder(128); 16371 for (Map.Entry<String, ArrayList<Intent>> ent 16372 : mStickyBroadcasts.valueAt(user).entrySet()) { 16373 pw.print(" * Sticky action "); pw.print(ent.getKey()); 16374 if (dumpAll) { 16375 pw.println(":"); 16376 ArrayList<Intent> intents = ent.getValue(); 16377 final int N = intents.size(); 16378 for (int i=0; i<N; i++) { 16379 sb.setLength(0); 16380 sb.append(" Intent: "); 16381 intents.get(i).toShortString(sb, false, true, false, false); 16382 pw.println(sb.toString()); 16383 Bundle bundle = intents.get(i).getExtras(); 16384 if (bundle != null) { 16385 pw.print(" "); 16386 pw.println(bundle.toString()); 16387 } 16388 } 16389 } else { 16390 pw.println(""); 16391 } 16392 } 16393 } 16394 } 16395 16396 if (!onlyHistory && dumpAll) { 16397 pw.println(); 16398 for (BroadcastQueue queue : mBroadcastQueues) { 16399 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 16400 + queue.mBroadcastsScheduled); 16401 } 16402 pw.println(" mHandler:"); 16403 mHandler.dump(new PrintWriterPrinter(pw), " "); 16404 needSep = true; 16405 printedAnything = true; 16406 } 16407 16408 if (!printedAnything) { 16409 pw.println(" (nothing)"); 16410 } 16411 } 16412 16413 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16414 int opti, boolean dumpAll, String dumpPackage) { 16415 if (mCurBroadcastStats == null) { 16416 return; 16417 } 16418 16419 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)"); 16420 final long now = SystemClock.elapsedRealtime(); 16421 if (mLastBroadcastStats != null) { 16422 pw.print(" Last stats (from "); 16423 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw); 16424 pw.print(" to "); 16425 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw); 16426 pw.print(", "); 16427 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime 16428 - mLastBroadcastStats.mStartUptime, pw); 16429 pw.println(" uptime):"); 16430 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) { 16431 pw.println(" (nothing)"); 16432 } 16433 pw.println(); 16434 } 16435 pw.print(" Current stats (from "); 16436 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw); 16437 pw.print(" to now, "); 16438 TimeUtils.formatDuration(SystemClock.uptimeMillis() 16439 - mCurBroadcastStats.mStartUptime, pw); 16440 pw.println(" uptime):"); 16441 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) { 16442 pw.println(" (nothing)"); 16443 } 16444 } 16445 16446 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16447 int opti, boolean fullCheckin, String dumpPackage) { 16448 if (mCurBroadcastStats == null) { 16449 return; 16450 } 16451 16452 if (mLastBroadcastStats != null) { 16453 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage); 16454 if (fullCheckin) { 16455 mLastBroadcastStats = null; 16456 return; 16457 } 16458 } 16459 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage); 16460 if (fullCheckin) { 16461 mCurBroadcastStats = null; 16462 } 16463 } 16464 16465 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16466 int opti, boolean dumpAll, String dumpPackage) { 16467 boolean needSep; 16468 boolean printedAnything = false; 16469 16470 ItemMatcher matcher = new ItemMatcher(); 16471 matcher.build(args, opti); 16472 16473 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 16474 16475 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 16476 printedAnything |= needSep; 16477 16478 if (mLaunchingProviders.size() > 0) { 16479 boolean printed = false; 16480 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 16481 ContentProviderRecord r = mLaunchingProviders.get(i); 16482 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 16483 continue; 16484 } 16485 if (!printed) { 16486 if (needSep) pw.println(); 16487 needSep = true; 16488 pw.println(" Launching content providers:"); 16489 printed = true; 16490 printedAnything = true; 16491 } 16492 pw.print(" Launching #"); pw.print(i); pw.print(": "); 16493 pw.println(r); 16494 } 16495 } 16496 16497 if (!printedAnything) { 16498 pw.println(" (nothing)"); 16499 } 16500 } 16501 16502 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16503 int opti, boolean dumpAll, String dumpPackage) { 16504 boolean needSep = false; 16505 boolean printedAnything = false; 16506 16507 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)"); 16508 16509 if (mGrantedUriPermissions.size() > 0) { 16510 boolean printed = false; 16511 int dumpUid = -2; 16512 if (dumpPackage != null) { 16513 try { 16514 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage, 16515 MATCH_ANY_USER, 0); 16516 } catch (NameNotFoundException e) { 16517 dumpUid = -1; 16518 } 16519 } 16520 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 16521 int uid = mGrantedUriPermissions.keyAt(i); 16522 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 16523 continue; 16524 } 16525 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 16526 if (!printed) { 16527 if (needSep) pw.println(); 16528 needSep = true; 16529 pw.println(" Granted Uri Permissions:"); 16530 printed = true; 16531 printedAnything = true; 16532 } 16533 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 16534 for (UriPermission perm : perms.values()) { 16535 pw.print(" "); pw.println(perm); 16536 if (dumpAll) { 16537 perm.dump(pw, " "); 16538 } 16539 } 16540 } 16541 } 16542 16543 if (!printedAnything) { 16544 pw.println(" (nothing)"); 16545 } 16546 } 16547 16548 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16549 int opti, boolean dumpAll, String dumpPackage) { 16550 boolean printed = false; 16551 16552 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 16553 16554 if (mIntentSenderRecords.size() > 0) { 16555 // Organize these by package name, so they are easier to read. 16556 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>(); 16557 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>(); 16558 final Iterator<WeakReference<PendingIntentRecord>> it 16559 = mIntentSenderRecords.values().iterator(); 16560 while (it.hasNext()) { 16561 WeakReference<PendingIntentRecord> ref = it.next(); 16562 PendingIntentRecord rec = ref != null ? ref.get() : null; 16563 if (rec == null) { 16564 weakRefs.add(ref); 16565 continue; 16566 } 16567 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) { 16568 continue; 16569 } 16570 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName); 16571 if (list == null) { 16572 list = new ArrayList<>(); 16573 byPackage.put(rec.key.packageName, list); 16574 } 16575 list.add(rec); 16576 } 16577 for (int i = 0; i < byPackage.size(); i++) { 16578 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i); 16579 printed = true; 16580 pw.print(" * "); pw.print(byPackage.keyAt(i)); 16581 pw.print(": "); pw.print(intents.size()); pw.println(" items"); 16582 for (int j = 0; j < intents.size(); j++) { 16583 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j)); 16584 if (dumpAll) { 16585 intents.get(j).dump(pw, " "); 16586 } 16587 } 16588 } 16589 if (weakRefs.size() > 0) { 16590 printed = true; 16591 pw.println(" * WEAK REFS:"); 16592 for (int i = 0; i < weakRefs.size(); i++) { 16593 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i)); 16594 } 16595 } 16596 } 16597 16598 if (!printed) { 16599 pw.println(" (nothing)"); 16600 } 16601 } 16602 16603 private static final int dumpProcessList(PrintWriter pw, 16604 ActivityManagerService service, List list, 16605 String prefix, String normalLabel, String persistentLabel, 16606 String dumpPackage) { 16607 int numPers = 0; 16608 final int N = list.size()-1; 16609 for (int i=N; i>=0; i--) { 16610 ProcessRecord r = (ProcessRecord)list.get(i); 16611 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 16612 continue; 16613 } 16614 pw.println(String.format("%s%s #%2d: %s", 16615 prefix, (r.persistent ? persistentLabel : normalLabel), 16616 i, r.toString())); 16617 if (r.persistent) { 16618 numPers++; 16619 } 16620 } 16621 return numPers; 16622 } 16623 16624 private static final boolean dumpProcessOomList(PrintWriter pw, 16625 ActivityManagerService service, List<ProcessRecord> origList, 16626 String prefix, String normalLabel, String persistentLabel, 16627 boolean inclDetails, String dumpPackage) { 16628 16629 ArrayList<Pair<ProcessRecord, Integer>> list 16630 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 16631 for (int i=0; i<origList.size(); i++) { 16632 ProcessRecord r = origList.get(i); 16633 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 16634 continue; 16635 } 16636 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 16637 } 16638 16639 if (list.size() <= 0) { 16640 return false; 16641 } 16642 16643 Comparator<Pair<ProcessRecord, Integer>> comparator 16644 = new Comparator<Pair<ProcessRecord, Integer>>() { 16645 @Override 16646 public int compare(Pair<ProcessRecord, Integer> object1, 16647 Pair<ProcessRecord, Integer> object2) { 16648 if (object1.first.setAdj != object2.first.setAdj) { 16649 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 16650 } 16651 if (object1.first.setProcState != object2.first.setProcState) { 16652 return object1.first.setProcState > object2.first.setProcState ? -1 : 1; 16653 } 16654 if (object1.second.intValue() != object2.second.intValue()) { 16655 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 16656 } 16657 return 0; 16658 } 16659 }; 16660 16661 Collections.sort(list, comparator); 16662 16663 final long curUptime = SystemClock.uptimeMillis(); 16664 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 16665 16666 for (int i=list.size()-1; i>=0; i--) { 16667 ProcessRecord r = list.get(i).first; 16668 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 16669 char schedGroup; 16670 switch (r.setSchedGroup) { 16671 case ProcessList.SCHED_GROUP_BACKGROUND: 16672 schedGroup = 'B'; 16673 break; 16674 case ProcessList.SCHED_GROUP_DEFAULT: 16675 schedGroup = 'F'; 16676 break; 16677 case ProcessList.SCHED_GROUP_TOP_APP: 16678 schedGroup = 'T'; 16679 break; 16680 default: 16681 schedGroup = '?'; 16682 break; 16683 } 16684 char foreground; 16685 if (r.foregroundActivities) { 16686 foreground = 'A'; 16687 } else if (r.foregroundServices) { 16688 foreground = 'S'; 16689 } else { 16690 foreground = ' '; 16691 } 16692 String procState = ProcessList.makeProcStateString(r.curProcState); 16693 pw.print(prefix); 16694 pw.print(r.persistent ? persistentLabel : normalLabel); 16695 pw.print(" #"); 16696 int num = (origList.size()-1)-list.get(i).second; 16697 if (num < 10) pw.print(' '); 16698 pw.print(num); 16699 pw.print(": "); 16700 pw.print(oomAdj); 16701 pw.print(' '); 16702 pw.print(schedGroup); 16703 pw.print('/'); 16704 pw.print(foreground); 16705 pw.print('/'); 16706 pw.print(procState); 16707 pw.print(" trm:"); 16708 if (r.trimMemoryLevel < 10) pw.print(' '); 16709 pw.print(r.trimMemoryLevel); 16710 pw.print(' '); 16711 pw.print(r.toShortString()); 16712 pw.print(" ("); 16713 pw.print(r.adjType); 16714 pw.println(')'); 16715 if (r.adjSource != null || r.adjTarget != null) { 16716 pw.print(prefix); 16717 pw.print(" "); 16718 if (r.adjTarget instanceof ComponentName) { 16719 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 16720 } else if (r.adjTarget != null) { 16721 pw.print(r.adjTarget.toString()); 16722 } else { 16723 pw.print("{null}"); 16724 } 16725 pw.print("<="); 16726 if (r.adjSource instanceof ProcessRecord) { 16727 pw.print("Proc{"); 16728 pw.print(((ProcessRecord)r.adjSource).toShortString()); 16729 pw.println("}"); 16730 } else if (r.adjSource != null) { 16731 pw.println(r.adjSource.toString()); 16732 } else { 16733 pw.println("{null}"); 16734 } 16735 } 16736 if (inclDetails) { 16737 pw.print(prefix); 16738 pw.print(" "); 16739 pw.print("oom: max="); pw.print(r.maxAdj); 16740 pw.print(" curRaw="); pw.print(r.curRawAdj); 16741 pw.print(" setRaw="); pw.print(r.setRawAdj); 16742 pw.print(" cur="); pw.print(r.curAdj); 16743 pw.print(" set="); pw.println(r.setAdj); 16744 pw.print(prefix); 16745 pw.print(" "); 16746 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 16747 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 16748 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024); 16749 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024); 16750 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024); 16751 pw.println(); 16752 pw.print(prefix); 16753 pw.print(" "); 16754 pw.print("cached="); pw.print(r.cached); 16755 pw.print(" empty="); pw.print(r.empty); 16756 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 16757 16758 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 16759 if (r.lastCpuTime != 0) { 16760 long timeUsed = r.curCpuTime - r.lastCpuTime; 16761 pw.print(prefix); 16762 pw.print(" "); 16763 pw.print("run cpu over "); 16764 TimeUtils.formatDuration(uptimeSince, pw); 16765 pw.print(" used "); 16766 TimeUtils.formatDuration(timeUsed, pw); 16767 pw.print(" ("); 16768 pw.print((timeUsed*100)/uptimeSince); 16769 pw.println("%)"); 16770 } 16771 } 16772 } 16773 } 16774 return true; 16775 } 16776 16777 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 16778 String[] args) { 16779 ArrayList<ProcessRecord> procs; 16780 synchronized (this) { 16781 if (args != null && args.length > start 16782 && args[start].charAt(0) != '-') { 16783 procs = new ArrayList<ProcessRecord>(); 16784 int pid = -1; 16785 try { 16786 pid = Integer.parseInt(args[start]); 16787 } catch (NumberFormatException e) { 16788 } 16789 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16790 ProcessRecord proc = mLruProcesses.get(i); 16791 if (proc.pid == pid) { 16792 procs.add(proc); 16793 } else if (allPkgs && proc.pkgList != null 16794 && proc.pkgList.containsKey(args[start])) { 16795 procs.add(proc); 16796 } else if (proc.processName.equals(args[start])) { 16797 procs.add(proc); 16798 } 16799 } 16800 if (procs.size() <= 0) { 16801 return null; 16802 } 16803 } else { 16804 procs = new ArrayList<ProcessRecord>(mLruProcesses); 16805 } 16806 } 16807 return procs; 16808 } 16809 16810 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 16811 PrintWriter pw, String[] args) { 16812 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 16813 if (procs == null) { 16814 pw.println("No process found for: " + args[0]); 16815 return; 16816 } 16817 16818 long uptime = SystemClock.uptimeMillis(); 16819 long realtime = SystemClock.elapsedRealtime(); 16820 pw.println("Applications Graphics Acceleration Info:"); 16821 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 16822 16823 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 16824 ProcessRecord r = procs.get(i); 16825 if (r.thread != null) { 16826 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 16827 pw.flush(); 16828 try { 16829 TransferPipe tp = new TransferPipe(); 16830 try { 16831 r.thread.dumpGfxInfo(tp.getWriteFd(), args); 16832 tp.go(fd); 16833 } finally { 16834 tp.kill(); 16835 } 16836 } catch (IOException e) { 16837 pw.println("Failure while dumping the app: " + r); 16838 pw.flush(); 16839 } catch (RemoteException e) { 16840 pw.println("Got a RemoteException while dumping the app " + r); 16841 pw.flush(); 16842 } 16843 } 16844 } 16845 } 16846 16847 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 16848 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 16849 if (procs == null) { 16850 pw.println("No process found for: " + args[0]); 16851 return; 16852 } 16853 16854 pw.println("Applications Database Info:"); 16855 16856 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 16857 ProcessRecord r = procs.get(i); 16858 if (r.thread != null) { 16859 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 16860 pw.flush(); 16861 try { 16862 TransferPipe tp = new TransferPipe(); 16863 try { 16864 r.thread.dumpDbInfo(tp.getWriteFd(), args); 16865 tp.go(fd); 16866 } finally { 16867 tp.kill(); 16868 } 16869 } catch (IOException e) { 16870 pw.println("Failure while dumping the app: " + r); 16871 pw.flush(); 16872 } catch (RemoteException e) { 16873 pw.println("Got a RemoteException while dumping the app " + r); 16874 pw.flush(); 16875 } 16876 } 16877 } 16878 } 16879 16880 final static class MemItem { 16881 final boolean isProc; 16882 final String label; 16883 final String shortLabel; 16884 final long pss; 16885 final long swapPss; 16886 final int id; 16887 final boolean hasActivities; 16888 ArrayList<MemItem> subitems; 16889 16890 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id, 16891 boolean _hasActivities) { 16892 isProc = true; 16893 label = _label; 16894 shortLabel = _shortLabel; 16895 pss = _pss; 16896 swapPss = _swapPss; 16897 id = _id; 16898 hasActivities = _hasActivities; 16899 } 16900 16901 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) { 16902 isProc = false; 16903 label = _label; 16904 shortLabel = _shortLabel; 16905 pss = _pss; 16906 swapPss = _swapPss; 16907 id = _id; 16908 hasActivities = false; 16909 } 16910 } 16911 16912 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 16913 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) { 16914 if (sort && !isCompact) { 16915 Collections.sort(items, new Comparator<MemItem>() { 16916 @Override 16917 public int compare(MemItem lhs, MemItem rhs) { 16918 if (lhs.pss < rhs.pss) { 16919 return 1; 16920 } else if (lhs.pss > rhs.pss) { 16921 return -1; 16922 } 16923 return 0; 16924 } 16925 }); 16926 } 16927 16928 for (int i=0; i<items.size(); i++) { 16929 MemItem mi = items.get(i); 16930 if (!isCompact) { 16931 if (dumpSwapPss) { 16932 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss), 16933 mi.label, stringifyKBSize(mi.swapPss)); 16934 } else { 16935 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label); 16936 } 16937 } else if (mi.isProc) { 16938 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 16939 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(","); 16940 pw.print(dumpSwapPss ? mi.swapPss : "N/A"); 16941 pw.println(mi.hasActivities ? ",a" : ",e"); 16942 } else { 16943 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 16944 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A"); 16945 } 16946 if (mi.subitems != null) { 16947 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 16948 true, isCompact, dumpSwapPss); 16949 } 16950 } 16951 } 16952 16953 // These are in KB. 16954 static final long[] DUMP_MEM_BUCKETS = new long[] { 16955 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 16956 120*1024, 160*1024, 200*1024, 16957 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 16958 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 16959 }; 16960 16961 static final void appendMemBucket(StringBuilder out, long memKB, String label, 16962 boolean stackLike) { 16963 int start = label.lastIndexOf('.'); 16964 if (start >= 0) start++; 16965 else start = 0; 16966 int end = label.length(); 16967 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 16968 if (DUMP_MEM_BUCKETS[i] >= memKB) { 16969 long bucket = DUMP_MEM_BUCKETS[i]/1024; 16970 out.append(bucket); 16971 out.append(stackLike ? "MB." : "MB "); 16972 out.append(label, start, end); 16973 return; 16974 } 16975 } 16976 out.append(memKB/1024); 16977 out.append(stackLike ? "MB." : "MB "); 16978 out.append(label, start, end); 16979 } 16980 16981 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 16982 ProcessList.NATIVE_ADJ, 16983 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 16984 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 16985 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 16986 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 16987 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 16988 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ 16989 }; 16990 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 16991 "Native", 16992 "System", "Persistent", "Persistent Service", "Foreground", 16993 "Visible", "Perceptible", 16994 "Heavy Weight", "Backup", 16995 "A Services", "Home", 16996 "Previous", "B Services", "Cached" 16997 }; 16998 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 16999 "native", 17000 "sys", "pers", "persvc", "fore", 17001 "vis", "percept", 17002 "heavy", "backup", 17003 "servicea", "home", 17004 "prev", "serviceb", "cached" 17005 }; 17006 17007 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 17008 long realtime, boolean isCheckinRequest, boolean isCompact) { 17009 if (isCompact) { 17010 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION); 17011 } 17012 if (isCheckinRequest || isCompact) { 17013 // short checkin version 17014 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 17015 } else { 17016 pw.println("Applications Memory Usage (in Kilobytes):"); 17017 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 17018 } 17019 } 17020 17021 private static final int KSM_SHARED = 0; 17022 private static final int KSM_SHARING = 1; 17023 private static final int KSM_UNSHARED = 2; 17024 private static final int KSM_VOLATILE = 3; 17025 17026 private final long[] getKsmInfo() { 17027 long[] longOut = new long[4]; 17028 final int[] SINGLE_LONG_FORMAT = new int[] { 17029 PROC_SPACE_TERM| PROC_OUT_LONG 17030 }; 17031 long[] longTmp = new long[1]; 17032 readProcFile("/sys/kernel/mm/ksm/pages_shared", 17033 SINGLE_LONG_FORMAT, null, longTmp, null); 17034 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 17035 longTmp[0] = 0; 17036 readProcFile("/sys/kernel/mm/ksm/pages_sharing", 17037 SINGLE_LONG_FORMAT, null, longTmp, null); 17038 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 17039 longTmp[0] = 0; 17040 readProcFile("/sys/kernel/mm/ksm/pages_unshared", 17041 SINGLE_LONG_FORMAT, null, longTmp, null); 17042 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 17043 longTmp[0] = 0; 17044 readProcFile("/sys/kernel/mm/ksm/pages_volatile", 17045 SINGLE_LONG_FORMAT, null, longTmp, null); 17046 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 17047 return longOut; 17048 } 17049 17050 private static String stringifySize(long size, int order) { 17051 Locale locale = Locale.US; 17052 switch (order) { 17053 case 1: 17054 return String.format(locale, "%,13d", size); 17055 case 1024: 17056 return String.format(locale, "%,9dK", size / 1024); 17057 case 1024 * 1024: 17058 return String.format(locale, "%,5dM", size / 1024 / 1024); 17059 case 1024 * 1024 * 1024: 17060 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024); 17061 default: 17062 throw new IllegalArgumentException("Invalid size order"); 17063 } 17064 } 17065 17066 private static String stringifyKBSize(long size) { 17067 return stringifySize(size * 1024, 1024); 17068 } 17069 17070 // Update this version number in case you change the 'compact' format 17071 private static final int MEMINFO_COMPACT_VERSION = 1; 17072 17073 final void dumpApplicationMemoryUsage(FileDescriptor fd, 17074 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 17075 boolean dumpDetails = false; 17076 boolean dumpFullDetails = false; 17077 boolean dumpDalvik = false; 17078 boolean dumpSummaryOnly = false; 17079 boolean dumpUnreachable = false; 17080 boolean oomOnly = false; 17081 boolean isCompact = false; 17082 boolean localOnly = false; 17083 boolean packages = false; 17084 boolean isCheckinRequest = false; 17085 boolean dumpSwapPss = false; 17086 17087 int opti = 0; 17088 while (opti < args.length) { 17089 String opt = args[opti]; 17090 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 17091 break; 17092 } 17093 opti++; 17094 if ("-a".equals(opt)) { 17095 dumpDetails = true; 17096 dumpFullDetails = true; 17097 dumpDalvik = true; 17098 dumpSwapPss = true; 17099 } else if ("-d".equals(opt)) { 17100 dumpDalvik = true; 17101 } else if ("-c".equals(opt)) { 17102 isCompact = true; 17103 } else if ("-s".equals(opt)) { 17104 dumpDetails = true; 17105 dumpSummaryOnly = true; 17106 } else if ("-S".equals(opt)) { 17107 dumpSwapPss = true; 17108 } else if ("--unreachable".equals(opt)) { 17109 dumpUnreachable = true; 17110 } else if ("--oom".equals(opt)) { 17111 oomOnly = true; 17112 } else if ("--local".equals(opt)) { 17113 localOnly = true; 17114 } else if ("--package".equals(opt)) { 17115 packages = true; 17116 } else if ("--checkin".equals(opt)) { 17117 isCheckinRequest = true; 17118 17119 } else if ("-h".equals(opt)) { 17120 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]"); 17121 pw.println(" -a: include all available information for each process."); 17122 pw.println(" -d: include dalvik details."); 17123 pw.println(" -c: dump in a compact machine-parseable representation."); 17124 pw.println(" -s: dump only summary of application memory usage."); 17125 pw.println(" -S: dump also SwapPss."); 17126 pw.println(" --oom: only show processes organized by oom adj."); 17127 pw.println(" --local: only collect details locally, don't call process."); 17128 pw.println(" --package: interpret process arg as package, dumping all"); 17129 pw.println(" processes that have loaded that package."); 17130 pw.println(" --checkin: dump data for a checkin"); 17131 pw.println("If [process] is specified it can be the name or "); 17132 pw.println("pid of a specific process to dump."); 17133 return; 17134 } else { 17135 pw.println("Unknown argument: " + opt + "; use -h for help"); 17136 } 17137 } 17138 17139 long uptime = SystemClock.uptimeMillis(); 17140 long realtime = SystemClock.elapsedRealtime(); 17141 final long[] tmpLong = new long[1]; 17142 17143 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 17144 if (procs == null) { 17145 // No Java processes. Maybe they want to print a native process. 17146 if (args != null && args.length > opti 17147 && args[opti].charAt(0) != '-') { 17148 ArrayList<ProcessCpuTracker.Stats> nativeProcs 17149 = new ArrayList<ProcessCpuTracker.Stats>(); 17150 updateCpuStatsNow(); 17151 int findPid = -1; 17152 try { 17153 findPid = Integer.parseInt(args[opti]); 17154 } catch (NumberFormatException e) { 17155 } 17156 synchronized (mProcessCpuTracker) { 17157 final int N = mProcessCpuTracker.countStats(); 17158 for (int i=0; i<N; i++) { 17159 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 17160 if (st.pid == findPid || (st.baseName != null 17161 && st.baseName.equals(args[opti]))) { 17162 nativeProcs.add(st); 17163 } 17164 } 17165 } 17166 if (nativeProcs.size() > 0) { 17167 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 17168 isCompact); 17169 Debug.MemoryInfo mi = null; 17170 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 17171 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 17172 final int pid = r.pid; 17173 if (!isCheckinRequest && dumpDetails) { 17174 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 17175 } 17176 if (mi == null) { 17177 mi = new Debug.MemoryInfo(); 17178 } 17179 if (dumpDetails || (!brief && !oomOnly)) { 17180 Debug.getMemoryInfo(pid, mi); 17181 } else { 17182 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 17183 mi.dalvikPrivateDirty = (int)tmpLong[0]; 17184 } 17185 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 17186 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0); 17187 if (isCheckinRequest) { 17188 pw.println(); 17189 } 17190 } 17191 return; 17192 } 17193 } 17194 pw.println("No process found for: " + args[opti]); 17195 return; 17196 } 17197 17198 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 17199 dumpDetails = true; 17200 } 17201 17202 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 17203 17204 String[] innerArgs = new String[args.length-opti]; 17205 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 17206 17207 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 17208 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 17209 long nativePss = 0; 17210 long nativeSwapPss = 0; 17211 long dalvikPss = 0; 17212 long dalvikSwapPss = 0; 17213 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] : 17214 EmptyArray.LONG; 17215 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] : 17216 EmptyArray.LONG; 17217 long otherPss = 0; 17218 long otherSwapPss = 0; 17219 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 17220 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 17221 17222 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 17223 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 17224 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 17225 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 17226 17227 long totalPss = 0; 17228 long totalSwapPss = 0; 17229 long cachedPss = 0; 17230 long cachedSwapPss = 0; 17231 boolean hasSwapPss = false; 17232 17233 Debug.MemoryInfo mi = null; 17234 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 17235 final ProcessRecord r = procs.get(i); 17236 final IApplicationThread thread; 17237 final int pid; 17238 final int oomAdj; 17239 final boolean hasActivities; 17240 synchronized (this) { 17241 thread = r.thread; 17242 pid = r.pid; 17243 oomAdj = r.getSetAdjWithServices(); 17244 hasActivities = r.activities.size() > 0; 17245 } 17246 if (thread != null) { 17247 if (!isCheckinRequest && dumpDetails) { 17248 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 17249 } 17250 if (mi == null) { 17251 mi = new Debug.MemoryInfo(); 17252 } 17253 if (dumpDetails || (!brief && !oomOnly)) { 17254 Debug.getMemoryInfo(pid, mi); 17255 hasSwapPss = mi.hasSwappedOutPss; 17256 } else { 17257 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 17258 mi.dalvikPrivateDirty = (int)tmpLong[0]; 17259 } 17260 if (dumpDetails) { 17261 if (localOnly) { 17262 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 17263 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0); 17264 if (isCheckinRequest) { 17265 pw.println(); 17266 } 17267 } else { 17268 pw.flush(); 17269 try { 17270 TransferPipe tp = new TransferPipe(); 17271 try { 17272 thread.dumpMemInfo(tp.getWriteFd(), 17273 mi, isCheckinRequest, dumpFullDetails, 17274 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs); 17275 tp.go(fd); 17276 } finally { 17277 tp.kill(); 17278 } 17279 } catch (IOException e) { 17280 if (!isCheckinRequest) { 17281 pw.println("Got IoException! " + e); 17282 pw.flush(); 17283 } 17284 } catch (RemoteException e) { 17285 if (!isCheckinRequest) { 17286 pw.println("Got RemoteException! " + e); 17287 pw.flush(); 17288 } 17289 } 17290 } 17291 } 17292 17293 final long myTotalPss = mi.getTotalPss(); 17294 final long myTotalUss = mi.getTotalUss(); 17295 final long myTotalSwapPss = mi.getTotalSwappedOutPss(); 17296 17297 synchronized (this) { 17298 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 17299 // Record this for posterity if the process has been stable. 17300 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 17301 } 17302 } 17303 17304 if (!isCheckinRequest && mi != null) { 17305 totalPss += myTotalPss; 17306 totalSwapPss += myTotalSwapPss; 17307 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 17308 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss, 17309 myTotalSwapPss, pid, hasActivities); 17310 procMems.add(pssItem); 17311 procMemsMap.put(pid, pssItem); 17312 17313 nativePss += mi.nativePss; 17314 nativeSwapPss += mi.nativeSwappedOutPss; 17315 dalvikPss += mi.dalvikPss; 17316 dalvikSwapPss += mi.dalvikSwappedOutPss; 17317 for (int j=0; j<dalvikSubitemPss.length; j++) { 17318 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 17319 dalvikSubitemSwapPss[j] += 17320 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 17321 } 17322 otherPss += mi.otherPss; 17323 otherSwapPss += mi.otherSwappedOutPss; 17324 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 17325 long mem = mi.getOtherPss(j); 17326 miscPss[j] += mem; 17327 otherPss -= mem; 17328 mem = mi.getOtherSwappedOutPss(j); 17329 miscSwapPss[j] += mem; 17330 otherSwapPss -= mem; 17331 } 17332 17333 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 17334 cachedPss += myTotalPss; 17335 cachedSwapPss += myTotalSwapPss; 17336 } 17337 17338 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 17339 if (oomIndex == (oomPss.length - 1) 17340 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex] 17341 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) { 17342 oomPss[oomIndex] += myTotalPss; 17343 oomSwapPss[oomIndex] += myTotalSwapPss; 17344 if (oomProcs[oomIndex] == null) { 17345 oomProcs[oomIndex] = new ArrayList<MemItem>(); 17346 } 17347 oomProcs[oomIndex].add(pssItem); 17348 break; 17349 } 17350 } 17351 } 17352 } 17353 } 17354 17355 long nativeProcTotalPss = 0; 17356 17357 if (!isCheckinRequest && procs.size() > 1 && !packages) { 17358 // If we are showing aggregations, also look for native processes to 17359 // include so that our aggregations are more accurate. 17360 updateCpuStatsNow(); 17361 mi = null; 17362 synchronized (mProcessCpuTracker) { 17363 final int N = mProcessCpuTracker.countStats(); 17364 for (int i=0; i<N; i++) { 17365 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 17366 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 17367 if (mi == null) { 17368 mi = new Debug.MemoryInfo(); 17369 } 17370 if (!brief && !oomOnly) { 17371 Debug.getMemoryInfo(st.pid, mi); 17372 } else { 17373 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 17374 mi.nativePrivateDirty = (int)tmpLong[0]; 17375 } 17376 17377 final long myTotalPss = mi.getTotalPss(); 17378 final long myTotalSwapPss = mi.getTotalSwappedOutPss(); 17379 totalPss += myTotalPss; 17380 nativeProcTotalPss += myTotalPss; 17381 17382 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 17383 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false); 17384 procMems.add(pssItem); 17385 17386 nativePss += mi.nativePss; 17387 nativeSwapPss += mi.nativeSwappedOutPss; 17388 dalvikPss += mi.dalvikPss; 17389 dalvikSwapPss += mi.dalvikSwappedOutPss; 17390 for (int j=0; j<dalvikSubitemPss.length; j++) { 17391 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 17392 dalvikSubitemSwapPss[j] += 17393 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 17394 } 17395 otherPss += mi.otherPss; 17396 otherSwapPss += mi.otherSwappedOutPss; 17397 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 17398 long mem = mi.getOtherPss(j); 17399 miscPss[j] += mem; 17400 otherPss -= mem; 17401 mem = mi.getOtherSwappedOutPss(j); 17402 miscSwapPss[j] += mem; 17403 otherSwapPss -= mem; 17404 } 17405 oomPss[0] += myTotalPss; 17406 oomSwapPss[0] += myTotalSwapPss; 17407 if (oomProcs[0] == null) { 17408 oomProcs[0] = new ArrayList<MemItem>(); 17409 } 17410 oomProcs[0].add(pssItem); 17411 } 17412 } 17413 } 17414 17415 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 17416 17417 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1)); 17418 final int dalvikId = -2; 17419 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId)); 17420 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3)); 17421 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 17422 String label = Debug.MemoryInfo.getOtherLabel(j); 17423 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j)); 17424 } 17425 if (dalvikSubitemPss.length > 0) { 17426 // Add dalvik subitems. 17427 for (MemItem memItem : catMems) { 17428 int memItemStart = 0, memItemEnd = 0; 17429 if (memItem.id == dalvikId) { 17430 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START; 17431 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END; 17432 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) { 17433 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START; 17434 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END; 17435 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) { 17436 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START; 17437 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END; 17438 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) { 17439 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START; 17440 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END; 17441 } else { 17442 continue; // No subitems, continue. 17443 } 17444 memItem.subitems = new ArrayList<MemItem>(); 17445 for (int j=memItemStart; j<=memItemEnd; j++) { 17446 final String name = Debug.MemoryInfo.getOtherLabel( 17447 Debug.MemoryInfo.NUM_OTHER_STATS + j); 17448 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], 17449 dalvikSubitemSwapPss[j], j)); 17450 } 17451 } 17452 } 17453 17454 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 17455 for (int j=0; j<oomPss.length; j++) { 17456 if (oomPss[j] != 0) { 17457 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 17458 : DUMP_MEM_OOM_LABEL[j]; 17459 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j], 17460 DUMP_MEM_OOM_ADJ[j]); 17461 item.subitems = oomProcs[j]; 17462 oomMems.add(item); 17463 } 17464 } 17465 17466 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0; 17467 if (!brief && !oomOnly && !isCompact) { 17468 pw.println(); 17469 pw.println("Total PSS by process:"); 17470 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss); 17471 pw.println(); 17472 } 17473 if (!isCompact) { 17474 pw.println("Total PSS by OOM adjustment:"); 17475 } 17476 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss); 17477 if (!brief && !oomOnly) { 17478 PrintWriter out = categoryPw != null ? categoryPw : pw; 17479 if (!isCompact) { 17480 out.println(); 17481 out.println("Total PSS by category:"); 17482 } 17483 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss); 17484 } 17485 if (!isCompact) { 17486 pw.println(); 17487 } 17488 MemInfoReader memInfo = new MemInfoReader(); 17489 memInfo.readMemInfo(); 17490 if (nativeProcTotalPss > 0) { 17491 synchronized (this) { 17492 final long cachedKb = memInfo.getCachedSizeKb(); 17493 final long freeKb = memInfo.getFreeSizeKb(); 17494 final long zramKb = memInfo.getZramTotalSizeKb(); 17495 final long kernelKb = memInfo.getKernelUsedSizeKb(); 17496 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024, 17497 kernelKb*1024, nativeProcTotalPss*1024); 17498 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb, 17499 nativeProcTotalPss); 17500 } 17501 } 17502 if (!brief) { 17503 if (!isCompact) { 17504 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb())); 17505 pw.print(" (status "); 17506 switch (mLastMemoryLevel) { 17507 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 17508 pw.println("normal)"); 17509 break; 17510 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 17511 pw.println("moderate)"); 17512 break; 17513 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17514 pw.println("low)"); 17515 break; 17516 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17517 pw.println("critical)"); 17518 break; 17519 default: 17520 pw.print(mLastMemoryLevel); 17521 pw.println(")"); 17522 break; 17523 } 17524 pw.print(" Free RAM: "); 17525 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb() 17526 + memInfo.getFreeSizeKb())); 17527 pw.print(" ("); 17528 pw.print(stringifyKBSize(cachedPss)); 17529 pw.print(" cached pss + "); 17530 pw.print(stringifyKBSize(memInfo.getCachedSizeKb())); 17531 pw.print(" cached kernel + "); 17532 pw.print(stringifyKBSize(memInfo.getFreeSizeKb())); 17533 pw.println(" free)"); 17534 } else { 17535 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 17536 pw.print(cachedPss + memInfo.getCachedSizeKb() 17537 + memInfo.getFreeSizeKb()); pw.print(","); 17538 pw.println(totalPss - cachedPss); 17539 } 17540 } 17541 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss) 17542 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 17543 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb(); 17544 if (!isCompact) { 17545 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss 17546 + memInfo.getKernelUsedSizeKb())); pw.print(" ("); 17547 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + "); 17548 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n"); 17549 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM)); 17550 } else { 17551 pw.print("lostram,"); pw.println(lostRAM); 17552 } 17553 if (!brief) { 17554 if (memInfo.getZramTotalSizeKb() != 0) { 17555 if (!isCompact) { 17556 pw.print(" ZRAM: "); 17557 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb())); 17558 pw.print(" physical used for "); 17559 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb() 17560 - memInfo.getSwapFreeSizeKb())); 17561 pw.print(" in swap ("); 17562 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb())); 17563 pw.println(" total swap)"); 17564 } else { 17565 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 17566 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 17567 pw.println(memInfo.getSwapFreeSizeKb()); 17568 } 17569 } 17570 final long[] ksm = getKsmInfo(); 17571 if (!isCompact) { 17572 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 17573 || ksm[KSM_VOLATILE] != 0) { 17574 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING])); 17575 pw.print(" saved from shared "); 17576 pw.print(stringifyKBSize(ksm[KSM_SHARED])); 17577 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED])); 17578 pw.print(" unshared; "); 17579 pw.print(stringifyKBSize( 17580 ksm[KSM_VOLATILE])); pw.println(" volatile"); 17581 } 17582 pw.print(" Tuning: "); 17583 pw.print(ActivityManager.staticGetMemoryClass()); 17584 pw.print(" (large "); 17585 pw.print(ActivityManager.staticGetLargeMemoryClass()); 17586 pw.print("), oom "); 17587 pw.print(stringifySize( 17588 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024)); 17589 pw.print(", restore limit "); 17590 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb())); 17591 if (ActivityManager.isLowRamDeviceStatic()) { 17592 pw.print(" (low-ram)"); 17593 } 17594 if (ActivityManager.isHighEndGfx()) { 17595 pw.print(" (high-end-gfx)"); 17596 } 17597 pw.println(); 17598 } else { 17599 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 17600 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 17601 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 17602 pw.print("tuning,"); 17603 pw.print(ActivityManager.staticGetMemoryClass()); 17604 pw.print(','); 17605 pw.print(ActivityManager.staticGetLargeMemoryClass()); 17606 pw.print(','); 17607 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 17608 if (ActivityManager.isLowRamDeviceStatic()) { 17609 pw.print(",low-ram"); 17610 } 17611 if (ActivityManager.isHighEndGfx()) { 17612 pw.print(",high-end-gfx"); 17613 } 17614 pw.println(); 17615 } 17616 } 17617 } 17618 } 17619 17620 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 17621 long memtrack, String name) { 17622 sb.append(" "); 17623 sb.append(ProcessList.makeOomAdjString(oomAdj)); 17624 sb.append(' '); 17625 sb.append(ProcessList.makeProcStateString(procState)); 17626 sb.append(' '); 17627 ProcessList.appendRamKb(sb, pss); 17628 sb.append(": "); 17629 sb.append(name); 17630 if (memtrack > 0) { 17631 sb.append(" ("); 17632 sb.append(stringifyKBSize(memtrack)); 17633 sb.append(" memtrack)"); 17634 } 17635 } 17636 17637 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 17638 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 17639 sb.append(" (pid "); 17640 sb.append(mi.pid); 17641 sb.append(") "); 17642 sb.append(mi.adjType); 17643 sb.append('\n'); 17644 if (mi.adjReason != null) { 17645 sb.append(" "); 17646 sb.append(mi.adjReason); 17647 sb.append('\n'); 17648 } 17649 } 17650 17651 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 17652 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 17653 for (int i=0, N=memInfos.size(); i<N; i++) { 17654 ProcessMemInfo mi = memInfos.get(i); 17655 infoMap.put(mi.pid, mi); 17656 } 17657 updateCpuStatsNow(); 17658 long[] memtrackTmp = new long[1]; 17659 final List<ProcessCpuTracker.Stats> stats; 17660 // Get a list of Stats that have vsize > 0 17661 synchronized (mProcessCpuTracker) { 17662 stats = mProcessCpuTracker.getStats((st) -> { 17663 return st.vsize > 0; 17664 }); 17665 } 17666 final int statsCount = stats.size(); 17667 for (int i = 0; i < statsCount; i++) { 17668 ProcessCpuTracker.Stats st = stats.get(i); 17669 long pss = Debug.getPss(st.pid, null, memtrackTmp); 17670 if (pss > 0) { 17671 if (infoMap.indexOfKey(st.pid) < 0) { 17672 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 17673 ProcessList.NATIVE_ADJ, -1, "native", null); 17674 mi.pss = pss; 17675 mi.memtrack = memtrackTmp[0]; 17676 memInfos.add(mi); 17677 } 17678 } 17679 } 17680 17681 long totalPss = 0; 17682 long totalMemtrack = 0; 17683 for (int i=0, N=memInfos.size(); i<N; i++) { 17684 ProcessMemInfo mi = memInfos.get(i); 17685 if (mi.pss == 0) { 17686 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 17687 mi.memtrack = memtrackTmp[0]; 17688 } 17689 totalPss += mi.pss; 17690 totalMemtrack += mi.memtrack; 17691 } 17692 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 17693 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 17694 if (lhs.oomAdj != rhs.oomAdj) { 17695 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 17696 } 17697 if (lhs.pss != rhs.pss) { 17698 return lhs.pss < rhs.pss ? 1 : -1; 17699 } 17700 return 0; 17701 } 17702 }); 17703 17704 StringBuilder tag = new StringBuilder(128); 17705 StringBuilder stack = new StringBuilder(128); 17706 tag.append("Low on memory -- "); 17707 appendMemBucket(tag, totalPss, "total", false); 17708 appendMemBucket(stack, totalPss, "total", true); 17709 17710 StringBuilder fullNativeBuilder = new StringBuilder(1024); 17711 StringBuilder shortNativeBuilder = new StringBuilder(1024); 17712 StringBuilder fullJavaBuilder = new StringBuilder(1024); 17713 17714 boolean firstLine = true; 17715 int lastOomAdj = Integer.MIN_VALUE; 17716 long extraNativeRam = 0; 17717 long extraNativeMemtrack = 0; 17718 long cachedPss = 0; 17719 for (int i=0, N=memInfos.size(); i<N; i++) { 17720 ProcessMemInfo mi = memInfos.get(i); 17721 17722 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 17723 cachedPss += mi.pss; 17724 } 17725 17726 if (mi.oomAdj != ProcessList.NATIVE_ADJ 17727 && (mi.oomAdj < ProcessList.SERVICE_ADJ 17728 || mi.oomAdj == ProcessList.HOME_APP_ADJ 17729 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 17730 if (lastOomAdj != mi.oomAdj) { 17731 lastOomAdj = mi.oomAdj; 17732 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 17733 tag.append(" / "); 17734 } 17735 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 17736 if (firstLine) { 17737 stack.append(":"); 17738 firstLine = false; 17739 } 17740 stack.append("\n\t at "); 17741 } else { 17742 stack.append("$"); 17743 } 17744 } else { 17745 tag.append(" "); 17746 stack.append("$"); 17747 } 17748 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 17749 appendMemBucket(tag, mi.pss, mi.name, false); 17750 } 17751 appendMemBucket(stack, mi.pss, mi.name, true); 17752 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 17753 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 17754 stack.append("("); 17755 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 17756 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 17757 stack.append(DUMP_MEM_OOM_LABEL[k]); 17758 stack.append(":"); 17759 stack.append(DUMP_MEM_OOM_ADJ[k]); 17760 } 17761 } 17762 stack.append(")"); 17763 } 17764 } 17765 17766 appendMemInfo(fullNativeBuilder, mi); 17767 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 17768 // The short form only has native processes that are >= 512K. 17769 if (mi.pss >= 512) { 17770 appendMemInfo(shortNativeBuilder, mi); 17771 } else { 17772 extraNativeRam += mi.pss; 17773 extraNativeMemtrack += mi.memtrack; 17774 } 17775 } else { 17776 // Short form has all other details, but if we have collected RAM 17777 // from smaller native processes let's dump a summary of that. 17778 if (extraNativeRam > 0) { 17779 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 17780 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 17781 shortNativeBuilder.append('\n'); 17782 extraNativeRam = 0; 17783 } 17784 appendMemInfo(fullJavaBuilder, mi); 17785 } 17786 } 17787 17788 fullJavaBuilder.append(" "); 17789 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 17790 fullJavaBuilder.append(": TOTAL"); 17791 if (totalMemtrack > 0) { 17792 fullJavaBuilder.append(" ("); 17793 fullJavaBuilder.append(stringifyKBSize(totalMemtrack)); 17794 fullJavaBuilder.append(" memtrack)"); 17795 } else { 17796 } 17797 fullJavaBuilder.append("\n"); 17798 17799 MemInfoReader memInfo = new MemInfoReader(); 17800 memInfo.readMemInfo(); 17801 final long[] infos = memInfo.getRawInfo(); 17802 17803 StringBuilder memInfoBuilder = new StringBuilder(1024); 17804 Debug.getMemInfo(infos); 17805 memInfoBuilder.append(" MemInfo: "); 17806 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, "); 17807 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, "); 17808 memInfoBuilder.append(stringifyKBSize( 17809 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, "); 17810 memInfoBuilder.append(stringifyKBSize( 17811 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables "); 17812 memInfoBuilder.append(stringifyKBSize( 17813 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n"); 17814 memInfoBuilder.append(" "); 17815 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, "); 17816 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, "); 17817 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, "); 17818 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n"); 17819 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 17820 memInfoBuilder.append(" ZRAM: "); 17821 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL])); 17822 memInfoBuilder.append(" RAM, "); 17823 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL])); 17824 memInfoBuilder.append(" swap total, "); 17825 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE])); 17826 memInfoBuilder.append(" swap free\n"); 17827 } 17828 final long[] ksm = getKsmInfo(); 17829 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 17830 || ksm[KSM_VOLATILE] != 0) { 17831 memInfoBuilder.append(" KSM: "); 17832 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING])); 17833 memInfoBuilder.append(" saved from shared "); 17834 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED])); 17835 memInfoBuilder.append("\n "); 17836 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED])); 17837 memInfoBuilder.append(" unshared; "); 17838 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE])); 17839 memInfoBuilder.append(" volatile\n"); 17840 } 17841 memInfoBuilder.append(" Free RAM: "); 17842 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb() 17843 + memInfo.getFreeSizeKb())); 17844 memInfoBuilder.append("\n"); 17845 memInfoBuilder.append(" Used RAM: "); 17846 memInfoBuilder.append(stringifyKBSize( 17847 totalPss - cachedPss + memInfo.getKernelUsedSizeKb())); 17848 memInfoBuilder.append("\n"); 17849 memInfoBuilder.append(" Lost RAM: "); 17850 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb() 17851 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 17852 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb())); 17853 memInfoBuilder.append("\n"); 17854 Slog.i(TAG, "Low on memory:"); 17855 Slog.i(TAG, shortNativeBuilder.toString()); 17856 Slog.i(TAG, fullJavaBuilder.toString()); 17857 Slog.i(TAG, memInfoBuilder.toString()); 17858 17859 StringBuilder dropBuilder = new StringBuilder(1024); 17860 /* 17861 StringWriter oomSw = new StringWriter(); 17862 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 17863 StringWriter catSw = new StringWriter(); 17864 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 17865 String[] emptyArgs = new String[] { }; 17866 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 17867 oomPw.flush(); 17868 String oomString = oomSw.toString(); 17869 */ 17870 dropBuilder.append("Low on memory:"); 17871 dropBuilder.append(stack); 17872 dropBuilder.append('\n'); 17873 dropBuilder.append(fullNativeBuilder); 17874 dropBuilder.append(fullJavaBuilder); 17875 dropBuilder.append('\n'); 17876 dropBuilder.append(memInfoBuilder); 17877 dropBuilder.append('\n'); 17878 /* 17879 dropBuilder.append(oomString); 17880 dropBuilder.append('\n'); 17881 */ 17882 StringWriter catSw = new StringWriter(); 17883 synchronized (ActivityManagerService.this) { 17884 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 17885 String[] emptyArgs = new String[] { }; 17886 catPw.println(); 17887 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 17888 catPw.println(); 17889 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, 17890 false, null).dumpLocked(); 17891 catPw.println(); 17892 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 17893 catPw.flush(); 17894 } 17895 dropBuilder.append(catSw.toString()); 17896 addErrorToDropBox("lowmem", null, "system_server", null, 17897 null, tag.toString(), dropBuilder.toString(), null, null); 17898 //Slog.i(TAG, "Sent to dropbox:"); 17899 //Slog.i(TAG, dropBuilder.toString()); 17900 synchronized (ActivityManagerService.this) { 17901 long now = SystemClock.uptimeMillis(); 17902 if (mLastMemUsageReportTime < now) { 17903 mLastMemUsageReportTime = now; 17904 } 17905 } 17906 } 17907 17908 /** 17909 * Searches array of arguments for the specified string 17910 * @param args array of argument strings 17911 * @param value value to search for 17912 * @return true if the value is contained in the array 17913 */ 17914 private static boolean scanArgs(String[] args, String value) { 17915 if (args != null) { 17916 for (String arg : args) { 17917 if (value.equals(arg)) { 17918 return true; 17919 } 17920 } 17921 } 17922 return false; 17923 } 17924 17925 private final boolean removeDyingProviderLocked(ProcessRecord proc, 17926 ContentProviderRecord cpr, boolean always) { 17927 final boolean inLaunching = mLaunchingProviders.contains(cpr); 17928 17929 if (!inLaunching || always) { 17930 synchronized (cpr) { 17931 cpr.launchingApp = null; 17932 cpr.notifyAll(); 17933 } 17934 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 17935 String names[] = cpr.info.authority.split(";"); 17936 for (int j = 0; j < names.length; j++) { 17937 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 17938 } 17939 } 17940 17941 for (int i = cpr.connections.size() - 1; i >= 0; i--) { 17942 ContentProviderConnection conn = cpr.connections.get(i); 17943 if (conn.waiting) { 17944 // If this connection is waiting for the provider, then we don't 17945 // need to mess with its process unless we are always removing 17946 // or for some reason the provider is not currently launching. 17947 if (inLaunching && !always) { 17948 continue; 17949 } 17950 } 17951 ProcessRecord capp = conn.client; 17952 conn.dead = true; 17953 if (conn.stableCount > 0) { 17954 if (!capp.persistent && capp.thread != null 17955 && capp.pid != 0 17956 && capp.pid != MY_PID) { 17957 capp.kill("depends on provider " 17958 + cpr.name.flattenToShortString() 17959 + " in dying proc " + (proc != null ? proc.processName : "??") 17960 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true); 17961 } 17962 } else if (capp.thread != null && conn.provider.provider != null) { 17963 try { 17964 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 17965 } catch (RemoteException e) { 17966 } 17967 // In the protocol here, we don't expect the client to correctly 17968 // clean up this connection, we'll just remove it. 17969 cpr.connections.remove(i); 17970 if (conn.client.conProviders.remove(conn)) { 17971 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 17972 } 17973 } 17974 } 17975 17976 if (inLaunching && always) { 17977 mLaunchingProviders.remove(cpr); 17978 } 17979 return inLaunching; 17980 } 17981 17982 /** 17983 * Main code for cleaning up a process when it has gone away. This is 17984 * called both as a result of the process dying, or directly when stopping 17985 * a process when running in single process mode. 17986 * 17987 * @return Returns true if the given process has been restarted, so the 17988 * app that was passed in must remain on the process lists. 17989 */ 17990 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 17991 boolean restarting, boolean allowRestart, int index, boolean replacingPid) { 17992 if (index >= 0) { 17993 removeLruProcessLocked(app); 17994 ProcessList.remove(app.pid); 17995 } 17996 17997 mProcessesToGc.remove(app); 17998 mPendingPssProcesses.remove(app); 17999 18000 // Dismiss any open dialogs. 18001 if (app.crashDialog != null && !app.forceCrashReport) { 18002 app.crashDialog.dismiss(); 18003 app.crashDialog = null; 18004 } 18005 if (app.anrDialog != null) { 18006 app.anrDialog.dismiss(); 18007 app.anrDialog = null; 18008 } 18009 if (app.waitDialog != null) { 18010 app.waitDialog.dismiss(); 18011 app.waitDialog = null; 18012 } 18013 18014 app.crashing = false; 18015 app.notResponding = false; 18016 18017 app.resetPackageList(mProcessStats); 18018 app.unlinkDeathRecipient(); 18019 app.makeInactive(mProcessStats); 18020 app.waitingToKill = null; 18021 app.forcingToImportant = null; 18022 updateProcessForegroundLocked(app, false, false); 18023 app.foregroundActivities = false; 18024 app.hasShownUi = false; 18025 app.treatLikeActivity = false; 18026 app.hasAboveClient = false; 18027 app.hasClientActivities = false; 18028 18029 mServices.killServicesLocked(app, allowRestart); 18030 18031 boolean restart = false; 18032 18033 // Remove published content providers. 18034 for (int i = app.pubProviders.size() - 1; i >= 0; i--) { 18035 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 18036 final boolean always = app.bad || !allowRestart; 18037 boolean inLaunching = removeDyingProviderLocked(app, cpr, always); 18038 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) { 18039 // We left the provider in the launching list, need to 18040 // restart it. 18041 restart = true; 18042 } 18043 18044 cpr.provider = null; 18045 cpr.proc = null; 18046 } 18047 app.pubProviders.clear(); 18048 18049 // Take care of any launching providers waiting for this process. 18050 if (cleanupAppInLaunchingProvidersLocked(app, false)) { 18051 restart = true; 18052 } 18053 18054 // Unregister from connected content providers. 18055 if (!app.conProviders.isEmpty()) { 18056 for (int i = app.conProviders.size() - 1; i >= 0; i--) { 18057 ContentProviderConnection conn = app.conProviders.get(i); 18058 conn.provider.connections.remove(conn); 18059 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 18060 conn.provider.name); 18061 } 18062 app.conProviders.clear(); 18063 } 18064 18065 // At this point there may be remaining entries in mLaunchingProviders 18066 // where we were the only one waiting, so they are no longer of use. 18067 // Look for these and clean up if found. 18068 // XXX Commented out for now. Trying to figure out a way to reproduce 18069 // the actual situation to identify what is actually going on. 18070 if (false) { 18071 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 18072 ContentProviderRecord cpr = mLaunchingProviders.get(i); 18073 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 18074 synchronized (cpr) { 18075 cpr.launchingApp = null; 18076 cpr.notifyAll(); 18077 } 18078 } 18079 } 18080 } 18081 18082 skipCurrentReceiverLocked(app); 18083 18084 // Unregister any receivers. 18085 for (int i = app.receivers.size() - 1; i >= 0; i--) { 18086 removeReceiverLocked(app.receivers.valueAt(i)); 18087 } 18088 app.receivers.clear(); 18089 18090 // If the app is undergoing backup, tell the backup manager about it 18091 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 18092 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App " 18093 + mBackupTarget.appInfo + " died during backup"); 18094 mHandler.post(new Runnable() { 18095 @Override 18096 public void run(){ 18097 try { 18098 IBackupManager bm = IBackupManager.Stub.asInterface( 18099 ServiceManager.getService(Context.BACKUP_SERVICE)); 18100 bm.agentDisconnected(app.info.packageName); 18101 } catch (RemoteException e) { 18102 // can't happen; backup manager is local 18103 } 18104 } 18105 }); 18106 } 18107 18108 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) { 18109 ProcessChangeItem item = mPendingProcessChanges.get(i); 18110 if (item.pid == app.pid) { 18111 mPendingProcessChanges.remove(i); 18112 mAvailProcessChanges.add(item); 18113 } 18114 } 18115 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid, 18116 null).sendToTarget(); 18117 18118 // If the caller is restarting this app, then leave it in its 18119 // current lists and let the caller take care of it. 18120 if (restarting) { 18121 return false; 18122 } 18123 18124 if (!app.persistent || app.isolated) { 18125 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 18126 "Removing non-persistent process during cleanup: " + app); 18127 if (!replacingPid) { 18128 removeProcessNameLocked(app.processName, app.uid, app); 18129 } 18130 if (mHeavyWeightProcess == app) { 18131 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 18132 mHeavyWeightProcess.userId, 0)); 18133 mHeavyWeightProcess = null; 18134 } 18135 } else if (!app.removed) { 18136 // This app is persistent, so we need to keep its record around. 18137 // If it is not already on the pending app list, add it there 18138 // and start a new process for it. 18139 if (mPersistentStartingProcesses.indexOf(app) < 0) { 18140 mPersistentStartingProcesses.add(app); 18141 restart = true; 18142 } 18143 } 18144 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v( 18145 TAG_CLEANUP, "Clean-up removing on hold: " + app); 18146 mProcessesOnHold.remove(app); 18147 18148 if (app == mHomeProcess) { 18149 mHomeProcess = null; 18150 } 18151 if (app == mPreviousProcess) { 18152 mPreviousProcess = null; 18153 } 18154 18155 if (restart && !app.isolated) { 18156 // We have components that still need to be running in the 18157 // process, so re-launch it. 18158 if (index < 0) { 18159 ProcessList.remove(app.pid); 18160 } 18161 addProcessNameLocked(app); 18162 startProcessLocked(app, "restart", app.processName); 18163 return true; 18164 } else if (app.pid > 0 && app.pid != MY_PID) { 18165 // Goodbye! 18166 boolean removed; 18167 synchronized (mPidsSelfLocked) { 18168 mPidsSelfLocked.remove(app.pid); 18169 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 18170 } 18171 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 18172 if (app.isolated) { 18173 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 18174 } 18175 app.setPid(0); 18176 } 18177 return false; 18178 } 18179 18180 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) { 18181 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 18182 ContentProviderRecord cpr = mLaunchingProviders.get(i); 18183 if (cpr.launchingApp == app) { 18184 return true; 18185 } 18186 } 18187 return false; 18188 } 18189 18190 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 18191 // Look through the content providers we are waiting to have launched, 18192 // and if any run in this process then either schedule a restart of 18193 // the process or kill the client waiting for it if this process has 18194 // gone bad. 18195 boolean restart = false; 18196 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 18197 ContentProviderRecord cpr = mLaunchingProviders.get(i); 18198 if (cpr.launchingApp == app) { 18199 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) { 18200 restart = true; 18201 } else { 18202 removeDyingProviderLocked(app, cpr, true); 18203 } 18204 } 18205 } 18206 return restart; 18207 } 18208 18209 // ========================================================= 18210 // SERVICES 18211 // ========================================================= 18212 18213 @Override 18214 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 18215 int flags) { 18216 enforceNotIsolatedCaller("getServices"); 18217 18218 final int callingUid = Binder.getCallingUid(); 18219 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission( 18220 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED); 18221 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(), 18222 callingUid); 18223 synchronized (this) { 18224 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, 18225 allowed, canInteractAcrossUsers); 18226 } 18227 } 18228 18229 @Override 18230 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 18231 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 18232 synchronized (this) { 18233 return mServices.getRunningServiceControlPanelLocked(name); 18234 } 18235 } 18236 18237 @Override 18238 public ComponentName startService(IApplicationThread caller, Intent service, 18239 String resolvedType, boolean requireForeground, String callingPackage, int userId) 18240 throws TransactionTooLargeException { 18241 enforceNotIsolatedCaller("startService"); 18242 // Refuse possible leaked file descriptors 18243 if (service != null && service.hasFileDescriptors() == true) { 18244 throw new IllegalArgumentException("File descriptors passed in Intent"); 18245 } 18246 18247 if (callingPackage == null) { 18248 throw new IllegalArgumentException("callingPackage cannot be null"); 18249 } 18250 18251 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, 18252 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground); 18253 synchronized(this) { 18254 final int callingPid = Binder.getCallingPid(); 18255 final int callingUid = Binder.getCallingUid(); 18256 final long origId = Binder.clearCallingIdentity(); 18257 ComponentName res; 18258 try { 18259 res = mServices.startServiceLocked(caller, service, 18260 resolvedType, callingPid, callingUid, 18261 requireForeground, callingPackage, userId); 18262 } finally { 18263 Binder.restoreCallingIdentity(origId); 18264 } 18265 return res; 18266 } 18267 } 18268 18269 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, 18270 boolean fgRequired, String callingPackage, int userId) 18271 throws TransactionTooLargeException { 18272 synchronized(this) { 18273 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, 18274 "startServiceInPackage: " + service + " type=" + resolvedType); 18275 final long origId = Binder.clearCallingIdentity(); 18276 ComponentName res; 18277 try { 18278 res = mServices.startServiceLocked(null, service, 18279 resolvedType, -1, uid, fgRequired, callingPackage, userId); 18280 } finally { 18281 Binder.restoreCallingIdentity(origId); 18282 } 18283 return res; 18284 } 18285 } 18286 18287 @Override 18288 public int stopService(IApplicationThread caller, Intent service, 18289 String resolvedType, int userId) { 18290 enforceNotIsolatedCaller("stopService"); 18291 // Refuse possible leaked file descriptors 18292 if (service != null && service.hasFileDescriptors() == true) { 18293 throw new IllegalArgumentException("File descriptors passed in Intent"); 18294 } 18295 18296 synchronized(this) { 18297 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 18298 } 18299 } 18300 18301 @Override 18302 public IBinder peekService(Intent service, String resolvedType, String callingPackage) { 18303 enforceNotIsolatedCaller("peekService"); 18304 // Refuse possible leaked file descriptors 18305 if (service != null && service.hasFileDescriptors() == true) { 18306 throw new IllegalArgumentException("File descriptors passed in Intent"); 18307 } 18308 18309 if (callingPackage == null) { 18310 throw new IllegalArgumentException("callingPackage cannot be null"); 18311 } 18312 18313 synchronized(this) { 18314 return mServices.peekServiceLocked(service, resolvedType, callingPackage); 18315 } 18316 } 18317 18318 @Override 18319 public boolean stopServiceToken(ComponentName className, IBinder token, 18320 int startId) { 18321 synchronized(this) { 18322 return mServices.stopServiceTokenLocked(className, token, startId); 18323 } 18324 } 18325 18326 @Override 18327 public void setServiceForeground(ComponentName className, IBinder token, 18328 int id, Notification notification, int flags) { 18329 synchronized(this) { 18330 mServices.setServiceForegroundLocked(className, token, id, notification, flags); 18331 } 18332 } 18333 18334 @Override 18335 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 18336 boolean requireFull, String name, String callerPackage) { 18337 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll, 18338 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 18339 } 18340 18341 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 18342 String className, int flags) { 18343 boolean result = false; 18344 // For apps that don't have pre-defined UIDs, check for permission 18345 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) { 18346 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 18347 if (ActivityManager.checkUidPermission( 18348 INTERACT_ACROSS_USERS, 18349 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 18350 ComponentName comp = new ComponentName(aInfo.packageName, className); 18351 String msg = "Permission Denial: Component " + comp.flattenToShortString() 18352 + " requests FLAG_SINGLE_USER, but app does not hold " 18353 + INTERACT_ACROSS_USERS; 18354 Slog.w(TAG, msg); 18355 throw new SecurityException(msg); 18356 } 18357 // Permission passed 18358 result = true; 18359 } 18360 } else if ("system".equals(componentProcessName)) { 18361 result = true; 18362 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 18363 // Phone app and persistent apps are allowed to export singleuser providers. 18364 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID) 18365 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 18366 } 18367 if (DEBUG_MU) Slog.v(TAG_MU, 18368 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x" 18369 + Integer.toHexString(flags) + ") = " + result); 18370 return result; 18371 } 18372 18373 /** 18374 * Checks to see if the caller is in the same app as the singleton 18375 * component, or the component is in a special app. It allows special apps 18376 * to export singleton components but prevents exporting singleton 18377 * components for regular apps. 18378 */ 18379 boolean isValidSingletonCall(int callingUid, int componentUid) { 18380 int componentAppId = UserHandle.getAppId(componentUid); 18381 return UserHandle.isSameApp(callingUid, componentUid) 18382 || componentAppId == SYSTEM_UID 18383 || componentAppId == PHONE_UID 18384 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 18385 == PackageManager.PERMISSION_GRANTED; 18386 } 18387 18388 public int bindService(IApplicationThread caller, IBinder token, Intent service, 18389 String resolvedType, IServiceConnection connection, int flags, String callingPackage, 18390 int userId) throws TransactionTooLargeException { 18391 enforceNotIsolatedCaller("bindService"); 18392 18393 // Refuse possible leaked file descriptors 18394 if (service != null && service.hasFileDescriptors() == true) { 18395 throw new IllegalArgumentException("File descriptors passed in Intent"); 18396 } 18397 18398 if (callingPackage == null) { 18399 throw new IllegalArgumentException("callingPackage cannot be null"); 18400 } 18401 18402 synchronized(this) { 18403 return mServices.bindServiceLocked(caller, token, service, 18404 resolvedType, connection, flags, callingPackage, userId); 18405 } 18406 } 18407 18408 public boolean unbindService(IServiceConnection connection) { 18409 synchronized (this) { 18410 return mServices.unbindServiceLocked(connection); 18411 } 18412 } 18413 18414 public void publishService(IBinder token, Intent intent, IBinder service) { 18415 // Refuse possible leaked file descriptors 18416 if (intent != null && intent.hasFileDescriptors() == true) { 18417 throw new IllegalArgumentException("File descriptors passed in Intent"); 18418 } 18419 18420 synchronized(this) { 18421 if (!(token instanceof ServiceRecord)) { 18422 throw new IllegalArgumentException("Invalid service token"); 18423 } 18424 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 18425 } 18426 } 18427 18428 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 18429 // Refuse possible leaked file descriptors 18430 if (intent != null && intent.hasFileDescriptors() == true) { 18431 throw new IllegalArgumentException("File descriptors passed in Intent"); 18432 } 18433 18434 synchronized(this) { 18435 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 18436 } 18437 } 18438 18439 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 18440 synchronized(this) { 18441 if (!(token instanceof ServiceRecord)) { 18442 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); 18443 throw new IllegalArgumentException("Invalid service token"); 18444 } 18445 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 18446 } 18447 } 18448 18449 // ========================================================= 18450 // BACKUP AND RESTORE 18451 // ========================================================= 18452 18453 // Cause the target app to be launched if necessary and its backup agent 18454 // instantiated. The backup agent will invoke backupAgentCreated() on the 18455 // activity manager to announce its creation. 18456 public boolean bindBackupAgent(String packageName, int backupMode, int userId) { 18457 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode); 18458 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 18459 18460 IPackageManager pm = AppGlobals.getPackageManager(); 18461 ApplicationInfo app = null; 18462 try { 18463 app = pm.getApplicationInfo(packageName, 0, userId); 18464 } catch (RemoteException e) { 18465 // can't happen; package manager is process-local 18466 } 18467 if (app == null) { 18468 Slog.w(TAG, "Unable to bind backup agent for " + packageName); 18469 return false; 18470 } 18471 18472 int oldBackupUid; 18473 int newBackupUid; 18474 18475 synchronized(this) { 18476 // !!! TODO: currently no check here that we're already bound 18477 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 18478 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 18479 synchronized (stats) { 18480 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 18481 } 18482 18483 // Backup agent is now in use, its package can't be stopped. 18484 try { 18485 AppGlobals.getPackageManager().setPackageStoppedState( 18486 app.packageName, false, UserHandle.getUserId(app.uid)); 18487 } catch (RemoteException e) { 18488 } catch (IllegalArgumentException e) { 18489 Slog.w(TAG, "Failed trying to unstop package " 18490 + app.packageName + ": " + e); 18491 } 18492 18493 BackupRecord r = new BackupRecord(ss, app, backupMode); 18494 ComponentName hostingName = 18495 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL) 18496 ? new ComponentName(app.packageName, app.backupAgentName) 18497 : new ComponentName("android", "FullBackupAgent"); 18498 // startProcessLocked() returns existing proc's record if it's already running 18499 ProcessRecord proc = startProcessLocked(app.processName, app, 18500 false, 0, "backup", hostingName, false, false, false); 18501 if (proc == null) { 18502 Slog.e(TAG, "Unable to start backup agent process " + r); 18503 return false; 18504 } 18505 18506 // If the app is a regular app (uid >= 10000) and not the system server or phone 18507 // process, etc, then mark it as being in full backup so that certain calls to the 18508 // process can be blocked. This is not reset to false anywhere because we kill the 18509 // process after the full backup is done and the ProcessRecord will vaporize anyway. 18510 if (UserHandle.isApp(app.uid) && 18511 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) { 18512 proc.inFullBackup = true; 18513 } 18514 r.app = proc; 18515 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1; 18516 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1; 18517 mBackupTarget = r; 18518 mBackupAppName = app.packageName; 18519 18520 // Try not to kill the process during backup 18521 updateOomAdjLocked(proc, true); 18522 18523 // If the process is already attached, schedule the creation of the backup agent now. 18524 // If it is not yet live, this will be done when it attaches to the framework. 18525 if (proc.thread != null) { 18526 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc); 18527 try { 18528 proc.thread.scheduleCreateBackupAgent(app, 18529 compatibilityInfoForPackageLocked(app), backupMode); 18530 } catch (RemoteException e) { 18531 // Will time out on the backup manager side 18532 } 18533 } else { 18534 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach"); 18535 } 18536 // Invariants: at this point, the target app process exists and the application 18537 // is either already running or in the process of coming up. mBackupTarget and 18538 // mBackupAppName describe the app, so that when it binds back to the AM we 18539 // know that it's scheduled for a backup-agent operation. 18540 } 18541 18542 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class); 18543 if (oldBackupUid != -1) { 18544 js.removeBackingUpUid(oldBackupUid); 18545 } 18546 if (newBackupUid != -1) { 18547 js.addBackingUpUid(newBackupUid); 18548 } 18549 18550 return true; 18551 } 18552 18553 @Override 18554 public void clearPendingBackup() { 18555 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup"); 18556 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 18557 18558 synchronized (this) { 18559 mBackupTarget = null; 18560 mBackupAppName = null; 18561 } 18562 18563 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class); 18564 js.clearAllBackingUpUids(); 18565 } 18566 18567 // A backup agent has just come up 18568 public void backupAgentCreated(String agentPackageName, IBinder agent) { 18569 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName 18570 + " = " + agent); 18571 18572 synchronized(this) { 18573 if (!agentPackageName.equals(mBackupAppName)) { 18574 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 18575 return; 18576 } 18577 } 18578 18579 long oldIdent = Binder.clearCallingIdentity(); 18580 try { 18581 IBackupManager bm = IBackupManager.Stub.asInterface( 18582 ServiceManager.getService(Context.BACKUP_SERVICE)); 18583 bm.agentConnected(agentPackageName, agent); 18584 } catch (RemoteException e) { 18585 // can't happen; the backup manager service is local 18586 } catch (Exception e) { 18587 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 18588 e.printStackTrace(); 18589 } finally { 18590 Binder.restoreCallingIdentity(oldIdent); 18591 } 18592 } 18593 18594 // done with this agent 18595 public void unbindBackupAgent(ApplicationInfo appInfo) { 18596 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo); 18597 if (appInfo == null) { 18598 Slog.w(TAG, "unbind backup agent for null app"); 18599 return; 18600 } 18601 18602 int oldBackupUid; 18603 18604 synchronized(this) { 18605 try { 18606 if (mBackupAppName == null) { 18607 Slog.w(TAG, "Unbinding backup agent with no active backup"); 18608 return; 18609 } 18610 18611 if (!mBackupAppName.equals(appInfo.packageName)) { 18612 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 18613 return; 18614 } 18615 18616 // Not backing this app up any more; reset its OOM adjustment 18617 final ProcessRecord proc = mBackupTarget.app; 18618 updateOomAdjLocked(proc, true); 18619 proc.inFullBackup = false; 18620 18621 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1; 18622 18623 // If the app crashed during backup, 'thread' will be null here 18624 if (proc.thread != null) { 18625 try { 18626 proc.thread.scheduleDestroyBackupAgent(appInfo, 18627 compatibilityInfoForPackageLocked(appInfo)); 18628 } catch (Exception e) { 18629 Slog.e(TAG, "Exception when unbinding backup agent:"); 18630 e.printStackTrace(); 18631 } 18632 } 18633 } finally { 18634 mBackupTarget = null; 18635 mBackupAppName = null; 18636 } 18637 } 18638 18639 if (oldBackupUid != -1) { 18640 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class); 18641 js.removeBackingUpUid(oldBackupUid); 18642 } 18643 } 18644 18645 // ========================================================= 18646 // BROADCASTS 18647 // ========================================================= 18648 18649 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) { 18650 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) { 18651 return false; 18652 } 18653 // Easy case -- we have the app's ProcessRecord. 18654 if (record != null) { 18655 return record.info.isInstantApp(); 18656 } 18657 // Otherwise check with PackageManager. 18658 if (callerPackage == null) { 18659 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name"); 18660 throw new IllegalArgumentException("Calling application did not provide package name"); 18661 } 18662 mAppOpsService.checkPackage(uid, callerPackage); 18663 try { 18664 IPackageManager pm = AppGlobals.getPackageManager(); 18665 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid)); 18666 } catch (RemoteException e) { 18667 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e); 18668 return true; 18669 } 18670 } 18671 18672 boolean isPendingBroadcastProcessLocked(int pid) { 18673 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 18674 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 18675 } 18676 18677 void skipPendingBroadcastLocked(int pid) { 18678 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 18679 for (BroadcastQueue queue : mBroadcastQueues) { 18680 queue.skipPendingBroadcastLocked(pid); 18681 } 18682 } 18683 18684 // The app just attached; send any pending broadcasts that it should receive 18685 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 18686 boolean didSomething = false; 18687 for (BroadcastQueue queue : mBroadcastQueues) { 18688 didSomething |= queue.sendPendingBroadcastsLocked(app); 18689 } 18690 return didSomething; 18691 } 18692 18693 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 18694 IIntentReceiver receiver, IntentFilter filter, String permission, int userId, 18695 int flags) { 18696 enforceNotIsolatedCaller("registerReceiver"); 18697 ArrayList<Intent> stickyIntents = null; 18698 ProcessRecord callerApp = null; 18699 final boolean visibleToInstantApps 18700 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0; 18701 int callingUid; 18702 int callingPid; 18703 boolean instantApp; 18704 synchronized(this) { 18705 if (caller != null) { 18706 callerApp = getRecordForAppLocked(caller); 18707 if (callerApp == null) { 18708 throw new SecurityException( 18709 "Unable to find app for caller " + caller 18710 + " (pid=" + Binder.getCallingPid() 18711 + ") when registering receiver " + receiver); 18712 } 18713 if (callerApp.info.uid != SYSTEM_UID && 18714 !callerApp.pkgList.containsKey(callerPackage) && 18715 !"android".equals(callerPackage)) { 18716 throw new SecurityException("Given caller package " + callerPackage 18717 + " is not running in process " + callerApp); 18718 } 18719 callingUid = callerApp.info.uid; 18720 callingPid = callerApp.pid; 18721 } else { 18722 callerPackage = null; 18723 callingUid = Binder.getCallingUid(); 18724 callingPid = Binder.getCallingPid(); 18725 } 18726 18727 instantApp = isInstantApp(callerApp, callerPackage, callingUid); 18728 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, 18729 ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 18730 18731 Iterator<String> actions = filter.actionsIterator(); 18732 if (actions == null) { 18733 ArrayList<String> noAction = new ArrayList<String>(1); 18734 noAction.add(null); 18735 actions = noAction.iterator(); 18736 } 18737 18738 // Collect stickies of users 18739 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) }; 18740 while (actions.hasNext()) { 18741 String action = actions.next(); 18742 for (int id : userIds) { 18743 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id); 18744 if (stickies != null) { 18745 ArrayList<Intent> intents = stickies.get(action); 18746 if (intents != null) { 18747 if (stickyIntents == null) { 18748 stickyIntents = new ArrayList<Intent>(); 18749 } 18750 stickyIntents.addAll(intents); 18751 } 18752 } 18753 } 18754 } 18755 } 18756 18757 ArrayList<Intent> allSticky = null; 18758 if (stickyIntents != null) { 18759 final ContentResolver resolver = mContext.getContentResolver(); 18760 // Look for any matching sticky broadcasts... 18761 for (int i = 0, N = stickyIntents.size(); i < N; i++) { 18762 Intent intent = stickyIntents.get(i); 18763 // Don't provided intents that aren't available to instant apps. 18764 if (instantApp && 18765 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) { 18766 continue; 18767 } 18768 // If intent has scheme "content", it will need to acccess 18769 // provider that needs to lock mProviderMap in ActivityThread 18770 // and also it may need to wait application response, so we 18771 // cannot lock ActivityManagerService here. 18772 if (filter.match(resolver, intent, true, TAG) >= 0) { 18773 if (allSticky == null) { 18774 allSticky = new ArrayList<Intent>(); 18775 } 18776 allSticky.add(intent); 18777 } 18778 } 18779 } 18780 18781 // The first sticky in the list is returned directly back to the client. 18782 Intent sticky = allSticky != null ? allSticky.get(0) : null; 18783 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky); 18784 if (receiver == null) { 18785 return sticky; 18786 } 18787 18788 synchronized (this) { 18789 if (callerApp != null && (callerApp.thread == null 18790 || callerApp.thread.asBinder() != caller.asBinder())) { 18791 // Original caller already died 18792 return null; 18793 } 18794 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 18795 if (rl == null) { 18796 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 18797 userId, receiver); 18798 if (rl.app != null) { 18799 rl.app.receivers.add(rl); 18800 } else { 18801 try { 18802 receiver.asBinder().linkToDeath(rl, 0); 18803 } catch (RemoteException e) { 18804 return sticky; 18805 } 18806 rl.linkedToDeath = true; 18807 } 18808 mRegisteredReceivers.put(receiver.asBinder(), rl); 18809 } else if (rl.uid != callingUid) { 18810 throw new IllegalArgumentException( 18811 "Receiver requested to register for uid " + callingUid 18812 + " was previously registered for uid " + rl.uid 18813 + " callerPackage is " + callerPackage); 18814 } else if (rl.pid != callingPid) { 18815 throw new IllegalArgumentException( 18816 "Receiver requested to register for pid " + callingPid 18817 + " was previously registered for pid " + rl.pid 18818 + " callerPackage is " + callerPackage); 18819 } else if (rl.userId != userId) { 18820 throw new IllegalArgumentException( 18821 "Receiver requested to register for user " + userId 18822 + " was previously registered for user " + rl.userId 18823 + " callerPackage is " + callerPackage); 18824 } 18825 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 18826 permission, callingUid, userId, instantApp, visibleToInstantApps); 18827 rl.add(bf); 18828 if (!bf.debugCheck()) { 18829 Slog.w(TAG, "==> For Dynamic broadcast"); 18830 } 18831 mReceiverResolver.addFilter(bf); 18832 18833 // Enqueue broadcasts for all existing stickies that match 18834 // this filter. 18835 if (allSticky != null) { 18836 ArrayList receivers = new ArrayList(); 18837 receivers.add(bf); 18838 18839 final int stickyCount = allSticky.size(); 18840 for (int i = 0; i < stickyCount; i++) { 18841 Intent intent = allSticky.get(i); 18842 BroadcastQueue queue = broadcastQueueForIntent(intent); 18843 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 18844 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers, 18845 null, 0, null, null, false, true, true, -1); 18846 queue.enqueueParallelBroadcastLocked(r); 18847 queue.scheduleBroadcastsLocked(); 18848 } 18849 } 18850 18851 return sticky; 18852 } 18853 } 18854 18855 public void unregisterReceiver(IIntentReceiver receiver) { 18856 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver); 18857 18858 final long origId = Binder.clearCallingIdentity(); 18859 try { 18860 boolean doTrim = false; 18861 18862 synchronized(this) { 18863 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 18864 if (rl != null) { 18865 final BroadcastRecord r = rl.curBroadcast; 18866 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) { 18867 final boolean doNext = r.queue.finishReceiverLocked( 18868 r, r.resultCode, r.resultData, r.resultExtras, 18869 r.resultAbort, false); 18870 if (doNext) { 18871 doTrim = true; 18872 r.queue.processNextBroadcast(false); 18873 } 18874 } 18875 18876 if (rl.app != null) { 18877 rl.app.receivers.remove(rl); 18878 } 18879 removeReceiverLocked(rl); 18880 if (rl.linkedToDeath) { 18881 rl.linkedToDeath = false; 18882 rl.receiver.asBinder().unlinkToDeath(rl, 0); 18883 } 18884 } 18885 } 18886 18887 // If we actually concluded any broadcasts, we might now be able 18888 // to trim the recipients' apps from our working set 18889 if (doTrim) { 18890 trimApplications(); 18891 return; 18892 } 18893 18894 } finally { 18895 Binder.restoreCallingIdentity(origId); 18896 } 18897 } 18898 18899 void removeReceiverLocked(ReceiverList rl) { 18900 mRegisteredReceivers.remove(rl.receiver.asBinder()); 18901 for (int i = rl.size() - 1; i >= 0; i--) { 18902 mReceiverResolver.removeFilter(rl.get(i)); 18903 } 18904 } 18905 18906 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 18907 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18908 ProcessRecord r = mLruProcesses.get(i); 18909 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 18910 try { 18911 r.thread.dispatchPackageBroadcast(cmd, packages); 18912 } catch (RemoteException ex) { 18913 } 18914 } 18915 } 18916 } 18917 18918 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 18919 int callingUid, int[] users) { 18920 // TODO: come back and remove this assumption to triage all broadcasts 18921 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING; 18922 18923 List<ResolveInfo> receivers = null; 18924 try { 18925 HashSet<ComponentName> singleUserReceivers = null; 18926 boolean scannedFirstReceivers = false; 18927 for (int user : users) { 18928 // Skip users that have Shell restrictions, with exception of always permitted 18929 // Shell broadcasts 18930 if (callingUid == SHELL_UID 18931 && mUserController.hasUserRestriction( 18932 UserManager.DISALLOW_DEBUGGING_FEATURES, user) 18933 && !isPermittedShellBroadcast(intent)) { 18934 continue; 18935 } 18936 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 18937 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList(); 18938 if (user != UserHandle.USER_SYSTEM && newReceivers != null) { 18939 // If this is not the system user, we need to check for 18940 // any receivers that should be filtered out. 18941 for (int i=0; i<newReceivers.size(); i++) { 18942 ResolveInfo ri = newReceivers.get(i); 18943 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 18944 newReceivers.remove(i); 18945 i--; 18946 } 18947 } 18948 } 18949 if (newReceivers != null && newReceivers.size() == 0) { 18950 newReceivers = null; 18951 } 18952 if (receivers == null) { 18953 receivers = newReceivers; 18954 } else if (newReceivers != null) { 18955 // We need to concatenate the additional receivers 18956 // found with what we have do far. This would be easy, 18957 // but we also need to de-dup any receivers that are 18958 // singleUser. 18959 if (!scannedFirstReceivers) { 18960 // Collect any single user receivers we had already retrieved. 18961 scannedFirstReceivers = true; 18962 for (int i=0; i<receivers.size(); i++) { 18963 ResolveInfo ri = receivers.get(i); 18964 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 18965 ComponentName cn = new ComponentName( 18966 ri.activityInfo.packageName, ri.activityInfo.name); 18967 if (singleUserReceivers == null) { 18968 singleUserReceivers = new HashSet<ComponentName>(); 18969 } 18970 singleUserReceivers.add(cn); 18971 } 18972 } 18973 } 18974 // Add the new results to the existing results, tracking 18975 // and de-dupping single user receivers. 18976 for (int i=0; i<newReceivers.size(); i++) { 18977 ResolveInfo ri = newReceivers.get(i); 18978 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 18979 ComponentName cn = new ComponentName( 18980 ri.activityInfo.packageName, ri.activityInfo.name); 18981 if (singleUserReceivers == null) { 18982 singleUserReceivers = new HashSet<ComponentName>(); 18983 } 18984 if (!singleUserReceivers.contains(cn)) { 18985 singleUserReceivers.add(cn); 18986 receivers.add(ri); 18987 } 18988 } else { 18989 receivers.add(ri); 18990 } 18991 } 18992 } 18993 } 18994 } catch (RemoteException ex) { 18995 // pm is in same process, this will never happen. 18996 } 18997 return receivers; 18998 } 18999 19000 private boolean isPermittedShellBroadcast(Intent intent) { 19001 // remote bugreport should always be allowed to be taken 19002 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction()); 19003 } 19004 19005 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp, 19006 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) { 19007 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) { 19008 // Don't yell about broadcasts sent via shell 19009 return; 19010 } 19011 19012 final String action = intent.getAction(); 19013 if (isProtectedBroadcast 19014 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) 19015 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action) 19016 || Intent.ACTION_MEDIA_BUTTON.equals(action) 19017 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action) 19018 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action) 19019 || Intent.ACTION_MASTER_CLEAR.equals(action) 19020 || Intent.ACTION_FACTORY_RESET.equals(action) 19021 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action) 19022 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action) 19023 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action) 19024 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action) 19025 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action) 19026 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action) 19027 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) { 19028 // Broadcast is either protected, or it's a public action that 19029 // we've relaxed, so it's fine for system internals to send. 19030 return; 19031 } 19032 19033 // This broadcast may be a problem... but there are often system components that 19034 // want to send an internal broadcast to themselves, which is annoying to have to 19035 // explicitly list each action as a protected broadcast, so we will check for that 19036 // one safe case and allow it: an explicit broadcast, only being received by something 19037 // that has protected itself. 19038 if (receivers != null && receivers.size() > 0 19039 && (intent.getPackage() != null || intent.getComponent() != null)) { 19040 boolean allProtected = true; 19041 for (int i = receivers.size()-1; i >= 0; i--) { 19042 Object target = receivers.get(i); 19043 if (target instanceof ResolveInfo) { 19044 ResolveInfo ri = (ResolveInfo)target; 19045 if (ri.activityInfo.exported && ri.activityInfo.permission == null) { 19046 allProtected = false; 19047 break; 19048 } 19049 } else { 19050 BroadcastFilter bf = (BroadcastFilter)target; 19051 if (bf.requiredPermission == null) { 19052 allProtected = false; 19053 break; 19054 } 19055 } 19056 } 19057 if (allProtected) { 19058 // All safe! 19059 return; 19060 } 19061 } 19062 19063 // The vast majority of broadcasts sent from system internals 19064 // should be protected to avoid security holes, so yell loudly 19065 // to ensure we examine these cases. 19066 if (callerApp != null) { 19067 Log.wtf(TAG, "Sending non-protected broadcast " + action 19068 + " from system " + callerApp.toShortString() + " pkg " + callerPackage, 19069 new Throwable()); 19070 } else { 19071 Log.wtf(TAG, "Sending non-protected broadcast " + action 19072 + " from system uid " + UserHandle.formatUid(callingUid) 19073 + " pkg " + callerPackage, 19074 new Throwable()); 19075 } 19076 } 19077 19078 final int broadcastIntentLocked(ProcessRecord callerApp, 19079 String callerPackage, Intent intent, String resolvedType, 19080 IIntentReceiver resultTo, int resultCode, String resultData, 19081 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, 19082 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) { 19083 intent = new Intent(intent); 19084 19085 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid); 19086 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS 19087 if (callerInstantApp) { 19088 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 19089 } 19090 19091 // By default broadcasts do not go to stopped apps. 19092 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 19093 19094 // If we have not finished booting, don't allow this to launch new processes. 19095 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 19096 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19097 } 19098 19099 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, 19100 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 19101 + " ordered=" + ordered + " userid=" + userId); 19102 if ((resultTo != null) && !ordered) { 19103 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 19104 } 19105 19106 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, 19107 ALLOW_NON_FULL, "broadcast", callerPackage); 19108 19109 // Make sure that the user who is receiving this broadcast is running. 19110 // If not, we will just skip it. Make an exception for shutdown broadcasts 19111 // and upgrade steps. 19112 19113 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) { 19114 if ((callingUid != SYSTEM_UID 19115 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 19116 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 19117 Slog.w(TAG, "Skipping broadcast of " + intent 19118 + ": user " + userId + " is stopped"); 19119 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 19120 } 19121 } 19122 19123 BroadcastOptions brOptions = null; 19124 if (bOptions != null) { 19125 brOptions = new BroadcastOptions(bOptions); 19126 if (brOptions.getTemporaryAppWhitelistDuration() > 0) { 19127 // See if the caller is allowed to do this. Note we are checking against 19128 // the actual real caller (not whoever provided the operation as say a 19129 // PendingIntent), because that who is actually supplied the arguments. 19130 if (checkComponentPermission( 19131 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, 19132 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 19133 != PackageManager.PERMISSION_GRANTED) { 19134 String msg = "Permission Denial: " + intent.getAction() 19135 + " broadcast from " + callerPackage + " (pid=" + callingPid 19136 + ", uid=" + callingUid + ")" 19137 + " requires " 19138 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; 19139 Slog.w(TAG, msg); 19140 throw new SecurityException(msg); 19141 } 19142 } 19143 } 19144 19145 // Verify that protected broadcasts are only being sent by system code, 19146 // and that system code is only sending protected broadcasts. 19147 final String action = intent.getAction(); 19148 final boolean isProtectedBroadcast; 19149 try { 19150 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action); 19151 } catch (RemoteException e) { 19152 Slog.w(TAG, "Remote exception", e); 19153 return ActivityManager.BROADCAST_SUCCESS; 19154 } 19155 19156 final boolean isCallerSystem; 19157 switch (UserHandle.getAppId(callingUid)) { 19158 case ROOT_UID: 19159 case SYSTEM_UID: 19160 case PHONE_UID: 19161 case BLUETOOTH_UID: 19162 case NFC_UID: 19163 isCallerSystem = true; 19164 break; 19165 default: 19166 isCallerSystem = (callerApp != null) && callerApp.persistent; 19167 break; 19168 } 19169 19170 // First line security check before anything else: stop non-system apps from 19171 // sending protected broadcasts. 19172 if (!isCallerSystem) { 19173 if (isProtectedBroadcast) { 19174 String msg = "Permission Denial: not allowed to send broadcast " 19175 + action + " from pid=" 19176 + callingPid + ", uid=" + callingUid; 19177 Slog.w(TAG, msg); 19178 throw new SecurityException(msg); 19179 19180 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action) 19181 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { 19182 // Special case for compatibility: we don't want apps to send this, 19183 // but historically it has not been protected and apps may be using it 19184 // to poke their own app widget. So, instead of making it protected, 19185 // just limit it to the caller. 19186 if (callerPackage == null) { 19187 String msg = "Permission Denial: not allowed to send broadcast " 19188 + action + " from unknown caller."; 19189 Slog.w(TAG, msg); 19190 throw new SecurityException(msg); 19191 } else if (intent.getComponent() != null) { 19192 // They are good enough to send to an explicit component... verify 19193 // it is being sent to the calling app. 19194 if (!intent.getComponent().getPackageName().equals( 19195 callerPackage)) { 19196 String msg = "Permission Denial: not allowed to send broadcast " 19197 + action + " to " 19198 + intent.getComponent().getPackageName() + " from " 19199 + callerPackage; 19200 Slog.w(TAG, msg); 19201 throw new SecurityException(msg); 19202 } 19203 } else { 19204 // Limit broadcast to their own package. 19205 intent.setPackage(callerPackage); 19206 } 19207 } 19208 } 19209 19210 if (action != null) { 19211 if (getBackgroundLaunchBroadcasts().contains(action)) { 19212 if (DEBUG_BACKGROUND_CHECK) { 19213 Slog.i(TAG, "Broadcast action " + action + " forcing include-background"); 19214 } 19215 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 19216 } 19217 19218 switch (action) { 19219 case Intent.ACTION_UID_REMOVED: 19220 case Intent.ACTION_PACKAGE_REMOVED: 19221 case Intent.ACTION_PACKAGE_CHANGED: 19222 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 19223 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 19224 case Intent.ACTION_PACKAGES_SUSPENDED: 19225 case Intent.ACTION_PACKAGES_UNSUSPENDED: 19226 // Handle special intents: if this broadcast is from the package 19227 // manager about a package being removed, we need to remove all of 19228 // its activities from the history stack. 19229 if (checkComponentPermission( 19230 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 19231 callingPid, callingUid, -1, true) 19232 != PackageManager.PERMISSION_GRANTED) { 19233 String msg = "Permission Denial: " + intent.getAction() 19234 + " broadcast from " + callerPackage + " (pid=" + callingPid 19235 + ", uid=" + callingUid + ")" 19236 + " requires " 19237 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 19238 Slog.w(TAG, msg); 19239 throw new SecurityException(msg); 19240 } 19241 switch (action) { 19242 case Intent.ACTION_UID_REMOVED: 19243 final int uid = getUidFromIntent(intent); 19244 if (uid >= 0) { 19245 mBatteryStatsService.removeUid(uid); 19246 mAppOpsService.uidRemoved(uid); 19247 } 19248 break; 19249 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 19250 // If resources are unavailable just force stop all those packages 19251 // and flush the attribute cache as well. 19252 String list[] = 19253 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 19254 if (list != null && list.length > 0) { 19255 for (int i = 0; i < list.length; i++) { 19256 forceStopPackageLocked(list[i], -1, false, true, true, 19257 false, false, userId, "storage unmount"); 19258 } 19259 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 19260 sendPackageBroadcastLocked( 19261 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE, 19262 list, userId); 19263 } 19264 break; 19265 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 19266 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 19267 break; 19268 case Intent.ACTION_PACKAGE_REMOVED: 19269 case Intent.ACTION_PACKAGE_CHANGED: 19270 Uri data = intent.getData(); 19271 String ssp; 19272 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 19273 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 19274 final boolean replacing = 19275 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 19276 final boolean killProcess = 19277 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false); 19278 final boolean fullUninstall = removed && !replacing; 19279 if (removed) { 19280 if (killProcess) { 19281 forceStopPackageLocked(ssp, UserHandle.getAppId( 19282 intent.getIntExtra(Intent.EXTRA_UID, -1)), 19283 false, true, true, false, fullUninstall, userId, 19284 removed ? "pkg removed" : "pkg changed"); 19285 } 19286 final int cmd = killProcess 19287 ? ApplicationThreadConstants.PACKAGE_REMOVED 19288 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL; 19289 sendPackageBroadcastLocked(cmd, 19290 new String[] {ssp}, userId); 19291 if (fullUninstall) { 19292 mAppOpsService.packageRemoved( 19293 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 19294 19295 // Remove all permissions granted from/to this package 19296 removeUriPermissionsForPackageLocked(ssp, userId, true); 19297 19298 removeTasksByPackageNameLocked(ssp, userId); 19299 19300 mServices.forceStopPackageLocked(ssp, userId); 19301 19302 // Hide the "unsupported display" dialog if necessary. 19303 if (mUnsupportedDisplaySizeDialog != null && ssp.equals( 19304 mUnsupportedDisplaySizeDialog.getPackageName())) { 19305 mUnsupportedDisplaySizeDialog.dismiss(); 19306 mUnsupportedDisplaySizeDialog = null; 19307 } 19308 mCompatModePackages.handlePackageUninstalledLocked(ssp); 19309 mBatteryStatsService.notePackageUninstalled(ssp); 19310 } 19311 } else { 19312 if (killProcess) { 19313 killPackageProcessesLocked(ssp, UserHandle.getAppId( 19314 intent.getIntExtra(Intent.EXTRA_UID, -1)), 19315 userId, ProcessList.INVALID_ADJ, 19316 false, true, true, false, "change " + ssp); 19317 } 19318 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess, 19319 intent.getStringArrayExtra( 19320 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST)); 19321 } 19322 } 19323 break; 19324 case Intent.ACTION_PACKAGES_SUSPENDED: 19325 case Intent.ACTION_PACKAGES_UNSUSPENDED: 19326 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals( 19327 intent.getAction()); 19328 final String[] packageNames = intent.getStringArrayExtra( 19329 Intent.EXTRA_CHANGED_PACKAGE_LIST); 19330 final int userHandle = intent.getIntExtra( 19331 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 19332 19333 synchronized(ActivityManagerService.this) { 19334 mRecentTasks.onPackagesSuspendedChanged( 19335 packageNames, suspended, userHandle); 19336 } 19337 break; 19338 } 19339 break; 19340 case Intent.ACTION_PACKAGE_REPLACED: 19341 { 19342 final Uri data = intent.getData(); 19343 final String ssp; 19344 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 19345 ApplicationInfo aInfo = null; 19346 try { 19347 aInfo = AppGlobals.getPackageManager() 19348 .getApplicationInfo(ssp, 0 /*flags*/, userId); 19349 } catch (RemoteException ignore) {} 19350 if (aInfo == null) { 19351 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:" 19352 + " ssp=" + ssp + " data=" + data); 19353 return ActivityManager.BROADCAST_SUCCESS; 19354 } 19355 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo); 19356 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED, 19357 new String[] {ssp}, userId); 19358 } 19359 break; 19360 } 19361 case Intent.ACTION_PACKAGE_ADDED: 19362 { 19363 // Special case for adding a package: by default turn on compatibility mode. 19364 Uri data = intent.getData(); 19365 String ssp; 19366 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 19367 final boolean replacing = 19368 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 19369 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 19370 19371 try { 19372 ApplicationInfo ai = AppGlobals.getPackageManager(). 19373 getApplicationInfo(ssp, 0, 0); 19374 mBatteryStatsService.notePackageInstalled(ssp, 19375 ai != null ? ai.versionCode : 0); 19376 } catch (RemoteException e) { 19377 } 19378 } 19379 break; 19380 } 19381 case Intent.ACTION_PACKAGE_DATA_CLEARED: 19382 { 19383 Uri data = intent.getData(); 19384 String ssp; 19385 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 19386 // Hide the "unsupported display" dialog if necessary. 19387 if (mUnsupportedDisplaySizeDialog != null && ssp.equals( 19388 mUnsupportedDisplaySizeDialog.getPackageName())) { 19389 mUnsupportedDisplaySizeDialog.dismiss(); 19390 mUnsupportedDisplaySizeDialog = null; 19391 } 19392 mCompatModePackages.handlePackageDataClearedLocked(ssp); 19393 } 19394 break; 19395 } 19396 case Intent.ACTION_TIMEZONE_CHANGED: 19397 // If this is the time zone changed action, queue up a message that will reset 19398 // the timezone of all currently running processes. This message will get 19399 // queued up before the broadcast happens. 19400 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 19401 break; 19402 case Intent.ACTION_TIME_CHANGED: 19403 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between 19404 // the tri-state value it may contain and "unknown". 19405 // For convenience we re-use the Intent extra values. 19406 final int NO_EXTRA_VALUE_FOUND = -1; 19407 final int timeFormatPreferenceMsgValue = intent.getIntExtra( 19408 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, 19409 NO_EXTRA_VALUE_FOUND /* defaultValue */); 19410 // Only send a message if the time preference is available. 19411 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) { 19412 Message updateTimePreferenceMsg = 19413 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG, 19414 timeFormatPreferenceMsgValue, 0); 19415 mHandler.sendMessage(updateTimePreferenceMsg); 19416 } 19417 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 19418 synchronized (stats) { 19419 stats.noteCurrentTimeChangedLocked(); 19420 } 19421 break; 19422 case Intent.ACTION_CLEAR_DNS_CACHE: 19423 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 19424 break; 19425 case Proxy.PROXY_CHANGE_ACTION: 19426 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 19427 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 19428 break; 19429 case android.hardware.Camera.ACTION_NEW_PICTURE: 19430 case android.hardware.Camera.ACTION_NEW_VIDEO: 19431 // In N we just turned these off; in O we are turing them back on partly, 19432 // only for registered receivers. This will still address the main problem 19433 // (a spam of apps waking up when a picture is taken putting significant 19434 // memory pressure on the system at a bad point), while still allowing apps 19435 // that are already actively running to know about this happening. 19436 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19437 break; 19438 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED: 19439 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG); 19440 break; 19441 case "com.android.launcher.action.INSTALL_SHORTCUT": 19442 // As of O, we no longer support this broadcasts, even for pre-O apps. 19443 // Apps should now be using ShortcutManager.pinRequestShortcut(). 19444 Log.w(TAG, "Broadcast " + action 19445 + " no longer supported. It will not be delivered."); 19446 return ActivityManager.BROADCAST_SUCCESS; 19447 } 19448 19449 if (Intent.ACTION_PACKAGE_ADDED.equals(action) || 19450 Intent.ACTION_PACKAGE_REMOVED.equals(action) || 19451 Intent.ACTION_PACKAGE_REPLACED.equals(action)) { 19452 final int uid = getUidFromIntent(intent); 19453 if (uid != -1) { 19454 final UidRecord uidRec = mActiveUids.get(uid); 19455 if (uidRec != null) { 19456 uidRec.updateHasInternetPermission(); 19457 } 19458 } 19459 } 19460 } 19461 19462 // Add to the sticky list if requested. 19463 if (sticky) { 19464 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 19465 callingPid, callingUid) 19466 != PackageManager.PERMISSION_GRANTED) { 19467 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 19468 + callingPid + ", uid=" + callingUid 19469 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 19470 Slog.w(TAG, msg); 19471 throw new SecurityException(msg); 19472 } 19473 if (requiredPermissions != null && requiredPermissions.length > 0) { 19474 Slog.w(TAG, "Can't broadcast sticky intent " + intent 19475 + " and enforce permissions " + Arrays.toString(requiredPermissions)); 19476 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 19477 } 19478 if (intent.getComponent() != null) { 19479 throw new SecurityException( 19480 "Sticky broadcasts can't target a specific component"); 19481 } 19482 // We use userId directly here, since the "all" target is maintained 19483 // as a separate set of sticky broadcasts. 19484 if (userId != UserHandle.USER_ALL) { 19485 // But first, if this is not a broadcast to all users, then 19486 // make sure it doesn't conflict with an existing broadcast to 19487 // all users. 19488 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 19489 UserHandle.USER_ALL); 19490 if (stickies != null) { 19491 ArrayList<Intent> list = stickies.get(intent.getAction()); 19492 if (list != null) { 19493 int N = list.size(); 19494 int i; 19495 for (i=0; i<N; i++) { 19496 if (intent.filterEquals(list.get(i))) { 19497 throw new IllegalArgumentException( 19498 "Sticky broadcast " + intent + " for user " 19499 + userId + " conflicts with existing global broadcast"); 19500 } 19501 } 19502 } 19503 } 19504 } 19505 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 19506 if (stickies == null) { 19507 stickies = new ArrayMap<>(); 19508 mStickyBroadcasts.put(userId, stickies); 19509 } 19510 ArrayList<Intent> list = stickies.get(intent.getAction()); 19511 if (list == null) { 19512 list = new ArrayList<>(); 19513 stickies.put(intent.getAction(), list); 19514 } 19515 final int stickiesCount = list.size(); 19516 int i; 19517 for (i = 0; i < stickiesCount; i++) { 19518 if (intent.filterEquals(list.get(i))) { 19519 // This sticky already exists, replace it. 19520 list.set(i, new Intent(intent)); 19521 break; 19522 } 19523 } 19524 if (i >= stickiesCount) { 19525 list.add(new Intent(intent)); 19526 } 19527 } 19528 19529 int[] users; 19530 if (userId == UserHandle.USER_ALL) { 19531 // Caller wants broadcast to go to all started users. 19532 users = mUserController.getStartedUserArrayLocked(); 19533 } else { 19534 // Caller wants broadcast to go to one specific user. 19535 users = new int[] {userId}; 19536 } 19537 19538 // Figure out who all will receive this broadcast. 19539 List receivers = null; 19540 List<BroadcastFilter> registeredReceivers = null; 19541 // Need to resolve the intent to interested receivers... 19542 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 19543 == 0) { 19544 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 19545 } 19546 if (intent.getComponent() == null) { 19547 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) { 19548 // Query one target user at a time, excluding shell-restricted users 19549 for (int i = 0; i < users.length; i++) { 19550 if (mUserController.hasUserRestriction( 19551 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 19552 continue; 19553 } 19554 List<BroadcastFilter> registeredReceiversForUser = 19555 mReceiverResolver.queryIntent(intent, 19556 resolvedType, false /*defaultOnly*/, users[i]); 19557 if (registeredReceivers == null) { 19558 registeredReceivers = registeredReceiversForUser; 19559 } else if (registeredReceiversForUser != null) { 19560 registeredReceivers.addAll(registeredReceiversForUser); 19561 } 19562 } 19563 } else { 19564 registeredReceivers = mReceiverResolver.queryIntent(intent, 19565 resolvedType, false /*defaultOnly*/, userId); 19566 } 19567 } 19568 19569 final boolean replacePending = 19570 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 19571 19572 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction() 19573 + " replacePending=" + replacePending); 19574 19575 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 19576 if (!ordered && NR > 0) { 19577 // If we are not serializing this broadcast, then send the 19578 // registered receivers separately so they don't wait for the 19579 // components to be launched. 19580 if (isCallerSystem) { 19581 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, 19582 isProtectedBroadcast, registeredReceivers); 19583 } 19584 final BroadcastQueue queue = broadcastQueueForIntent(intent); 19585 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 19586 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType, 19587 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo, 19588 resultCode, resultData, resultExtras, ordered, sticky, false, userId); 19589 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r); 19590 final boolean replaced = replacePending 19591 && (queue.replaceParallelBroadcastLocked(r) != null); 19592 // Note: We assume resultTo is null for non-ordered broadcasts. 19593 if (!replaced) { 19594 queue.enqueueParallelBroadcastLocked(r); 19595 queue.scheduleBroadcastsLocked(); 19596 } 19597 registeredReceivers = null; 19598 NR = 0; 19599 } 19600 19601 // Merge into one list. 19602 int ir = 0; 19603 if (receivers != null) { 19604 // A special case for PACKAGE_ADDED: do not allow the package 19605 // being added to see this broadcast. This prevents them from 19606 // using this as a back door to get run as soon as they are 19607 // installed. Maybe in the future we want to have a special install 19608 // broadcast or such for apps, but we'd like to deliberately make 19609 // this decision. 19610 String skipPackages[] = null; 19611 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 19612 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 19613 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 19614 Uri data = intent.getData(); 19615 if (data != null) { 19616 String pkgName = data.getSchemeSpecificPart(); 19617 if (pkgName != null) { 19618 skipPackages = new String[] { pkgName }; 19619 } 19620 } 19621 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 19622 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 19623 } 19624 if (skipPackages != null && (skipPackages.length > 0)) { 19625 for (String skipPackage : skipPackages) { 19626 if (skipPackage != null) { 19627 int NT = receivers.size(); 19628 for (int it=0; it<NT; it++) { 19629 ResolveInfo curt = (ResolveInfo)receivers.get(it); 19630 if (curt.activityInfo.packageName.equals(skipPackage)) { 19631 receivers.remove(it); 19632 it--; 19633 NT--; 19634 } 19635 } 19636 } 19637 } 19638 } 19639 19640 int NT = receivers != null ? receivers.size() : 0; 19641 int it = 0; 19642 ResolveInfo curt = null; 19643 BroadcastFilter curr = null; 19644 while (it < NT && ir < NR) { 19645 if (curt == null) { 19646 curt = (ResolveInfo)receivers.get(it); 19647 } 19648 if (curr == null) { 19649 curr = registeredReceivers.get(ir); 19650 } 19651 if (curr.getPriority() >= curt.priority) { 19652 // Insert this broadcast record into the final list. 19653 receivers.add(it, curr); 19654 ir++; 19655 curr = null; 19656 it++; 19657 NT++; 19658 } else { 19659 // Skip to the next ResolveInfo in the final list. 19660 it++; 19661 curt = null; 19662 } 19663 } 19664 } 19665 while (ir < NR) { 19666 if (receivers == null) { 19667 receivers = new ArrayList(); 19668 } 19669 receivers.add(registeredReceivers.get(ir)); 19670 ir++; 19671 } 19672 19673 if (isCallerSystem) { 19674 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, 19675 isProtectedBroadcast, receivers); 19676 } 19677 19678 if ((receivers != null && receivers.size() > 0) 19679 || resultTo != null) { 19680 BroadcastQueue queue = broadcastQueueForIntent(intent); 19681 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 19682 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType, 19683 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode, 19684 resultData, resultExtras, ordered, sticky, false, userId); 19685 19686 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r 19687 + ": prev had " + queue.mOrderedBroadcasts.size()); 19688 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST, 19689 "Enqueueing broadcast " + r.intent.getAction()); 19690 19691 final BroadcastRecord oldRecord = 19692 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null; 19693 if (oldRecord != null) { 19694 // Replaced, fire the result-to receiver. 19695 if (oldRecord.resultTo != null) { 19696 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent); 19697 try { 19698 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo, 19699 oldRecord.intent, 19700 Activity.RESULT_CANCELED, null, null, 19701 false, false, oldRecord.userId); 19702 } catch (RemoteException e) { 19703 Slog.w(TAG, "Failure [" 19704 + queue.mQueueName + "] sending broadcast result of " 19705 + intent, e); 19706 19707 } 19708 } 19709 } else { 19710 queue.enqueueOrderedBroadcastLocked(r); 19711 queue.scheduleBroadcastsLocked(); 19712 } 19713 } else { 19714 // There was nobody interested in the broadcast, but we still want to record 19715 // that it happened. 19716 if (intent.getComponent() == null && intent.getPackage() == null 19717 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 19718 // This was an implicit broadcast... let's record it for posterity. 19719 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0); 19720 } 19721 } 19722 19723 return ActivityManager.BROADCAST_SUCCESS; 19724 } 19725 19726 /** 19727 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1 19728 */ 19729 private int getUidFromIntent(Intent intent) { 19730 if (intent == null) { 19731 return -1; 19732 } 19733 final Bundle intentExtras = intent.getExtras(); 19734 return intent.hasExtra(Intent.EXTRA_UID) 19735 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 19736 } 19737 19738 final void rotateBroadcastStatsIfNeededLocked() { 19739 final long now = SystemClock.elapsedRealtime(); 19740 if (mCurBroadcastStats == null || 19741 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) { 19742 mLastBroadcastStats = mCurBroadcastStats; 19743 if (mLastBroadcastStats != null) { 19744 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime(); 19745 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis(); 19746 } 19747 mCurBroadcastStats = new BroadcastStats(); 19748 } 19749 } 19750 19751 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount, 19752 int skipCount, long dispatchTime) { 19753 rotateBroadcastStatsIfNeededLocked(); 19754 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime); 19755 } 19756 19757 final void addBackgroundCheckViolationLocked(String action, String targetPackage) { 19758 rotateBroadcastStatsIfNeededLocked(); 19759 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage); 19760 } 19761 19762 final Intent verifyBroadcastLocked(Intent intent) { 19763 // Refuse possible leaked file descriptors 19764 if (intent != null && intent.hasFileDescriptors() == true) { 19765 throw new IllegalArgumentException("File descriptors passed in Intent"); 19766 } 19767 19768 int flags = intent.getFlags(); 19769 19770 if (!mProcessesReady) { 19771 // if the caller really truly claims to know what they're doing, go 19772 // ahead and allow the broadcast without launching any receivers 19773 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 19774 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed. 19775 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 19776 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 19777 + " before boot completion"); 19778 throw new IllegalStateException("Cannot broadcast before boot completed"); 19779 } 19780 } 19781 19782 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 19783 throw new IllegalArgumentException( 19784 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 19785 } 19786 19787 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) { 19788 switch (Binder.getCallingUid()) { 19789 case ROOT_UID: 19790 case SHELL_UID: 19791 break; 19792 default: 19793 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID " 19794 + Binder.getCallingUid()); 19795 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL); 19796 break; 19797 } 19798 } 19799 19800 return intent; 19801 } 19802 19803 public final int broadcastIntent(IApplicationThread caller, 19804 Intent intent, String resolvedType, IIntentReceiver resultTo, 19805 int resultCode, String resultData, Bundle resultExtras, 19806 String[] requiredPermissions, int appOp, Bundle bOptions, 19807 boolean serialized, boolean sticky, int userId) { 19808 enforceNotIsolatedCaller("broadcastIntent"); 19809 synchronized(this) { 19810 intent = verifyBroadcastLocked(intent); 19811 19812 final ProcessRecord callerApp = getRecordForAppLocked(caller); 19813 final int callingPid = Binder.getCallingPid(); 19814 final int callingUid = Binder.getCallingUid(); 19815 final long origId = Binder.clearCallingIdentity(); 19816 int res = broadcastIntentLocked(callerApp, 19817 callerApp != null ? callerApp.info.packageName : null, 19818 intent, resolvedType, resultTo, resultCode, resultData, resultExtras, 19819 requiredPermissions, appOp, bOptions, serialized, sticky, 19820 callingPid, callingUid, userId); 19821 Binder.restoreCallingIdentity(origId); 19822 return res; 19823 } 19824 } 19825 19826 19827 int broadcastIntentInPackage(String packageName, int uid, 19828 Intent intent, String resolvedType, IIntentReceiver resultTo, 19829 int resultCode, String resultData, Bundle resultExtras, 19830 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky, 19831 int userId) { 19832 synchronized(this) { 19833 intent = verifyBroadcastLocked(intent); 19834 19835 final long origId = Binder.clearCallingIdentity(); 19836 String[] requiredPermissions = requiredPermission == null ? null 19837 : new String[] {requiredPermission}; 19838 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 19839 resultTo, resultCode, resultData, resultExtras, 19840 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized, 19841 sticky, -1, uid, userId); 19842 Binder.restoreCallingIdentity(origId); 19843 return res; 19844 } 19845 } 19846 19847 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 19848 // Refuse possible leaked file descriptors 19849 if (intent != null && intent.hasFileDescriptors() == true) { 19850 throw new IllegalArgumentException("File descriptors passed in Intent"); 19851 } 19852 19853 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 19854 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 19855 19856 synchronized(this) { 19857 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 19858 != PackageManager.PERMISSION_GRANTED) { 19859 String msg = "Permission Denial: unbroadcastIntent() from pid=" 19860 + Binder.getCallingPid() 19861 + ", uid=" + Binder.getCallingUid() 19862 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 19863 Slog.w(TAG, msg); 19864 throw new SecurityException(msg); 19865 } 19866 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 19867 if (stickies != null) { 19868 ArrayList<Intent> list = stickies.get(intent.getAction()); 19869 if (list != null) { 19870 int N = list.size(); 19871 int i; 19872 for (i=0; i<N; i++) { 19873 if (intent.filterEquals(list.get(i))) { 19874 list.remove(i); 19875 break; 19876 } 19877 } 19878 if (list.size() <= 0) { 19879 stickies.remove(intent.getAction()); 19880 } 19881 } 19882 if (stickies.size() <= 0) { 19883 mStickyBroadcasts.remove(userId); 19884 } 19885 } 19886 } 19887 } 19888 19889 void backgroundServicesFinishedLocked(int userId) { 19890 for (BroadcastQueue queue : mBroadcastQueues) { 19891 queue.backgroundServicesFinishedLocked(userId); 19892 } 19893 } 19894 19895 public void finishReceiver(IBinder who, int resultCode, String resultData, 19896 Bundle resultExtras, boolean resultAbort, int flags) { 19897 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who); 19898 19899 // Refuse possible leaked file descriptors 19900 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 19901 throw new IllegalArgumentException("File descriptors passed in Bundle"); 19902 } 19903 19904 final long origId = Binder.clearCallingIdentity(); 19905 try { 19906 boolean doNext = false; 19907 BroadcastRecord r; 19908 19909 synchronized(this) { 19910 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0 19911 ? mFgBroadcastQueue : mBgBroadcastQueue; 19912 r = queue.getMatchingOrderedReceiver(who); 19913 if (r != null) { 19914 doNext = r.queue.finishReceiverLocked(r, resultCode, 19915 resultData, resultExtras, resultAbort, true); 19916 } 19917 } 19918 19919 if (doNext) { 19920 r.queue.processNextBroadcast(false); 19921 } 19922 trimApplications(); 19923 } finally { 19924 Binder.restoreCallingIdentity(origId); 19925 } 19926 } 19927 19928 // ========================================================= 19929 // INSTRUMENTATION 19930 // ========================================================= 19931 19932 public boolean startInstrumentation(ComponentName className, 19933 String profileFile, int flags, Bundle arguments, 19934 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 19935 int userId, String abiOverride) { 19936 enforceNotIsolatedCaller("startInstrumentation"); 19937 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 19938 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 19939 // Refuse possible leaked file descriptors 19940 if (arguments != null && arguments.hasFileDescriptors()) { 19941 throw new IllegalArgumentException("File descriptors passed in Bundle"); 19942 } 19943 19944 synchronized(this) { 19945 InstrumentationInfo ii = null; 19946 ApplicationInfo ai = null; 19947 try { 19948 ii = mContext.getPackageManager().getInstrumentationInfo( 19949 className, STOCK_PM_FLAGS); 19950 ai = AppGlobals.getPackageManager().getApplicationInfo( 19951 ii.targetPackage, STOCK_PM_FLAGS, userId); 19952 } catch (PackageManager.NameNotFoundException e) { 19953 } catch (RemoteException e) { 19954 } 19955 if (ii == null) { 19956 reportStartInstrumentationFailureLocked(watcher, className, 19957 "Unable to find instrumentation info for: " + className); 19958 return false; 19959 } 19960 if (ai == null) { 19961 reportStartInstrumentationFailureLocked(watcher, className, 19962 "Unable to find instrumentation target package: " + ii.targetPackage); 19963 return false; 19964 } 19965 if (!ai.hasCode()) { 19966 reportStartInstrumentationFailureLocked(watcher, className, 19967 "Instrumentation target has no code: " + ii.targetPackage); 19968 return false; 19969 } 19970 19971 int match = mContext.getPackageManager().checkSignatures( 19972 ii.targetPackage, ii.packageName); 19973 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 19974 String msg = "Permission Denial: starting instrumentation " 19975 + className + " from pid=" 19976 + Binder.getCallingPid() 19977 + ", uid=" + Binder.getCallingPid() 19978 + " not allowed because package " + ii.packageName 19979 + " does not have a signature matching the target " 19980 + ii.targetPackage; 19981 reportStartInstrumentationFailureLocked(watcher, className, msg); 19982 throw new SecurityException(msg); 19983 } 19984 19985 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this); 19986 activeInstr.mClass = className; 19987 String defProcess = ai.processName;; 19988 if (ii.targetProcesses == null) { 19989 activeInstr.mTargetProcesses = new String[]{ai.processName}; 19990 } else if (ii.targetProcesses.equals("*")) { 19991 activeInstr.mTargetProcesses = new String[0]; 19992 } else { 19993 activeInstr.mTargetProcesses = ii.targetProcesses.split(","); 19994 defProcess = activeInstr.mTargetProcesses[0]; 19995 } 19996 activeInstr.mTargetInfo = ai; 19997 activeInstr.mProfileFile = profileFile; 19998 activeInstr.mArguments = arguments; 19999 activeInstr.mWatcher = watcher; 20000 activeInstr.mUiAutomationConnection = uiAutomationConnection; 20001 activeInstr.mResultClass = className; 20002 20003 final long origId = Binder.clearCallingIdentity(); 20004 // Instrumentation can kill and relaunch even persistent processes 20005 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 20006 "start instr"); 20007 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride); 20008 app.instr = activeInstr; 20009 activeInstr.mFinished = false; 20010 activeInstr.mRunningProcesses.add(app); 20011 if (!mActiveInstrumentation.contains(activeInstr)) { 20012 mActiveInstrumentation.add(activeInstr); 20013 } 20014 Binder.restoreCallingIdentity(origId); 20015 } 20016 20017 return true; 20018 } 20019 20020 /** 20021 * Report errors that occur while attempting to start Instrumentation. Always writes the 20022 * error to the logs, but if somebody is watching, send the report there too. This enables 20023 * the "am" command to report errors with more information. 20024 * 20025 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 20026 * @param cn The component name of the instrumentation. 20027 * @param report The error report. 20028 */ 20029 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher, 20030 ComponentName cn, String report) { 20031 Slog.w(TAG, report); 20032 if (watcher != null) { 20033 Bundle results = new Bundle(); 20034 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 20035 results.putString("Error", report); 20036 mInstrumentationReporter.reportStatus(watcher, cn, -1, results); 20037 } 20038 } 20039 20040 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) { 20041 if (app.instr == null) { 20042 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app); 20043 return; 20044 } 20045 20046 if (!app.instr.mFinished && results != null) { 20047 if (app.instr.mCurResults == null) { 20048 app.instr.mCurResults = new Bundle(results); 20049 } else { 20050 app.instr.mCurResults.putAll(results); 20051 } 20052 } 20053 } 20054 20055 public void addInstrumentationResults(IApplicationThread target, Bundle results) { 20056 int userId = UserHandle.getCallingUserId(); 20057 // Refuse possible leaked file descriptors 20058 if (results != null && results.hasFileDescriptors()) { 20059 throw new IllegalArgumentException("File descriptors passed in Intent"); 20060 } 20061 20062 synchronized(this) { 20063 ProcessRecord app = getRecordForAppLocked(target); 20064 if (app == null) { 20065 Slog.w(TAG, "addInstrumentationResults: no app for " + target); 20066 return; 20067 } 20068 final long origId = Binder.clearCallingIdentity(); 20069 addInstrumentationResultsLocked(app, results); 20070 Binder.restoreCallingIdentity(origId); 20071 } 20072 } 20073 20074 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 20075 if (app.instr == null) { 20076 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app); 20077 return; 20078 } 20079 20080 if (!app.instr.mFinished) { 20081 if (app.instr.mWatcher != null) { 20082 Bundle finalResults = app.instr.mCurResults; 20083 if (finalResults != null) { 20084 if (app.instr.mCurResults != null && results != null) { 20085 finalResults.putAll(results); 20086 } 20087 } else { 20088 finalResults = results; 20089 } 20090 mInstrumentationReporter.reportFinished(app.instr.mWatcher, 20091 app.instr.mClass, resultCode, finalResults); 20092 } 20093 20094 // Can't call out of the system process with a lock held, so post a message. 20095 if (app.instr.mUiAutomationConnection != null) { 20096 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG, 20097 app.instr.mUiAutomationConnection).sendToTarget(); 20098 } 20099 app.instr.mFinished = true; 20100 } 20101 20102 app.instr.removeProcess(app); 20103 app.instr = null; 20104 20105 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 20106 "finished inst"); 20107 } 20108 20109 public void finishInstrumentation(IApplicationThread target, 20110 int resultCode, Bundle results) { 20111 int userId = UserHandle.getCallingUserId(); 20112 // Refuse possible leaked file descriptors 20113 if (results != null && results.hasFileDescriptors()) { 20114 throw new IllegalArgumentException("File descriptors passed in Intent"); 20115 } 20116 20117 synchronized(this) { 20118 ProcessRecord app = getRecordForAppLocked(target); 20119 if (app == null) { 20120 Slog.w(TAG, "finishInstrumentation: no app for " + target); 20121 return; 20122 } 20123 final long origId = Binder.clearCallingIdentity(); 20124 finishInstrumentationLocked(app, resultCode, results); 20125 Binder.restoreCallingIdentity(origId); 20126 } 20127 } 20128 20129 // ========================================================= 20130 // CONFIGURATION 20131 // ========================================================= 20132 20133 public ConfigurationInfo getDeviceConfigurationInfo() { 20134 ConfigurationInfo config = new ConfigurationInfo(); 20135 synchronized (this) { 20136 final Configuration globalConfig = getGlobalConfiguration(); 20137 config.reqTouchScreen = globalConfig.touchscreen; 20138 config.reqKeyboardType = globalConfig.keyboard; 20139 config.reqNavigation = globalConfig.navigation; 20140 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD 20141 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) { 20142 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 20143 } 20144 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED 20145 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) { 20146 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 20147 } 20148 config.reqGlEsVersion = GL_ES_VERSION; 20149 } 20150 return config; 20151 } 20152 20153 ActivityStack getFocusedStack() { 20154 return mStackSupervisor.getFocusedStack(); 20155 } 20156 20157 @Override 20158 public int getFocusedStackId() throws RemoteException { 20159 ActivityStack focusedStack = getFocusedStack(); 20160 if (focusedStack != null) { 20161 return focusedStack.getStackId(); 20162 } 20163 return -1; 20164 } 20165 20166 public Configuration getConfiguration() { 20167 Configuration ci; 20168 synchronized(this) { 20169 ci = new Configuration(getGlobalConfiguration()); 20170 ci.userSetLocale = false; 20171 } 20172 return ci; 20173 } 20174 20175 @Override 20176 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException { 20177 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()"); 20178 synchronized (this) { 20179 mSuppressResizeConfigChanges = suppress; 20180 } 20181 } 20182 20183 /** 20184 * NOTE: For the pinned stack, this method is usually called after the bounds animation has 20185 * animated the stack to the fullscreen, but can also be called if we are relaunching an 20186 * activity and clearing the task at the same time. 20187 */ 20188 @Override 20189 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) { 20190 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()"); 20191 if (StackId.isHomeOrRecentsStack(fromStackId)) { 20192 throw new IllegalArgumentException("You can't move tasks from the home/recents stack."); 20193 } 20194 synchronized (this) { 20195 final long origId = Binder.clearCallingIdentity(); 20196 try { 20197 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop); 20198 } finally { 20199 Binder.restoreCallingIdentity(origId); 20200 } 20201 } 20202 } 20203 20204 @Override 20205 public void updatePersistentConfiguration(Configuration values) { 20206 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()"); 20207 enforceWriteSettingsPermission("updatePersistentConfiguration()"); 20208 if (values == null) { 20209 throw new NullPointerException("Configuration must not be null"); 20210 } 20211 20212 int userId = UserHandle.getCallingUserId(); 20213 20214 synchronized(this) { 20215 updatePersistentConfigurationLocked(values, userId); 20216 } 20217 } 20218 20219 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) { 20220 final long origId = Binder.clearCallingIdentity(); 20221 try { 20222 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */); 20223 } finally { 20224 Binder.restoreCallingIdentity(origId); 20225 } 20226 } 20227 20228 private void updateFontScaleIfNeeded(@UserIdInt int userId) { 20229 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(), 20230 FONT_SCALE, 1.0f, userId); 20231 20232 synchronized (this) { 20233 if (getGlobalConfiguration().fontScale == scaleFactor) { 20234 return; 20235 } 20236 20237 final Configuration configuration 20238 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); 20239 configuration.fontScale = scaleFactor; 20240 updatePersistentConfigurationLocked(configuration, userId); 20241 } 20242 } 20243 20244 private void enforceWriteSettingsPermission(String func) { 20245 int uid = Binder.getCallingUid(); 20246 if (uid == ROOT_UID) { 20247 return; 20248 } 20249 20250 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid, 20251 Settings.getPackageNameForUid(mContext, uid), false)) { 20252 return; 20253 } 20254 20255 String msg = "Permission Denial: " + func + " from pid=" 20256 + Binder.getCallingPid() 20257 + ", uid=" + uid 20258 + " requires " + android.Manifest.permission.WRITE_SETTINGS; 20259 Slog.w(TAG, msg); 20260 throw new SecurityException(msg); 20261 } 20262 20263 @Override 20264 public boolean updateConfiguration(Configuration values) { 20265 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()"); 20266 20267 synchronized(this) { 20268 if (values == null && mWindowManager != null) { 20269 // sentinel: fetch the current configuration from the window manager 20270 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); 20271 } 20272 20273 if (mWindowManager != null) { 20274 // Update OOM levels based on display size. 20275 mProcessList.applyDisplaySize(mWindowManager); 20276 } 20277 20278 final long origId = Binder.clearCallingIdentity(); 20279 try { 20280 if (values != null) { 20281 Settings.System.clearConfiguration(values); 20282 } 20283 updateConfigurationLocked(values, null, false, false /* persistent */, 20284 UserHandle.USER_NULL, false /* deferResume */, 20285 mTmpUpdateConfigurationResult); 20286 return mTmpUpdateConfigurationResult.changes != 0; 20287 } finally { 20288 Binder.restoreCallingIdentity(origId); 20289 } 20290 } 20291 } 20292 20293 void updateUserConfigurationLocked() { 20294 final Configuration configuration = new Configuration(getGlobalConfiguration()); 20295 final int currentUserId = mUserController.getCurrentUserIdLocked(); 20296 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration, 20297 currentUserId, Settings.System.canWrite(mContext)); 20298 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */, 20299 false /* persistent */, currentUserId, false /* deferResume */); 20300 } 20301 20302 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 20303 boolean initLocale) { 20304 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */); 20305 } 20306 20307 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 20308 boolean initLocale, boolean deferResume) { 20309 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user 20310 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */, 20311 UserHandle.USER_NULL, deferResume); 20312 } 20313 20314 // To cache the list of supported system locales 20315 private String[] mSupportedSystemLocales = null; 20316 20317 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 20318 boolean initLocale, boolean persistent, int userId, boolean deferResume) { 20319 return updateConfigurationLocked(values, starting, initLocale, persistent, userId, 20320 deferResume, null /* result */); 20321 } 20322 20323 /** 20324 * Do either or both things: (1) change the current configuration, and (2) 20325 * make sure the given activity is running with the (now) current 20326 * configuration. Returns true if the activity has been left running, or 20327 * false if <var>starting</var> is being destroyed to match the new 20328 * configuration. 20329 * 20330 * @param userId is only used when persistent parameter is set to true to persist configuration 20331 * for that particular user 20332 */ 20333 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 20334 boolean initLocale, boolean persistent, int userId, boolean deferResume, 20335 UpdateConfigurationResult result) { 20336 int changes = 0; 20337 boolean kept = true; 20338 20339 if (mWindowManager != null) { 20340 mWindowManager.deferSurfaceLayout(); 20341 } 20342 try { 20343 if (values != null) { 20344 changes = updateGlobalConfiguration(values, initLocale, persistent, userId, 20345 deferResume); 20346 } 20347 20348 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); 20349 } finally { 20350 if (mWindowManager != null) { 20351 mWindowManager.continueSurfaceLayout(); 20352 } 20353 } 20354 20355 if (result != null) { 20356 result.changes = changes; 20357 result.activityRelaunched = !kept; 20358 } 20359 return kept; 20360 } 20361 20362 /** Update default (global) configuration and notify listeners about changes. */ 20363 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale, 20364 boolean persistent, int userId, boolean deferResume) { 20365 mTempConfig.setTo(getGlobalConfiguration()); 20366 final int changes = mTempConfig.updateFrom(values); 20367 if (changes == 0) { 20368 // Since calling to Activity.setRequestedOrientation leads to freezing the window with 20369 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call 20370 // performDisplayOverrideConfigUpdate in order to send the new display configuration 20371 // (even if there are no actual changes) to unfreeze the window. 20372 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY); 20373 return 0; 20374 } 20375 20376 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION, 20377 "Updating global configuration to: " + values); 20378 20379 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 20380 20381 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) { 20382 final LocaleList locales = values.getLocales(); 20383 int bestLocaleIndex = 0; 20384 if (locales.size() > 1) { 20385 if (mSupportedSystemLocales == null) { 20386 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales(); 20387 } 20388 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales)); 20389 } 20390 SystemProperties.set("persist.sys.locale", 20391 locales.get(bestLocaleIndex).toLanguageTag()); 20392 LocaleList.setDefault(locales, bestLocaleIndex); 20393 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, 20394 locales.get(bestLocaleIndex))); 20395 } 20396 20397 mConfigurationSeq = Math.max(++mConfigurationSeq, 1); 20398 mTempConfig.seq = mConfigurationSeq; 20399 20400 // Update stored global config and notify everyone about the change. 20401 mStackSupervisor.onConfigurationChanged(mTempConfig); 20402 20403 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig); 20404 // TODO(multi-display): Update UsageEvents#Event to include displayId. 20405 mUsageStatsService.reportConfigurationChange(mTempConfig, 20406 mUserController.getCurrentUserIdLocked()); 20407 20408 // TODO: If our config changes, should we auto dismiss any currently showing dialogs? 20409 mShowDialogs = shouldShowDialogs(mTempConfig); 20410 20411 AttributeCache ac = AttributeCache.instance(); 20412 if (ac != null) { 20413 ac.updateConfiguration(mTempConfig); 20414 } 20415 20416 // Make sure all resources in our process are updated right now, so that anyone who is going 20417 // to retrieve resource values after we return will be sure to get the new ones. This is 20418 // especially important during boot, where the first config change needs to guarantee all 20419 // resources have that config before following boot code is executed. 20420 mSystemThread.applyConfigurationToResources(mTempConfig); 20421 20422 // We need another copy of global config because we're scheduling some calls instead of 20423 // running them in place. We need to be sure that object we send will be handled unchanged. 20424 final Configuration configCopy = new Configuration(mTempConfig); 20425 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 20426 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 20427 msg.obj = configCopy; 20428 msg.arg1 = userId; 20429 mHandler.sendMessage(msg); 20430 } 20431 20432 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 20433 ProcessRecord app = mLruProcesses.get(i); 20434 try { 20435 if (app.thread != null) { 20436 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc " 20437 + app.processName + " new config " + configCopy); 20438 app.thread.scheduleConfigurationChanged(configCopy); 20439 } 20440 } catch (Exception e) { 20441 } 20442 } 20443 20444 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 20445 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING 20446 | Intent.FLAG_RECEIVER_FOREGROUND 20447 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 20448 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 20449 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, 20450 UserHandle.USER_ALL); 20451 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) { 20452 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 20453 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND 20454 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 20455 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 20456 if (initLocale || !mProcessesReady) { 20457 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 20458 } 20459 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 20460 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, 20461 UserHandle.USER_ALL); 20462 } 20463 20464 // Override configuration of the default display duplicates global config, so we need to 20465 // update it also. This will also notify WindowManager about changes. 20466 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume, 20467 DEFAULT_DISPLAY); 20468 20469 return changes; 20470 } 20471 20472 @Override 20473 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) { 20474 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()"); 20475 20476 synchronized (this) { 20477 // Check if display is initialized in AM. 20478 if (!mStackSupervisor.isDisplayAdded(displayId)) { 20479 // Call might come when display is not yet added or has already been removed. 20480 if (DEBUG_CONFIGURATION) { 20481 Slog.w(TAG, "Trying to update display configuration for non-existing displayId=" 20482 + displayId); 20483 } 20484 return false; 20485 } 20486 20487 if (values == null && mWindowManager != null) { 20488 // sentinel: fetch the current configuration from the window manager 20489 values = mWindowManager.computeNewConfiguration(displayId); 20490 } 20491 20492 if (mWindowManager != null) { 20493 // Update OOM levels based on display size. 20494 mProcessList.applyDisplaySize(mWindowManager); 20495 } 20496 20497 final long origId = Binder.clearCallingIdentity(); 20498 try { 20499 if (values != null) { 20500 Settings.System.clearConfiguration(values); 20501 } 20502 updateDisplayOverrideConfigurationLocked(values, null /* starting */, 20503 false /* deferResume */, displayId, mTmpUpdateConfigurationResult); 20504 return mTmpUpdateConfigurationResult.changes != 0; 20505 } finally { 20506 Binder.restoreCallingIdentity(origId); 20507 } 20508 } 20509 } 20510 20511 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting, 20512 boolean deferResume, int displayId) { 20513 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */, 20514 displayId, null /* result */); 20515 } 20516 20517 /** 20518 * Updates override configuration specific for the selected display. If no config is provided, 20519 * new one will be computed in WM based on current display info. 20520 */ 20521 private boolean updateDisplayOverrideConfigurationLocked(Configuration values, 20522 ActivityRecord starting, boolean deferResume, int displayId, 20523 UpdateConfigurationResult result) { 20524 int changes = 0; 20525 boolean kept = true; 20526 20527 if (mWindowManager != null) { 20528 mWindowManager.deferSurfaceLayout(); 20529 } 20530 try { 20531 if (values != null) { 20532 if (displayId == DEFAULT_DISPLAY) { 20533 // Override configuration of the default display duplicates global config, so 20534 // we're calling global config update instead for default display. It will also 20535 // apply the correct override config. 20536 changes = updateGlobalConfiguration(values, false /* initLocale */, 20537 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume); 20538 } else { 20539 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId); 20540 } 20541 } 20542 20543 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); 20544 } finally { 20545 if (mWindowManager != null) { 20546 mWindowManager.continueSurfaceLayout(); 20547 } 20548 } 20549 20550 if (result != null) { 20551 result.changes = changes; 20552 result.activityRelaunched = !kept; 20553 } 20554 return kept; 20555 } 20556 20557 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume, 20558 int displayId) { 20559 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId)); 20560 final int changes = mTempConfig.updateFrom(values); 20561 if (changes != 0) { 20562 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " 20563 + mTempConfig + " for displayId=" + displayId); 20564 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId); 20565 20566 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; 20567 if (isDensityChange && displayId == DEFAULT_DISPLAY) { 20568 // Reset the unsupported display size dialog. 20569 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG); 20570 20571 killAllBackgroundProcessesExcept(N, 20572 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 20573 } 20574 } 20575 20576 // Update the configuration with WM first and check if any of the stacks need to be resized 20577 // due to the configuration change. If so, resize the stacks now and do any relaunches if 20578 // necessary. This way we don't need to relaunch again afterwards in 20579 // ensureActivityConfigurationLocked(). 20580 if (mWindowManager != null) { 20581 final int[] resizedStacks = 20582 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId); 20583 if (resizedStacks != null) { 20584 for (int stackId : resizedStacks) { 20585 resizeStackWithBoundsFromWindowManager(stackId, deferResume); 20586 } 20587 } 20588 } 20589 20590 return changes; 20591 } 20592 20593 /** Applies latest configuration and/or visibility updates if needed. */ 20594 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) { 20595 boolean kept = true; 20596 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 20597 // mainStack is null during startup. 20598 if (mainStack != null) { 20599 if (changes != 0 && starting == null) { 20600 // If the configuration changed, and the caller is not already 20601 // in the process of starting an activity, then find the top 20602 // activity to check if its configuration needs to change. 20603 starting = mainStack.topRunningActivityLocked(); 20604 } 20605 20606 if (starting != null) { 20607 kept = starting.ensureActivityConfigurationLocked(changes, 20608 false /* preserveWindow */); 20609 // And we need to make sure at this point that all other activities 20610 // are made visible with the correct configuration. 20611 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes, 20612 !PRESERVE_WINDOWS); 20613 } 20614 } 20615 20616 return kept; 20617 } 20618 20619 /** Helper method that requests bounds from WM and applies them to stack. */ 20620 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) { 20621 final Rect newStackBounds = new Rect(); 20622 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds); 20623 mStackSupervisor.resizeStackLocked( 20624 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */, 20625 null /* tempTaskBounds */, null /* tempTaskInsetBounds */, 20626 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume); 20627 } 20628 20629 /** 20630 * Decide based on the configuration whether we should show the ANR, 20631 * crash, etc dialogs. The idea is that if there is no affordance to 20632 * press the on-screen buttons, or the user experience would be more 20633 * greatly impacted than the crash itself, we shouldn't show the dialog. 20634 * 20635 * A thought: SystemUI might also want to get told about this, the Power 20636 * dialog / global actions also might want different behaviors. 20637 */ 20638 private static boolean shouldShowDialogs(Configuration config) { 20639 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS 20640 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH 20641 && config.navigation == Configuration.NAVIGATION_NONAV); 20642 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK; 20643 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR 20644 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER) 20645 && modeType != Configuration.UI_MODE_TYPE_TELEVISION 20646 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET); 20647 return inputMethodExists && uiModeSupportsDialogs; 20648 } 20649 20650 @Override 20651 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 20652 synchronized (this) { 20653 ActivityRecord srec = ActivityRecord.forTokenLocked(token); 20654 if (srec != null) { 20655 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity); 20656 } 20657 } 20658 return false; 20659 } 20660 20661 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 20662 Intent resultData) { 20663 20664 synchronized (this) { 20665 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 20666 if (r != null) { 20667 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData); 20668 } 20669 return false; 20670 } 20671 } 20672 20673 public int getLaunchedFromUid(IBinder activityToken) { 20674 ActivityRecord srec; 20675 synchronized (this) { 20676 srec = ActivityRecord.forTokenLocked(activityToken); 20677 } 20678 if (srec == null) { 20679 return -1; 20680 } 20681 return srec.launchedFromUid; 20682 } 20683 20684 public String getLaunchedFromPackage(IBinder activityToken) { 20685 ActivityRecord srec; 20686 synchronized (this) { 20687 srec = ActivityRecord.forTokenLocked(activityToken); 20688 } 20689 if (srec == null) { 20690 return null; 20691 } 20692 return srec.launchedFromPackage; 20693 } 20694 20695 // ========================================================= 20696 // LIFETIME MANAGEMENT 20697 // ========================================================= 20698 20699 // Returns whether the app is receiving broadcast. 20700 // If receiving, fetch all broadcast queues which the app is 20701 // the current [or imminent] receiver on. 20702 private boolean isReceivingBroadcastLocked(ProcessRecord app, 20703 ArraySet<BroadcastQueue> receivingQueues) { 20704 if (!app.curReceivers.isEmpty()) { 20705 for (BroadcastRecord r : app.curReceivers) { 20706 receivingQueues.add(r.queue); 20707 } 20708 return true; 20709 } 20710 20711 // It's not the current receiver, but it might be starting up to become one 20712 for (BroadcastQueue queue : mBroadcastQueues) { 20713 final BroadcastRecord r = queue.mPendingBroadcast; 20714 if (r != null && r.curApp == app) { 20715 // found it; report which queue it's in 20716 receivingQueues.add(queue); 20717 } 20718 } 20719 20720 return !receivingQueues.isEmpty(); 20721 } 20722 20723 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState, 20724 int targetUid, ComponentName targetComponent, String targetProcess) { 20725 if (!mTrackingAssociations) { 20726 return null; 20727 } 20728 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 20729 = mAssociations.get(targetUid); 20730 if (components == null) { 20731 components = new ArrayMap<>(); 20732 mAssociations.put(targetUid, components); 20733 } 20734 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 20735 if (sourceUids == null) { 20736 sourceUids = new SparseArray<>(); 20737 components.put(targetComponent, sourceUids); 20738 } 20739 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 20740 if (sourceProcesses == null) { 20741 sourceProcesses = new ArrayMap<>(); 20742 sourceUids.put(sourceUid, sourceProcesses); 20743 } 20744 Association ass = sourceProcesses.get(sourceProcess); 20745 if (ass == null) { 20746 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 20747 targetProcess); 20748 sourceProcesses.put(sourceProcess, ass); 20749 } 20750 ass.mCount++; 20751 ass.mNesting++; 20752 if (ass.mNesting == 1) { 20753 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis(); 20754 ass.mLastState = sourceState; 20755 } 20756 return ass; 20757 } 20758 20759 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 20760 ComponentName targetComponent) { 20761 if (!mTrackingAssociations) { 20762 return; 20763 } 20764 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 20765 = mAssociations.get(targetUid); 20766 if (components == null) { 20767 return; 20768 } 20769 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 20770 if (sourceUids == null) { 20771 return; 20772 } 20773 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 20774 if (sourceProcesses == null) { 20775 return; 20776 } 20777 Association ass = sourceProcesses.get(sourceProcess); 20778 if (ass == null || ass.mNesting <= 0) { 20779 return; 20780 } 20781 ass.mNesting--; 20782 if (ass.mNesting == 0) { 20783 long uptime = SystemClock.uptimeMillis(); 20784 ass.mTime += uptime - ass.mStartTime; 20785 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE] 20786 += uptime - ass.mLastStateUptime; 20787 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2; 20788 } 20789 } 20790 20791 private void noteUidProcessState(final int uid, final int state) { 20792 mBatteryStatsService.noteUidProcessState(uid, state); 20793 if (mTrackingAssociations) { 20794 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 20795 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 20796 = mAssociations.valueAt(i1); 20797 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 20798 SparseArray<ArrayMap<String, Association>> sourceUids 20799 = targetComponents.valueAt(i2); 20800 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid); 20801 if (sourceProcesses != null) { 20802 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 20803 Association ass = sourceProcesses.valueAt(i4); 20804 if (ass.mNesting >= 1) { 20805 // currently associated 20806 long uptime = SystemClock.uptimeMillis(); 20807 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE] 20808 += uptime - ass.mLastStateUptime; 20809 ass.mLastState = state; 20810 ass.mLastStateUptime = uptime; 20811 } 20812 } 20813 } 20814 } 20815 } 20816 } 20817 } 20818 20819 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 20820 boolean doingAll, long now) { 20821 if (mAdjSeq == app.adjSeq) { 20822 // This adjustment has already been computed. 20823 return app.curRawAdj; 20824 } 20825 20826 if (app.thread == null) { 20827 app.adjSeq = mAdjSeq; 20828 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 20829 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 20830 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 20831 } 20832 20833 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 20834 app.adjSource = null; 20835 app.adjTarget = null; 20836 app.empty = false; 20837 app.cached = false; 20838 20839 final int activitiesSize = app.activities.size(); 20840 20841 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 20842 // The max adjustment doesn't allow this app to be anything 20843 // below foreground, so it is not worth doing work for it. 20844 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app); 20845 app.adjType = "fixed"; 20846 app.adjSeq = mAdjSeq; 20847 app.curRawAdj = app.maxAdj; 20848 app.foregroundActivities = false; 20849 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20850 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 20851 // System processes can do UI, and when they do we want to have 20852 // them trim their memory after the user leaves the UI. To 20853 // facilitate this, here we need to determine whether or not it 20854 // is currently showing UI. 20855 app.systemNoUi = true; 20856 if (app == TOP_APP) { 20857 app.systemNoUi = false; 20858 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; 20859 app.adjType = "pers-top-activity"; 20860 } else if (app.hasTopUi) { 20861 app.systemNoUi = false; 20862 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; 20863 app.adjType = "pers-top-ui"; 20864 } else if (activitiesSize > 0) { 20865 for (int j = 0; j < activitiesSize; j++) { 20866 final ActivityRecord r = app.activities.get(j); 20867 if (r.visible) { 20868 app.systemNoUi = false; 20869 } 20870 } 20871 } 20872 if (!app.systemNoUi) { 20873 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 20874 } 20875 return (app.curAdj=app.maxAdj); 20876 } 20877 20878 app.systemNoUi = false; 20879 20880 final int PROCESS_STATE_CUR_TOP = mTopProcessState; 20881 20882 // Determine the importance of the process, starting with most 20883 // important to least, and assign an appropriate OOM adjustment. 20884 int adj; 20885 int schedGroup; 20886 int procState; 20887 boolean foregroundActivities = false; 20888 mTmpBroadcastQueue.clear(); 20889 if (app == TOP_APP) { 20890 // The last app on the list is the foreground app. 20891 adj = ProcessList.FOREGROUND_APP_ADJ; 20892 schedGroup = ProcessList.SCHED_GROUP_TOP_APP; 20893 app.adjType = "top-activity"; 20894 foregroundActivities = true; 20895 procState = PROCESS_STATE_CUR_TOP; 20896 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app); 20897 } else if (app.instr != null) { 20898 // Don't want to kill running instrumentation. 20899 adj = ProcessList.FOREGROUND_APP_ADJ; 20900 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20901 app.adjType = "instrumentation"; 20902 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 20903 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app); 20904 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) { 20905 // An app that is currently receiving a broadcast also 20906 // counts as being in the foreground for OOM killer purposes. 20907 // It's placed in a sched group based on the nature of the 20908 // broadcast as reflected by which queue it's active in. 20909 adj = ProcessList.FOREGROUND_APP_ADJ; 20910 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue)) 20911 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; 20912 app.adjType = "broadcast"; 20913 procState = ActivityManager.PROCESS_STATE_RECEIVER; 20914 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app); 20915 } else if (app.executingServices.size() > 0) { 20916 // An app that is currently executing a service callback also 20917 // counts as being in the foreground. 20918 adj = ProcessList.FOREGROUND_APP_ADJ; 20919 schedGroup = app.execServicesFg ? 20920 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; 20921 app.adjType = "exec-service"; 20922 procState = ActivityManager.PROCESS_STATE_SERVICE; 20923 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app); 20924 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 20925 } else { 20926 // As far as we know the process is empty. We may change our mind later. 20927 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 20928 // At this point we don't actually know the adjustment. Use the cached adj 20929 // value that the caller wants us to. 20930 adj = cachedAdj; 20931 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 20932 app.cached = true; 20933 app.empty = true; 20934 app.adjType = "cch-empty"; 20935 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app); 20936 } 20937 20938 // Examine all activities if not already foreground. 20939 if (!foregroundActivities && activitiesSize > 0) { 20940 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX; 20941 for (int j = 0; j < activitiesSize; j++) { 20942 final ActivityRecord r = app.activities.get(j); 20943 if (r.app != app) { 20944 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app 20945 + " instead of expected " + app); 20946 if (r.app == null || (r.app.uid == app.uid)) { 20947 // Only fix things up when they look sane 20948 r.app = app; 20949 } else { 20950 continue; 20951 } 20952 } 20953 if (r.visible) { 20954 // App has a visible activity; only upgrade adjustment. 20955 if (adj > ProcessList.VISIBLE_APP_ADJ) { 20956 adj = ProcessList.VISIBLE_APP_ADJ; 20957 app.adjType = "vis-activity"; 20958 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app); 20959 } 20960 if (procState > PROCESS_STATE_CUR_TOP) { 20961 procState = PROCESS_STATE_CUR_TOP; 20962 app.adjType = "vis-activity"; 20963 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app); 20964 } 20965 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20966 app.cached = false; 20967 app.empty = false; 20968 foregroundActivities = true; 20969 final TaskRecord task = r.getTask(); 20970 if (task != null && minLayer > 0) { 20971 final int layer = task.mLayerRank; 20972 if (layer >= 0 && minLayer > layer) { 20973 minLayer = layer; 20974 } 20975 } 20976 break; 20977 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 20978 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 20979 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 20980 app.adjType = "pause-activity"; 20981 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app); 20982 } 20983 if (procState > PROCESS_STATE_CUR_TOP) { 20984 procState = PROCESS_STATE_CUR_TOP; 20985 app.adjType = "pause-activity"; 20986 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app); 20987 } 20988 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20989 app.cached = false; 20990 app.empty = false; 20991 foregroundActivities = true; 20992 } else if (r.state == ActivityState.STOPPING) { 20993 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 20994 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 20995 app.adjType = "stop-activity"; 20996 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app); 20997 } 20998 // For the process state, we will at this point consider the 20999 // process to be cached. It will be cached either as an activity 21000 // or empty depending on whether the activity is finishing. We do 21001 // this so that we can treat the process as cached for purposes of 21002 // memory trimming (determing current memory level, trim command to 21003 // send to process) since there can be an arbitrary number of stopping 21004 // processes and they should soon all go into the cached state. 21005 if (!r.finishing) { 21006 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 21007 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 21008 app.adjType = "stop-activity"; 21009 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app); 21010 } 21011 } 21012 app.cached = false; 21013 app.empty = false; 21014 foregroundActivities = true; 21015 } else { 21016 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 21017 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 21018 app.adjType = "cch-act"; 21019 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app); 21020 } 21021 } 21022 } 21023 if (adj == ProcessList.VISIBLE_APP_ADJ) { 21024 adj += minLayer; 21025 } 21026 } 21027 21028 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ 21029 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 21030 if (app.foregroundServices) { 21031 // The user is aware of this app, so make it visible. 21032 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 21033 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 21034 app.cached = false; 21035 app.adjType = "fg-service"; 21036 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21037 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app); 21038 } else if (app.hasOverlayUi) { 21039 // The process is display an overlay UI. 21040 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 21041 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 21042 app.cached = false; 21043 app.adjType = "has-overlay-ui"; 21044 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21045 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app); 21046 } 21047 } 21048 21049 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ 21050 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { 21051 if (app.forcingToImportant != null) { 21052 // This is currently used for toasts... they are not interactive, and 21053 // we don't want them to cause the app to become fully foreground (and 21054 // thus out of background check), so we yes the best background level we can. 21055 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 21056 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; 21057 app.cached = false; 21058 app.adjType = "force-imp"; 21059 app.adjSource = app.forcingToImportant; 21060 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21061 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app); 21062 } 21063 } 21064 21065 if (app == mHeavyWeightProcess) { 21066 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 21067 // We don't want to kill the current heavy-weight process. 21068 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 21069 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 21070 app.cached = false; 21071 app.adjType = "heavy"; 21072 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app); 21073 } 21074 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 21075 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 21076 app.adjType = "heavy"; 21077 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app); 21078 } 21079 } 21080 21081 if (app == mHomeProcess) { 21082 if (adj > ProcessList.HOME_APP_ADJ) { 21083 // This process is hosting what we currently consider to be the 21084 // home app, so we don't want to let it go into the background. 21085 adj = ProcessList.HOME_APP_ADJ; 21086 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 21087 app.cached = false; 21088 app.adjType = "home"; 21089 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app); 21090 } 21091 if (procState > ActivityManager.PROCESS_STATE_HOME) { 21092 procState = ActivityManager.PROCESS_STATE_HOME; 21093 app.adjType = "home"; 21094 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app); 21095 } 21096 } 21097 21098 if (app == mPreviousProcess && app.activities.size() > 0) { 21099 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 21100 // This was the previous process that showed UI to the user. 21101 // We want to try to keep it around more aggressively, to give 21102 // a good experience around switching between two apps. 21103 adj = ProcessList.PREVIOUS_APP_ADJ; 21104 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 21105 app.cached = false; 21106 app.adjType = "previous"; 21107 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app); 21108 } 21109 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 21110 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 21111 app.adjType = "previous"; 21112 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app); 21113 } 21114 } 21115 21116 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 21117 + " reason=" + app.adjType); 21118 21119 // By default, we use the computed adjustment. It may be changed if 21120 // there are applications dependent on our services or providers, but 21121 // this gives us a baseline and makes sure we don't get into an 21122 // infinite recursion. 21123 app.adjSeq = mAdjSeq; 21124 app.curRawAdj = adj; 21125 app.hasStartedServices = false; 21126 21127 if (mBackupTarget != null && app == mBackupTarget.app) { 21128 // If possible we want to avoid killing apps while they're being backed up 21129 if (adj > ProcessList.BACKUP_APP_ADJ) { 21130 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app); 21131 adj = ProcessList.BACKUP_APP_ADJ; 21132 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { 21133 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; 21134 } 21135 app.adjType = "backup"; 21136 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app); 21137 app.cached = false; 21138 } 21139 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 21140 procState = ActivityManager.PROCESS_STATE_BACKUP; 21141 app.adjType = "backup"; 21142 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app); 21143 } 21144 } 21145 21146 boolean mayBeTop = false; 21147 String mayBeTopType = null; 21148 Object mayBeTopSource = null; 21149 Object mayBeTopTarget = null; 21150 21151 for (int is = app.services.size()-1; 21152 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 21153 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 21154 || procState > ActivityManager.PROCESS_STATE_TOP); 21155 is--) { 21156 ServiceRecord s = app.services.valueAt(is); 21157 if (s.startRequested) { 21158 app.hasStartedServices = true; 21159 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 21160 procState = ActivityManager.PROCESS_STATE_SERVICE; 21161 app.adjType = "started-services"; 21162 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app); 21163 } 21164 if (app.hasShownUi && app != mHomeProcess) { 21165 // If this process has shown some UI, let it immediately 21166 // go to the LRU list because it may be pretty heavy with 21167 // UI stuff. We'll tag it with a label just to help 21168 // debug and understand what is going on. 21169 if (adj > ProcessList.SERVICE_ADJ) { 21170 app.adjType = "cch-started-ui-services"; 21171 } 21172 } else { 21173 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) { 21174 // This service has seen some activity within 21175 // recent memory, so we will keep its process ahead 21176 // of the background processes. 21177 if (adj > ProcessList.SERVICE_ADJ) { 21178 adj = ProcessList.SERVICE_ADJ; 21179 app.adjType = "started-services"; 21180 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app); 21181 app.cached = false; 21182 } 21183 } 21184 // If we have let the service slide into the background 21185 // state, still have some text describing what it is doing 21186 // even though the service no longer has an impact. 21187 if (adj > ProcessList.SERVICE_ADJ) { 21188 app.adjType = "cch-started-services"; 21189 } 21190 } 21191 } 21192 21193 for (int conni = s.connections.size()-1; 21194 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 21195 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 21196 || procState > ActivityManager.PROCESS_STATE_TOP); 21197 conni--) { 21198 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 21199 for (int i = 0; 21200 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 21201 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 21202 || procState > ActivityManager.PROCESS_STATE_TOP); 21203 i++) { 21204 // XXX should compute this based on the max of 21205 // all connected clients. 21206 ConnectionRecord cr = clist.get(i); 21207 if (cr.binding.client == app) { 21208 // Binding to ourself is not interesting. 21209 continue; 21210 } 21211 21212 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 21213 ProcessRecord client = cr.binding.client; 21214 int clientAdj = computeOomAdjLocked(client, cachedAdj, 21215 TOP_APP, doingAll, now); 21216 int clientProcState = client.curProcState; 21217 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 21218 // If the other app is cached for any reason, for purposes here 21219 // we are going to consider it empty. The specific cached state 21220 // doesn't propagate except under certain conditions. 21221 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 21222 } 21223 String adjType = null; 21224 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 21225 // Not doing bind OOM management, so treat 21226 // this guy more like a started service. 21227 if (app.hasShownUi && app != mHomeProcess) { 21228 // If this process has shown some UI, let it immediately 21229 // go to the LRU list because it may be pretty heavy with 21230 // UI stuff. We'll tag it with a label just to help 21231 // debug and understand what is going on. 21232 if (adj > clientAdj) { 21233 adjType = "cch-bound-ui-services"; 21234 } 21235 app.cached = false; 21236 clientAdj = adj; 21237 clientProcState = procState; 21238 } else { 21239 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) { 21240 // This service has not seen activity within 21241 // recent memory, so allow it to drop to the 21242 // LRU list if there is no other reason to keep 21243 // it around. We'll also tag it with a label just 21244 // to help debug and undertand what is going on. 21245 if (adj > clientAdj) { 21246 adjType = "cch-bound-services"; 21247 } 21248 clientAdj = adj; 21249 } 21250 } 21251 } 21252 if (adj > clientAdj) { 21253 // If this process has recently shown UI, and 21254 // the process that is binding to it is less 21255 // important than being visible, then we don't 21256 // care about the binding as much as we care 21257 // about letting this process get into the LRU 21258 // list to be killed and restarted if needed for 21259 // memory. 21260 if (app.hasShownUi && app != mHomeProcess 21261 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 21262 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 21263 adjType = "cch-bound-ui-services"; 21264 } 21265 } else { 21266 int newAdj; 21267 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 21268 |Context.BIND_IMPORTANT)) != 0) { 21269 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 21270 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 21271 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 21272 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 21273 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 21274 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ; 21275 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 21276 newAdj = clientAdj; 21277 } else { 21278 if (adj > ProcessList.VISIBLE_APP_ADJ) { 21279 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ); 21280 } else { 21281 newAdj = adj; 21282 } 21283 } 21284 if (!client.cached) { 21285 app.cached = false; 21286 } 21287 if (adj > newAdj) { 21288 adj = newAdj; 21289 adjType = "service"; 21290 } 21291 } 21292 } 21293 if ((cr.flags & (Context.BIND_NOT_FOREGROUND 21294 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) { 21295 // This will treat important bound services identically to 21296 // the top app, which may behave differently than generic 21297 // foreground work. 21298 if (client.curSchedGroup > schedGroup) { 21299 if ((cr.flags&Context.BIND_IMPORTANT) != 0) { 21300 schedGroup = client.curSchedGroup; 21301 } else { 21302 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21303 } 21304 } 21305 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 21306 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 21307 // Special handling of clients who are in the top state. 21308 // We *may* want to consider this process to be in the 21309 // top state as well, but only if there is not another 21310 // reason for it to be running. Being on the top is a 21311 // special state, meaning you are specifically running 21312 // for the current top app. If the process is already 21313 // running in the background for some other reason, it 21314 // is more important to continue considering it to be 21315 // in the background state. 21316 mayBeTop = true; 21317 mayBeTopType = "service"; 21318 mayBeTopSource = cr.binding.client; 21319 mayBeTopTarget = s.name; 21320 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 21321 } else { 21322 // Special handling for above-top states (persistent 21323 // processes). These should not bring the current process 21324 // into the top state, since they are not on top. Instead 21325 // give them the best state after that. 21326 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) { 21327 clientProcState = 21328 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 21329 } else if (mWakefulness 21330 == PowerManagerInternal.WAKEFULNESS_AWAKE && 21331 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) 21332 != 0) { 21333 clientProcState = 21334 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 21335 } else { 21336 clientProcState = 21337 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 21338 } 21339 } 21340 } 21341 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) { 21342 if (clientProcState < 21343 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { 21344 clientProcState = 21345 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; 21346 } 21347 } else { 21348 if (clientProcState < 21349 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 21350 clientProcState = 21351 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 21352 } 21353 } 21354 if (procState > clientProcState) { 21355 procState = clientProcState; 21356 if (adjType == null) { 21357 adjType = "service"; 21358 } 21359 } 21360 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 21361 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 21362 app.pendingUiClean = true; 21363 } 21364 if (adjType != null) { 21365 app.adjType = adjType; 21366 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 21367 .REASON_SERVICE_IN_USE; 21368 app.adjSource = cr.binding.client; 21369 app.adjSourceProcState = clientProcState; 21370 app.adjTarget = s.name; 21371 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType 21372 + ": " + app + ", due to " + cr.binding.client 21373 + " adj=" + adj + " procState=" + procState); 21374 } 21375 } 21376 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 21377 app.treatLikeActivity = true; 21378 } 21379 final ActivityRecord a = cr.activity; 21380 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 21381 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 21382 (a.visible || a.state == ActivityState.RESUMED || 21383 a.state == ActivityState.PAUSING)) { 21384 adj = ProcessList.FOREGROUND_APP_ADJ; 21385 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 21386 if ((cr.flags&Context.BIND_IMPORTANT) != 0) { 21387 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND; 21388 } else { 21389 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21390 } 21391 } 21392 app.cached = false; 21393 app.adjType = "service"; 21394 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 21395 .REASON_SERVICE_IN_USE; 21396 app.adjSource = a; 21397 app.adjSourceProcState = procState; 21398 app.adjTarget = s.name; 21399 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: " 21400 + app); 21401 } 21402 } 21403 } 21404 } 21405 } 21406 21407 for (int provi = app.pubProviders.size()-1; 21408 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 21409 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 21410 || procState > ActivityManager.PROCESS_STATE_TOP); 21411 provi--) { 21412 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 21413 for (int i = cpr.connections.size()-1; 21414 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 21415 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 21416 || procState > ActivityManager.PROCESS_STATE_TOP); 21417 i--) { 21418 ContentProviderConnection conn = cpr.connections.get(i); 21419 ProcessRecord client = conn.client; 21420 if (client == app) { 21421 // Being our own client is not interesting. 21422 continue; 21423 } 21424 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 21425 int clientProcState = client.curProcState; 21426 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 21427 // If the other app is cached for any reason, for purposes here 21428 // we are going to consider it empty. 21429 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 21430 } 21431 String adjType = null; 21432 if (adj > clientAdj) { 21433 if (app.hasShownUi && app != mHomeProcess 21434 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 21435 adjType = "cch-ui-provider"; 21436 } else { 21437 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 21438 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 21439 adjType = "provider"; 21440 } 21441 app.cached &= client.cached; 21442 } 21443 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 21444 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 21445 // Special handling of clients who are in the top state. 21446 // We *may* want to consider this process to be in the 21447 // top state as well, but only if there is not another 21448 // reason for it to be running. Being on the top is a 21449 // special state, meaning you are specifically running 21450 // for the current top app. If the process is already 21451 // running in the background for some other reason, it 21452 // is more important to continue considering it to be 21453 // in the background state. 21454 mayBeTop = true; 21455 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 21456 mayBeTopType = adjType = "provider-top"; 21457 mayBeTopSource = client; 21458 mayBeTopTarget = cpr.name; 21459 } else { 21460 // Special handling for above-top states (persistent 21461 // processes). These should not bring the current process 21462 // into the top state, since they are not on top. Instead 21463 // give them the best state after that. 21464 clientProcState = 21465 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 21466 if (adjType == null) { 21467 adjType = "provider"; 21468 } 21469 } 21470 } 21471 if (procState > clientProcState) { 21472 procState = clientProcState; 21473 } 21474 if (client.curSchedGroup > schedGroup) { 21475 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21476 } 21477 if (adjType != null) { 21478 app.adjType = adjType; 21479 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 21480 .REASON_PROVIDER_IN_USE; 21481 app.adjSource = client; 21482 app.adjSourceProcState = clientProcState; 21483 app.adjTarget = cpr.name; 21484 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType 21485 + ": " + app + ", due to " + client 21486 + " adj=" + adj + " procState=" + procState); 21487 } 21488 } 21489 // If the provider has external (non-framework) process 21490 // dependencies, ensure that its adjustment is at least 21491 // FOREGROUND_APP_ADJ. 21492 if (cpr.hasExternalProcessHandles()) { 21493 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 21494 adj = ProcessList.FOREGROUND_APP_ADJ; 21495 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21496 app.cached = false; 21497 app.adjType = "ext-provider"; 21498 app.adjTarget = cpr.name; 21499 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app); 21500 } 21501 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 21502 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 21503 } 21504 } 21505 } 21506 21507 if (app.lastProviderTime > 0 && 21508 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) { 21509 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 21510 adj = ProcessList.PREVIOUS_APP_ADJ; 21511 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 21512 app.cached = false; 21513 app.adjType = "recent-provider"; 21514 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app); 21515 } 21516 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 21517 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 21518 app.adjType = "recent-provider"; 21519 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app); 21520 } 21521 } 21522 21523 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 21524 // A client of one of our services or providers is in the top state. We 21525 // *may* want to be in the top state, but not if we are already running in 21526 // the background for some other reason. For the decision here, we are going 21527 // to pick out a few specific states that we want to remain in when a client 21528 // is top (states that tend to be longer-term) and otherwise allow it to go 21529 // to the top state. 21530 switch (procState) { 21531 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: 21532 // Something else is keeping it at this level, just leave it. 21533 break; 21534 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 21535 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 21536 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND: 21537 case ActivityManager.PROCESS_STATE_SERVICE: 21538 // These all are longer-term states, so pull them up to the top 21539 // of the background states, but not all the way to the top state. 21540 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 21541 app.adjType = mayBeTopType; 21542 app.adjSource = mayBeTopSource; 21543 app.adjTarget = mayBeTopTarget; 21544 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType 21545 + ": " + app + ", due to " + mayBeTopSource 21546 + " adj=" + adj + " procState=" + procState); 21547 break; 21548 default: 21549 // Otherwise, top is a better choice, so take it. 21550 procState = ActivityManager.PROCESS_STATE_TOP; 21551 app.adjType = mayBeTopType; 21552 app.adjSource = mayBeTopSource; 21553 app.adjTarget = mayBeTopTarget; 21554 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType 21555 + ": " + app + ", due to " + mayBeTopSource 21556 + " adj=" + adj + " procState=" + procState); 21557 break; 21558 } 21559 } 21560 21561 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 21562 if (app.hasClientActivities) { 21563 // This is a cached process, but with client activities. Mark it so. 21564 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 21565 app.adjType = "cch-client-act"; 21566 } else if (app.treatLikeActivity) { 21567 // This is a cached process, but somebody wants us to treat it like it has 21568 // an activity, okay! 21569 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 21570 app.adjType = "cch-as-act"; 21571 } 21572 } 21573 21574 if (adj == ProcessList.SERVICE_ADJ) { 21575 if (doingAll) { 21576 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 21577 mNewNumServiceProcs++; 21578 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 21579 if (!app.serviceb) { 21580 // This service isn't far enough down on the LRU list to 21581 // normally be a B service, but if we are low on RAM and it 21582 // is large we want to force it down since we would prefer to 21583 // keep launcher over it. 21584 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 21585 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 21586 app.serviceHighRam = true; 21587 app.serviceb = true; 21588 //Slog.i(TAG, "ADJ " + app + " high ram!"); 21589 } else { 21590 mNewNumAServiceProcs++; 21591 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 21592 } 21593 } else { 21594 app.serviceHighRam = false; 21595 } 21596 } 21597 if (app.serviceb) { 21598 adj = ProcessList.SERVICE_B_ADJ; 21599 } 21600 } 21601 21602 app.curRawAdj = adj; 21603 21604 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 21605 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 21606 if (adj > app.maxAdj) { 21607 adj = app.maxAdj; 21608 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 21609 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21610 } 21611 } 21612 21613 // Do final modification to adj. Everything we do between here and applying 21614 // the final setAdj must be done in this function, because we will also use 21615 // it when computing the final cached adj later. Note that we don't need to 21616 // worry about this for max adj above, since max adj will always be used to 21617 // keep it out of the cached vaues. 21618 app.curAdj = app.modifyRawOomAdj(adj); 21619 app.curSchedGroup = schedGroup; 21620 app.curProcState = procState; 21621 app.foregroundActivities = foregroundActivities; 21622 21623 return app.curRawAdj; 21624 } 21625 21626 /** 21627 * Record new PSS sample for a process. 21628 */ 21629 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss, 21630 long now) { 21631 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024, 21632 swapPss * 1024); 21633 proc.lastPssTime = now; 21634 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 21635 if (DEBUG_PSS) Slog.d(TAG_PSS, 21636 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss 21637 + " state=" + ProcessList.makeProcStateString(procState)); 21638 if (proc.initialIdlePss == 0) { 21639 proc.initialIdlePss = pss; 21640 } 21641 proc.lastPss = pss; 21642 proc.lastSwapPss = swapPss; 21643 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 21644 proc.lastCachedPss = pss; 21645 proc.lastCachedSwapPss = swapPss; 21646 } 21647 21648 final SparseArray<Pair<Long, String>> watchUids 21649 = mMemWatchProcesses.getMap().get(proc.processName); 21650 Long check = null; 21651 if (watchUids != null) { 21652 Pair<Long, String> val = watchUids.get(proc.uid); 21653 if (val == null) { 21654 val = watchUids.get(0); 21655 } 21656 if (val != null) { 21657 check = val.first; 21658 } 21659 } 21660 if (check != null) { 21661 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) { 21662 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 21663 if (!isDebuggable) { 21664 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 21665 isDebuggable = true; 21666 } 21667 } 21668 if (isDebuggable) { 21669 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting"); 21670 final ProcessRecord myProc = proc; 21671 final File heapdumpFile = DumpHeapProvider.getJavaFile(); 21672 mMemWatchDumpProcName = proc.processName; 21673 mMemWatchDumpFile = heapdumpFile.toString(); 21674 mMemWatchDumpPid = proc.pid; 21675 mMemWatchDumpUid = proc.uid; 21676 BackgroundThread.getHandler().post(new Runnable() { 21677 @Override 21678 public void run() { 21679 revokeUriPermission(ActivityThread.currentActivityThread() 21680 .getApplicationThread(), 21681 null, DumpHeapActivity.JAVA_URI, 21682 Intent.FLAG_GRANT_READ_URI_PERMISSION 21683 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 21684 UserHandle.myUserId()); 21685 ParcelFileDescriptor fd = null; 21686 try { 21687 heapdumpFile.delete(); 21688 fd = ParcelFileDescriptor.open(heapdumpFile, 21689 ParcelFileDescriptor.MODE_CREATE | 21690 ParcelFileDescriptor.MODE_TRUNCATE | 21691 ParcelFileDescriptor.MODE_WRITE_ONLY | 21692 ParcelFileDescriptor.MODE_APPEND); 21693 IApplicationThread thread = myProc.thread; 21694 if (thread != null) { 21695 try { 21696 if (DEBUG_PSS) Slog.d(TAG_PSS, 21697 "Requesting dump heap from " 21698 + myProc + " to " + heapdumpFile); 21699 thread.dumpHeap(/* managed= */ true, 21700 /* mallocInfo= */ false, /* runGc= */ false, 21701 heapdumpFile.toString(), fd); 21702 } catch (RemoteException e) { 21703 } 21704 } 21705 } catch (FileNotFoundException e) { 21706 e.printStackTrace(); 21707 } finally { 21708 if (fd != null) { 21709 try { 21710 fd.close(); 21711 } catch (IOException e) { 21712 } 21713 } 21714 } 21715 } 21716 }); 21717 } else { 21718 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check 21719 + ", but debugging not enabled"); 21720 } 21721 } 21722 } 21723 } 21724 21725 /** 21726 * Schedule PSS collection of a process. 21727 */ 21728 void requestPssLocked(ProcessRecord proc, int procState) { 21729 if (mPendingPssProcesses.contains(proc)) { 21730 return; 21731 } 21732 if (mPendingPssProcesses.size() == 0) { 21733 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 21734 } 21735 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc); 21736 proc.pssProcState = procState; 21737 mPendingPssProcesses.add(proc); 21738 } 21739 21740 /** 21741 * Schedule PSS collection of all processes. 21742 */ 21743 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 21744 if (!always) { 21745 if (now < (mLastFullPssTime + 21746 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL 21747 : mConstants.FULL_PSS_MIN_INTERVAL))) { 21748 return; 21749 } 21750 } 21751 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered); 21752 mLastFullPssTime = now; 21753 mFullPssPending = true; 21754 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 21755 mPendingPssProcesses.clear(); 21756 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 21757 ProcessRecord app = mLruProcesses.get(i); 21758 if (app.thread == null 21759 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) { 21760 continue; 21761 } 21762 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 21763 app.pssProcState = app.setProcState; 21764 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 21765 mTestPssMode, isSleepingLocked(), now); 21766 mPendingPssProcesses.add(app); 21767 } 21768 } 21769 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 21770 } 21771 21772 public void setTestPssMode(boolean enabled) { 21773 synchronized (this) { 21774 mTestPssMode = enabled; 21775 if (enabled) { 21776 // Whenever we enable the mode, we want to take a snapshot all of current 21777 // process mem use. 21778 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 21779 } 21780 } 21781 } 21782 21783 /** 21784 * Ask a given process to GC right now. 21785 */ 21786 final void performAppGcLocked(ProcessRecord app) { 21787 try { 21788 app.lastRequestedGc = SystemClock.uptimeMillis(); 21789 if (app.thread != null) { 21790 if (app.reportLowMemory) { 21791 app.reportLowMemory = false; 21792 app.thread.scheduleLowMemory(); 21793 } else { 21794 app.thread.processInBackground(); 21795 } 21796 } 21797 } catch (Exception e) { 21798 // whatever. 21799 } 21800 } 21801 21802 /** 21803 * Returns true if things are idle enough to perform GCs. 21804 */ 21805 private final boolean canGcNowLocked() { 21806 boolean processingBroadcasts = false; 21807 for (BroadcastQueue q : mBroadcastQueues) { 21808 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 21809 processingBroadcasts = true; 21810 } 21811 } 21812 return !processingBroadcasts 21813 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle()); 21814 } 21815 21816 /** 21817 * Perform GCs on all processes that are waiting for it, but only 21818 * if things are idle. 21819 */ 21820 final void performAppGcsLocked() { 21821 final int N = mProcessesToGc.size(); 21822 if (N <= 0) { 21823 return; 21824 } 21825 if (canGcNowLocked()) { 21826 while (mProcessesToGc.size() > 0) { 21827 ProcessRecord proc = mProcessesToGc.remove(0); 21828 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 21829 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL) 21830 <= SystemClock.uptimeMillis()) { 21831 // To avoid spamming the system, we will GC processes one 21832 // at a time, waiting a few seconds between each. 21833 performAppGcLocked(proc); 21834 scheduleAppGcsLocked(); 21835 return; 21836 } else { 21837 // It hasn't been long enough since we last GCed this 21838 // process... put it in the list to wait for its time. 21839 addProcessToGcListLocked(proc); 21840 break; 21841 } 21842 } 21843 } 21844 21845 scheduleAppGcsLocked(); 21846 } 21847 } 21848 21849 /** 21850 * If all looks good, perform GCs on all processes waiting for them. 21851 */ 21852 final void performAppGcsIfAppropriateLocked() { 21853 if (canGcNowLocked()) { 21854 performAppGcsLocked(); 21855 return; 21856 } 21857 // Still not idle, wait some more. 21858 scheduleAppGcsLocked(); 21859 } 21860 21861 /** 21862 * Schedule the execution of all pending app GCs. 21863 */ 21864 final void scheduleAppGcsLocked() { 21865 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 21866 21867 if (mProcessesToGc.size() > 0) { 21868 // Schedule a GC for the time to the next process. 21869 ProcessRecord proc = mProcessesToGc.get(0); 21870 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 21871 21872 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL; 21873 long now = SystemClock.uptimeMillis(); 21874 if (when < (now+mConstants.GC_TIMEOUT)) { 21875 when = now + mConstants.GC_TIMEOUT; 21876 } 21877 mHandler.sendMessageAtTime(msg, when); 21878 } 21879 } 21880 21881 /** 21882 * Add a process to the array of processes waiting to be GCed. Keeps the 21883 * list in sorted order by the last GC time. The process can't already be 21884 * on the list. 21885 */ 21886 final void addProcessToGcListLocked(ProcessRecord proc) { 21887 boolean added = false; 21888 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 21889 if (mProcessesToGc.get(i).lastRequestedGc < 21890 proc.lastRequestedGc) { 21891 added = true; 21892 mProcessesToGc.add(i+1, proc); 21893 break; 21894 } 21895 } 21896 if (!added) { 21897 mProcessesToGc.add(0, proc); 21898 } 21899 } 21900 21901 /** 21902 * Set up to ask a process to GC itself. This will either do it 21903 * immediately, or put it on the list of processes to gc the next 21904 * time things are idle. 21905 */ 21906 final void scheduleAppGcLocked(ProcessRecord app) { 21907 long now = SystemClock.uptimeMillis(); 21908 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) { 21909 return; 21910 } 21911 if (!mProcessesToGc.contains(app)) { 21912 addProcessToGcListLocked(app); 21913 scheduleAppGcsLocked(); 21914 } 21915 } 21916 21917 final void checkExcessivePowerUsageLocked() { 21918 updateCpuStatsNow(); 21919 21920 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 21921 boolean doCpuKills = true; 21922 if (mLastPowerCheckUptime == 0) { 21923 doCpuKills = false; 21924 } 21925 final long curUptime = SystemClock.uptimeMillis(); 21926 final long uptimeSince = curUptime - mLastPowerCheckUptime; 21927 mLastPowerCheckUptime = curUptime; 21928 int i = mLruProcesses.size(); 21929 while (i > 0) { 21930 i--; 21931 ProcessRecord app = mLruProcesses.get(i); 21932 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 21933 if (app.lastCpuTime <= 0) { 21934 continue; 21935 } 21936 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 21937 if (DEBUG_POWER) { 21938 StringBuilder sb = new StringBuilder(128); 21939 sb.append("CPU for "); 21940 app.toShortString(sb); 21941 sb.append(": over "); 21942 TimeUtils.formatDuration(uptimeSince, sb); 21943 sb.append(" used "); 21944 TimeUtils.formatDuration(cputimeUsed, sb); 21945 sb.append(" ("); 21946 sb.append((cputimeUsed*100)/uptimeSince); 21947 sb.append("%)"); 21948 Slog.i(TAG_POWER, sb.toString()); 21949 } 21950 // If the process has used too much CPU over the last duration, the 21951 // user probably doesn't want this, so kill! 21952 if (doCpuKills && uptimeSince > 0) { 21953 // What is the limit for this process? 21954 int cpuLimit; 21955 long checkDur = curUptime - app.whenUnimportant; 21956 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) { 21957 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1; 21958 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2) 21959 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) { 21960 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2; 21961 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) { 21962 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3; 21963 } else { 21964 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4; 21965 } 21966 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) { 21967 synchronized (stats) { 21968 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 21969 uptimeSince, cputimeUsed); 21970 } 21971 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince 21972 + " dur=" + checkDur + " limit=" + cpuLimit, true); 21973 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 21974 } 21975 } 21976 app.lastCpuTime = app.curCpuTime; 21977 } 21978 } 21979 } 21980 21981 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now, 21982 long nowElapsed) { 21983 boolean success = true; 21984 21985 if (app.curRawAdj != app.setRawAdj) { 21986 app.setRawAdj = app.curRawAdj; 21987 } 21988 21989 int changes = 0; 21990 21991 if (app.curAdj != app.setAdj) { 21992 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj); 21993 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) { 21994 String msg = "Set " + app.pid + " " + app.processName + " adj " 21995 + app.curAdj + ": " + app.adjType; 21996 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); 21997 } 21998 app.setAdj = app.curAdj; 21999 app.verifiedAdj = ProcessList.INVALID_ADJ; 22000 } 22001 22002 if (app.setSchedGroup != app.curSchedGroup) { 22003 int oldSchedGroup = app.setSchedGroup; 22004 app.setSchedGroup = app.curSchedGroup; 22005 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) { 22006 String msg = "Setting sched group of " + app.processName 22007 + " to " + app.curSchedGroup; 22008 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); 22009 } 22010 if (app.waitingToKill != null && app.curReceivers.isEmpty() 22011 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) { 22012 app.kill(app.waitingToKill, true); 22013 success = false; 22014 } else { 22015 int processGroup; 22016 switch (app.curSchedGroup) { 22017 case ProcessList.SCHED_GROUP_BACKGROUND: 22018 processGroup = THREAD_GROUP_BG_NONINTERACTIVE; 22019 break; 22020 case ProcessList.SCHED_GROUP_TOP_APP: 22021 case ProcessList.SCHED_GROUP_TOP_APP_BOUND: 22022 processGroup = THREAD_GROUP_TOP_APP; 22023 break; 22024 default: 22025 processGroup = THREAD_GROUP_DEFAULT; 22026 break; 22027 } 22028 long oldId = Binder.clearCallingIdentity(); 22029 try { 22030 setProcessGroup(app.pid, processGroup); 22031 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { 22032 // do nothing if we already switched to RT 22033 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { 22034 mVrController.onTopProcChangedLocked(app); 22035 if (mUseFifoUiScheduling) { 22036 // Switch UI pipeline for app to SCHED_FIFO 22037 app.savedPriority = Process.getThreadPriority(app.pid); 22038 scheduleAsFifoPriority(app.pid, /* suppressLogs */true); 22039 if (app.renderThreadTid != 0) { 22040 scheduleAsFifoPriority(app.renderThreadTid, 22041 /* suppressLogs */true); 22042 if (DEBUG_OOM_ADJ) { 22043 Slog.d("UI_FIFO", "Set RenderThread (TID " + 22044 app.renderThreadTid + ") to FIFO"); 22045 } 22046 } else { 22047 if (DEBUG_OOM_ADJ) { 22048 Slog.d("UI_FIFO", "Not setting RenderThread TID"); 22049 } 22050 } 22051 } else { 22052 // Boost priority for top app UI and render threads 22053 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST); 22054 if (app.renderThreadTid != 0) { 22055 try { 22056 setThreadPriority(app.renderThreadTid, 22057 TOP_APP_PRIORITY_BOOST); 22058 } catch (IllegalArgumentException e) { 22059 // thread died, ignore 22060 } 22061 } 22062 } 22063 } 22064 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && 22065 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { 22066 mVrController.onTopProcChangedLocked(app); 22067 if (mUseFifoUiScheduling) { 22068 try { 22069 // Reset UI pipeline to SCHED_OTHER 22070 setThreadScheduler(app.pid, SCHED_OTHER, 0); 22071 setThreadPriority(app.pid, app.savedPriority); 22072 if (app.renderThreadTid != 0) { 22073 setThreadScheduler(app.renderThreadTid, 22074 SCHED_OTHER, 0); 22075 setThreadPriority(app.renderThreadTid, -4); 22076 } 22077 } catch (IllegalArgumentException e) { 22078 Slog.w(TAG, 22079 "Failed to set scheduling policy, thread does not exist:\n" 22080 + e); 22081 } catch (SecurityException e) { 22082 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e); 22083 } 22084 } else { 22085 // Reset priority for top app UI and render threads 22086 setThreadPriority(app.pid, 0); 22087 if (app.renderThreadTid != 0) { 22088 setThreadPriority(app.renderThreadTid, 0); 22089 } 22090 } 22091 } 22092 } catch (Exception e) { 22093 if (false) { 22094 Slog.w(TAG, "Failed setting process group of " + app.pid 22095 + " to " + app.curSchedGroup); 22096 Slog.w(TAG, "at location", e); 22097 } 22098 } finally { 22099 Binder.restoreCallingIdentity(oldId); 22100 } 22101 } 22102 } 22103 if (app.repForegroundActivities != app.foregroundActivities) { 22104 app.repForegroundActivities = app.foregroundActivities; 22105 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 22106 } 22107 if (app.repProcState != app.curProcState) { 22108 app.repProcState = app.curProcState; 22109 if (app.thread != null) { 22110 try { 22111 if (false) { 22112 //RuntimeException h = new RuntimeException("here"); 22113 Slog.i(TAG, "Sending new process state " + app.repProcState 22114 + " to " + app /*, h*/); 22115 } 22116 app.thread.setProcessState(app.repProcState); 22117 } catch (RemoteException e) { 22118 } 22119 } 22120 } 22121 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT 22122 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) { 22123 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 22124 // Experimental code to more aggressively collect pss while 22125 // running test... the problem is that this tends to collect 22126 // the data right when a process is transitioning between process 22127 // states, which well tend to give noisy data. 22128 long start = SystemClock.uptimeMillis(); 22129 long pss = Debug.getPss(app.pid, mTmpLong, null); 22130 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now); 22131 mPendingPssProcesses.remove(app); 22132 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 22133 + " to " + app.curProcState + ": " 22134 + (SystemClock.uptimeMillis()-start) + "ms"); 22135 } 22136 app.lastStateTime = now; 22137 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 22138 mTestPssMode, isSleepingLocked(), now); 22139 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from " 22140 + ProcessList.makeProcStateString(app.setProcState) + " to " 22141 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 22142 + (app.nextPssTime-now) + ": " + app); 22143 } else { 22144 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 22145 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 22146 mTestPssMode)))) { 22147 requestPssLocked(app, app.setProcState); 22148 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 22149 mTestPssMode, isSleepingLocked(), now); 22150 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS, 22151 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 22152 } 22153 if (app.setProcState != app.curProcState) { 22154 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) { 22155 String msg = "Proc state change of " + app.processName 22156 + " to " + app.curProcState; 22157 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); 22158 } 22159 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 22160 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 22161 if (setImportant && !curImportant) { 22162 // This app is no longer something we consider important enough to allow to 22163 // use arbitrary amounts of battery power. Note 22164 // its current CPU time to later know to kill it if 22165 // it is not behaving well. 22166 app.whenUnimportant = now; 22167 app.lastCpuTime = 0; 22168 } 22169 // Inform UsageStats of important process state change 22170 // Must be called before updating setProcState 22171 maybeUpdateUsageStatsLocked(app, nowElapsed); 22172 22173 app.setProcState = app.curProcState; 22174 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 22175 app.notCachedSinceIdle = false; 22176 } 22177 if (!doingAll) { 22178 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 22179 } else { 22180 app.procStateChanged = true; 22181 } 22182 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime) 22183 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) { 22184 // For apps that sit around for a long time in the interactive state, we need 22185 // to report this at least once a day so they don't go idle. 22186 maybeUpdateUsageStatsLocked(app, nowElapsed); 22187 } 22188 22189 if (changes != 0) { 22190 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22191 "Changes in " + app + ": " + changes); 22192 int i = mPendingProcessChanges.size()-1; 22193 ProcessChangeItem item = null; 22194 while (i >= 0) { 22195 item = mPendingProcessChanges.get(i); 22196 if (item.pid == app.pid) { 22197 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22198 "Re-using existing item: " + item); 22199 break; 22200 } 22201 i--; 22202 } 22203 if (i < 0) { 22204 // No existing item in pending changes; need a new one. 22205 final int NA = mAvailProcessChanges.size(); 22206 if (NA > 0) { 22207 item = mAvailProcessChanges.remove(NA-1); 22208 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22209 "Retrieving available item: " + item); 22210 } else { 22211 item = new ProcessChangeItem(); 22212 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22213 "Allocating new item: " + item); 22214 } 22215 item.changes = 0; 22216 item.pid = app.pid; 22217 item.uid = app.info.uid; 22218 if (mPendingProcessChanges.size() == 0) { 22219 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22220 "*** Enqueueing dispatch processes changed!"); 22221 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget(); 22222 } 22223 mPendingProcessChanges.add(item); 22224 } 22225 item.changes |= changes; 22226 item.foregroundActivities = app.repForegroundActivities; 22227 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22228 "Item " + Integer.toHexString(System.identityHashCode(item)) 22229 + " " + app.toShortString() + ": changes=" + item.changes 22230 + " foreground=" + item.foregroundActivities 22231 + " type=" + app.adjType + " source=" + app.adjSource 22232 + " target=" + app.adjTarget); 22233 } 22234 22235 return success; 22236 } 22237 22238 private boolean isEphemeralLocked(int uid) { 22239 String packages[] = mContext.getPackageManager().getPackagesForUid(uid); 22240 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid 22241 return false; 22242 } 22243 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid), 22244 packages[0]); 22245 } 22246 22247 @VisibleForTesting 22248 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) { 22249 final UidRecord.ChangeItem pendingChange; 22250 if (uidRec == null || uidRec.pendingChange == null) { 22251 if (mPendingUidChanges.size() == 0) { 22252 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22253 "*** Enqueueing dispatch uid changed!"); 22254 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget(); 22255 } 22256 final int NA = mAvailUidChanges.size(); 22257 if (NA > 0) { 22258 pendingChange = mAvailUidChanges.remove(NA-1); 22259 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22260 "Retrieving available item: " + pendingChange); 22261 } else { 22262 pendingChange = new UidRecord.ChangeItem(); 22263 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22264 "Allocating new item: " + pendingChange); 22265 } 22266 if (uidRec != null) { 22267 uidRec.pendingChange = pendingChange; 22268 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) { 22269 // If this uid is going away, and we haven't yet reported it is gone, 22270 // then do so now. 22271 change |= UidRecord.CHANGE_IDLE; 22272 } 22273 } else if (uid < 0) { 22274 throw new IllegalArgumentException("No UidRecord or uid"); 22275 } 22276 pendingChange.uidRecord = uidRec; 22277 pendingChange.uid = uidRec != null ? uidRec.uid : uid; 22278 mPendingUidChanges.add(pendingChange); 22279 } else { 22280 pendingChange = uidRec.pendingChange; 22281 // If there is no change in idle or active state, then keep whatever was pending. 22282 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) { 22283 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE 22284 | UidRecord.CHANGE_ACTIVE)); 22285 } 22286 // If there is no change in cached or uncached state, then keep whatever was pending. 22287 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) { 22288 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED 22289 | UidRecord.CHANGE_UNCACHED)); 22290 } 22291 // If this is a report of the UID being gone, then we shouldn't keep any previous 22292 // report of it being active or cached. (That is, a gone uid is never active, 22293 // and never cached.) 22294 if ((change & UidRecord.CHANGE_GONE) != 0) { 22295 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED); 22296 if (!uidRec.idle) { 22297 // If this uid is going away, and we haven't yet reported it is gone, 22298 // then do so now. 22299 change |= UidRecord.CHANGE_IDLE; 22300 } 22301 } 22302 } 22303 pendingChange.change = change; 22304 pendingChange.processState = uidRec != null 22305 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT; 22306 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid); 22307 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0; 22308 if (uidRec != null) { 22309 uidRec.lastReportedChange = change; 22310 uidRec.updateLastDispatchedProcStateSeq(change); 22311 } 22312 22313 // Directly update the power manager, since we sit on top of it and it is critical 22314 // it be kept in sync (so wake locks will be held as soon as appropriate). 22315 if (mLocalPowerManager != null) { 22316 // TO DO: dispatch cached/uncached changes here, so we don't need to report 22317 // all proc state changes. 22318 if ((change & UidRecord.CHANGE_ACTIVE) != 0) { 22319 mLocalPowerManager.uidActive(pendingChange.uid); 22320 } 22321 if ((change & UidRecord.CHANGE_IDLE) != 0) { 22322 mLocalPowerManager.uidIdle(pendingChange.uid); 22323 } 22324 if ((change & UidRecord.CHANGE_GONE) != 0) { 22325 mLocalPowerManager.uidGone(pendingChange.uid); 22326 } else { 22327 mLocalPowerManager.updateUidProcState(pendingChange.uid, 22328 pendingChange.processState); 22329 } 22330 } 22331 } 22332 22333 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName, 22334 String authority) { 22335 if (app == null) return; 22336 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 22337 UserState userState = mUserController.getStartedUserStateLocked(app.userId); 22338 if (userState == null) return; 22339 final long now = SystemClock.elapsedRealtime(); 22340 Long lastReported = userState.mProviderLastReportedFg.get(authority); 22341 if (lastReported == null || lastReported < now - 60 * 1000L) { 22342 if (mSystemReady) { 22343 // Cannot touch the user stats if not system ready 22344 mUsageStatsService.reportContentProviderUsage( 22345 authority, providerPkgName, app.userId); 22346 } 22347 userState.mProviderLastReportedFg.put(authority, now); 22348 } 22349 } 22350 } 22351 22352 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) { 22353 if (DEBUG_USAGE_STATS) { 22354 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList()) 22355 + "] state changes: old = " + app.setProcState + ", new = " 22356 + app.curProcState); 22357 } 22358 if (mUsageStatsService == null) { 22359 return; 22360 } 22361 boolean isInteraction; 22362 // To avoid some abuse patterns, we are going to be careful about what we consider 22363 // to be an app interaction. Being the top activity doesn't count while the display 22364 // is sleeping, nor do short foreground services. 22365 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { 22366 isInteraction = true; 22367 app.fgInteractionTime = 0; 22368 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) { 22369 if (app.fgInteractionTime == 0) { 22370 app.fgInteractionTime = nowElapsed; 22371 isInteraction = false; 22372 } else { 22373 isInteraction = nowElapsed > app.fgInteractionTime 22374 + mConstants.SERVICE_USAGE_INTERACTION_TIME; 22375 } 22376 } else { 22377 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 22378 app.fgInteractionTime = 0; 22379 } 22380 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime) 22381 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) { 22382 app.interactionEventTime = nowElapsed; 22383 String[] packages = app.getPackageList(); 22384 if (packages != null) { 22385 for (int i = 0; i < packages.length; i++) { 22386 mUsageStatsService.reportEvent(packages[i], app.userId, 22387 UsageEvents.Event.SYSTEM_INTERACTION); 22388 } 22389 } 22390 } 22391 app.reportedInteraction = isInteraction; 22392 if (!isInteraction) { 22393 app.interactionEventTime = 0; 22394 } 22395 } 22396 22397 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 22398 if (proc.thread != null) { 22399 if (proc.baseProcessTracker != null) { 22400 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 22401 } 22402 } 22403 } 22404 22405 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 22406 ProcessRecord TOP_APP, boolean doingAll, long now) { 22407 if (app.thread == null) { 22408 return false; 22409 } 22410 22411 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 22412 22413 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime()); 22414 } 22415 22416 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 22417 boolean oomAdj) { 22418 if (isForeground != proc.foregroundServices) { 22419 proc.foregroundServices = isForeground; 22420 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 22421 proc.info.uid); 22422 if (isForeground) { 22423 if (curProcs == null) { 22424 curProcs = new ArrayList<ProcessRecord>(); 22425 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 22426 } 22427 if (!curProcs.contains(proc)) { 22428 curProcs.add(proc); 22429 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 22430 proc.info.packageName, proc.info.uid); 22431 } 22432 } else { 22433 if (curProcs != null) { 22434 if (curProcs.remove(proc)) { 22435 mBatteryStatsService.noteEvent( 22436 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 22437 proc.info.packageName, proc.info.uid); 22438 if (curProcs.size() <= 0) { 22439 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 22440 } 22441 } 22442 } 22443 } 22444 if (oomAdj) { 22445 updateOomAdjLocked(); 22446 } 22447 } 22448 } 22449 22450 private final ActivityRecord resumedAppLocked() { 22451 ActivityRecord act = mStackSupervisor.getResumedActivityLocked(); 22452 String pkg; 22453 int uid; 22454 if (act != null) { 22455 pkg = act.packageName; 22456 uid = act.info.applicationInfo.uid; 22457 } else { 22458 pkg = null; 22459 uid = -1; 22460 } 22461 // Has the UID or resumed package name changed? 22462 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 22463 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 22464 if (mCurResumedPackage != null) { 22465 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 22466 mCurResumedPackage, mCurResumedUid); 22467 } 22468 mCurResumedPackage = pkg; 22469 mCurResumedUid = uid; 22470 if (mCurResumedPackage != null) { 22471 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 22472 mCurResumedPackage, mCurResumedUid); 22473 } 22474 } 22475 return act; 22476 } 22477 22478 /** 22479 * Update OomAdj for a specific process. 22480 * @param app The process to update 22481 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps 22482 * if necessary, or skip. 22483 * @return whether updateOomAdjLocked(app) was successful. 22484 */ 22485 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) { 22486 final ActivityRecord TOP_ACT = resumedAppLocked(); 22487 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 22488 final boolean wasCached = app.cached; 22489 22490 mAdjSeq++; 22491 22492 // This is the desired cached adjusment we want to tell it to use. 22493 // If our app is currently cached, we know it, and that is it. Otherwise, 22494 // we don't know it yet, and it needs to now be cached we will then 22495 // need to do a complete oom adj. 22496 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 22497 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 22498 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 22499 SystemClock.uptimeMillis()); 22500 if (oomAdjAll 22501 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) { 22502 // Changed to/from cached state, so apps after it in the LRU 22503 // list may also be changed. 22504 updateOomAdjLocked(); 22505 } 22506 return success; 22507 } 22508 22509 final void updateOomAdjLocked() { 22510 final ActivityRecord TOP_ACT = resumedAppLocked(); 22511 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 22512 final long now = SystemClock.uptimeMillis(); 22513 final long nowElapsed = SystemClock.elapsedRealtime(); 22514 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 22515 final int N = mLruProcesses.size(); 22516 22517 if (false) { 22518 RuntimeException e = new RuntimeException(); 22519 e.fillInStackTrace(); 22520 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 22521 } 22522 22523 // Reset state in all uid records. 22524 for (int i=mActiveUids.size()-1; i>=0; i--) { 22525 final UidRecord uidRec = mActiveUids.valueAt(i); 22526 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22527 "Starting update of " + uidRec); 22528 uidRec.reset(); 22529 } 22530 22531 mStackSupervisor.rankTaskLayersIfNeeded(); 22532 22533 mAdjSeq++; 22534 mNewNumServiceProcs = 0; 22535 mNewNumAServiceProcs = 0; 22536 22537 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES; 22538 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit; 22539 22540 // Let's determine how many processes we have running vs. 22541 // how many slots we have for background processes; we may want 22542 // to put multiple processes in a slot of there are enough of 22543 // them. 22544 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 22545 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 22546 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 22547 if (numEmptyProcs > cachedProcessLimit) { 22548 // If there are more empty processes than our limit on cached 22549 // processes, then use the cached process limit for the factor. 22550 // This ensures that the really old empty processes get pushed 22551 // down to the bottom, so if we are running low on memory we will 22552 // have a better chance at keeping around more cached processes 22553 // instead of a gazillion empty processes. 22554 numEmptyProcs = cachedProcessLimit; 22555 } 22556 int emptyFactor = numEmptyProcs/numSlots; 22557 if (emptyFactor < 1) emptyFactor = 1; 22558 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 22559 if (cachedFactor < 1) cachedFactor = 1; 22560 int stepCached = 0; 22561 int stepEmpty = 0; 22562 int numCached = 0; 22563 int numEmpty = 0; 22564 int numTrimming = 0; 22565 22566 mNumNonCachedProcs = 0; 22567 mNumCachedHiddenProcs = 0; 22568 22569 // First update the OOM adjustment for each of the 22570 // application processes based on their current state. 22571 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 22572 int nextCachedAdj = curCachedAdj+1; 22573 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 22574 int nextEmptyAdj = curEmptyAdj+2; 22575 for (int i=N-1; i>=0; i--) { 22576 ProcessRecord app = mLruProcesses.get(i); 22577 if (!app.killedByAm && app.thread != null) { 22578 app.procStateChanged = false; 22579 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 22580 22581 // If we haven't yet assigned the final cached adj 22582 // to the process, do that now. 22583 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 22584 switch (app.curProcState) { 22585 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 22586 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 22587 // This process is a cached process holding activities... 22588 // assign it the next cached value for that type, and then 22589 // step that cached level. 22590 app.curRawAdj = curCachedAdj; 22591 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 22592 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i 22593 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 22594 + ")"); 22595 if (curCachedAdj != nextCachedAdj) { 22596 stepCached++; 22597 if (stepCached >= cachedFactor) { 22598 stepCached = 0; 22599 curCachedAdj = nextCachedAdj; 22600 nextCachedAdj += 2; 22601 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 22602 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 22603 } 22604 } 22605 } 22606 break; 22607 default: 22608 // For everything else, assign next empty cached process 22609 // level and bump that up. Note that this means that 22610 // long-running services that have dropped down to the 22611 // cached level will be treated as empty (since their process 22612 // state is still as a service), which is what we want. 22613 app.curRawAdj = curEmptyAdj; 22614 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 22615 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i 22616 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 22617 + ")"); 22618 if (curEmptyAdj != nextEmptyAdj) { 22619 stepEmpty++; 22620 if (stepEmpty >= emptyFactor) { 22621 stepEmpty = 0; 22622 curEmptyAdj = nextEmptyAdj; 22623 nextEmptyAdj += 2; 22624 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 22625 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 22626 } 22627 } 22628 } 22629 break; 22630 } 22631 } 22632 22633 applyOomAdjLocked(app, true, now, nowElapsed); 22634 22635 // Count the number of process types. 22636 switch (app.curProcState) { 22637 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 22638 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 22639 mNumCachedHiddenProcs++; 22640 numCached++; 22641 if (numCached > cachedProcessLimit) { 22642 app.kill("cached #" + numCached, true); 22643 } 22644 break; 22645 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 22646 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES 22647 && app.lastActivityTime < oldTime) { 22648 app.kill("empty for " 22649 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 22650 / 1000) + "s", true); 22651 } else { 22652 numEmpty++; 22653 if (numEmpty > emptyProcessLimit) { 22654 app.kill("empty #" + numEmpty, true); 22655 } 22656 } 22657 break; 22658 default: 22659 mNumNonCachedProcs++; 22660 break; 22661 } 22662 22663 if (app.isolated && app.services.size() <= 0) { 22664 // If this is an isolated process, and there are no 22665 // services running in it, then the process is no longer 22666 // needed. We agressively kill these because we can by 22667 // definition not re-use the same process again, and it is 22668 // good to avoid having whatever code was running in them 22669 // left sitting around after no longer needed. 22670 app.kill("isolated not needed", true); 22671 } else { 22672 // Keeping this process, update its uid. 22673 final UidRecord uidRec = app.uidRecord; 22674 if (uidRec != null) { 22675 uidRec.ephemeral = app.info.isInstantApp(); 22676 if (uidRec.curProcState > app.curProcState) { 22677 uidRec.curProcState = app.curProcState; 22678 } 22679 if (app.foregroundServices) { 22680 uidRec.foregroundServices = true; 22681 } 22682 } 22683 } 22684 22685 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 22686 && !app.killedByAm) { 22687 numTrimming++; 22688 } 22689 } 22690 } 22691 22692 incrementProcStateSeqAndNotifyAppsLocked(); 22693 22694 mNumServiceProcs = mNewNumServiceProcs; 22695 22696 // Now determine the memory trimming level of background processes. 22697 // Unfortunately we need to start at the back of the list to do this 22698 // properly. We only do this if the number of background apps we 22699 // are managing to keep around is less than half the maximum we desire; 22700 // if we are keeping a good number around, we'll let them use whatever 22701 // memory they want. 22702 final int numCachedAndEmpty = numCached + numEmpty; 22703 int memFactor; 22704 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES 22705 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) { 22706 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 22707 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 22708 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 22709 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 22710 } else { 22711 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 22712 } 22713 } else { 22714 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 22715 } 22716 // We always allow the memory level to go up (better). We only allow it to go 22717 // down if we are in a state where that is allowed, *and* the total number of processes 22718 // has gone down since last time. 22719 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor 22720 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel 22721 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses); 22722 if (memFactor > mLastMemoryLevel) { 22723 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 22724 memFactor = mLastMemoryLevel; 22725 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!"); 22726 } 22727 } 22728 if (memFactor != mLastMemoryLevel) { 22729 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel); 22730 } 22731 mLastMemoryLevel = memFactor; 22732 mLastNumProcesses = mLruProcesses.size(); 22733 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now); 22734 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 22735 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 22736 if (mLowRamStartTime == 0) { 22737 mLowRamStartTime = now; 22738 } 22739 int step = 0; 22740 int fgTrimLevel; 22741 switch (memFactor) { 22742 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 22743 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 22744 break; 22745 case ProcessStats.ADJ_MEM_FACTOR_LOW: 22746 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 22747 break; 22748 default: 22749 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 22750 break; 22751 } 22752 int factor = numTrimming/3; 22753 int minFactor = 2; 22754 if (mHomeProcess != null) minFactor++; 22755 if (mPreviousProcess != null) minFactor++; 22756 if (factor < minFactor) factor = minFactor; 22757 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 22758 for (int i=N-1; i>=0; i--) { 22759 ProcessRecord app = mLruProcesses.get(i); 22760 if (allChanged || app.procStateChanged) { 22761 setProcessTrackerStateLocked(app, trackerMemFactor, now); 22762 app.procStateChanged = false; 22763 } 22764 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 22765 && !app.killedByAm) { 22766 if (app.trimMemoryLevel < curLevel && app.thread != null) { 22767 try { 22768 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22769 "Trimming memory of " + app.processName + " to " + curLevel); 22770 app.thread.scheduleTrimMemory(curLevel); 22771 } catch (RemoteException e) { 22772 } 22773 if (false) { 22774 // For now we won't do this; our memory trimming seems 22775 // to be good enough at this point that destroying 22776 // activities causes more harm than good. 22777 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 22778 && app != mHomeProcess && app != mPreviousProcess) { 22779 // Need to do this on its own message because the stack may not 22780 // be in a consistent state at this point. 22781 // For these apps we will also finish their activities 22782 // to help them free memory. 22783 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 22784 } 22785 } 22786 } 22787 app.trimMemoryLevel = curLevel; 22788 step++; 22789 if (step >= factor) { 22790 step = 0; 22791 switch (curLevel) { 22792 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 22793 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 22794 break; 22795 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 22796 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 22797 break; 22798 } 22799 } 22800 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 22801 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 22802 && app.thread != null) { 22803 try { 22804 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22805 "Trimming memory of heavy-weight " + app.processName 22806 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 22807 app.thread.scheduleTrimMemory( 22808 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 22809 } catch (RemoteException e) { 22810 } 22811 } 22812 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 22813 } else { 22814 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 22815 || app.systemNoUi) && app.pendingUiClean) { 22816 // If this application is now in the background and it 22817 // had done UI, then give it the special trim level to 22818 // have it free UI resources. 22819 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 22820 if (app.trimMemoryLevel < level && app.thread != null) { 22821 try { 22822 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22823 "Trimming memory of bg-ui " + app.processName 22824 + " to " + level); 22825 app.thread.scheduleTrimMemory(level); 22826 } catch (RemoteException e) { 22827 } 22828 } 22829 app.pendingUiClean = false; 22830 } 22831 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 22832 try { 22833 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22834 "Trimming memory of fg " + app.processName 22835 + " to " + fgTrimLevel); 22836 app.thread.scheduleTrimMemory(fgTrimLevel); 22837 } catch (RemoteException e) { 22838 } 22839 } 22840 app.trimMemoryLevel = fgTrimLevel; 22841 } 22842 } 22843 } else { 22844 if (mLowRamStartTime != 0) { 22845 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 22846 mLowRamStartTime = 0; 22847 } 22848 for (int i=N-1; i>=0; i--) { 22849 ProcessRecord app = mLruProcesses.get(i); 22850 if (allChanged || app.procStateChanged) { 22851 setProcessTrackerStateLocked(app, trackerMemFactor, now); 22852 app.procStateChanged = false; 22853 } 22854 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 22855 || app.systemNoUi) && app.pendingUiClean) { 22856 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 22857 && app.thread != null) { 22858 try { 22859 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22860 "Trimming memory of ui hidden " + app.processName 22861 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 22862 app.thread.scheduleTrimMemory( 22863 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 22864 } catch (RemoteException e) { 22865 } 22866 } 22867 app.pendingUiClean = false; 22868 } 22869 app.trimMemoryLevel = 0; 22870 } 22871 } 22872 22873 if (mAlwaysFinishActivities) { 22874 // Need to do this on its own message because the stack may not 22875 // be in a consistent state at this point. 22876 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 22877 } 22878 22879 if (allChanged) { 22880 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 22881 } 22882 22883 ArrayList<UidRecord> becameIdle = null; 22884 22885 // Update from any uid changes. 22886 if (mLocalPowerManager != null) { 22887 mLocalPowerManager.startUidChanges(); 22888 } 22889 for (int i=mActiveUids.size()-1; i>=0; i--) { 22890 final UidRecord uidRec = mActiveUids.valueAt(i); 22891 int uidChange = UidRecord.CHANGE_PROCSTATE; 22892 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT 22893 && (uidRec.setProcState != uidRec.curProcState 22894 || uidRec.setWhitelist != uidRec.curWhitelist)) { 22895 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22896 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState 22897 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist 22898 + " to " + uidRec.curWhitelist); 22899 if (ActivityManager.isProcStateBackground(uidRec.curProcState) 22900 && !uidRec.curWhitelist) { 22901 // UID is now in the background (and not on the temp whitelist). Was it 22902 // previously in the foreground (or on the temp whitelist)? 22903 if (!ActivityManager.isProcStateBackground(uidRec.setProcState) 22904 || uidRec.setWhitelist) { 22905 uidRec.lastBackgroundTime = nowElapsed; 22906 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) { 22907 // Note: the background settle time is in elapsed realtime, while 22908 // the handler time base is uptime. All this means is that we may 22909 // stop background uids later than we had intended, but that only 22910 // happens because the device was sleeping so we are okay anyway. 22911 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 22912 mConstants.BACKGROUND_SETTLE_TIME); 22913 } 22914 } 22915 if (uidRec.idle && !uidRec.setIdle) { 22916 uidChange = UidRecord.CHANGE_IDLE; 22917 if (becameIdle == null) { 22918 becameIdle = new ArrayList<>(); 22919 } 22920 becameIdle.add(uidRec); 22921 } 22922 } else { 22923 if (uidRec.idle) { 22924 uidChange = UidRecord.CHANGE_ACTIVE; 22925 EventLogTags.writeAmUidActive(uidRec.uid); 22926 uidRec.idle = false; 22927 } 22928 uidRec.lastBackgroundTime = 0; 22929 } 22930 final boolean wasCached = uidRec.setProcState 22931 > ActivityManager.PROCESS_STATE_RECEIVER; 22932 final boolean isCached = uidRec.curProcState 22933 > ActivityManager.PROCESS_STATE_RECEIVER; 22934 if (wasCached != isCached || 22935 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) { 22936 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED; 22937 } 22938 uidRec.setProcState = uidRec.curProcState; 22939 uidRec.setWhitelist = uidRec.curWhitelist; 22940 uidRec.setIdle = uidRec.idle; 22941 enqueueUidChangeLocked(uidRec, -1, uidChange); 22942 noteUidProcessState(uidRec.uid, uidRec.curProcState); 22943 if (uidRec.foregroundServices) { 22944 mServices.foregroundServiceProcStateChangedLocked(uidRec); 22945 } 22946 } 22947 } 22948 if (mLocalPowerManager != null) { 22949 mLocalPowerManager.finishUidChanges(); 22950 } 22951 22952 if (becameIdle != null) { 22953 // If we have any new uids that became idle this time, we need to make sure 22954 // they aren't left with running services. 22955 for (int i = becameIdle.size() - 1; i >= 0; i--) { 22956 mServices.stopInBackgroundLocked(becameIdle.get(i).uid); 22957 } 22958 } 22959 22960 if (mProcessStats.shouldWriteNowLocked(now)) { 22961 mHandler.post(new Runnable() { 22962 @Override public void run() { 22963 synchronized (ActivityManagerService.this) { 22964 mProcessStats.writeStateAsyncLocked(); 22965 } 22966 } 22967 }); 22968 } 22969 22970 if (DEBUG_OOM_ADJ) { 22971 final long duration = SystemClock.uptimeMillis() - now; 22972 if (false) { 22973 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms", 22974 new RuntimeException("here").fillInStackTrace()); 22975 } else { 22976 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms"); 22977 } 22978 } 22979 } 22980 22981 @Override 22982 public void makePackageIdle(String packageName, int userId) { 22983 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 22984 != PackageManager.PERMISSION_GRANTED) { 22985 String msg = "Permission Denial: makePackageIdle() from pid=" 22986 + Binder.getCallingPid() 22987 + ", uid=" + Binder.getCallingUid() 22988 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 22989 Slog.w(TAG, msg); 22990 throw new SecurityException(msg); 22991 } 22992 final int callingPid = Binder.getCallingPid(); 22993 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(), 22994 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null); 22995 long callingId = Binder.clearCallingIdentity(); 22996 synchronized(this) { 22997 try { 22998 IPackageManager pm = AppGlobals.getPackageManager(); 22999 int pkgUid = -1; 23000 try { 23001 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES 23002 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM); 23003 } catch (RemoteException e) { 23004 } 23005 if (pkgUid == -1) { 23006 throw new IllegalArgumentException("Unknown package name " + packageName); 23007 } 23008 23009 if (mLocalPowerManager != null) { 23010 mLocalPowerManager.startUidChanges(); 23011 } 23012 final int appId = UserHandle.getAppId(pkgUid); 23013 final int N = mActiveUids.size(); 23014 for (int i=N-1; i>=0; i--) { 23015 final UidRecord uidRec = mActiveUids.valueAt(i); 23016 final long bgTime = uidRec.lastBackgroundTime; 23017 if (bgTime > 0 && !uidRec.idle) { 23018 if (UserHandle.getAppId(uidRec.uid) == appId) { 23019 if (userId == UserHandle.USER_ALL || 23020 userId == UserHandle.getUserId(uidRec.uid)) { 23021 EventLogTags.writeAmUidIdle(uidRec.uid); 23022 uidRec.idle = true; 23023 uidRec.setIdle = true; 23024 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid) 23025 + " from package " + packageName + " user " + userId); 23026 doStopUidLocked(uidRec.uid, uidRec); 23027 } 23028 } 23029 } 23030 } 23031 } finally { 23032 if (mLocalPowerManager != null) { 23033 mLocalPowerManager.finishUidChanges(); 23034 } 23035 Binder.restoreCallingIdentity(callingId); 23036 } 23037 } 23038 } 23039 23040 final void idleUids() { 23041 synchronized (this) { 23042 final int N = mActiveUids.size(); 23043 if (N <= 0) { 23044 return; 23045 } 23046 final long nowElapsed = SystemClock.elapsedRealtime(); 23047 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME; 23048 long nextTime = 0; 23049 if (mLocalPowerManager != null) { 23050 mLocalPowerManager.startUidChanges(); 23051 } 23052 for (int i=N-1; i>=0; i--) { 23053 final UidRecord uidRec = mActiveUids.valueAt(i); 23054 final long bgTime = uidRec.lastBackgroundTime; 23055 if (bgTime > 0 && !uidRec.idle) { 23056 if (bgTime <= maxBgTime) { 23057 EventLogTags.writeAmUidIdle(uidRec.uid); 23058 uidRec.idle = true; 23059 uidRec.setIdle = true; 23060 doStopUidLocked(uidRec.uid, uidRec); 23061 } else { 23062 if (nextTime == 0 || nextTime > bgTime) { 23063 nextTime = bgTime; 23064 } 23065 } 23066 } 23067 } 23068 if (mLocalPowerManager != null) { 23069 mLocalPowerManager.finishUidChanges(); 23070 } 23071 if (nextTime > 0) { 23072 mHandler.removeMessages(IDLE_UIDS_MSG); 23073 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 23074 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed); 23075 } 23076 } 23077 } 23078 23079 /** 23080 * Checks if any uid is coming from background to foreground or vice versa and if so, increments 23081 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter 23082 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block. 23083 */ 23084 @VisibleForTesting 23085 @GuardedBy("this") 23086 void incrementProcStateSeqAndNotifyAppsLocked() { 23087 if (mWaitForNetworkTimeoutMs <= 0) { 23088 return; 23089 } 23090 // Used for identifying which uids need to block for network. 23091 ArrayList<Integer> blockingUids = null; 23092 for (int i = mActiveUids.size() - 1; i >= 0; --i) { 23093 final UidRecord uidRec = mActiveUids.valueAt(i); 23094 // If the network is not restricted for uid, then nothing to do here. 23095 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) { 23096 continue; 23097 } 23098 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) { 23099 continue; 23100 } 23101 // If process state is not changed, then there's nothing to do. 23102 if (uidRec.setProcState == uidRec.curProcState) { 23103 continue; 23104 } 23105 final int blockState = getBlockStateForUid(uidRec); 23106 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as 23107 // there's nothing the app needs to do in this scenario. 23108 if (blockState == NETWORK_STATE_NO_CHANGE) { 23109 continue; 23110 } 23111 synchronized (uidRec.networkStateLock) { 23112 uidRec.curProcStateSeq = ++mProcStateSeqCounter; 23113 if (blockState == NETWORK_STATE_BLOCK) { 23114 if (blockingUids == null) { 23115 blockingUids = new ArrayList<>(); 23116 } 23117 blockingUids.add(uidRec.uid); 23118 } else { 23119 if (DEBUG_NETWORK) { 23120 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking" 23121 + " threads for uid: " + uidRec); 23122 } 23123 if (uidRec.waitingForNetwork) { 23124 uidRec.networkStateLock.notifyAll(); 23125 } 23126 } 23127 } 23128 } 23129 23130 // There are no uids that need to block, so nothing more to do. 23131 if (blockingUids == null) { 23132 return; 23133 } 23134 23135 for (int i = mLruProcesses.size() - 1; i >= 0; --i) { 23136 final ProcessRecord app = mLruProcesses.get(i); 23137 if (!blockingUids.contains(app.uid)) { 23138 continue; 23139 } 23140 if (!app.killedByAm && app.thread != null) { 23141 final UidRecord uidRec = mActiveUids.get(app.uid); 23142 try { 23143 if (DEBUG_NETWORK) { 23144 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: " 23145 + uidRec); 23146 } 23147 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq); 23148 } catch (RemoteException ignored) { 23149 } 23150 } 23151 } 23152 } 23153 23154 /** 23155 * Checks if the uid is coming from background to foreground or vice versa and returns 23156 * appropriate block state based on this. 23157 * 23158 * @return blockState based on whether the uid is coming from background to foreground or 23159 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or 23160 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise 23161 * {@link #NETWORK_STATE_NO_CHANGE}. 23162 */ 23163 @VisibleForTesting 23164 int getBlockStateForUid(UidRecord uidRec) { 23165 // Denotes whether uid's process state is currently allowed network access. 23166 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState) 23167 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState); 23168 // Denotes whether uid's process state was previously allowed network access. 23169 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState) 23170 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState); 23171 23172 // When the uid is coming to foreground, AMS should inform the app thread that it should 23173 // block for the network rules to get updated before launching an activity. 23174 if (!wasAllowed && isAllowed) { 23175 return NETWORK_STATE_BLOCK; 23176 } 23177 // When the uid is going to background, AMS should inform the app thread that if an 23178 // activity launch is blocked for the network rules to get updated, it should be unblocked. 23179 if (wasAllowed && !isAllowed) { 23180 return NETWORK_STATE_UNBLOCK; 23181 } 23182 return NETWORK_STATE_NO_CHANGE; 23183 } 23184 23185 final void runInBackgroundDisabled(int uid) { 23186 synchronized (this) { 23187 UidRecord uidRec = mActiveUids.get(uid); 23188 if (uidRec != null) { 23189 // This uid is actually running... should it be considered background now? 23190 if (uidRec.idle) { 23191 doStopUidLocked(uidRec.uid, uidRec); 23192 } 23193 } else { 23194 // This uid isn't actually running... still send a report about it being "stopped". 23195 doStopUidLocked(uid, null); 23196 } 23197 } 23198 } 23199 23200 final void doStopUidLocked(int uid, final UidRecord uidRec) { 23201 mServices.stopInBackgroundLocked(uid); 23202 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE); 23203 } 23204 23205 /** 23206 * Whitelists {@code targetUid} to temporarily bypass Power Save mode. 23207 */ 23208 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid, 23209 long duration, String tag) { 23210 if (DEBUG_WHITELISTS) { 23211 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", " 23212 + targetUid + ", " + duration + ")"); 23213 } 23214 23215 synchronized (mPidsSelfLocked) { 23216 final ProcessRecord pr = mPidsSelfLocked.get(callerPid); 23217 if (pr == null) { 23218 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid " 23219 + callerPid); 23220 return; 23221 } 23222 if (!pr.whitelistManager) { 23223 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid) 23224 != PackageManager.PERMISSION_GRANTED) { 23225 if (DEBUG_WHITELISTS) { 23226 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid 23227 + ": pid " + callerPid + " is not allowed"); 23228 } 23229 return; 23230 } 23231 } 23232 } 23233 23234 tempWhitelistUidLocked(targetUid, duration, tag); 23235 } 23236 23237 /** 23238 * Whitelists {@code targetUid} to temporarily bypass Power Save mode. 23239 */ 23240 void tempWhitelistUidLocked(int targetUid, long duration, String tag) { 23241 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag)); 23242 setUidTempWhitelistStateLocked(targetUid, true); 23243 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget(); 23244 } 23245 23246 void pushTempWhitelist() { 23247 final int N; 23248 final PendingTempWhitelist[] list; 23249 23250 // First copy out the pending changes... we need to leave them in the map for now, 23251 // in case someone needs to check what is coming up while we don't have the lock held. 23252 synchronized(this) { 23253 N = mPendingTempWhitelist.size(); 23254 list = new PendingTempWhitelist[N]; 23255 for (int i = 0; i < N; i++) { 23256 list[i] = mPendingTempWhitelist.valueAt(i); 23257 } 23258 } 23259 23260 // Now safely dispatch changes to device idle controller. 23261 for (int i = 0; i < N; i++) { 23262 PendingTempWhitelist ptw = list[i]; 23263 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid, 23264 ptw.duration, true, ptw.tag); 23265 } 23266 23267 // And now we can safely remove them from the map. 23268 synchronized(this) { 23269 for (int i = 0; i < N; i++) { 23270 PendingTempWhitelist ptw = list[i]; 23271 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid); 23272 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) { 23273 mPendingTempWhitelist.removeAt(index); 23274 } 23275 } 23276 } 23277 } 23278 23279 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) { 23280 boolean changed = false; 23281 for (int i=mActiveUids.size()-1; i>=0; i--) { 23282 final UidRecord uidRec = mActiveUids.valueAt(i); 23283 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) { 23284 uidRec.curWhitelist = onWhitelist; 23285 changed = true; 23286 } 23287 } 23288 if (changed) { 23289 updateOomAdjLocked(); 23290 } 23291 } 23292 23293 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) { 23294 boolean changed = false; 23295 final UidRecord uidRec = mActiveUids.get(uid); 23296 if (uidRec != null && uidRec.curWhitelist != onWhitelist) { 23297 uidRec.curWhitelist = onWhitelist; 23298 updateOomAdjLocked(); 23299 } 23300 } 23301 23302 final void trimApplications() { 23303 synchronized (this) { 23304 int i; 23305 23306 // First remove any unused application processes whose package 23307 // has been removed. 23308 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 23309 final ProcessRecord app = mRemovedProcesses.get(i); 23310 if (app.activities.size() == 0 23311 && app.curReceivers.isEmpty() && app.services.size() == 0) { 23312 Slog.i( 23313 TAG, "Exiting empty application process " 23314 + app.toShortString() + " (" 23315 + (app.thread != null ? app.thread.asBinder() : null) 23316 + ")\n"); 23317 if (app.pid > 0 && app.pid != MY_PID) { 23318 app.kill("empty", false); 23319 } else { 23320 try { 23321 app.thread.scheduleExit(); 23322 } catch (Exception e) { 23323 // Ignore exceptions. 23324 } 23325 } 23326 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/); 23327 mRemovedProcesses.remove(i); 23328 23329 if (app.persistent) { 23330 addAppLocked(app.info, null, false, null /* ABI override */); 23331 } 23332 } 23333 } 23334 23335 // Now update the oom adj for all processes. 23336 updateOomAdjLocked(); 23337 } 23338 } 23339 23340 /** This method sends the specified signal to each of the persistent apps */ 23341 public void signalPersistentProcesses(int sig) throws RemoteException { 23342 if (sig != SIGNAL_USR1) { 23343 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 23344 } 23345 23346 synchronized (this) { 23347 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 23348 != PackageManager.PERMISSION_GRANTED) { 23349 throw new SecurityException("Requires permission " 23350 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 23351 } 23352 23353 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 23354 ProcessRecord r = mLruProcesses.get(i); 23355 if (r.thread != null && r.persistent) { 23356 sendSignal(r.pid, sig); 23357 } 23358 } 23359 } 23360 } 23361 23362 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 23363 if (proc == null || proc == mProfileProc) { 23364 proc = mProfileProc; 23365 profileType = mProfileType; 23366 clearProfilerLocked(); 23367 } 23368 if (proc == null) { 23369 return; 23370 } 23371 try { 23372 proc.thread.profilerControl(false, null, profileType); 23373 } catch (RemoteException e) { 23374 throw new IllegalStateException("Process disappeared"); 23375 } 23376 } 23377 23378 private void clearProfilerLocked() { 23379 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) { 23380 try { 23381 mProfilerInfo.profileFd.close(); 23382 } catch (IOException e) { 23383 } 23384 } 23385 mProfileApp = null; 23386 mProfileProc = null; 23387 mProfilerInfo = null; 23388 } 23389 23390 public boolean profileControl(String process, int userId, boolean start, 23391 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 23392 23393 try { 23394 synchronized (this) { 23395 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 23396 // its own permission. 23397 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 23398 != PackageManager.PERMISSION_GRANTED) { 23399 throw new SecurityException("Requires permission " 23400 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 23401 } 23402 23403 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 23404 throw new IllegalArgumentException("null profile info or fd"); 23405 } 23406 23407 ProcessRecord proc = null; 23408 if (process != null) { 23409 proc = findProcessLocked(process, userId, "profileControl"); 23410 } 23411 23412 if (start && (proc == null || proc.thread == null)) { 23413 throw new IllegalArgumentException("Unknown process: " + process); 23414 } 23415 23416 if (start) { 23417 stopProfilerLocked(null, 0); 23418 setProfileApp(proc.info, proc.processName, profilerInfo); 23419 mProfileProc = proc; 23420 mProfileType = profileType; 23421 ParcelFileDescriptor fd = profilerInfo.profileFd; 23422 try { 23423 fd = fd.dup(); 23424 } catch (IOException e) { 23425 fd = null; 23426 } 23427 profilerInfo.profileFd = fd; 23428 proc.thread.profilerControl(start, profilerInfo, profileType); 23429 fd = null; 23430 try { 23431 mProfilerInfo.profileFd.close(); 23432 } catch (IOException e) { 23433 } 23434 mProfilerInfo.profileFd = null; 23435 } else { 23436 stopProfilerLocked(proc, profileType); 23437 if (profilerInfo != null && profilerInfo.profileFd != null) { 23438 try { 23439 profilerInfo.profileFd.close(); 23440 } catch (IOException e) { 23441 } 23442 } 23443 } 23444 23445 return true; 23446 } 23447 } catch (RemoteException e) { 23448 throw new IllegalStateException("Process disappeared"); 23449 } finally { 23450 if (profilerInfo != null && profilerInfo.profileFd != null) { 23451 try { 23452 profilerInfo.profileFd.close(); 23453 } catch (IOException e) { 23454 } 23455 } 23456 } 23457 } 23458 23459 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 23460 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 23461 userId, true, ALLOW_FULL_ONLY, callName, null); 23462 ProcessRecord proc = null; 23463 try { 23464 int pid = Integer.parseInt(process); 23465 synchronized (mPidsSelfLocked) { 23466 proc = mPidsSelfLocked.get(pid); 23467 } 23468 } catch (NumberFormatException e) { 23469 } 23470 23471 if (proc == null) { 23472 ArrayMap<String, SparseArray<ProcessRecord>> all 23473 = mProcessNames.getMap(); 23474 SparseArray<ProcessRecord> procs = all.get(process); 23475 if (procs != null && procs.size() > 0) { 23476 proc = procs.valueAt(0); 23477 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 23478 for (int i=1; i<procs.size(); i++) { 23479 ProcessRecord thisProc = procs.valueAt(i); 23480 if (thisProc.userId == userId) { 23481 proc = thisProc; 23482 break; 23483 } 23484 } 23485 } 23486 } 23487 } 23488 23489 return proc; 23490 } 23491 23492 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo, 23493 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException { 23494 23495 try { 23496 synchronized (this) { 23497 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 23498 // its own permission (same as profileControl). 23499 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 23500 != PackageManager.PERMISSION_GRANTED) { 23501 throw new SecurityException("Requires permission " 23502 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 23503 } 23504 23505 if (fd == null) { 23506 throw new IllegalArgumentException("null fd"); 23507 } 23508 23509 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 23510 if (proc == null || proc.thread == null) { 23511 throw new IllegalArgumentException("Unknown process: " + process); 23512 } 23513 23514 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 23515 if (!isDebuggable) { 23516 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 23517 throw new SecurityException("Process not debuggable: " + proc); 23518 } 23519 } 23520 23521 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd); 23522 fd = null; 23523 return true; 23524 } 23525 } catch (RemoteException e) { 23526 throw new IllegalStateException("Process disappeared"); 23527 } finally { 23528 if (fd != null) { 23529 try { 23530 fd.close(); 23531 } catch (IOException e) { 23532 } 23533 } 23534 } 23535 } 23536 23537 @Override 23538 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize, 23539 String reportPackage) { 23540 if (processName != null) { 23541 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 23542 "setDumpHeapDebugLimit()"); 23543 } else { 23544 synchronized (mPidsSelfLocked) { 23545 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid()); 23546 if (proc == null) { 23547 throw new SecurityException("No process found for calling pid " 23548 + Binder.getCallingPid()); 23549 } 23550 if (!Build.IS_DEBUGGABLE 23551 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 23552 throw new SecurityException("Not running a debuggable build"); 23553 } 23554 processName = proc.processName; 23555 uid = proc.uid; 23556 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) { 23557 throw new SecurityException("Package " + reportPackage + " is not running in " 23558 + proc); 23559 } 23560 } 23561 } 23562 synchronized (this) { 23563 if (maxMemSize > 0) { 23564 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage)); 23565 } else { 23566 if (uid != 0) { 23567 mMemWatchProcesses.remove(processName, uid); 23568 } else { 23569 mMemWatchProcesses.getMap().remove(processName); 23570 } 23571 } 23572 } 23573 } 23574 23575 @Override 23576 public void dumpHeapFinished(String path) { 23577 synchronized (this) { 23578 if (Binder.getCallingPid() != mMemWatchDumpPid) { 23579 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid() 23580 + " does not match last pid " + mMemWatchDumpPid); 23581 return; 23582 } 23583 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) { 23584 Slog.w(TAG, "dumpHeapFinished: Calling path " + path 23585 + " does not match last path " + mMemWatchDumpFile); 23586 return; 23587 } 23588 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path); 23589 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG); 23590 23591 // Forced gc to clean up the remnant hprof fd. 23592 Runtime.getRuntime().gc(); 23593 } 23594 } 23595 23596 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 23597 public void monitor() { 23598 synchronized (this) { } 23599 } 23600 23601 void onCoreSettingsChange(Bundle settings) { 23602 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 23603 ProcessRecord processRecord = mLruProcesses.get(i); 23604 try { 23605 if (processRecord.thread != null) { 23606 processRecord.thread.setCoreSettings(settings); 23607 } 23608 } catch (RemoteException re) { 23609 /* ignore */ 23610 } 23611 } 23612 } 23613 23614 // Multi-user methods 23615 23616 /** 23617 * Start user, if its not already running, but don't bring it to foreground. 23618 */ 23619 @Override 23620 public boolean startUserInBackground(final int userId) { 23621 return mUserController.startUser(userId, /* foreground */ false); 23622 } 23623 23624 @Override 23625 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) { 23626 return mUserController.unlockUser(userId, token, secret, listener); 23627 } 23628 23629 @Override 23630 public boolean switchUser(final int targetUserId) { 23631 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId); 23632 int currentUserId; 23633 UserInfo targetUserInfo; 23634 synchronized (this) { 23635 currentUserId = mUserController.getCurrentUserIdLocked(); 23636 targetUserInfo = mUserController.getUserInfo(targetUserId); 23637 if (targetUserId == currentUserId) { 23638 Slog.i(TAG, "user #" + targetUserId + " is already the current user"); 23639 return true; 23640 } 23641 if (targetUserInfo == null) { 23642 Slog.w(TAG, "No user info for user #" + targetUserId); 23643 return false; 23644 } 23645 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) { 23646 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId 23647 + " when device is in demo mode"); 23648 return false; 23649 } 23650 if (!targetUserInfo.supportsSwitchTo()) { 23651 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported"); 23652 return false; 23653 } 23654 if (targetUserInfo.isManagedProfile()) { 23655 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user"); 23656 return false; 23657 } 23658 mUserController.setTargetUserIdLocked(targetUserId); 23659 } 23660 if (mUserController.mUserSwitchUiEnabled) { 23661 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId); 23662 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo); 23663 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG); 23664 mUiHandler.sendMessage(mHandler.obtainMessage( 23665 START_USER_SWITCH_UI_MSG, userNames)); 23666 } else { 23667 mHandler.removeMessages(START_USER_SWITCH_FG_MSG); 23668 mHandler.sendMessage(mHandler.obtainMessage( 23669 START_USER_SWITCH_FG_MSG, targetUserId, 0)); 23670 } 23671 return true; 23672 } 23673 23674 void scheduleStartProfilesLocked() { 23675 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 23676 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 23677 DateUtils.SECOND_IN_MILLIS); 23678 } 23679 } 23680 23681 @Override 23682 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) { 23683 return mUserController.stopUser(userId, force, callback); 23684 } 23685 23686 @Override 23687 public UserInfo getCurrentUser() { 23688 return mUserController.getCurrentUser(); 23689 } 23690 23691 String getStartedUserState(int userId) { 23692 synchronized (this) { 23693 final UserState userState = mUserController.getStartedUserStateLocked(userId); 23694 return UserState.stateToString(userState.state); 23695 } 23696 } 23697 23698 @Override 23699 public boolean isUserRunning(int userId, int flags) { 23700 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId()) 23701 && checkCallingPermission(INTERACT_ACROSS_USERS) 23702 != PackageManager.PERMISSION_GRANTED) { 23703 String msg = "Permission Denial: isUserRunning() from pid=" 23704 + Binder.getCallingPid() 23705 + ", uid=" + Binder.getCallingUid() 23706 + " requires " + INTERACT_ACROSS_USERS; 23707 Slog.w(TAG, msg); 23708 throw new SecurityException(msg); 23709 } 23710 synchronized (this) { 23711 return mUserController.isUserRunningLocked(userId, flags); 23712 } 23713 } 23714 23715 @Override 23716 public int[] getRunningUserIds() { 23717 if (checkCallingPermission(INTERACT_ACROSS_USERS) 23718 != PackageManager.PERMISSION_GRANTED) { 23719 String msg = "Permission Denial: isUserRunning() from pid=" 23720 + Binder.getCallingPid() 23721 + ", uid=" + Binder.getCallingUid() 23722 + " requires " + INTERACT_ACROSS_USERS; 23723 Slog.w(TAG, msg); 23724 throw new SecurityException(msg); 23725 } 23726 synchronized (this) { 23727 return mUserController.getStartedUserArrayLocked(); 23728 } 23729 } 23730 23731 @Override 23732 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) { 23733 mUserController.registerUserSwitchObserver(observer, name); 23734 } 23735 23736 @Override 23737 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 23738 mUserController.unregisterUserSwitchObserver(observer); 23739 } 23740 23741 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 23742 if (info == null) return null; 23743 ApplicationInfo newInfo = new ApplicationInfo(info); 23744 newInfo.initForUser(userId); 23745 return newInfo; 23746 } 23747 23748 public boolean isUserStopped(int userId) { 23749 synchronized (this) { 23750 return mUserController.getStartedUserStateLocked(userId) == null; 23751 } 23752 } 23753 23754 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 23755 if (aInfo == null 23756 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 23757 return aInfo; 23758 } 23759 23760 ActivityInfo info = new ActivityInfo(aInfo); 23761 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 23762 return info; 23763 } 23764 23765 private boolean processSanityChecksLocked(ProcessRecord process) { 23766 if (process == null || process.thread == null) { 23767 return false; 23768 } 23769 23770 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 23771 if (!isDebuggable) { 23772 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 23773 return false; 23774 } 23775 } 23776 23777 return true; 23778 } 23779 23780 public boolean startBinderTracking() throws RemoteException { 23781 synchronized (this) { 23782 mBinderTransactionTrackingEnabled = true; 23783 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own 23784 // permission (same as profileControl). 23785 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 23786 != PackageManager.PERMISSION_GRANTED) { 23787 throw new SecurityException("Requires permission " 23788 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 23789 } 23790 23791 for (int i = 0; i < mLruProcesses.size(); i++) { 23792 ProcessRecord process = mLruProcesses.get(i); 23793 if (!processSanityChecksLocked(process)) { 23794 continue; 23795 } 23796 try { 23797 process.thread.startBinderTracking(); 23798 } catch (RemoteException e) { 23799 Log.v(TAG, "Process disappared"); 23800 } 23801 } 23802 return true; 23803 } 23804 } 23805 23806 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException { 23807 try { 23808 synchronized (this) { 23809 mBinderTransactionTrackingEnabled = false; 23810 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own 23811 // permission (same as profileControl). 23812 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 23813 != PackageManager.PERMISSION_GRANTED) { 23814 throw new SecurityException("Requires permission " 23815 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 23816 } 23817 23818 if (fd == null) { 23819 throw new IllegalArgumentException("null fd"); 23820 } 23821 23822 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor())); 23823 pw.println("Binder transaction traces for all processes.\n"); 23824 for (ProcessRecord process : mLruProcesses) { 23825 if (!processSanityChecksLocked(process)) { 23826 continue; 23827 } 23828 23829 pw.println("Traces for process: " + process.processName); 23830 pw.flush(); 23831 try { 23832 TransferPipe tp = new TransferPipe(); 23833 try { 23834 process.thread.stopBinderTrackingAndDump(tp.getWriteFd()); 23835 tp.go(fd.getFileDescriptor()); 23836 } finally { 23837 tp.kill(); 23838 } 23839 } catch (IOException e) { 23840 pw.println("Failure while dumping IPC traces from " + process + 23841 ". Exception: " + e); 23842 pw.flush(); 23843 } catch (RemoteException e) { 23844 pw.println("Got a RemoteException while dumping IPC traces from " + 23845 process + ". Exception: " + e); 23846 pw.flush(); 23847 } 23848 } 23849 fd = null; 23850 return true; 23851 } 23852 } finally { 23853 if (fd != null) { 23854 try { 23855 fd.close(); 23856 } catch (IOException e) { 23857 } 23858 } 23859 } 23860 } 23861 23862 @VisibleForTesting 23863 final class LocalService extends ActivityManagerInternal { 23864 @Override 23865 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent, 23866 int targetUserId) { 23867 synchronized (ActivityManagerService.this) { 23868 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid, 23869 targetPkg, intent, null, targetUserId); 23870 } 23871 } 23872 23873 @Override 23874 public String checkContentProviderAccess(String authority, int userId) { 23875 return ActivityManagerService.this.checkContentProviderAccess(authority, userId); 23876 } 23877 23878 @Override 23879 public void onWakefulnessChanged(int wakefulness) { 23880 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 23881 } 23882 23883 @Override 23884 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 23885 String processName, String abiOverride, int uid, Runnable crashHandler) { 23886 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 23887 processName, abiOverride, uid, crashHandler); 23888 } 23889 23890 @Override 23891 public SleepToken acquireSleepToken(String tag, int displayId) { 23892 Preconditions.checkNotNull(tag); 23893 return ActivityManagerService.this.acquireSleepToken(tag, displayId); 23894 } 23895 23896 @Override 23897 public ComponentName getHomeActivityForUser(int userId) { 23898 synchronized (ActivityManagerService.this) { 23899 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId); 23900 return homeActivity == null ? null : homeActivity.realActivity; 23901 } 23902 } 23903 23904 @Override 23905 public void onUserRemoved(int userId) { 23906 synchronized (ActivityManagerService.this) { 23907 ActivityManagerService.this.onUserStoppedLocked(userId); 23908 } 23909 mBatteryStatsService.onUserRemoved(userId); 23910 } 23911 23912 @Override 23913 public void onLocalVoiceInteractionStarted(IBinder activity, 23914 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { 23915 synchronized (ActivityManagerService.this) { 23916 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity, 23917 voiceSession, voiceInteractor); 23918 } 23919 } 23920 23921 @Override 23922 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) { 23923 synchronized (ActivityManagerService.this) { 23924 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting( 23925 reasons, timestamp); 23926 } 23927 } 23928 23929 @Override 23930 public void notifyAppTransitionFinished() { 23931 synchronized (ActivityManagerService.this) { 23932 mStackSupervisor.notifyAppTransitionDone(); 23933 } 23934 } 23935 23936 @Override 23937 public void notifyAppTransitionCancelled() { 23938 synchronized (ActivityManagerService.this) { 23939 mStackSupervisor.notifyAppTransitionDone(); 23940 } 23941 } 23942 23943 @Override 23944 public List<IBinder> getTopVisibleActivities() { 23945 synchronized (ActivityManagerService.this) { 23946 return mStackSupervisor.getTopVisibleActivities(); 23947 } 23948 } 23949 23950 @Override 23951 public void notifyDockedStackMinimizedChanged(boolean minimized) { 23952 synchronized (ActivityManagerService.this) { 23953 mStackSupervisor.setDockedStackMinimized(minimized); 23954 } 23955 } 23956 23957 @Override 23958 public void killForegroundAppsForUser(int userHandle) { 23959 synchronized (ActivityManagerService.this) { 23960 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 23961 final int NP = mProcessNames.getMap().size(); 23962 for (int ip = 0; ip < NP; ip++) { 23963 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 23964 final int NA = apps.size(); 23965 for (int ia = 0; ia < NA; ia++) { 23966 final ProcessRecord app = apps.valueAt(ia); 23967 if (app.persistent) { 23968 // We don't kill persistent processes. 23969 continue; 23970 } 23971 if (app.removed) { 23972 procs.add(app); 23973 } else if (app.userId == userHandle && app.foregroundActivities) { 23974 app.removed = true; 23975 procs.add(app); 23976 } 23977 } 23978 } 23979 23980 final int N = procs.size(); 23981 for (int i = 0; i < N; i++) { 23982 removeProcessLocked(procs.get(i), false, true, "kill all fg"); 23983 } 23984 } 23985 } 23986 23987 @Override 23988 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken, 23989 long duration) { 23990 if (!(target instanceof PendingIntentRecord)) { 23991 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target); 23992 return; 23993 } 23994 synchronized (ActivityManagerService.this) { 23995 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration); 23996 } 23997 } 23998 23999 @Override 24000 public void setDeviceIdleWhitelist(int[] appids) { 24001 synchronized (ActivityManagerService.this) { 24002 mDeviceIdleWhitelist = appids; 24003 } 24004 } 24005 24006 @Override 24007 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) { 24008 synchronized (ActivityManagerService.this) { 24009 mDeviceIdleTempWhitelist = appids; 24010 setAppIdTempWhitelistStateLocked(changingAppId, adding); 24011 } 24012 } 24013 24014 @Override 24015 public void updatePersistentConfigurationForUser(@NonNull Configuration values, 24016 int userId) { 24017 Preconditions.checkNotNull(values, "Configuration must not be null"); 24018 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported"); 24019 synchronized (ActivityManagerService.this) { 24020 updateConfigurationLocked(values, null, false, true, userId, 24021 false /* deferResume */); 24022 } 24023 } 24024 24025 @Override 24026 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents, 24027 Bundle bOptions) { 24028 Preconditions.checkNotNull(intents, "intents"); 24029 final String[] resolvedTypes = new String[intents.length]; 24030 for (int i = 0; i < intents.length; i++) { 24031 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver()); 24032 } 24033 24034 // UID of the package on user userId. 24035 // "= 0" is needed because otherwise catch(RemoteException) would make it look like 24036 // packageUid may not be initialized. 24037 int packageUid = 0; 24038 try { 24039 packageUid = AppGlobals.getPackageManager().getPackageUid( 24040 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId); 24041 } catch (RemoteException e) { 24042 // Shouldn't happen. 24043 } 24044 24045 synchronized (ActivityManagerService.this) { 24046 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes, 24047 /*resultTo*/ null, bOptions, userId); 24048 } 24049 } 24050 24051 @Override 24052 public int getUidProcessState(int uid) { 24053 return getUidState(uid); 24054 } 24055 24056 @Override 24057 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) { 24058 synchronized (ActivityManagerService.this) { 24059 24060 // We might change the visibilities here, so prepare an empty app transition which 24061 // might be overridden later if we actually change visibilities. 24062 final boolean wasTransitionSet = 24063 mWindowManager.getPendingAppTransition() != TRANSIT_NONE; 24064 if (!wasTransitionSet) { 24065 mWindowManager.prepareAppTransition(TRANSIT_NONE, 24066 false /* alwaysKeepCurrent */); 24067 } 24068 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 24069 24070 // If there was a transition set already we don't want to interfere with it as we 24071 // might be starting it too early. 24072 if (!wasTransitionSet) { 24073 mWindowManager.executeAppTransition(); 24074 } 24075 } 24076 if (callback != null) { 24077 callback.run(); 24078 } 24079 } 24080 24081 @Override 24082 public boolean isSystemReady() { 24083 // no need to synchronize(this) just to read & return the value 24084 return mSystemReady; 24085 } 24086 24087 @Override 24088 public void notifyKeyguardTrustedChanged() { 24089 synchronized (ActivityManagerService.this) { 24090 if (mKeyguardController.isKeyguardShowing()) { 24091 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 24092 } 24093 } 24094 } 24095 24096 /** 24097 * Sets if the given pid has an overlay UI or not. 24098 * 24099 * @param pid The pid we are setting overlay UI for. 24100 * @param hasOverlayUi True if the process has overlay UI. 24101 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY 24102 */ 24103 @Override 24104 public void setHasOverlayUi(int pid, boolean hasOverlayUi) { 24105 synchronized (ActivityManagerService.this) { 24106 final ProcessRecord pr; 24107 synchronized (mPidsSelfLocked) { 24108 pr = mPidsSelfLocked.get(pid); 24109 if (pr == null) { 24110 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid); 24111 return; 24112 } 24113 } 24114 if (pr.hasOverlayUi == hasOverlayUi) { 24115 return; 24116 } 24117 pr.hasOverlayUi = hasOverlayUi; 24118 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid); 24119 updateOomAdjLocked(pr, true); 24120 } 24121 } 24122 24123 /** 24124 * Called after the network policy rules are updated by 24125 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid} 24126 * and {@param procStateSeq}. 24127 */ 24128 @Override 24129 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) { 24130 if (DEBUG_NETWORK) { 24131 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: " 24132 + uid + " seq: " + procStateSeq); 24133 } 24134 UidRecord record; 24135 synchronized (ActivityManagerService.this) { 24136 record = mActiveUids.get(uid); 24137 if (record == null) { 24138 if (DEBUG_NETWORK) { 24139 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid 24140 + " procStateSeq: " + procStateSeq); 24141 } 24142 return; 24143 } 24144 } 24145 synchronized (record.networkStateLock) { 24146 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) { 24147 if (DEBUG_NETWORK) { 24148 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already" 24149 + " been handled for uid: " + uid); 24150 } 24151 return; 24152 } 24153 record.lastNetworkUpdatedProcStateSeq = procStateSeq; 24154 if (record.curProcStateSeq > procStateSeq) { 24155 if (DEBUG_NETWORK) { 24156 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid 24157 + ", curProcstateSeq: " + record.curProcStateSeq 24158 + ", procStateSeq: " + procStateSeq); 24159 } 24160 return; 24161 } 24162 if (record.waitingForNetwork) { 24163 if (DEBUG_NETWORK) { 24164 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid 24165 + ", procStateSeq: " + procStateSeq); 24166 } 24167 record.networkStateLock.notifyAll(); 24168 } 24169 } 24170 } 24171 24172 /** 24173 * Called after virtual display Id is updated by 24174 * {@link com.android.server.vr.Vr2dDisplay} with a specific 24175 * {@param vrVr2dDisplayId}. 24176 */ 24177 @Override 24178 public void setVr2dDisplayId(int vr2dDisplayId) { 24179 if (DEBUG_STACK) { 24180 Slog.d(TAG, "setVr2dDisplayId called for: " + 24181 vr2dDisplayId); 24182 } 24183 synchronized (ActivityManagerService.this) { 24184 mVr2dDisplayId = vr2dDisplayId; 24185 } 24186 } 24187 24188 @Override 24189 public void saveANRState(String reason) { 24190 synchronized (ActivityManagerService.this) { 24191 final StringWriter sw = new StringWriter(); 24192 final PrintWriter pw = new FastPrintWriter(sw, false, 1024); 24193 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date())); 24194 if (reason != null) { 24195 pw.println(" Reason: " + reason); 24196 } 24197 pw.println(); 24198 mActivityStarter.dump(pw, " ", null); 24199 pw.println(); 24200 pw.println("-------------------------------------------------------------------------------"); 24201 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */, 24202 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */, 24203 "" /* header */); 24204 pw.println(); 24205 pw.close(); 24206 24207 mLastANRState = sw.toString(); 24208 } 24209 } 24210 24211 @Override 24212 public void clearSavedANRState() { 24213 synchronized (ActivityManagerService.this) { 24214 mLastANRState = null; 24215 } 24216 } 24217 24218 @Override 24219 public void setFocusedActivity(IBinder token) { 24220 synchronized (ActivityManagerService.this) { 24221 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 24222 if (r == null) { 24223 throw new IllegalArgumentException( 24224 "setFocusedActivity: No activity record matching token=" + token); 24225 } 24226 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked( 24227 r, "setFocusedActivity")) { 24228 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 24229 } 24230 } 24231 } 24232 } 24233 24234 /** 24235 * Called by app main thread to wait for the network policy rules to get updated. 24236 * 24237 * @param procStateSeq The sequence number indicating the process state change that the main 24238 * thread is interested in. 24239 */ 24240 @Override 24241 public void waitForNetworkStateUpdate(long procStateSeq) { 24242 final int callingUid = Binder.getCallingUid(); 24243 if (DEBUG_NETWORK) { 24244 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq); 24245 } 24246 UidRecord record; 24247 synchronized (this) { 24248 record = mActiveUids.get(callingUid); 24249 if (record == null) { 24250 return; 24251 } 24252 } 24253 synchronized (record.networkStateLock) { 24254 if (record.lastDispatchedProcStateSeq < procStateSeq) { 24255 if (DEBUG_NETWORK) { 24256 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not " 24257 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid 24258 + " lastProcStateSeqDispatchedToObservers: " 24259 + record.lastDispatchedProcStateSeq); 24260 } 24261 return; 24262 } 24263 if (record.curProcStateSeq > procStateSeq) { 24264 if (DEBUG_NETWORK) { 24265 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: " 24266 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq 24267 + ", procStateSeq: " + procStateSeq); 24268 } 24269 return; 24270 } 24271 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) { 24272 if (DEBUG_NETWORK) { 24273 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. " 24274 + procStateSeq + ", so no need to wait. Uid: " 24275 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: " 24276 + record.lastNetworkUpdatedProcStateSeq); 24277 } 24278 return; 24279 } 24280 try { 24281 if (DEBUG_NETWORK) { 24282 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update." 24283 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq); 24284 } 24285 final long startTime = SystemClock.uptimeMillis(); 24286 record.waitingForNetwork = true; 24287 record.networkStateLock.wait(mWaitForNetworkTimeoutMs); 24288 record.waitingForNetwork = false; 24289 final long totalTime = SystemClock.uptimeMillis() - startTime; 24290 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) { 24291 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: " 24292 + totalTime + ". Uid: " + callingUid + " procStateSeq: " 24293 + procStateSeq + " UidRec: " + record 24294 + " validateUidRec: " + mValidateUids.get(callingUid)); 24295 } 24296 } catch (InterruptedException e) { 24297 Thread.currentThread().interrupt(); 24298 } 24299 } 24300 } 24301 24302 public void waitForBroadcastIdle(PrintWriter pw) { 24303 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()"); 24304 while (true) { 24305 boolean idle = true; 24306 synchronized (this) { 24307 for (BroadcastQueue queue : mBroadcastQueues) { 24308 if (!queue.isIdle()) { 24309 final String msg = "Waiting for queue " + queue + " to become idle..."; 24310 pw.println(msg); 24311 pw.flush(); 24312 Slog.v(TAG, msg); 24313 idle = false; 24314 } 24315 } 24316 } 24317 24318 if (idle) { 24319 final String msg = "All broadcast queues are idle!"; 24320 pw.println(msg); 24321 pw.flush(); 24322 Slog.v(TAG, msg); 24323 return; 24324 } else { 24325 SystemClock.sleep(1000); 24326 } 24327 } 24328 } 24329 24330 /** 24331 * Return the user id of the last resumed activity. 24332 */ 24333 @Override 24334 public @UserIdInt int getLastResumedActivityUserId() { 24335 enforceCallingPermission( 24336 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()"); 24337 synchronized (this) { 24338 if (mLastResumedActivity == null) { 24339 return mUserController.getCurrentUserIdLocked(); 24340 } 24341 return mLastResumedActivity.userId; 24342 } 24343 } 24344 24345 /** 24346 * An implementation of IAppTask, that allows an app to manage its own tasks via 24347 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 24348 * only the process that calls getAppTasks() can call the AppTask methods. 24349 */ 24350 class AppTaskImpl extends IAppTask.Stub { 24351 private int mTaskId; 24352 private int mCallingUid; 24353 24354 public AppTaskImpl(int taskId, int callingUid) { 24355 mTaskId = taskId; 24356 mCallingUid = callingUid; 24357 } 24358 24359 private void checkCaller() { 24360 if (mCallingUid != Binder.getCallingUid()) { 24361 throw new SecurityException("Caller " + mCallingUid 24362 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 24363 } 24364 } 24365 24366 @Override 24367 public void finishAndRemoveTask() { 24368 checkCaller(); 24369 24370 synchronized (ActivityManagerService.this) { 24371 long origId = Binder.clearCallingIdentity(); 24372 try { 24373 // We remove the task from recents to preserve backwards 24374 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false, 24375 REMOVE_FROM_RECENTS)) { 24376 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 24377 } 24378 } finally { 24379 Binder.restoreCallingIdentity(origId); 24380 } 24381 } 24382 } 24383 24384 @Override 24385 public ActivityManager.RecentTaskInfo getTaskInfo() { 24386 checkCaller(); 24387 24388 synchronized (ActivityManagerService.this) { 24389 long origId = Binder.clearCallingIdentity(); 24390 try { 24391 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 24392 if (tr == null) { 24393 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 24394 } 24395 return createRecentTaskInfoFromTaskRecord(tr); 24396 } finally { 24397 Binder.restoreCallingIdentity(origId); 24398 } 24399 } 24400 } 24401 24402 @Override 24403 public void moveToFront() { 24404 checkCaller(); 24405 // Will bring task to front if it already has a root activity. 24406 final long origId = Binder.clearCallingIdentity(); 24407 try { 24408 synchronized (this) { 24409 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null); 24410 } 24411 } finally { 24412 Binder.restoreCallingIdentity(origId); 24413 } 24414 } 24415 24416 @Override 24417 public int startActivity(IBinder whoThread, String callingPackage, 24418 Intent intent, String resolvedType, Bundle bOptions) { 24419 checkCaller(); 24420 24421 int callingUser = UserHandle.getCallingUserId(); 24422 TaskRecord tr; 24423 IApplicationThread appThread; 24424 synchronized (ActivityManagerService.this) { 24425 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 24426 if (tr == null) { 24427 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 24428 } 24429 appThread = IApplicationThread.Stub.asInterface(whoThread); 24430 if (appThread == null) { 24431 throw new IllegalArgumentException("Bad app thread " + appThread); 24432 } 24433 } 24434 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent, 24435 resolvedType, null, null, null, null, 0, 0, null, null, 24436 null, bOptions, false, callingUser, tr, "AppTaskImpl"); 24437 } 24438 24439 @Override 24440 public void setExcludeFromRecents(boolean exclude) { 24441 checkCaller(); 24442 24443 synchronized (ActivityManagerService.this) { 24444 long origId = Binder.clearCallingIdentity(); 24445 try { 24446 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 24447 if (tr == null) { 24448 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 24449 } 24450 Intent intent = tr.getBaseIntent(); 24451 if (exclude) { 24452 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 24453 } else { 24454 intent.setFlags(intent.getFlags() 24455 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 24456 } 24457 } finally { 24458 Binder.restoreCallingIdentity(origId); 24459 } 24460 } 24461 } 24462 } 24463 24464 /** 24465 * Kill processes for the user with id userId and that depend on the package named packageName 24466 */ 24467 @Override 24468 public void killPackageDependents(String packageName, int userId) { 24469 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()"); 24470 if (packageName == null) { 24471 throw new NullPointerException( 24472 "Cannot kill the dependents of a package without its name."); 24473 } 24474 24475 long callingId = Binder.clearCallingIdentity(); 24476 IPackageManager pm = AppGlobals.getPackageManager(); 24477 int pkgUid = -1; 24478 try { 24479 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 24480 } catch (RemoteException e) { 24481 } 24482 if (userId != UserHandle.USER_ALL && pkgUid == -1) { 24483 throw new IllegalArgumentException( 24484 "Cannot kill dependents of non-existing package " + packageName); 24485 } 24486 try { 24487 synchronized(this) { 24488 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId, 24489 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false, 24490 "dep: " + packageName); 24491 } 24492 } finally { 24493 Binder.restoreCallingIdentity(callingId); 24494 } 24495 } 24496 24497 @Override 24498 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback) 24499 throws RemoteException { 24500 final long callingId = Binder.clearCallingIdentity(); 24501 try { 24502 mKeyguardController.dismissKeyguard(token, callback); 24503 } finally { 24504 Binder.restoreCallingIdentity(callingId); 24505 } 24506 } 24507 24508 @Override 24509 public int restartUserInBackground(final int userId) { 24510 return mUserController.restartUser(userId, /* foreground */ false); 24511 } 24512 24513 @Override 24514 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) { 24515 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 24516 "scheduleApplicationInfoChanged()"); 24517 24518 synchronized (this) { 24519 final long origId = Binder.clearCallingIdentity(); 24520 try { 24521 updateApplicationInfoLocked(packageNames, userId); 24522 } finally { 24523 Binder.restoreCallingIdentity(origId); 24524 } 24525 } 24526 } 24527 24528 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) { 24529 final boolean updateFrameworkRes = packagesToUpdate.contains("android"); 24530 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 24531 final ProcessRecord app = mLruProcesses.get(i); 24532 if (app.thread == null) { 24533 continue; 24534 } 24535 24536 if (userId != UserHandle.USER_ALL && app.userId != userId) { 24537 continue; 24538 } 24539 24540 final int packageCount = app.pkgList.size(); 24541 for (int j = 0; j < packageCount; j++) { 24542 final String packageName = app.pkgList.keyAt(j); 24543 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) { 24544 try { 24545 final ApplicationInfo ai = AppGlobals.getPackageManager() 24546 .getApplicationInfo(packageName, 0 /*flags*/, app.userId); 24547 if (ai != null) { 24548 app.thread.scheduleApplicationInfoChanged(ai); 24549 } 24550 } catch (RemoteException e) { 24551 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s", 24552 packageName, app)); 24553 } 24554 } 24555 } 24556 } 24557 } 24558 24559 /** 24560 * Attach an agent to the specified process (proces name or PID) 24561 */ 24562 public void attachAgent(String process, String path) { 24563 try { 24564 synchronized (this) { 24565 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent"); 24566 if (proc == null || proc.thread == null) { 24567 throw new IllegalArgumentException("Unknown process: " + process); 24568 } 24569 24570 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 24571 if (!isDebuggable) { 24572 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 24573 throw new SecurityException("Process not debuggable: " + proc); 24574 } 24575 } 24576 24577 proc.thread.attachAgent(path); 24578 } 24579 } catch (RemoteException e) { 24580 throw new IllegalStateException("Process disappeared"); 24581 } 24582 } 24583 24584 @VisibleForTesting 24585 public static class Injector { 24586 private NetworkManagementInternal mNmi; 24587 24588 public Context getContext() { 24589 return null; 24590 } 24591 24592 public AppOpsService getAppOpsService(File file, Handler handler) { 24593 return new AppOpsService(file, handler); 24594 } 24595 24596 public Handler getUiHandler(ActivityManagerService service) { 24597 return service.new UiHandler(); 24598 } 24599 24600 public boolean isNetworkRestrictedForUid(int uid) { 24601 if (ensureHasNetworkManagementInternal()) { 24602 return mNmi.isNetworkRestrictedForUid(uid); 24603 } 24604 return false; 24605 } 24606 24607 private boolean ensureHasNetworkManagementInternal() { 24608 if (mNmi == null) { 24609 mNmi = LocalServices.getService(NetworkManagementInternal.class); 24610 } 24611 return mNmi != null; 24612 } 24613 } 24614 24615 @Override 24616 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) 24617 throws RemoteException { 24618 synchronized (this) { 24619 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 24620 if (r == null) { 24621 return; 24622 } 24623 final long origId = Binder.clearCallingIdentity(); 24624 try { 24625 r.setShowWhenLocked(showWhenLocked); 24626 } finally { 24627 Binder.restoreCallingIdentity(origId); 24628 } 24629 } 24630 } 24631 24632 @Override 24633 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException { 24634 synchronized (this) { 24635 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 24636 if (r == null) { 24637 return; 24638 } 24639 final long origId = Binder.clearCallingIdentity(); 24640 try { 24641 r.setTurnScreenOn(turnScreenOn); 24642 } finally { 24643 Binder.restoreCallingIdentity(origId); 24644 } 24645 } 24646 } 24647} 24648