am 1242af06: am 32cfe2bb: am d37afa37: Merge "docs: Unbuntu troubleshooting link to CamelCase ID" into klp-modular-docs

* commit '1242af060bec63ec3a37512ebbbdbe545bd9f0f7':
  docs: Unbuntu troubleshooting link to CamelCase ID
diff --git a/Android.mk b/Android.mk
index 8f0869c..6a9da2f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -31,6 +31,10 @@
 # So we first build the framework as a monolithic static library then split it
 # up into smaller pieces.
 # ============================================================
+
+# embedded builds use nothing in frameworks/base
+ifneq ($(ANDROID_BUILD_EMBEDDED),true)
+
 include $(CLEAR_VARS)
 
 # FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
@@ -64,6 +68,7 @@
 	core/java/android/app/IActivityController.aidl \
 	core/java/android/app/IActivityPendingResult.aidl \
 	core/java/android/app/IAlarmManager.aidl \
+	core/java/android/app/IAppTask.aidl \
 	core/java/android/app/IBackupAgent.aidl \
 	core/java/android/app/IInstrumentationWatcher.aidl \
 	core/java/android/app/INotificationManager.aidl \
@@ -72,8 +77,9 @@
 	core/java/android/app/ISearchManagerCallback.aidl \
 	core/java/android/app/IServiceConnection.aidl \
 	core/java/android/app/IStopUserCallback.aidl \
-	core/java/android/app/IThumbnailReceiver.aidl \
-	core/java/android/app/IThumbnailRetriever.aidl \
+	core/java/android/app/job/IJobCallback.aidl \
+	core/java/android/app/job/IJobScheduler.aidl \
+	core/java/android/app/job/IJobService.aidl \
 	core/java/android/app/ITransientNotification.aidl \
 	core/java/android/app/IUiAutomationConnection.aidl \
 	core/java/android/app/IUiModeManager.aidl \
@@ -81,12 +87,17 @@
 	core/java/android/app/IWallpaperManager.aidl \
 	core/java/android/app/IWallpaperManagerCallback.aidl \
 	core/java/android/app/admin/IDevicePolicyManager.aidl \
+	core/java/android/app/trust/ITrustManager.aidl \
+	core/java/android/app/trust/ITrustListener.aidl \
 	core/java/android/app/backup/IBackupManager.aidl \
 	core/java/android/app/backup/IFullBackupRestoreObserver.aidl \
 	core/java/android/app/backup/IRestoreObserver.aidl \
 	core/java/android/app/backup/IRestoreSession.aidl \
+	core/java/android/app/usage/IUsageStatsManager.aidl \
 	core/java/android/bluetooth/IBluetooth.aidl \
 	core/java/android/bluetooth/IBluetoothA2dp.aidl \
+	core/java/android/bluetooth/IBluetoothA2dpSink.aidl \
+	core/java/android/bluetooth/IBluetoothAvrcpController.aidl \
 	core/java/android/bluetooth/IBluetoothCallback.aidl \
 	core/java/android/bluetooth/IBluetoothHeadset.aidl \
 	core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl \
@@ -99,6 +110,7 @@
 	core/java/android/bluetooth/IBluetoothPbap.aidl \
 	core/java/android/bluetooth/IBluetoothMap.aidl \
 	core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl \
+	core/java/android/bluetooth/IBluetoothHeadsetClient.aidl \
 	core/java/android/bluetooth/IBluetoothGatt.aidl \
 	core/java/android/bluetooth/IBluetoothGattCallback.aidl \
 	core/java/android/bluetooth/IBluetoothGattServerCallback.aidl \
@@ -107,13 +119,21 @@
 	core/java/android/content/IIntentReceiver.aidl \
 	core/java/android/content/IIntentSender.aidl \
 	core/java/android/content/IOnPrimaryClipChangedListener.aidl \
-	core/java/android/content/IAnonymousSyncAdapter.aidl \
+	core/java/android/content/IRestrictionsManager.aidl \
 	core/java/android/content/ISyncAdapter.aidl \
 	core/java/android/content/ISyncContext.aidl \
+	core/java/android/content/ISyncServiceAdapter.aidl \
 	core/java/android/content/ISyncStatusObserver.aidl \
+	core/java/android/content/pm/ILauncherApps.aidl \
+	core/java/android/content/pm/IOnAppsChangedListener.aidl \
 	core/java/android/content/pm/IPackageDataObserver.aidl \
 	core/java/android/content/pm/IPackageDeleteObserver.aidl \
+	core/java/android/content/pm/IPackageDeleteObserver2.aidl \
 	core/java/android/content/pm/IPackageInstallObserver.aidl \
+	core/java/android/content/pm/IPackageInstallObserver2.aidl \
+	core/java/android/content/pm/IPackageInstaller.aidl \
+	core/java/android/content/pm/IPackageInstallerCallback.aidl \
+	core/java/android/content/pm/IPackageInstallerSession.aidl \
 	core/java/android/content/pm/IPackageManager.aidl \
 	core/java/android/content/pm/IPackageMoveObserver.aidl \
 	core/java/android/content/pm/IPackageStatsObserver.aidl \
@@ -130,20 +150,35 @@
 	core/java/android/hardware/ISerialManager.aidl \
 	core/java/android/hardware/display/IDisplayManager.aidl \
 	core/java/android/hardware/display/IDisplayManagerCallback.aidl \
-	core/java/android/hardware/hdmi/IHdmiCecListener.aidl \
-	core/java/android/hardware/hdmi/IHdmiCecService.aidl \
+	core/java/android/hardware/display/IVirtualDisplayCallback.aidl \
+	core/java/android/hardware/hdmi/IHdmiControlCallback.aidl \
+	core/java/android/hardware/hdmi/IHdmiControlService.aidl \
+	core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl \
+	core/java/android/hardware/hdmi/IHdmiHotplugEventListener.aidl \
+	core/java/android/hardware/hdmi/IHdmiInputChangeListener.aidl \
+	core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl \
+	core/java/android/hardware/hdmi/IHdmiRecordListener.aidl \
+	core/java/android/hardware/hdmi/IHdmiSystemAudioModeChangeListener.aidl \
+	core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl \
 	core/java/android/hardware/input/IInputManager.aidl \
 	core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
+	core/java/android/hardware/location/IActivityRecognitionHardware.aidl \
+	core/java/android/hardware/location/IActivityRecognitionHardwareSink.aidl \
+	core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl \
 	core/java/android/hardware/location/IFusedLocationHardware.aidl \
 	core/java/android/hardware/location/IFusedLocationHardwareSink.aidl \
 	core/java/android/hardware/location/IGeofenceHardware.aidl \
 	core/java/android/hardware/location/IGeofenceHardwareCallback.aidl \
 	core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl \
+	core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl \
 	core/java/android/hardware/usb/IUsbManager.aidl \
 	core/java/android/net/IConnectivityManager.aidl \
+	core/java/android/net/IEthernetManager.aidl \
 	core/java/android/net/INetworkManagementEventObserver.aidl \
 	core/java/android/net/INetworkPolicyListener.aidl \
 	core/java/android/net/INetworkPolicyManager.aidl \
+	core/java/android/net/INetworkScoreCache.aidl \
+	core/java/android/net/INetworkScoreService.aidl \
 	core/java/android/net/INetworkStatsService.aidl \
 	core/java/android/net/INetworkStatsSession.aidl \
 	core/java/android/net/nsd/INsdManager.aidl \
@@ -152,11 +187,14 @@
 	core/java/android/nfc/INfcAdapterExtras.aidl \
 	core/java/android/nfc/INfcTag.aidl \
 	core/java/android/nfc/INfcCardEmulation.aidl \
+	core/java/android/nfc/INfcLockscreenDispatch.aidl \
+	core/java/android/nfc/INfcUnlockHandler.aidl \
 	core/java/android/os/IBatteryPropertiesListener.aidl \
 	core/java/android/os/IBatteryPropertiesRegistrar.aidl \
 	core/java/android/os/ICancellationSignal.aidl \
 	core/java/android/os/IHardwareService.aidl \
 	core/java/android/os/IMessenger.aidl \
+	core/java/android/os/INetworkActivityListener.aidl \
 	core/java/android/os/INetworkManagementService.aidl \
 	core/java/android/os/IPermissionController.aidl \
 	core/java/android/os/IPowerManager.aidl \
@@ -167,6 +205,8 @@
 	core/java/android/os/IVibratorService.aidl \
 	core/java/android/service/notification/INotificationListener.aidl \
 	core/java/android/service/notification/IStatusBarNotificationHolder.aidl \
+	core/java/android/service/notification/IConditionListener.aidl \
+	core/java/android/service/notification/IConditionProvider.aidl \
 	core/java/android/print/ILayoutResultCallback.aidl \
 	core/java/android/print/IPrinterDiscoveryObserver.aidl \
 	core/java/android/print/IPrintDocumentAdapter.aidl \
@@ -179,9 +219,16 @@
 	core/java/android/print/IWriteResultCallback.aidl \
 	core/java/android/printservice/IPrintService.aidl \
 	core/java/android/printservice/IPrintServiceClient.aidl \
-	core/java/android/service/dreams/IDozeHardware.aidl \
 	core/java/android/service/dreams/IDreamManager.aidl \
 	core/java/android/service/dreams/IDreamService.aidl \
+	core/java/android/service/persistentdata/IPersistentDataBlockService.aidl \
+	core/java/android/service/fingerprint/IFingerprintService.aidl \
+	core/java/android/service/fingerprint/IFingerprintServiceReceiver.aidl \
+	core/java/android/service/trust/ITrustAgentService.aidl \
+	core/java/android/service/trust/ITrustAgentServiceCallback.aidl \
+	core/java/android/service/voice/IVoiceInteractionService.aidl \
+	core/java/android/service/voice/IVoiceInteractionSession.aidl \
+	core/java/android/service/voice/IVoiceInteractionSessionService.aidl \
 	core/java/android/service/wallpaper/IWallpaperConnection.aidl \
 	core/java/android/service/wallpaper/IWallpaperEngine.aidl \
 	core/java/android/service/wallpaper/IWallpaperService.aidl \
@@ -191,7 +238,6 @@
 	core/java/android/view/accessibility/IAccessibilityManagerClient.aidl \
 	core/java/android/view/IApplicationToken.aidl \
 	core/java/android/view/IAssetAtlas.aidl \
-	core/java/android/view/IMagnificationCallbacks.aidl \
 	core/java/android/view/IInputFilter.aidl \
 	core/java/android/view/IInputFilterHost.aidl \
 	core/java/android/view/IOnKeyguardExitResult.aidl \
@@ -201,6 +247,8 @@
 	core/java/android/view/IWindowId.aidl \
 	core/java/android/view/IWindowManager.aidl \
 	core/java/android/view/IWindowSession.aidl \
+	core/java/android/view/IWindowSessionCallback.aidl \
+	core/java/android/webkit/IWebViewUpdateService.aidl \
 	core/java/android/speech/IRecognitionListener.aidl \
 	core/java/android/speech/IRecognitionService.aidl \
 	core/java/android/speech/tts/ITextToSpeechCallback.aidl \
@@ -209,7 +257,10 @@
 	core/java/com/android/internal/app/IAppOpsService.aidl \
 	core/java/com/android/internal/app/IBatteryStats.aidl \
 	core/java/com/android/internal/app/IProcessStats.aidl \
-	core/java/com/android/internal/app/IUsageStats.aidl \
+	core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl \
+	core/java/com/android/internal/app/IVoiceInteractor.aidl \
+	core/java/com/android/internal/app/IVoiceInteractorCallback.aidl \
+	core/java/com/android/internal/app/IVoiceInteractorRequest.aidl \
 	core/java/com/android/internal/app/IMediaContainerService.aidl \
 	core/java/com/android/internal/appwidget/IAppWidgetService.aidl \
 	core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
@@ -221,6 +272,7 @@
 	core/java/com/android/internal/policy/IKeyguardExitCallback.aidl \
 	core/java/com/android/internal/policy/IKeyguardService.aidl \
 	core/java/com/android/internal/os/IDropBoxManagerService.aidl \
+	core/java/com/android/internal/os/IParcelFileDescriptorFactory.aidl \
 	core/java/com/android/internal/os/IResultReceiver.aidl \
 	core/java/com/android/internal/statusbar/IStatusBar.aidl \
 	core/java/com/android/internal/statusbar/IStatusBarService.aidl \
@@ -237,6 +289,7 @@
 	core/java/com/android/internal/view/IInputMethodSession.aidl \
 	core/java/com/android/internal/view/IInputSessionCallback.aidl \
 	core/java/com/android/internal/widget/ILockSettings.aidl \
+	core/java/com/android/internal/widget/ILockSettingsObserver.aidl \
 	core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \
 	core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \
 	keystore/java/android/security/IKeyChainAliasCallback.aidl \
@@ -246,6 +299,8 @@
 	location/java/android/location/IFusedProvider.aidl \
 	location/java/android/location/IGeocodeProvider.aidl \
 	location/java/android/location/IGeofenceProvider.aidl \
+	location/java/android/location/IGpsMeasurementsListener.aidl \
+	location/java/android/location/IGpsNavigationMessageListener.aidl \
 	location/java/android/location/IGpsStatusListener.aidl \
 	location/java/android/location/IGpsStatusProvider.aidl \
 	location/java/android/location/ILocationListener.aidl \
@@ -257,6 +312,8 @@
 	media/java/android/media/IAudioService.aidl \
 	media/java/android/media/IAudioFocusDispatcher.aidl \
 	media/java/android/media/IAudioRoutesObserver.aidl \
+	media/java/android/media/IMediaHTTPConnection.aidl \
+	media/java/android/media/IMediaHTTPService.aidl \
 	media/java/android/media/IMediaRouterClient.aidl \
 	media/java/android/media/IMediaRouterService.aidl \
 	media/java/android/media/IMediaScannerListener.aidl \
@@ -265,17 +322,64 @@
 	media/java/android/media/IRemoteControlDisplay.aidl \
 	media/java/android/media/IRemoteDisplayCallback.aidl \
 	media/java/android/media/IRemoteDisplayProvider.aidl \
+	media/java/android/media/IRemoteVolumeController.aidl \
 	media/java/android/media/IRemoteVolumeObserver.aidl \
 	media/java/android/media/IRingtonePlayer.aidl \
+	media/java/android/media/IVolumeController.aidl \
+	media/java/android/media/projection/IMediaProjection.aidl \
+	media/java/android/media/projection/IMediaProjectionCallback.aidl \
+	media/java/android/media/projection/IMediaProjectionManager.aidl \
+	media/java/android/media/projection/IMediaProjectionWatcherCallback.aidl \
+	media/java/android/media/session/IActiveSessionsListener.aidl \
+	media/java/android/media/session/ISessionController.aidl \
+	media/java/android/media/session/ISessionControllerCallback.aidl \
+	media/java/android/media/session/ISession.aidl \
+	media/java/android/media/session/ISessionCallback.aidl \
+	media/java/android/media/session/ISessionManager.aidl \
+	media/java/android/media/tv/ITvInputClient.aidl \
+	media/java/android/media/tv/ITvInputHardware.aidl \
+	media/java/android/media/tv/ITvInputHardwareCallback.aidl \
+	media/java/android/media/tv/ITvInputManager.aidl \
+	media/java/android/media/tv/ITvInputManagerCallback.aidl \
+	media/java/android/media/tv/ITvInputService.aidl \
+	media/java/android/media/tv/ITvInputServiceCallback.aidl \
+	media/java/android/media/tv/ITvInputSession.aidl \
+	media/java/android/media/tv/ITvInputSessionCallback.aidl \
+	media/java/android/service/media/IMediaBrowserService.aidl \
+	media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl \
+	telecomm/java/com/android/internal/telecom/IVideoCallback.aidl \
+	telecomm/java/com/android/internal/telecom/IVideoProvider.aidl \
+	telecomm/java/com/android/internal/telecom/IConnectionService.aidl \
+	telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl \
+	telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl \
+	telecomm/java/com/android/internal/telecom/IInCallService.aidl \
+	telecomm/java/com/android/internal/telecom/ITelecomService.aidl \
+	telecomm/java/com/android/internal/telecom/RemoteServiceCallback.aidl \
+	telephony/java/com/android/ims/internal/IImsCallSession.aidl \
+	telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl \
+	telephony/java/com/android/ims/internal/IImsConfig.aidl \
+	telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl \
+	telephony/java/com/android/ims/internal/IImsEcbm.aidl \
+	telephony/java/com/android/ims/internal/IImsEcbmListener.aidl \
+	telephony/java/com/android/ims/internal/IImsService.aidl \
+	telephony/java/com/android/ims/internal/IImsStreamMediaSession.aidl \
+	telephony/java/com/android/ims/internal/IImsUt.aidl \
+	telephony/java/com/android/ims/internal/IImsUtListener.aidl \
+	telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl \
+	telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl \
+	telephony/java/com/android/ims/ImsConfigListener.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
-	telephony/java/com/android/internal/telephony/ITelephonyListener.aidl \
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/ISms.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
+	telephony/java/com/android/internal/telephony/ISub.aidl \
+	telephony/java/com/android/internal/telephony/IMms.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
 	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
+	wifi/java/android/net/wifi/IWifiScanner.aidl \
+	wifi/java/android/net/wifi/IRttManager.aidl \
 	packages/services/PacProcessor/com/android/net/IProxyService.aidl \
 	packages/services/Proxy/com/android/net/IProxyCallback.aidl \
 	packages/services/Proxy/com/android/net/IProxyPortListener.aidl \
@@ -291,30 +395,11 @@
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := core-libart conscrypt okhttp core-junit bouncycastle ext
 
-LOCAL_MODULE := framework-base
-
-LOCAL_JAR_EXCLUDE_FILES := none
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-# Make sure that R.java and Manifest.java are built before we build
-# the source for this library.
-framework_res_R_stamp := \
-	$(call intermediates-dir-for,APPS,framework-res,,COMMON)/src/R.stamp
-$(full_classes_compiled_jar): $(framework_res_R_stamp)
-
-# Build part 1 of the framework library.
-# ============================================================
-include $(CLEAR_VARS)
-
 LOCAL_MODULE := framework
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_STATIC_JAVA_LIBRARIES := framework-base
-LOCAL_DX_FLAGS := --core-library
 
-# Packages to include, use \* wildcard to include descendants.
-LOCAL_JAR_PACKAGES := android\*
+LOCAL_DX_FLAGS := --core-library --multi-dex
+
+LOCAL_RMTYPEDEFS := true
 
 # List of classes and interfaces which should be loaded by the Zygote.
 LOCAL_JAVA_RESOURCE_FILES += $(LOCAL_PATH)/preloaded-classes
@@ -322,28 +407,15 @@
 include $(BUILD_JAVA_LIBRARY)
 framework_module := $(LOCAL_INSTALLED_MODULE)
 
-# Build part 2 of the framework library.
-# ============================================================
-include $(CLEAR_VARS)
+# Make sure that R.java and Manifest.java are built before we build
+# the source for this library.
+framework_res_R_stamp := \
+	$(call intermediates-dir-for,APPS,framework-res,,COMMON)/src/R.stamp
+$(full_classes_compiled_jar): $(framework_res_R_stamp)
 
-LOCAL_MODULE := framework2
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_STATIC_JAVA_LIBRARIES := framework-base
-LOCAL_DX_FLAGS := --core-library
-
-# Packages to include, use \* wildcard to include descendants.
-LOCAL_JAR_PACKAGES := com\* javax\*
-
-include $(BUILD_JAVA_LIBRARY)
-framework2_module := $(LOCAL_INSTALLED_MODULE)
-
-# Make sure that all framework modules are installed when framework is.
-# ============================================================
 $(framework_module): | $(dir $(framework_module))framework-res.apk
-$(framework_module): | $(dir $(framework_module))framework2.jar
 
-framework_built := $(call java-lib-deps,framework framework2)
+framework_built := $(call java-lib-deps,framework)
 
 # Copy AIDL files to be preprocessed and included in the SDK,
 # specified relative to the root of the build tree.
@@ -378,10 +450,25 @@
 	frameworks/base/core/java/android/os/DropBoxManager.aidl \
 	frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \
 	frameworks/base/core/java/android/os/ParcelUuid.aidl \
+    frameworks/base/core/java/android/os/PersistableBundle.aidl \
+	frameworks/base/core/java/android/print/PrinterInfo.aidl \
+	frameworks/base/core/java/android/print/PageRange.aidl \
+	frameworks/base/core/java/android/print/PrintAttributes.aidl \
+	frameworks/base/core/java/android/print/PrinterCapabilitiesInfo.aidl \
+	frameworks/base/core/java/android/print/PrinterId.aidl \
+	frameworks/base/core/java/android/print/PrintJobId.aidl \
+	frameworks/base/core/java/android/print/PrintJobInfo.aidl \
+    frameworks/base/core/java/android/service/notification/StatusBarNotification.aidl \
+	frameworks/base/core/java/android/view/accessibility/AccessibilityEvent.aidl \
+	frameworks/base/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl \
+	frameworks/base/core/java/android/view/accessibility/AccessibilityRecord.aidl \
+	frameworks/base/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl \
 	frameworks/base/core/java/android/view/KeyEvent.aidl \
 	frameworks/base/core/java/android/view/MotionEvent.aidl \
 	frameworks/base/core/java/android/view/Surface.aidl \
 	frameworks/base/core/java/android/view/WindowManager.aidl \
+	frameworks/base/core/java/android/view/WindowAnimationFrameStats.aidl \
+	frameworks/base/core/java/android/view/WindowContentFrameStats.aidl \
 	frameworks/base/core/java/android/widget/RemoteViews.aidl \
 	frameworks/base/core/java/com/android/internal/textservice/ISpellCheckerService.aidl \
 	frameworks/base/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl \
@@ -403,6 +490,13 @@
 	frameworks/base/location/java/android/location/FusedBatchOptions.aidl \
 	frameworks/base/location/java/com/android/internal/location/ProviderProperties.aidl \
 	frameworks/base/location/java/com/android/internal/location/ProviderRequest.aidl \
+	frameworks/base/media/java/android/media/AudioAttributes.aidl \
+	frameworks/base/media/java/android/media/MediaDescription.aidl \
+	frameworks/base/media/java/android/media/MediaMetadata.aidl \
+	frameworks/base/media/java/android/media/Rating.aidl \
+	frameworks/base/media/java/android/media/browse/MediaBrowser.aidl \
+	frameworks/base/media/java/android/media/session/MediaSession.aidl \
+	frameworks/base/media/java/android/media/session/PlaybackState.aidl \
 	frameworks/base/telephony/java/android/telephony/ServiceState.aidl \
 	frameworks/base/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
 	frameworks/base/telephony/java/com/android/internal/telephony/ITelephony.aidl \
@@ -501,8 +595,6 @@
 	okhttp \
 	ext \
 	framework \
-	framework2 \
-	mms-common \
 	telephony-common \
 	voip-common
 
@@ -514,8 +606,12 @@
 framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html
 # The since flag (-since N.xml API_LEVEL) is used to add API Level information
 # to the reference documentation. Must be in order of oldest to newest.
+#
+# Conscrypt (com.android.org.conscrypt) is an implementation detail and should
+# not be referenced in the documentation.
 framework_docs_LOCAL_DROIDDOC_OPTIONS := \
     -knowntags ./frameworks/base/docs/knowntags.txt \
+    -hidePackage com.android.org.conscrypt \
     -since $(SRC_API_DIR)/1.xml 1 \
     -since $(SRC_API_DIR)/2.xml 2 \
     -since $(SRC_API_DIR)/3.xml 3 \
@@ -536,11 +632,11 @@
     -since $(SRC_API_DIR)/18.txt 18 \
     -since $(SRC_API_DIR)/19.txt 19 \
     -since $(SRC_API_DIR)/20.txt 20 \
-		-werror -hide 113 \
+		-werror -hide 111 -hide 113 \
 		-overview $(LOCAL_PATH)/core/java/overview.html
 
 framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR:= \
-	$(call intermediates-dir-for,JAVA_LIBRARIES,framework-base,,COMMON)
+	$(call intermediates-dir-for,JAVA_LIBRARIES,framework,,COMMON)
 
 framework_docs_LOCAL_ADDITIONAL_JAVA_DIR:= \
 	$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR) \
@@ -596,6 +692,7 @@
 		$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
 		-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_stubs_current_intermediates/src \
 		-api $(INTERNAL_PLATFORM_API_FILE) \
+		-removedApi $(INTERNAL_PLATFORM_REMOVED_API_FILE) \
 		-nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
@@ -609,7 +706,7 @@
 $(INTERNAL_PLATFORM_API_FILE): $(full_target)
 $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_API_FILE))
 
-# ====  the private api stubs ===================================
+# ====  the system api stubs ===================================
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=$(framework_docs_LOCAL_API_CHECK_SRC_FILES)
@@ -621,12 +718,14 @@
 LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
 LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
 
-LOCAL_MODULE := private-api-stubs
+LOCAL_MODULE := system-api-stubs
 
 LOCAL_DROIDDOC_OPTIONS:=\
 		$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
-		-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_private_stubs_current_intermediates/src \
-        -showAnnotation android.annotation.PrivateApi \
+		-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_system_stubs_current_intermediates/src \
+		-showAnnotation android.annotation.SystemApi \
+		-api $(INTERNAL_PLATFORM_SYSTEM_API_FILE) \
+		-removedApi $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE) \
 		-nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
@@ -663,8 +762,9 @@
 $(full_target): $(framework_built) $(gen)
 
 # Run this for checkbuild
-.PHONY: checkbuild
 checkbuild: doc-comment-check-docs
+# Check comment when you are updating the API
+update-api: doc-comment-check-docs
 
 # ====  static html in the sdk ==================================
 include $(CLEAR_VARS)
@@ -730,6 +830,41 @@
 
 include $(BUILD_DROIDDOC)
 
+# ==== docs for the web (on the androiddevdocs app engine server) =======================
+# TODO: Fix the System API docs build.
+ifneq ($(filter online-system-api-sdk-docs,$(MAKECMDGOALS)),)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
+LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_STATIC_JAVA_LIBRARIES:=$(framework_docs_LOCAL_STATIC_JAVA_LIBRARIES)
+LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES)
+LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
+LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
+LOCAL_DROIDDOC_HTML_DIR:=$(framework_docs_LOCAL_DROIDDOC_HTML_DIR)
+LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_ADDITIONAL_JAVA_DIR)
+LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
+LOCAL_ADDITIONAL_HTML_DIR:=docs/html-intl /
+
+LOCAL_MODULE := online-system-api-sdk
+
+LOCAL_DROIDDOC_OPTIONS:= \
+		$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
+		-showAnnotation android.annotation.SystemApi \
+		-title "Android SDK - Including system APIs." \
+		-toroot / \
+		-hdf android.whichdoc online \
+		$(sample_groups) \
+		-hdf android.hasSamples true \
+		-samplesdir $(samples_dir)
+
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
+# Don't build by default
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_DROIDDOC)
+endif  # online-system-api-sdk-docs in make command line.
+
 # ==== docs for the web (on the devsite app engine server) =======================
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
@@ -821,3 +956,5 @@
 ifeq (,$(ONE_SHOT_MAKEFILE))
 include $(call first-makefiles-under,$(LOCAL_PATH))
 endif
+
+endif # ANDROID_BUILD_EMBEDDED
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 82651bd..28c2172 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -34,9 +34,9 @@
 # made today requires touching the same file, just copy the old
 # touch step and add it to the end of the list.
 #
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
+# *****************************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THE BANNER
+# *****************************************************************
 
 # For example:
 #$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
@@ -171,6 +171,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/printservice/)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/packages/services/Proxy/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrinterDiscoverySessionObserver.*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrinterDiscoverySessionClient.*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/os/IBattery*)
@@ -185,8 +186,45 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/framework-res_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrintClient.*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/media/java/android/media/IMedia*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/view/IMagnificationCallbacks*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/tv/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/media/java/android/media/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/app)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/android/app/wearable)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/tv/ITv*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes/android/app/task)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/app/task)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes/android/app/TaskManager)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/app/maintenance)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes/android/app/maintenance)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes/android/app/maintenance)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes/android/app/maintenance)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/android/app/maintenance)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/app)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/ims-common_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework2_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/telecomm/java/com/android/internal/telecom)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework.* $(PRODUCT_OUT)/system/framework2.*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/docs/api-stubs-timestamp)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services.core_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services.core_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/inputflinger $(PRODUCT_OUT)/symbols/system/bin/inputflinger)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/RsFountainFbo_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/telecomm/java/com/android/internal/telecomm)
 
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
+# ******************************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
+# ******************************************************************
diff --git a/api/current.txt b/api/current.txt
index 9db066a..eb7891a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -21,12 +21,15 @@
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
     field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
     field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
+    field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
     field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
     field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
     field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
     field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
     field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
     field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
+    field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
+    field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
     field public static final java.lang.String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
     field public static final java.lang.String BIND_WALLPAPER = "android.permission.BIND_WALLPAPER";
     field public static final java.lang.String BLUETOOTH = "android.permission.BLUETOOTH";
@@ -99,10 +102,11 @@
     field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
     field public static final java.lang.String READ_PROFILE = "android.permission.READ_PROFILE";
     field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
-    field public static final java.lang.String READ_SOCIAL_STREAM = "android.permission.READ_SOCIAL_STREAM";
+    field public static final deprecated java.lang.String READ_SOCIAL_STREAM = "android.permission.READ_SOCIAL_STREAM";
     field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
     field public static final java.lang.String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS";
     field public static final java.lang.String READ_USER_DICTIONARY = "android.permission.READ_USER_DICTIONARY";
+    field public static final java.lang.String READ_VOICEMAIL = "com.android.voicemail.permission.READ_VOICEMAIL";
     field public static final java.lang.String REBOOT = "android.permission.REBOOT";
     field public static final java.lang.String RECEIVE_BOOT_COMPLETED = "android.permission.RECEIVE_BOOT_COMPLETED";
     field public static final java.lang.String RECEIVE_MMS = "android.permission.RECEIVE_MMS";
@@ -149,9 +153,10 @@
     field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
     field public static final java.lang.String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS";
     field public static final java.lang.String WRITE_SMS = "android.permission.WRITE_SMS";
-    field public static final java.lang.String WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM";
+    field public static final deprecated java.lang.String WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM";
     field public static final java.lang.String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS";
     field public static final java.lang.String WRITE_USER_DICTIONARY = "android.permission.WRITE_USER_DICTIONARY";
+    field public static final java.lang.String WRITE_VOICEMAIL = "com.android.voicemail.permission.WRITE_VOICEMAIL";
   }
 
   public static final class Manifest.permission_group {
@@ -237,12 +242,14 @@
     field public static final int action = 16842797; // 0x101002d
     field public static final int actionBarDivider = 16843675; // 0x101039b
     field public static final int actionBarItemBackground = 16843676; // 0x101039c
+    field public static final int actionBarPopupTheme = 16843917; // 0x101048d
     field public static final int actionBarSize = 16843499; // 0x10102eb
     field public static final int actionBarSplitStyle = 16843656; // 0x1010388
     field public static final int actionBarStyle = 16843470; // 0x10102ce
     field public static final int actionBarTabBarStyle = 16843508; // 0x10102f4
     field public static final int actionBarTabStyle = 16843507; // 0x10102f3
     field public static final int actionBarTabTextStyle = 16843509; // 0x10102f5
+    field public static final int actionBarTheme = 16843825; // 0x1010431
     field public static final int actionBarWidgetTheme = 16843671; // 0x1010397
     field public static final int actionButtonStyle = 16843480; // 0x10102d8
     field public static final int actionDropDownStyle = 16843479; // 0x10102d7
@@ -254,11 +261,15 @@
     field public static final int actionModeCloseDrawable = 16843484; // 0x10102dc
     field public static final int actionModeCopyDrawable = 16843538; // 0x1010312
     field public static final int actionModeCutDrawable = 16843537; // 0x1010311
+    field public static final int actionModeFindDrawable = 16843898; // 0x101047a
     field public static final int actionModePasteDrawable = 16843539; // 0x1010313
     field public static final int actionModeSelectAllDrawable = 16843646; // 0x101037e
+    field public static final int actionModeShareDrawable = 16843897; // 0x1010479
     field public static final int actionModeSplitBackground = 16843677; // 0x101039d
     field public static final int actionModeStyle = 16843668; // 0x1010394
+    field public static final int actionModeWebSearchDrawable = 16843899; // 0x101047b
     field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6
+    field public static final int actionOverflowMenuStyle = 16843844; // 0x1010444
     field public static final int actionProviderClass = 16843657; // 0x1010389
     field public static final int actionViewClass = 16843516; // 0x10102fc
     field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
@@ -285,6 +296,9 @@
     field public static final int alphabeticShortcut = 16843235; // 0x10101e3
     field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef
     field public static final int alwaysRetainTaskState = 16843267; // 0x1010203
+    field public static final int amPmBackgroundColor = 16843941; // 0x10104a5
+    field public static final int amPmTextColor = 16843940; // 0x10104a4
+    field public static final int ambientShadowAlpha = 16843966; // 0x10104be
     field public static final int angle = 16843168; // 0x10101a0
     field public static final int animateFirstView = 16843477; // 0x10102d5
     field public static final int animateLayoutChanges = 16843506; // 0x10102f2
@@ -304,6 +318,7 @@
     field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
     field public static final int autoLink = 16842928; // 0x10100b0
     field public static final int autoMirrored = 16843754; // 0x10103ea
+    field public static final int autoRemoveFromRecents = 16843847; // 0x1010447
     field public static final int autoStart = 16843445; // 0x10102b5
     field public static final deprecated int autoText = 16843114; // 0x101016a
     field public static final int autoUrlDetect = 16843404; // 0x101028c
@@ -312,7 +327,10 @@
     field public static final int backgroundDimEnabled = 16843295; // 0x101021f
     field public static final int backgroundSplit = 16843659; // 0x101038b
     field public static final int backgroundStacked = 16843658; // 0x101038a
+    field public static final int backgroundTint = 16843883; // 0x101046b
+    field public static final int backgroundTintMode = 16843884; // 0x101046c
     field public static final int backupAgent = 16843391; // 0x101027f
+    field public static final int banner = 16843762; // 0x10103f2
     field public static final int baseline = 16843548; // 0x101031c
     field public static final int baselineAlignBottom = 16843042; // 0x1010122
     field public static final int baselineAligned = 16843046; // 0x1010126
@@ -330,12 +348,18 @@
     field public static final int bufferType = 16843086; // 0x101014e
     field public static final int button = 16843015; // 0x1010107
     field public static final int buttonBarButtonStyle = 16843567; // 0x101032f
+    field public static final int buttonBarNegativeButtonStyle = 16843915; // 0x101048b
+    field public static final int buttonBarNeutralButtonStyle = 16843914; // 0x101048a
+    field public static final int buttonBarPositiveButtonStyle = 16843913; // 0x1010489
     field public static final int buttonBarStyle = 16843566; // 0x101032e
     field public static final int buttonStyle = 16842824; // 0x1010048
     field public static final int buttonStyleInset = 16842826; // 0x101004a
     field public static final int buttonStyleSmall = 16842825; // 0x1010049
     field public static final int buttonStyleToggle = 16842827; // 0x101004b
+    field public static final int buttonTint = 16843887; // 0x101046f
+    field public static final int buttonTintMode = 16843888; // 0x1010470
     field public static final int cacheColorHint = 16843009; // 0x1010101
+    field public static final int calendarTextColor = 16843931; // 0x101049b
     field public static final int calendarViewShown = 16843596; // 0x101034c
     field public static final int calendarViewStyle = 16843613; // 0x101035d
     field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
@@ -353,6 +377,8 @@
     field public static final int centerY = 16843171; // 0x10101a3
     field public static final int checkBoxPreferenceStyle = 16842895; // 0x101008f
     field public static final int checkMark = 16843016; // 0x1010108
+    field public static final int checkMarkTint = 16843943; // 0x10104a7
+    field public static final int checkMarkTintMode = 16843944; // 0x10104a8
     field public static final int checkable = 16843237; // 0x10101e5
     field public static final int checkableBehavior = 16843232; // 0x10101e0
     field public static final int checkboxStyle = 16842860; // 0x101006c
@@ -371,22 +397,32 @@
     field public static final int clipChildren = 16842986; // 0x10100ea
     field public static final int clipOrientation = 16843274; // 0x101020a
     field public static final int clipToPadding = 16842987; // 0x10100eb
+    field public static final int closeIcon = 16843905; // 0x1010481
     field public static final int codes = 16843330; // 0x1010242
     field public static final int collapseColumns = 16843083; // 0x101014b
     field public static final int color = 16843173; // 0x10101a5
+    field public static final int colorAccent = 16843829; // 0x1010435
     field public static final int colorActivatedHighlight = 16843664; // 0x1010390
     field public static final int colorBackground = 16842801; // 0x1010031
     field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
+    field public static final int colorButtonNormal = 16843819; // 0x101042b
+    field public static final int colorControlActivated = 16843818; // 0x101042a
+    field public static final int colorControlHighlight = 16843820; // 0x101042c
+    field public static final int colorControlNormal = 16843817; // 0x1010429
+    field public static final int colorEdgeEffect = 16843982; // 0x10104ce
     field public static final int colorFocusedHighlight = 16843663; // 0x101038f
     field public static final int colorForeground = 16842800; // 0x1010030
     field public static final int colorForegroundInverse = 16843270; // 0x1010206
     field public static final int colorLongPressedHighlight = 16843662; // 0x101038e
     field public static final int colorMultiSelectHighlight = 16843665; // 0x1010391
     field public static final int colorPressedHighlight = 16843661; // 0x101038d
+    field public static final int colorPrimary = 16843827; // 0x1010433
+    field public static final int colorPrimaryDark = 16843828; // 0x1010434
     field public static final int columnCount = 16843639; // 0x1010377
     field public static final int columnDelay = 16843215; // 0x10101cf
     field public static final int columnOrderPreserved = 16843640; // 0x1010378
     field public static final int columnWidth = 16843031; // 0x1010117
+    field public static final int commitIcon = 16843909; // 0x1010485
     field public static final int compatibleWidthLimitDp = 16843621; // 0x1010365
     field public static final int completionHint = 16843122; // 0x1010172
     field public static final int completionHintView = 16843123; // 0x1010173
@@ -395,8 +431,18 @@
     field public static final int configure = 16843357; // 0x101025d
     field public static final int constantSize = 16843158; // 0x1010196
     field public static final int content = 16843355; // 0x101025b
+    field public static final int contentAgeHint = 16843961; // 0x10104b9
     field public static final int contentAuthority = 16843408; // 0x1010290
     field public static final int contentDescription = 16843379; // 0x1010273
+    field public static final int contentInsetEnd = 16843860; // 0x1010454
+    field public static final int contentInsetLeft = 16843861; // 0x1010455
+    field public static final int contentInsetRight = 16843862; // 0x1010456
+    field public static final int contentInsetStart = 16843859; // 0x1010453
+    field public static final int controlX1 = 16843772; // 0x10103fc
+    field public static final int controlX2 = 16843774; // 0x10103fe
+    field public static final int controlY1 = 16843773; // 0x10103fd
+    field public static final int controlY2 = 16843775; // 0x10103ff
+    field public static final int country = 16843962; // 0x10104ba
     field public static final int cropToPadding = 16843043; // 0x1010123
     field public static final int cursorVisible = 16843090; // 0x1010152
     field public static final int customNavigationLayout = 16843474; // 0x10102d2
@@ -405,8 +451,12 @@
     field public static final int dashGap = 16843175; // 0x10101a7
     field public static final int dashWidth = 16843174; // 0x10101a6
     field public static final int data = 16842798; // 0x101002e
+    field public static final int datePickerDialogTheme = 16843948; // 0x10104ac
+    field public static final int datePickerMode = 16843955; // 0x10104b3
     field public static final int datePickerStyle = 16843612; // 0x101035c
     field public static final int dateTextAppearance = 16843593; // 0x1010349
+    field public static final int dayOfWeekBackground = 16843924; // 0x1010494
+    field public static final int dayOfWeekTextAppearance = 16843925; // 0x1010495
     field public static final int debuggable = 16842767; // 0x101000f
     field public static final int defaultValue = 16843245; // 0x10101ed
     field public static final int delay = 16843212; // 0x10101cc
@@ -437,6 +487,7 @@
     field public static final int dividerHorizontal = 16843564; // 0x101032c
     field public static final int dividerPadding = 16843562; // 0x101032a
     field public static final int dividerVertical = 16843530; // 0x101030a
+    field public static final int documentLaunchMode = 16843845; // 0x1010445
     field public static final int drawSelectorOnTop = 16843004; // 0x10100fc
     field public static final int drawable = 16843161; // 0x1010199
     field public static final int drawableBottom = 16843118; // 0x101016e
@@ -465,6 +516,8 @@
     field public static final int editTextStyle = 16842862; // 0x101006e
     field public static final deprecated int editable = 16843115; // 0x101016b
     field public static final int editorExtras = 16843300; // 0x1010224
+    field public static final int elegantTextHeight = 16843869; // 0x101045d
+    field public static final int elevation = 16843840; // 0x1010440
     field public static final int ellipsize = 16842923; // 0x10100ab
     field public static final int ems = 16843096; // 0x1010158
     field public static final int enabled = 16842766; // 0x101000e
@@ -474,7 +527,10 @@
     field public static final int entries = 16842930; // 0x10100b2
     field public static final int entryValues = 16843256; // 0x10101f8
     field public static final int eventsInterceptionEnabled = 16843389; // 0x101027d
+    field public static final int excludeClass = 16843842; // 0x1010442
     field public static final int excludeFromRecents = 16842775; // 0x1010017
+    field public static final int excludeId = 16843841; // 0x1010441
+    field public static final int excludeName = 16843854; // 0x101044e
     field public static final int exitFadeDuration = 16843533; // 0x101030d
     field public static final int expandableListPreferredChildIndicatorLeft = 16842834; // 0x1010052
     field public static final int expandableListPreferredChildIndicatorRight = 16842835; // 0x1010053
@@ -499,11 +555,14 @@
     field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a
     field public static final int fastScrollPreviewBackgroundLeft = 16843575; // 0x1010337
     field public static final int fastScrollPreviewBackgroundRight = 16843576; // 0x1010338
+    field public static final int fastScrollStyle = 16843767; // 0x10103f7
     field public static final int fastScrollTextColor = 16843609; // 0x1010359
     field public static final int fastScrollThumbDrawable = 16843574; // 0x1010336
     field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339
     field public static final int fillAfter = 16843197; // 0x10101bd
+    field public static final int fillAlpha = 16843980; // 0x10104cc
     field public static final int fillBefore = 16843196; // 0x10101bc
+    field public static final int fillColor = 16843780; // 0x1010404
     field public static final int fillEnabled = 16843343; // 0x101024f
     field public static final int fillViewport = 16843130; // 0x101017a
     field public static final int filter = 16843035; // 0x101011b
@@ -517,27 +576,40 @@
     field public static final int focusableInTouchMode = 16842971; // 0x10100db
     field public static final int focusedMonthDateColor = 16843587; // 0x1010343
     field public static final int fontFamily = 16843692; // 0x10103ac
+    field public static final int fontFeatureSettings = 16843959; // 0x10104b7
     field public static final int footerDividersEnabled = 16843311; // 0x101022f
     field public static final int foreground = 16843017; // 0x1010109
     field public static final int foregroundGravity = 16843264; // 0x1010200
+    field public static final int foregroundTint = 16843885; // 0x101046d
+    field public static final int foregroundTintMode = 16843886; // 0x101046e
     field public static final int format = 16843013; // 0x1010105
     field public static final int format12Hour = 16843722; // 0x10103ca
     field public static final int format24Hour = 16843723; // 0x10103cb
     field public static final int fragment = 16843491; // 0x10102e3
+    field public static final int fragmentAllowEnterTransitionOverlap = 16843976; // 0x10104c8
+    field public static final int fragmentAllowReturnTransitionOverlap = 16843977; // 0x10104c9
     field public static final int fragmentCloseEnterAnimation = 16843495; // 0x10102e7
     field public static final int fragmentCloseExitAnimation = 16843496; // 0x10102e8
+    field public static final int fragmentEnterTransition = 16843971; // 0x10104c3
+    field public static final int fragmentExitTransition = 16843970; // 0x10104c2
     field public static final int fragmentFadeEnterAnimation = 16843497; // 0x10102e9
     field public static final int fragmentFadeExitAnimation = 16843498; // 0x10102ea
     field public static final int fragmentOpenEnterAnimation = 16843493; // 0x10102e5
     field public static final int fragmentOpenExitAnimation = 16843494; // 0x10102e6
+    field public static final int fragmentReenterTransition = 16843975; // 0x10104c7
+    field public static final int fragmentReturnTransition = 16843973; // 0x10104c5
+    field public static final int fragmentSharedElementEnterTransition = 16843972; // 0x10104c4
+    field public static final int fragmentSharedElementReturnTransition = 16843974; // 0x10104c6
     field public static final int freezesText = 16843116; // 0x101016c
     field public static final int fromAlpha = 16843210; // 0x10101ca
     field public static final int fromDegrees = 16843187; // 0x10101b3
+    field public static final int fromId = 16843850; // 0x101044a
     field public static final int fromScene = 16843741; // 0x10103dd
     field public static final int fromXDelta = 16843206; // 0x10101c6
     field public static final int fromXScale = 16843202; // 0x10101c2
     field public static final int fromYDelta = 16843208; // 0x10101c8
     field public static final int fromYScale = 16843204; // 0x10101c4
+    field public static final int fullBackupOnly = 16843891; // 0x1010473
     field public static final int fullBright = 16842954; // 0x10100ca
     field public static final int fullDark = 16842950; // 0x10100c6
     field public static final int functionalTest = 16842787; // 0x1010023
@@ -550,6 +622,7 @@
     field public static final int gestureStrokeType = 16843385; // 0x1010279
     field public static final int gestureStrokeWidth = 16843380; // 0x1010274
     field public static final int glEsVersion = 16843393; // 0x1010281
+    field public static final int goIcon = 16843906; // 0x1010482
     field public static final int gradientRadius = 16843172; // 0x10101a4
     field public static final int grantUriPermissions = 16842779; // 0x101001b
     field public static final int gravity = 16842927; // 0x10100af
@@ -562,9 +635,15 @@
     field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
     field public static final int hardwareAccelerated = 16843475; // 0x10102d3
     field public static final int hasCode = 16842764; // 0x101000c
+    field public static final int headerAmPmTextAppearance = 16843936; // 0x10104a0
     field public static final int headerBackground = 16843055; // 0x101012f
+    field public static final int headerDayOfMonthTextAppearance = 16843927; // 0x1010497
     field public static final int headerDividersEnabled = 16843310; // 0x101022e
+    field public static final int headerMonthTextAppearance = 16843926; // 0x1010496
+    field public static final int headerTimeTextAppearance = 16843935; // 0x101049f
+    field public static final int headerYearTextAppearance = 16843928; // 0x1010498
     field public static final int height = 16843093; // 0x1010155
+    field public static final int hideOnContentScroll = 16843843; // 0x1010443
     field public static final int hint = 16843088; // 0x1010150
     field public static final int homeAsUpIndicator = 16843531; // 0x101030b
     field public static final int homeLayout = 16843549; // 0x101031d
@@ -600,6 +679,8 @@
     field public static final int indeterminateDuration = 16843069; // 0x101013d
     field public static final int indeterminateOnly = 16843066; // 0x101013a
     field public static final int indeterminateProgressStyle = 16843544; // 0x1010318
+    field public static final int indeterminateTint = 16843881; // 0x1010469
+    field public static final int indeterminateTintMode = 16843882; // 0x101046a
     field public static final int indicatorEnd = 16843730; // 0x10103d2
     field public static final int indicatorLeft = 16843021; // 0x101010d
     field public static final int indicatorRight = 16843022; // 0x101010e
@@ -612,6 +693,7 @@
     field public static final int innerRadiusRatio = 16843163; // 0x101019b
     field public static final deprecated int inputMethod = 16843112; // 0x1010168
     field public static final int inputType = 16843296; // 0x1010220
+    field public static final int inset = 16843957; // 0x10104b5
     field public static final int insetBottom = 16843194; // 0x10101ba
     field public static final int insetLeft = 16843191; // 0x10101b7
     field public static final int insetRight = 16843192; // 0x10101b8
@@ -622,6 +704,7 @@
     field public static final int isAsciiCapable = 16843753; // 0x10103e9
     field public static final int isAuxiliary = 16843647; // 0x101037f
     field public static final int isDefault = 16843297; // 0x1010221
+    field public static final int isGame = 16843764; // 0x10103f4
     field public static final int isIndicator = 16843079; // 0x1010147
     field public static final int isModifier = 16843334; // 0x1010246
     field public static final int isRepeatable = 16843336; // 0x1010248
@@ -658,6 +741,8 @@
     field public static final int largeScreens = 16843398; // 0x1010286
     field public static final int largestWidthLimitDp = 16843622; // 0x1010366
     field public static final int launchMode = 16842781; // 0x101001d
+    field public static final int launchTaskBehindSourceAnimation = 16843922; // 0x1010492
+    field public static final int launchTaskBehindTargetAnimation = 16843921; // 0x1010491
     field public static final int layerType = 16843604; // 0x1010354
     field public static final int layout = 16842994; // 0x10100f2
     field public static final int layoutAnimation = 16842988; // 0x10100ec
@@ -684,6 +769,7 @@
     field public static final int layout_centerVertical = 16843153; // 0x1010191
     field public static final int layout_column = 16843084; // 0x101014c
     field public static final int layout_columnSpan = 16843645; // 0x101037d
+    field public static final int layout_columnWeight = 16843865; // 0x1010459
     field public static final int layout_gravity = 16842931; // 0x10100b3
     field public static final int layout_height = 16842997; // 0x10100f5
     field public static final int layout_margin = 16842998; // 0x10100f6
@@ -695,6 +781,7 @@
     field public static final int layout_marginTop = 16843000; // 0x10100f8
     field public static final int layout_row = 16843643; // 0x101037b
     field public static final int layout_rowSpan = 16843644; // 0x101037c
+    field public static final int layout_rowWeight = 16843864; // 0x1010458
     field public static final int layout_scale = 16843155; // 0x1010193
     field public static final int layout_span = 16843085; // 0x101014d
     field public static final int layout_toEndOf = 16843704; // 0x10103b8
@@ -706,6 +793,7 @@
     field public static final int layout_x = 16843135; // 0x101017f
     field public static final int layout_y = 16843136; // 0x1010180
     field public static final int left = 16843181; // 0x10101ad
+    field public static final int letterSpacing = 16843958; // 0x10104b6
     field public static final int lineSpacingExtra = 16843287; // 0x1010217
     field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
     field public static final int lines = 16843092; // 0x1010154
@@ -733,6 +821,7 @@
     field public static final int manageSpaceActivity = 16842756; // 0x1010004
     field public static final int mapViewStyle = 16842890; // 0x101008a
     field public static final int marqueeRepeatLimit = 16843293; // 0x101021d
+    field public static final int matchOrder = 16843855; // 0x101044f
     field public static final int max = 16843062; // 0x1010136
     field public static final int maxDate = 16843584; // 0x1010340
     field public static final int maxEms = 16843095; // 0x1010157
@@ -741,9 +830,11 @@
     field public static final int maxLength = 16843104; // 0x1010160
     field public static final int maxLevel = 16843186; // 0x10101b2
     field public static final int maxLines = 16843091; // 0x1010153
+    field public static final int maxRecents = 16843846; // 0x1010446
     field public static final int maxRows = 16843059; // 0x1010133
     field public static final int maxSdkVersion = 16843377; // 0x1010271
     field public static final int maxWidth = 16843039; // 0x101011f
+    field public static final int maximumAngle = 16843903; // 0x101047f
     field public static final int measureAllChildren = 16843018; // 0x101010a
     field public static final int measureWithLargestChild = 16843476; // 0x10102d4
     field public static final int mediaRouteButtonStyle = 16843693; // 0x10103ad
@@ -759,14 +850,21 @@
     field public static final int minResizeWidth = 16843669; // 0x1010395
     field public static final int minSdkVersion = 16843276; // 0x101020c
     field public static final int minWidth = 16843071; // 0x101013f
+    field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
+    field public static final int minimumVerticalAngle = 16843902; // 0x101047e
     field public static final int mipMap = 16843725; // 0x10103cd
     field public static final int mirrorForRtl = 16843726; // 0x10103ce
     field public static final int mode = 16843134; // 0x101017e
     field public static final int moreIcon = 16843061; // 0x1010135
+    field public static final int multiArch = 16843918; // 0x101048e
     field public static final int multiprocess = 16842771; // 0x1010013
     field public static final int name = 16842755; // 0x1010003
+    field public static final int navigationBarColor = 16843858; // 0x1010452
+    field public static final int navigationContentDescription = 16843969; // 0x10104c1
+    field public static final int navigationIcon = 16843968; // 0x10104c0
     field public static final int navigationMode = 16843471; // 0x10102cf
     field public static final int negativeButtonText = 16843254; // 0x10101f6
+    field public static final int nestedScrollingEnabled = 16843830; // 0x1010436
     field public static final int nextFocusDown = 16842980; // 0x10100e4
     field public static final int nextFocusForward = 16843580; // 0x101033c
     field public static final int nextFocusLeft = 16842977; // 0x10100e1
@@ -777,6 +875,9 @@
     field public static final int notificationTimeout = 16843651; // 0x1010383
     field public static final int numColumns = 16843032; // 0x1010118
     field public static final int numStars = 16843076; // 0x1010144
+    field public static final int numbersBackgroundColor = 16843938; // 0x10104a2
+    field public static final int numbersSelectorColor = 16843939; // 0x10104a3
+    field public static final int numbersTextColor = 16843937; // 0x10104a1
     field public static final deprecated int numeric = 16843109; // 0x1010165
     field public static final int numericShortcut = 16843236; // 0x10101e4
     field public static final int onClick = 16843375; // 0x101026f
@@ -788,15 +889,18 @@
     field public static final int orderingFromXml = 16843239; // 0x10101e7
     field public static final int orientation = 16842948; // 0x10100c4
     field public static final int outAnimation = 16843128; // 0x1010178
+    field public static final int outlineProvider = 16843960; // 0x10104b8
     field public static final int overScrollFooter = 16843459; // 0x10102c3
     field public static final int overScrollHeader = 16843458; // 0x10102c2
     field public static final int overScrollMode = 16843457; // 0x10102c1
+    field public static final int overlapAnchor = 16843874; // 0x1010462
     field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2
     field public static final int packageNames = 16843649; // 0x1010381
     field public static final int padding = 16842965; // 0x10100d5
     field public static final int paddingBottom = 16842969; // 0x10100d9
     field public static final int paddingEnd = 16843700; // 0x10103b4
     field public static final int paddingLeft = 16842966; // 0x10100d6
+    field public static final int paddingMode = 16843863; // 0x1010457
     field public static final int paddingRight = 16842968; // 0x10100d8
     field public static final int paddingStart = 16843699; // 0x10103b3
     field public static final int paddingTop = 16842967; // 0x10100d7
@@ -808,12 +912,15 @@
     field public static final int parentActivityName = 16843687; // 0x10103a7
     field public static final deprecated int password = 16843100; // 0x101015c
     field public static final int path = 16842794; // 0x101002a
+    field public static final int pathData = 16843781; // 0x1010405
     field public static final int pathPattern = 16842796; // 0x101002c
     field public static final int pathPrefix = 16842795; // 0x101002b
+    field public static final int patternPathData = 16843978; // 0x10104ca
     field public static final int permission = 16842758; // 0x1010006
     field public static final int permissionFlags = 16843719; // 0x10103c7
     field public static final int permissionGroup = 16842762; // 0x101000a
     field public static final int permissionGroupFlags = 16843717; // 0x10103c5
+    field public static final int persistableMode = 16843821; // 0x101042d
     field public static final int persistent = 16842765; // 0x101000d
     field public static final int persistentDrawingCache = 16842990; // 0x10100ee
     field public static final deprecated int phoneNumber = 16843111; // 0x1010167
@@ -822,9 +929,11 @@
     field public static final int popupAnimationStyle = 16843465; // 0x10102c9
     field public static final int popupBackground = 16843126; // 0x1010176
     field public static final int popupCharacters = 16843332; // 0x1010244
+    field public static final int popupElevation = 16843916; // 0x101048c
     field public static final int popupKeyboard = 16843331; // 0x1010243
     field public static final int popupLayout = 16843323; // 0x101023b
     field public static final int popupMenuStyle = 16843520; // 0x1010300
+    field public static final int popupTheme = 16843945; // 0x10104a9
     field public static final int popupWindowStyle = 16842870; // 0x1010076
     field public static final int port = 16842793; // 0x1010029
     field public static final int positiveButtonText = 16843253; // 0x10101f5
@@ -839,6 +948,8 @@
     field public static final int privateImeOptions = 16843299; // 0x1010223
     field public static final int process = 16842769; // 0x1010011
     field public static final int progress = 16843063; // 0x1010137
+    field public static final int progressBackgroundTint = 16843877; // 0x1010465
+    field public static final int progressBackgroundTintMode = 16843878; // 0x1010466
     field public static final int progressBarPadding = 16843545; // 0x1010319
     field public static final int progressBarStyle = 16842871; // 0x1010077
     field public static final int progressBarStyleHorizontal = 16842872; // 0x1010078
@@ -849,12 +960,17 @@
     field public static final int progressBarStyleSmallInverse = 16843400; // 0x1010288
     field public static final int progressBarStyleSmallTitle = 16843279; // 0x101020f
     field public static final int progressDrawable = 16843068; // 0x101013c
+    field public static final int progressTint = 16843875; // 0x1010463
+    field public static final int progressTintMode = 16843876; // 0x1010464
     field public static final int prompt = 16843131; // 0x101017b
     field public static final int propertyName = 16843489; // 0x10102e1
+    field public static final int propertyXName = 16843892; // 0x1010474
+    field public static final int propertyYName = 16843893; // 0x1010475
     field public static final int protectionLevel = 16842761; // 0x1010009
     field public static final int publicKey = 16843686; // 0x10103a6
     field public static final int queryActionMsg = 16843227; // 0x10101db
     field public static final int queryAfterZeroResults = 16843394; // 0x1010282
+    field public static final int queryBackground = 16843911; // 0x1010487
     field public static final int queryHint = 16843608; // 0x1010358
     field public static final int quickContactBadgeStyleSmallWindowLarge = 16843443; // 0x10102b3
     field public static final int quickContactBadgeStyleSmallWindowMedium = 16843442; // 0x10102b2
@@ -869,6 +985,10 @@
     field public static final int ratingBarStyleIndicator = 16843280; // 0x1010210
     field public static final int ratingBarStyleSmall = 16842877; // 0x101007d
     field public static final int readPermission = 16842759; // 0x1010007
+    field public static final int recognitionService = 16843932; // 0x101049c
+    field public static final int relinquishTaskIdentity = 16843894; // 0x1010476
+    field public static final int reparent = 16843964; // 0x10104bc
+    field public static final int reparentWithOverlay = 16843965; // 0x10104bd
     field public static final int repeatCount = 16843199; // 0x10101bf
     field public static final int repeatMode = 16843200; // 0x10101c0
     field public static final int reqFiveWayNav = 16843314; // 0x1010232
@@ -888,6 +1008,9 @@
     field public static final int restoreAnyVersion = 16843450; // 0x10102ba
     field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
     field public static final int restrictedAccountType = 16843733; // 0x10103d5
+    field public static final int restrictionType = 16843923; // 0x1010493
+    field public static final int resumeWhilePausing = 16843954; // 0x10104b2
+    field public static final int reversible = 16843851; // 0x101044b
     field public static final int right = 16843183; // 0x10101af
     field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
     field public static final int ringtoneType = 16843257; // 0x10101f9
@@ -927,6 +1050,7 @@
     field public static final int scrollbars = 16842974; // 0x10100de
     field public static final int scrollingCache = 16843006; // 0x10100fe
     field public static final deprecated int searchButtonText = 16843269; // 0x1010205
+    field public static final int searchIcon = 16843907; // 0x1010483
     field public static final int searchMode = 16843221; // 0x10101d5
     field public static final int searchSettingsDescription = 16843402; // 0x101028a
     field public static final int searchSuggestAuthority = 16843222; // 0x10101d6
@@ -935,15 +1059,21 @@
     field public static final int searchSuggestPath = 16843223; // 0x10101d7
     field public static final int searchSuggestSelection = 16843224; // 0x10101d8
     field public static final int searchSuggestThreshold = 16843373; // 0x101026d
+    field public static final int searchViewStyle = 16843904; // 0x1010480
     field public static final int secondaryProgress = 16843064; // 0x1010138
+    field public static final int secondaryProgressTint = 16843879; // 0x1010467
+    field public static final int secondaryProgressTintMode = 16843880; // 0x1010468
     field public static final int seekBarStyle = 16842875; // 0x101007b
     field public static final int segmentedButtonStyle = 16843568; // 0x1010330
     field public static final int selectAllOnFocus = 16843102; // 0x101015e
     field public static final int selectable = 16843238; // 0x10101e6
     field public static final int selectableItemBackground = 16843534; // 0x101030e
+    field public static final int selectableItemBackgroundBorderless = 16843868; // 0x101045c
     field public static final int selectedDateVerticalBar = 16843591; // 0x1010347
     field public static final int selectedWeekBackgroundColor = 16843586; // 0x1010342
+    field public static final int sessionService = 16843837; // 0x101043d
     field public static final int settingsActivity = 16843301; // 0x1010225
+    field public static final int setupActivity = 16843766; // 0x10103f6
     field public static final int shadowColor = 16843105; // 0x1010161
     field public static final int shadowDx = 16843106; // 0x1010162
     field public static final int shadowDy = 16843107; // 0x1010163
@@ -958,11 +1088,13 @@
     field public static final int showDividers = 16843561; // 0x1010329
     field public static final int showOnLockScreen = 16843721; // 0x10103c9
     field public static final int showSilent = 16843259; // 0x10101fb
+    field public static final int showText = 16843949; // 0x10104ad
     field public static final int showWeekNumber = 16843582; // 0x101033e
     field public static final int shownWeekCount = 16843585; // 0x1010341
     field public static final int shrinkColumns = 16843082; // 0x101014a
     field public static final deprecated int singleLine = 16843101; // 0x101015d
     field public static final int singleUser = 16843711; // 0x10103bf
+    field public static final int slideEdge = 16843824; // 0x1010430
     field public static final int smallIcon = 16843422; // 0x101029e
     field public static final int smallScreens = 16843396; // 0x1010284
     field public static final int smoothScrollbar = 16843313; // 0x1010231
@@ -974,16 +1106,20 @@
     field public static final int spinnerStyle = 16842881; // 0x1010081
     field public static final int spinnersShown = 16843595; // 0x101034b
     field public static final int splitMotionEvents = 16843503; // 0x10102ef
+    field public static final int splitTrack = 16843852; // 0x101044c
+    field public static final int spotShadowAlpha = 16843967; // 0x10104bf
     field public static final int src = 16843033; // 0x1010119
     field public static final int ssp = 16843747; // 0x10103e3
     field public static final int sspPattern = 16843749; // 0x10103e5
     field public static final int sspPrefix = 16843748; // 0x10103e4
     field public static final int stackFromBottom = 16843005; // 0x10100fd
+    field public static final int stackViewStyle = 16843838; // 0x101043e
     field public static final int starStyle = 16842882; // 0x1010082
     field public static final int startColor = 16843165; // 0x101019d
     field public static final int startDelay = 16843746; // 0x10103e2
     field public static final int startOffset = 16843198; // 0x10101be
     field public static final deprecated int startYear = 16843132; // 0x101017c
+    field public static final int stateListAnimator = 16843848; // 0x1010448
     field public static final int stateNotNeeded = 16842774; // 0x1010016
     field public static final int state_above_anchor = 16842922; // 0x10100aa
     field public static final int state_accelerated = 16843547; // 0x101031b
@@ -1008,18 +1144,28 @@
     field public static final int state_single = 16842915; // 0x10100a3
     field public static final int state_window_focused = 16842909; // 0x101009d
     field public static final int staticWallpaperPreview = 16843569; // 0x1010331
+    field public static final int statusBarColor = 16843857; // 0x1010451
     field public static final int stepSize = 16843078; // 0x1010146
     field public static final int stopWithTask = 16843626; // 0x101036a
     field public static final int streamType = 16843273; // 0x1010209
     field public static final int stretchColumns = 16843081; // 0x1010149
     field public static final int stretchMode = 16843030; // 0x1010116
+    field public static final int strokeAlpha = 16843979; // 0x10104cb
+    field public static final int strokeColor = 16843782; // 0x1010406
+    field public static final int strokeLineCap = 16843787; // 0x101040b
+    field public static final int strokeLineJoin = 16843788; // 0x101040c
+    field public static final int strokeMiterLimit = 16843789; // 0x101040d
+    field public static final int strokeWidth = 16843783; // 0x1010407
+    field public static final int submitBackground = 16843912; // 0x1010488
     field public static final int subtitle = 16843473; // 0x10102d1
+    field public static final int subtitleTextAppearance = 16843823; // 0x101042f
     field public static final int subtitleTextStyle = 16843513; // 0x10102f9
     field public static final int subtypeExtraValue = 16843674; // 0x101039a
     field public static final int subtypeId = 16843713; // 0x10103c1
     field public static final int subtypeLocale = 16843673; // 0x1010399
     field public static final int suggestActionMsg = 16843228; // 0x10101dc
     field public static final int suggestActionMsgColumn = 16843229; // 0x10101dd
+    field public static final int suggestionRowLayout = 16843910; // 0x1010486
     field public static final int summary = 16843241; // 0x10101e9
     field public static final int summaryColumn = 16843426; // 0x10102a2
     field public static final int summaryOff = 16843248; // 0x10101f0
@@ -1030,6 +1176,7 @@
     field public static final int switchMinWidth = 16843632; // 0x1010370
     field public static final int switchPadding = 16843633; // 0x1010371
     field public static final int switchPreferenceStyle = 16843629; // 0x101036d
+    field public static final int switchStyle = 16843839; // 0x101043f
     field public static final int switchTextAppearance = 16843630; // 0x101036e
     field public static final int switchTextOff = 16843628; // 0x101036c
     field public static final int switchTextOn = 16843627; // 0x101036b
@@ -1043,6 +1190,7 @@
     field public static final int targetClass = 16842799; // 0x101002f
     field public static final int targetDescriptions = 16843680; // 0x10103a0
     field public static final int targetId = 16843740; // 0x10103dc
+    field public static final int targetName = 16843853; // 0x101044d
     field public static final int targetPackage = 16842785; // 0x1010021
     field public static final int targetSdkVersion = 16843376; // 0x1010270
     field public static final int taskAffinity = 16842770; // 0x1010012
@@ -1066,6 +1214,7 @@
     field public static final int textAppearanceLargeInverse = 16842819; // 0x1010043
     field public static final int textAppearanceLargePopupMenu = 16843521; // 0x1010301
     field public static final int textAppearanceListItem = 16843678; // 0x101039e
+    field public static final int textAppearanceListItemSecondary = 16843826; // 0x1010432
     field public static final int textAppearanceListItemSmall = 16843679; // 0x101039f
     field public static final int textAppearanceMedium = 16842817; // 0x1010041
     field public static final int textAppearanceMediumInverse = 16842820; // 0x1010044
@@ -1122,34 +1271,55 @@
     field public static final int thumb = 16843074; // 0x1010142
     field public static final int thumbOffset = 16843075; // 0x1010143
     field public static final int thumbTextPadding = 16843634; // 0x1010372
+    field public static final int thumbTint = 16843889; // 0x1010471
+    field public static final int thumbTintMode = 16843890; // 0x1010472
     field public static final int thumbnail = 16843429; // 0x10102a5
     field public static final int tileMode = 16843265; // 0x1010201
+    field public static final int tileModeX = 16843895; // 0x1010477
+    field public static final int tileModeY = 16843896; // 0x1010478
+    field public static final int timePickerDialogTheme = 16843934; // 0x101049e
+    field public static final int timePickerMode = 16843956; // 0x10104b4
+    field public static final int timePickerStyle = 16843933; // 0x101049d
     field public static final int timeZone = 16843724; // 0x10103cc
     field public static final int tint = 16843041; // 0x1010121
+    field public static final int tintMode = 16843771; // 0x10103fb
     field public static final int title = 16843233; // 0x10101e1
     field public static final int titleCondensed = 16843234; // 0x10101e2
+    field public static final int titleTextAppearance = 16843822; // 0x101042e
     field public static final int titleTextStyle = 16843512; // 0x10102f8
     field public static final int toAlpha = 16843211; // 0x10101cb
     field public static final int toDegrees = 16843188; // 0x10101b4
+    field public static final int toId = 16843849; // 0x1010449
     field public static final int toScene = 16843742; // 0x10103de
     field public static final int toXDelta = 16843207; // 0x10101c7
     field public static final int toXScale = 16843203; // 0x10101c3
     field public static final int toYDelta = 16843209; // 0x10101c9
     field public static final int toYScale = 16843205; // 0x10101c5
+    field public static final int toolbarStyle = 16843946; // 0x10104aa
     field public static final int top = 16843182; // 0x10101ae
     field public static final int topBright = 16842955; // 0x10100cb
     field public static final int topDark = 16842951; // 0x10100c7
     field public static final int topLeftRadius = 16843177; // 0x10101a9
     field public static final int topOffset = 16843352; // 0x1010258
     field public static final int topRightRadius = 16843178; // 0x10101aa
+    field public static final int touchscreenBlocksFocus = 16843919; // 0x101048f
     field public static final int track = 16843631; // 0x101036f
     field public static final int transcriptMode = 16843008; // 0x1010100
     field public static final int transformPivotX = 16843552; // 0x1010320
     field public static final int transformPivotY = 16843553; // 0x1010321
     field public static final int transition = 16843743; // 0x10103df
+    field public static final int transitionGroup = 16843777; // 0x1010401
+    field public static final int transitionName = 16843776; // 0x1010400
     field public static final int transitionOrdering = 16843744; // 0x10103e0
+    field public static final int transitionVisibilityMode = 16843900; // 0x101047c
+    field public static final int translateX = 16843866; // 0x101045a
+    field public static final int translateY = 16843867; // 0x101045b
     field public static final int translationX = 16843554; // 0x1010322
     field public static final int translationY = 16843555; // 0x1010323
+    field public static final int translationZ = 16843770; // 0x10103fa
+    field public static final int trimPathEnd = 16843785; // 0x1010409
+    field public static final int trimPathOffset = 16843786; // 0x101040a
+    field public static final int trimPathStart = 16843784; // 0x1010408
     field public static final int type = 16843169; // 0x10101a1
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
@@ -1174,9 +1344,12 @@
     field public static final int verticalGap = 16843328; // 0x1010240
     field public static final int verticalScrollbarPosition = 16843572; // 0x1010334
     field public static final int verticalSpacing = 16843029; // 0x1010115
+    field public static final int viewportHeight = 16843779; // 0x1010403
+    field public static final int viewportWidth = 16843778; // 0x1010402
     field public static final int visibility = 16842972; // 0x10100dc
     field public static final int visible = 16843156; // 0x1010194
     field public static final int vmSafeMode = 16843448; // 0x10102b8
+    field public static final int voiceIcon = 16843908; // 0x1010484
     field public static final int voiceLanguage = 16843349; // 0x1010255
     field public static final int voiceLanguageModel = 16843347; // 0x1010253
     field public static final int voiceMaxResults = 16843350; // 0x1010256
@@ -1202,14 +1375,24 @@
     field public static final int windowActionBar = 16843469; // 0x10102cd
     field public static final int windowActionBarOverlay = 16843492; // 0x10102e4
     field public static final int windowActionModeOverlay = 16843485; // 0x10102dd
+    field public static final int windowActivityTransitions = 16843981; // 0x10104cd
+    field public static final int windowAllowEnterTransitionOverlap = 16843836; // 0x101043c
+    field public static final int windowAllowReturnTransitionOverlap = 16843835; // 0x101043b
     field public static final int windowAnimationStyle = 16842926; // 0x10100ae
     field public static final int windowBackground = 16842836; // 0x1010054
+    field public static final int windowClipToOutline = 16843947; // 0x10104ab
     field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
     field public static final int windowContentOverlay = 16842841; // 0x1010059
+    field public static final int windowContentTransitionManager = 16843769; // 0x10103f9
+    field public static final int windowContentTransitions = 16843768; // 0x10103f8
     field public static final int windowDisablePreview = 16843298; // 0x1010222
+    field public static final int windowDrawsSystemBarBackgrounds = 16843856; // 0x1010450
+    field public static final int windowElevation = 16843920; // 0x1010490
     field public static final int windowEnableSplitTouch = 16843543; // 0x1010317
     field public static final int windowEnterAnimation = 16842932; // 0x10100b4
+    field public static final int windowEnterTransition = 16843831; // 0x1010437
     field public static final int windowExitAnimation = 16842933; // 0x10100b5
+    field public static final int windowExitTransition = 16843832; // 0x1010438
     field public static final int windowFrame = 16842837; // 0x1010055
     field public static final int windowFullscreen = 16843277; // 0x101020d
     field public static final int windowHideAnimation = 16842935; // 0x10100b7
@@ -1220,6 +1403,13 @@
     field public static final int windowNoDisplay = 16843294; // 0x101021e
     field public static final int windowNoTitle = 16842838; // 0x1010056
     field public static final int windowOverscan = 16843727; // 0x10103cf
+    field public static final int windowReenterTransition = 16843951; // 0x10104af
+    field public static final int windowReturnTransition = 16843950; // 0x10104ae
+    field public static final int windowSharedElementEnterTransition = 16843833; // 0x1010439
+    field public static final int windowSharedElementExitTransition = 16843834; // 0x101043a
+    field public static final int windowSharedElementReenterTransition = 16843953; // 0x10104b1
+    field public static final int windowSharedElementReturnTransition = 16843952; // 0x10104b0
+    field public static final int windowSharedElementsUseOverlay = 16843963; // 0x10104bb
     field public static final int windowShowAnimation = 16842934; // 0x10100b6
     field public static final int windowShowWallpaper = 16843410; // 0x1010292
     field public static final int windowSoftInputMode = 16843307; // 0x101022b
@@ -1227,12 +1417,15 @@
     field public static final int windowTitleBackgroundStyle = 16842844; // 0x101005c
     field public static final int windowTitleSize = 16842842; // 0x101005a
     field public static final int windowTitleStyle = 16842843; // 0x101005b
+    field public static final int windowTransitionBackgroundFadeDuration = 16843873; // 0x1010461
     field public static final int windowTranslucentNavigation = 16843760; // 0x10103f0
     field public static final int windowTranslucentStatus = 16843759; // 0x10103ef
     field public static final int writePermission = 16842760; // 0x1010008
     field public static final int x = 16842924; // 0x10100ac
     field public static final int xlargeScreens = 16843455; // 0x10102bf
     field public static final int y = 16842925; // 0x10100ad
+    field public static final int yearListItemTextAppearance = 16843929; // 0x1010499
+    field public static final int yearListSelectorColor = 16843930; // 0x101049a
     field public static final int yesNoPreferenceStyle = 16842896; // 0x1010090
     field public static final int zAdjustment = 16843201; // 0x10101c1
   }
@@ -1494,7 +1687,9 @@
     field public static final int inputExtractEditText = 16908325; // 0x1020025
     field public static final int keyboardView = 16908326; // 0x1020026
     field public static final int list = 16908298; // 0x102000a
+    field public static final int mask = 16908334; // 0x102002e
     field public static final int message = 16908299; // 0x102000b
+    field public static final int navigationBarBackground = 16908336; // 0x1020030
     field public static final int paste = 16908322; // 0x1020022
     field public static final int primary = 16908300; // 0x102000c
     field public static final int progress = 16908301; // 0x102000d
@@ -1503,6 +1698,7 @@
     field public static final int selectTextMode = 16908333; // 0x102002d
     field public static final int selectedIcon = 16908302; // 0x102000e
     field public static final int startSelectingText = 16908328; // 0x1020028
+    field public static final int statusBarBackground = 16908335; // 0x102002f
     field public static final int stopSelectingText = 16908329; // 0x1020029
     field public static final int summary = 16908304; // 0x1020010
     field public static final int switchInputMethod = 16908324; // 0x1020024
@@ -1537,7 +1733,10 @@
     field public static final int decelerate_cubic = 17563651; // 0x10c0003
     field public static final int decelerate_quad = 17563649; // 0x10c0001
     field public static final int decelerate_quint = 17563653; // 0x10c0005
+    field public static final int fast_out_linear_in = 17563663; // 0x10c000f
+    field public static final int fast_out_slow_in = 17563661; // 0x10c000d
     field public static final int linear = 17563659; // 0x10c000b
+    field public static final int linear_out_slow_in = 17563662; // 0x10c000e
     field public static final int overshoot = 17563656; // 0x10c0008
   }
 
@@ -1656,13 +1855,13 @@
     field public static final int TextAppearance_DeviceDefault_Widget = 16974265; // 0x10301b9
     field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Menu = 16974286; // 0x10301ce
     field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Subtitle = 16974279; // 0x10301c7
-    field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Subtitle_Inverse = 16974283; // 0x10301cb
+    field public static final deprecated int TextAppearance_DeviceDefault_Widget_ActionBar_Subtitle_Inverse = 16974283; // 0x10301cb
     field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Title = 16974278; // 0x10301c6
-    field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Title_Inverse = 16974282; // 0x10301ca
+    field public static final deprecated int TextAppearance_DeviceDefault_Widget_ActionBar_Title_Inverse = 16974282; // 0x10301ca
     field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Subtitle = 16974281; // 0x10301c9
-    field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Subtitle_Inverse = 16974285; // 0x10301cd
+    field public static final deprecated int TextAppearance_DeviceDefault_Widget_ActionMode_Subtitle_Inverse = 16974285; // 0x10301cd
     field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Title = 16974280; // 0x10301c8
-    field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Title_Inverse = 16974284; // 0x10301cc
+    field public static final deprecated int TextAppearance_DeviceDefault_Widget_ActionMode_Title_Inverse = 16974284; // 0x10301cc
     field public static final int TextAppearance_DeviceDefault_Widget_Button = 16974266; // 0x10301ba
     field public static final int TextAppearance_DeviceDefault_Widget_DropDownHint = 16974271; // 0x10301bf
     field public static final int TextAppearance_DeviceDefault_Widget_DropDownItem = 16974272; // 0x10301c0
@@ -1714,6 +1913,60 @@
     field public static final int TextAppearance_Inverse = 16973887; // 0x103003f
     field public static final int TextAppearance_Large = 16973890; // 0x1030042
     field public static final int TextAppearance_Large_Inverse = 16973891; // 0x1030043
+    field public static final int TextAppearance_Material = 16974317; // 0x10301ed
+    field public static final int TextAppearance_Material_Body1 = 16974320; // 0x10301f0
+    field public static final int TextAppearance_Material_Body2 = 16974319; // 0x10301ef
+    field public static final int TextAppearance_Material_Button = 16974318; // 0x10301ee
+    field public static final int TextAppearance_Material_Caption = 16974321; // 0x10301f1
+    field public static final int TextAppearance_Material_DialogWindowTitle = 16974322; // 0x10301f2
+    field public static final int TextAppearance_Material_Display1 = 16974326; // 0x10301f6
+    field public static final int TextAppearance_Material_Display2 = 16974325; // 0x10301f5
+    field public static final int TextAppearance_Material_Display3 = 16974324; // 0x10301f4
+    field public static final int TextAppearance_Material_Display4 = 16974323; // 0x10301f3
+    field public static final int TextAppearance_Material_Headline = 16974327; // 0x10301f7
+    field public static final int TextAppearance_Material_Inverse = 16974328; // 0x10301f8
+    field public static final int TextAppearance_Material_Large = 16974329; // 0x10301f9
+    field public static final int TextAppearance_Material_Large_Inverse = 16974330; // 0x10301fa
+    field public static final int TextAppearance_Material_Medium = 16974331; // 0x10301fb
+    field public static final int TextAppearance_Material_Medium_Inverse = 16974332; // 0x10301fc
+    field public static final int TextAppearance_Material_Menu = 16974333; // 0x10301fd
+    field public static final int TextAppearance_Material_Notification = 16974334; // 0x10301fe
+    field public static final int TextAppearance_Material_Notification_Emphasis = 16974335; // 0x10301ff
+    field public static final int TextAppearance_Material_Notification_Info = 16974336; // 0x1030200
+    field public static final int TextAppearance_Material_Notification_Line2 = 16974337; // 0x1030201
+    field public static final int TextAppearance_Material_Notification_Time = 16974338; // 0x1030202
+    field public static final int TextAppearance_Material_Notification_Title = 16974339; // 0x1030203
+    field public static final int TextAppearance_Material_SearchResult_Subtitle = 16974340; // 0x1030204
+    field public static final int TextAppearance_Material_SearchResult_Title = 16974341; // 0x1030205
+    field public static final int TextAppearance_Material_Small = 16974342; // 0x1030206
+    field public static final int TextAppearance_Material_Small_Inverse = 16974343; // 0x1030207
+    field public static final int TextAppearance_Material_Subhead = 16974344; // 0x1030208
+    field public static final int TextAppearance_Material_Title = 16974345; // 0x1030209
+    field public static final int TextAppearance_Material_Widget = 16974347; // 0x103020b
+    field public static final int TextAppearance_Material_Widget_ActionBar_Menu = 16974348; // 0x103020c
+    field public static final int TextAppearance_Material_Widget_ActionBar_Subtitle = 16974349; // 0x103020d
+    field public static final int TextAppearance_Material_Widget_ActionBar_Subtitle_Inverse = 16974350; // 0x103020e
+    field public static final int TextAppearance_Material_Widget_ActionBar_Title = 16974351; // 0x103020f
+    field public static final int TextAppearance_Material_Widget_ActionBar_Title_Inverse = 16974352; // 0x1030210
+    field public static final int TextAppearance_Material_Widget_ActionMode_Subtitle = 16974353; // 0x1030211
+    field public static final int TextAppearance_Material_Widget_ActionMode_Subtitle_Inverse = 16974354; // 0x1030212
+    field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974355; // 0x1030213
+    field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974356; // 0x1030214
+    field public static final int TextAppearance_Material_Widget_Button = 16974357; // 0x1030215
+    field public static final int TextAppearance_Material_Widget_DropDownHint = 16974358; // 0x1030216
+    field public static final int TextAppearance_Material_Widget_DropDownItem = 16974359; // 0x1030217
+    field public static final int TextAppearance_Material_Widget_EditText = 16974360; // 0x1030218
+    field public static final int TextAppearance_Material_Widget_IconMenu_Item = 16974361; // 0x1030219
+    field public static final int TextAppearance_Material_Widget_PopupMenu = 16974362; // 0x103021a
+    field public static final int TextAppearance_Material_Widget_PopupMenu_Large = 16974363; // 0x103021b
+    field public static final int TextAppearance_Material_Widget_PopupMenu_Small = 16974364; // 0x103021c
+    field public static final int TextAppearance_Material_Widget_TabWidget = 16974365; // 0x103021d
+    field public static final int TextAppearance_Material_Widget_TextView = 16974366; // 0x103021e
+    field public static final int TextAppearance_Material_Widget_TextView_PopupMenu = 16974367; // 0x103021f
+    field public static final int TextAppearance_Material_Widget_TextView_SpinnerItem = 16974368; // 0x1030220
+    field public static final int TextAppearance_Material_Widget_Toolbar_Subtitle = 16974369; // 0x1030221
+    field public static final int TextAppearance_Material_Widget_Toolbar_Title = 16974370; // 0x1030222
+    field public static final int TextAppearance_Material_WindowTitle = 16974346; // 0x103020a
     field public static final int TextAppearance_Medium = 16973892; // 0x1030044
     field public static final int TextAppearance_Medium_Inverse = 16973893; // 0x1030045
     field public static final int TextAppearance_Small = 16973894; // 0x1030046
@@ -1739,6 +1992,12 @@
     field public static final int TextAppearance_Widget_TextView_SpinnerItem = 16973906; // 0x1030052
     field public static final int TextAppearance_WindowTitle = 16973907; // 0x1030053
     field public static final int Theme = 16973829; // 0x1030005
+    field public static final int ThemeOverlay = 16974407; // 0x1030247
+    field public static final int ThemeOverlay_Material = 16974408; // 0x1030248
+    field public static final int ThemeOverlay_Material_ActionBar = 16974409; // 0x1030249
+    field public static final int ThemeOverlay_Material_Dark = 16974411; // 0x103024b
+    field public static final int ThemeOverlay_Material_Dark_ActionBar = 16974412; // 0x103024c
+    field public static final int ThemeOverlay_Material_Light = 16974410; // 0x103024a
     field public static final int Theme_Black = 16973832; // 0x1030008
     field public static final int Theme_Black_NoTitleBar = 16973833; // 0x1030009
     field public static final int Theme_Black_NoTitleBar_Fullscreen = 16973834; // 0x103000a
@@ -1768,6 +2027,7 @@
     field public static final int Theme_DeviceDefault_NoActionBar_Overscan = 16974303; // 0x10301df
     field public static final int Theme_DeviceDefault_NoActionBar_TranslucentDecor = 16974307; // 0x10301e3
     field public static final int Theme_DeviceDefault_Panel = 16974138; // 0x103013a
+    field public static final int Theme_DeviceDefault_Settings = 16974371; // 0x1030223
     field public static final int Theme_DeviceDefault_Wallpaper = 16974140; // 0x103013c
     field public static final int Theme_DeviceDefault_Wallpaper_NoTitleBar = 16974141; // 0x103013d
     field public static final int Theme_Dialog = 16973835; // 0x103000b
@@ -1805,6 +2065,41 @@
     field public static final int Theme_Light_NoTitleBar_Fullscreen = 16973838; // 0x103000e
     field public static final int Theme_Light_Panel = 16973914; // 0x103005a
     field public static final int Theme_Light_WallpaperSettings = 16973922; // 0x1030062
+    field public static final int Theme_Material = 16974372; // 0x1030224
+    field public static final int Theme_Material_Dialog = 16974373; // 0x1030225
+    field public static final int Theme_Material_DialogWhenLarge = 16974379; // 0x103022b
+    field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974380; // 0x103022c
+    field public static final int Theme_Material_Dialog_Alert = 16974374; // 0x1030226
+    field public static final int Theme_Material_Dialog_MinWidth = 16974375; // 0x1030227
+    field public static final int Theme_Material_Dialog_NoActionBar = 16974376; // 0x1030228
+    field public static final int Theme_Material_Dialog_NoActionBar_MinWidth = 16974377; // 0x1030229
+    field public static final int Theme_Material_Dialog_Presentation = 16974378; // 0x103022a
+    field public static final int Theme_Material_InputMethod = 16974381; // 0x103022d
+    field public static final int Theme_Material_Light = 16974391; // 0x1030237
+    field public static final int Theme_Material_Light_DarkActionBar = 16974392; // 0x1030238
+    field public static final int Theme_Material_Light_Dialog = 16974393; // 0x1030239
+    field public static final int Theme_Material_Light_DialogWhenLarge = 16974399; // 0x103023f
+    field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974400; // 0x1030240
+    field public static final int Theme_Material_Light_Dialog_Alert = 16974394; // 0x103023a
+    field public static final int Theme_Material_Light_Dialog_MinWidth = 16974395; // 0x103023b
+    field public static final int Theme_Material_Light_Dialog_NoActionBar = 16974396; // 0x103023c
+    field public static final int Theme_Material_Light_Dialog_NoActionBar_MinWidth = 16974397; // 0x103023d
+    field public static final int Theme_Material_Light_Dialog_Presentation = 16974398; // 0x103023e
+    field public static final int Theme_Material_Light_NoActionBar = 16974401; // 0x1030241
+    field public static final int Theme_Material_Light_NoActionBar_Fullscreen = 16974402; // 0x1030242
+    field public static final int Theme_Material_Light_NoActionBar_Overscan = 16974403; // 0x1030243
+    field public static final int Theme_Material_Light_NoActionBar_TranslucentDecor = 16974404; // 0x1030244
+    field public static final int Theme_Material_Light_Panel = 16974405; // 0x1030245
+    field public static final int Theme_Material_Light_Voice = 16974406; // 0x1030246
+    field public static final int Theme_Material_NoActionBar = 16974382; // 0x103022e
+    field public static final int Theme_Material_NoActionBar_Fullscreen = 16974383; // 0x103022f
+    field public static final int Theme_Material_NoActionBar_Overscan = 16974384; // 0x1030230
+    field public static final int Theme_Material_NoActionBar_TranslucentDecor = 16974385; // 0x1030231
+    field public static final int Theme_Material_Panel = 16974386; // 0x1030232
+    field public static final int Theme_Material_Settings = 16974387; // 0x1030233
+    field public static final int Theme_Material_Voice = 16974388; // 0x1030234
+    field public static final int Theme_Material_Wallpaper = 16974389; // 0x1030235
+    field public static final int Theme_Material_Wallpaper_NoTitleBar = 16974390; // 0x1030236
     field public static final int Theme_NoDisplay = 16973909; // 0x1030055
     field public static final int Theme_NoTitleBar = 16973830; // 0x1030006
     field public static final int Theme_NoTitleBar_Fullscreen = 16973831; // 0x1030007
@@ -1866,24 +2161,25 @@
     field public static final int Widget_DeviceDefault_DropDownItem_Spinner = 16974178; // 0x1030162
     field public static final int Widget_DeviceDefault_EditText = 16974154; // 0x103014a
     field public static final int Widget_DeviceDefault_ExpandableListView = 16974155; // 0x103014b
+    field public static final int Widget_DeviceDefault_FastScroll = 16974313; // 0x10301e9
     field public static final int Widget_DeviceDefault_GridView = 16974156; // 0x103014c
     field public static final int Widget_DeviceDefault_HorizontalScrollView = 16974171; // 0x103015b
     field public static final int Widget_DeviceDefault_ImageButton = 16974157; // 0x103014d
     field public static final int Widget_DeviceDefault_Light = 16974196; // 0x1030174
     field public static final int Widget_DeviceDefault_Light_ActionBar = 16974243; // 0x10301a3
     field public static final int Widget_DeviceDefault_Light_ActionBar_Solid = 16974247; // 0x10301a7
-    field public static final int Widget_DeviceDefault_Light_ActionBar_Solid_Inverse = 16974248; // 0x10301a8
+    field public static final deprecated int Widget_DeviceDefault_Light_ActionBar_Solid_Inverse = 16974248; // 0x10301a8
     field public static final int Widget_DeviceDefault_Light_ActionBar_TabBar = 16974246; // 0x10301a6
-    field public static final int Widget_DeviceDefault_Light_ActionBar_TabBar_Inverse = 16974249; // 0x10301a9
+    field public static final deprecated int Widget_DeviceDefault_Light_ActionBar_TabBar_Inverse = 16974249; // 0x10301a9
     field public static final int Widget_DeviceDefault_Light_ActionBar_TabText = 16974245; // 0x10301a5
-    field public static final int Widget_DeviceDefault_Light_ActionBar_TabText_Inverse = 16974251; // 0x10301ab
+    field public static final deprecated int Widget_DeviceDefault_Light_ActionBar_TabText_Inverse = 16974251; // 0x10301ab
     field public static final int Widget_DeviceDefault_Light_ActionBar_TabView = 16974244; // 0x10301a4
-    field public static final int Widget_DeviceDefault_Light_ActionBar_TabView_Inverse = 16974250; // 0x10301aa
+    field public static final deprecated int Widget_DeviceDefault_Light_ActionBar_TabView_Inverse = 16974250; // 0x10301aa
     field public static final int Widget_DeviceDefault_Light_ActionButton = 16974239; // 0x103019f
     field public static final int Widget_DeviceDefault_Light_ActionButton_CloseMode = 16974242; // 0x10301a2
     field public static final int Widget_DeviceDefault_Light_ActionButton_Overflow = 16974240; // 0x10301a0
     field public static final int Widget_DeviceDefault_Light_ActionMode = 16974241; // 0x10301a1
-    field public static final int Widget_DeviceDefault_Light_ActionMode_Inverse = 16974252; // 0x10301ac
+    field public static final deprecated int Widget_DeviceDefault_Light_ActionMode_Inverse = 16974252; // 0x10301ac
     field public static final int Widget_DeviceDefault_Light_AutoCompleteTextView = 16974203; // 0x103017b
     field public static final int Widget_DeviceDefault_Light_Button = 16974197; // 0x1030175
     field public static final int Widget_DeviceDefault_Light_Button_Borderless_Small = 16974201; // 0x1030179
@@ -1899,6 +2195,7 @@
     field public static final int Widget_DeviceDefault_Light_DropDownItem_Spinner = 16974233; // 0x1030199
     field public static final int Widget_DeviceDefault_Light_EditText = 16974206; // 0x103017e
     field public static final int Widget_DeviceDefault_Light_ExpandableListView = 16974207; // 0x103017f
+    field public static final int Widget_DeviceDefault_Light_FastScroll = 16974315; // 0x10301eb
     field public static final int Widget_DeviceDefault_Light_GridView = 16974208; // 0x1030180
     field public static final int Widget_DeviceDefault_Light_HorizontalScrollView = 16974226; // 0x1030192
     field public static final int Widget_DeviceDefault_Light_ImageButton = 16974209; // 0x1030181
@@ -1922,6 +2219,7 @@
     field public static final int Widget_DeviceDefault_Light_ScrollView = 16974225; // 0x1030191
     field public static final int Widget_DeviceDefault_Light_SeekBar = 16974220; // 0x103018c
     field public static final int Widget_DeviceDefault_Light_Spinner = 16974227; // 0x1030193
+    field public static final int Widget_DeviceDefault_Light_StackView = 16974316; // 0x10301ec
     field public static final int Widget_DeviceDefault_Light_Tab = 16974237; // 0x103019d
     field public static final int Widget_DeviceDefault_Light_TabWidget = 16974229; // 0x1030195
     field public static final int Widget_DeviceDefault_Light_TextView = 16974202; // 0x103017a
@@ -1945,6 +2243,7 @@
     field public static final int Widget_DeviceDefault_ScrollView = 16974170; // 0x103015a
     field public static final int Widget_DeviceDefault_SeekBar = 16974165; // 0x1030155
     field public static final int Widget_DeviceDefault_Spinner = 16974172; // 0x103015c
+    field public static final int Widget_DeviceDefault_StackView = 16974314; // 0x10301ea
     field public static final int Widget_DeviceDefault_Tab = 16974189; // 0x103016d
     field public static final int Widget_DeviceDefault_TabWidget = 16974174; // 0x103015e
     field public static final int Widget_DeviceDefault_TextView = 16974150; // 0x1030146
@@ -1955,6 +2254,7 @@
     field public static final int Widget_DropDownItem_Spinner = 16973868; // 0x103002c
     field public static final int Widget_EditText = 16973859; // 0x1030023
     field public static final int Widget_ExpandableListView = 16973860; // 0x1030024
+    field public static final int Widget_FastScroll = 16974309; // 0x10301e5
     field public static final int Widget_FragmentBreadCrumbs = 16973961; // 0x1030089
     field public static final int Widget_Gallery = 16973877; // 0x1030035
     field public static final int Widget_GridView = 16973874; // 0x1030032
@@ -2079,6 +2379,137 @@
     field public static final int Widget_ListView_DropDown = 16973872; // 0x1030030
     field public static final int Widget_ListView_Menu = 16973873; // 0x1030031
     field public static final int Widget_ListView_White = 16973871; // 0x103002f
+    field public static final int Widget_Material = 16974413; // 0x103024d
+    field public static final int Widget_Material_ActionBar = 16974414; // 0x103024e
+    field public static final int Widget_Material_ActionBar_Solid = 16974415; // 0x103024f
+    field public static final int Widget_Material_ActionBar_TabBar = 16974416; // 0x1030250
+    field public static final int Widget_Material_ActionBar_TabText = 16974417; // 0x1030251
+    field public static final int Widget_Material_ActionBar_TabView = 16974418; // 0x1030252
+    field public static final int Widget_Material_ActionButton = 16974419; // 0x1030253
+    field public static final int Widget_Material_ActionButton_CloseMode = 16974420; // 0x1030254
+    field public static final int Widget_Material_ActionButton_Overflow = 16974421; // 0x1030255
+    field public static final int Widget_Material_ActionMode = 16974422; // 0x1030256
+    field public static final int Widget_Material_AutoCompleteTextView = 16974423; // 0x1030257
+    field public static final int Widget_Material_Button = 16974424; // 0x1030258
+    field public static final int Widget_Material_ButtonBar = 16974431; // 0x103025f
+    field public static final int Widget_Material_ButtonBar_AlertDialog = 16974432; // 0x1030260
+    field public static final int Widget_Material_Button_Borderless = 16974425; // 0x1030259
+    field public static final int Widget_Material_Button_Borderless_Colored = 16974426; // 0x103025a
+    field public static final int Widget_Material_Button_Borderless_Small = 16974427; // 0x103025b
+    field public static final int Widget_Material_Button_Inset = 16974428; // 0x103025c
+    field public static final int Widget_Material_Button_Small = 16974429; // 0x103025d
+    field public static final int Widget_Material_Button_Toggle = 16974430; // 0x103025e
+    field public static final int Widget_Material_CalendarView = 16974433; // 0x1030261
+    field public static final int Widget_Material_CheckedTextView = 16974434; // 0x1030262
+    field public static final int Widget_Material_CompoundButton_CheckBox = 16974435; // 0x1030263
+    field public static final int Widget_Material_CompoundButton_RadioButton = 16974436; // 0x1030264
+    field public static final int Widget_Material_CompoundButton_Star = 16974437; // 0x1030265
+    field public static final int Widget_Material_DatePicker = 16974438; // 0x1030266
+    field public static final int Widget_Material_DropDownItem = 16974439; // 0x1030267
+    field public static final int Widget_Material_DropDownItem_Spinner = 16974440; // 0x1030268
+    field public static final int Widget_Material_EditText = 16974441; // 0x1030269
+    field public static final int Widget_Material_ExpandableListView = 16974442; // 0x103026a
+    field public static final int Widget_Material_FastScroll = 16974443; // 0x103026b
+    field public static final int Widget_Material_GridView = 16974444; // 0x103026c
+    field public static final int Widget_Material_HorizontalScrollView = 16974445; // 0x103026d
+    field public static final int Widget_Material_ImageButton = 16974446; // 0x103026e
+    field public static final int Widget_Material_Light = 16974478; // 0x103028e
+    field public static final int Widget_Material_Light_ActionBar = 16974479; // 0x103028f
+    field public static final int Widget_Material_Light_ActionBar_Solid = 16974480; // 0x1030290
+    field public static final int Widget_Material_Light_ActionBar_TabBar = 16974481; // 0x1030291
+    field public static final int Widget_Material_Light_ActionBar_TabText = 16974482; // 0x1030292
+    field public static final int Widget_Material_Light_ActionBar_TabView = 16974483; // 0x1030293
+    field public static final int Widget_Material_Light_ActionButton = 16974484; // 0x1030294
+    field public static final int Widget_Material_Light_ActionButton_CloseMode = 16974485; // 0x1030295
+    field public static final int Widget_Material_Light_ActionButton_Overflow = 16974486; // 0x1030296
+    field public static final int Widget_Material_Light_ActionMode = 16974487; // 0x1030297
+    field public static final int Widget_Material_Light_AutoCompleteTextView = 16974488; // 0x1030298
+    field public static final int Widget_Material_Light_Button = 16974489; // 0x1030299
+    field public static final int Widget_Material_Light_ButtonBar = 16974496; // 0x10302a0
+    field public static final int Widget_Material_Light_ButtonBar_AlertDialog = 16974497; // 0x10302a1
+    field public static final int Widget_Material_Light_Button_Borderless = 16974490; // 0x103029a
+    field public static final int Widget_Material_Light_Button_Borderless_Colored = 16974491; // 0x103029b
+    field public static final int Widget_Material_Light_Button_Borderless_Small = 16974492; // 0x103029c
+    field public static final int Widget_Material_Light_Button_Inset = 16974493; // 0x103029d
+    field public static final int Widget_Material_Light_Button_Small = 16974494; // 0x103029e
+    field public static final int Widget_Material_Light_Button_Toggle = 16974495; // 0x103029f
+    field public static final int Widget_Material_Light_CalendarView = 16974498; // 0x10302a2
+    field public static final int Widget_Material_Light_CheckedTextView = 16974499; // 0x10302a3
+    field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974500; // 0x10302a4
+    field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974501; // 0x10302a5
+    field public static final int Widget_Material_Light_CompoundButton_Star = 16974502; // 0x10302a6
+    field public static final int Widget_Material_Light_DatePicker = 16974503; // 0x10302a7
+    field public static final int Widget_Material_Light_DropDownItem = 16974504; // 0x10302a8
+    field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974505; // 0x10302a9
+    field public static final int Widget_Material_Light_EditText = 16974506; // 0x10302aa
+    field public static final int Widget_Material_Light_ExpandableListView = 16974507; // 0x10302ab
+    field public static final int Widget_Material_Light_FastScroll = 16974508; // 0x10302ac
+    field public static final int Widget_Material_Light_GridView = 16974509; // 0x10302ad
+    field public static final int Widget_Material_Light_HorizontalScrollView = 16974510; // 0x10302ae
+    field public static final int Widget_Material_Light_ImageButton = 16974511; // 0x10302af
+    field public static final int Widget_Material_Light_ListPopupWindow = 16974512; // 0x10302b0
+    field public static final int Widget_Material_Light_ListView = 16974513; // 0x10302b1
+    field public static final int Widget_Material_Light_ListView_DropDown = 16974514; // 0x10302b2
+    field public static final int Widget_Material_Light_MediaRouteButton = 16974515; // 0x10302b3
+    field public static final int Widget_Material_Light_PopupMenu = 16974516; // 0x10302b4
+    field public static final int Widget_Material_Light_PopupMenu_Overflow = 16974517; // 0x10302b5
+    field public static final int Widget_Material_Light_PopupWindow = 16974518; // 0x10302b6
+    field public static final int Widget_Material_Light_ProgressBar = 16974519; // 0x10302b7
+    field public static final int Widget_Material_Light_ProgressBar_Horizontal = 16974520; // 0x10302b8
+    field public static final int Widget_Material_Light_ProgressBar_Inverse = 16974521; // 0x10302b9
+    field public static final int Widget_Material_Light_ProgressBar_Large = 16974522; // 0x10302ba
+    field public static final int Widget_Material_Light_ProgressBar_Large_Inverse = 16974523; // 0x10302bb
+    field public static final int Widget_Material_Light_ProgressBar_Small = 16974524; // 0x10302bc
+    field public static final int Widget_Material_Light_ProgressBar_Small_Inverse = 16974525; // 0x10302bd
+    field public static final int Widget_Material_Light_ProgressBar_Small_Title = 16974526; // 0x10302be
+    field public static final int Widget_Material_Light_RatingBar = 16974527; // 0x10302bf
+    field public static final int Widget_Material_Light_RatingBar_Indicator = 16974528; // 0x10302c0
+    field public static final int Widget_Material_Light_RatingBar_Small = 16974529; // 0x10302c1
+    field public static final int Widget_Material_Light_ScrollView = 16974530; // 0x10302c2
+    field public static final int Widget_Material_Light_SearchView = 16974531; // 0x10302c3
+    field public static final int Widget_Material_Light_SeekBar = 16974532; // 0x10302c4
+    field public static final int Widget_Material_Light_SegmentedButton = 16974533; // 0x10302c5
+    field public static final int Widget_Material_Light_Spinner = 16974535; // 0x10302c7
+    field public static final int Widget_Material_Light_Spinner_Underlined = 16974536; // 0x10302c8
+    field public static final int Widget_Material_Light_StackView = 16974534; // 0x10302c6
+    field public static final int Widget_Material_Light_Tab = 16974537; // 0x10302c9
+    field public static final int Widget_Material_Light_TabWidget = 16974538; // 0x10302ca
+    field public static final int Widget_Material_Light_TextView = 16974539; // 0x10302cb
+    field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974540; // 0x10302cc
+    field public static final int Widget_Material_Light_TimePicker = 16974541; // 0x10302cd
+    field public static final int Widget_Material_Light_WebTextView = 16974542; // 0x10302ce
+    field public static final int Widget_Material_Light_WebView = 16974543; // 0x10302cf
+    field public static final int Widget_Material_ListPopupWindow = 16974447; // 0x103026f
+    field public static final int Widget_Material_ListView = 16974448; // 0x1030270
+    field public static final int Widget_Material_ListView_DropDown = 16974449; // 0x1030271
+    field public static final int Widget_Material_MediaRouteButton = 16974450; // 0x1030272
+    field public static final int Widget_Material_PopupMenu = 16974451; // 0x1030273
+    field public static final int Widget_Material_PopupMenu_Overflow = 16974452; // 0x1030274
+    field public static final int Widget_Material_PopupWindow = 16974453; // 0x1030275
+    field public static final int Widget_Material_ProgressBar = 16974454; // 0x1030276
+    field public static final int Widget_Material_ProgressBar_Horizontal = 16974455; // 0x1030277
+    field public static final int Widget_Material_ProgressBar_Large = 16974456; // 0x1030278
+    field public static final int Widget_Material_ProgressBar_Small = 16974457; // 0x1030279
+    field public static final int Widget_Material_ProgressBar_Small_Title = 16974458; // 0x103027a
+    field public static final int Widget_Material_RatingBar = 16974459; // 0x103027b
+    field public static final int Widget_Material_RatingBar_Indicator = 16974460; // 0x103027c
+    field public static final int Widget_Material_RatingBar_Small = 16974461; // 0x103027d
+    field public static final int Widget_Material_ScrollView = 16974462; // 0x103027e
+    field public static final int Widget_Material_SearchView = 16974463; // 0x103027f
+    field public static final int Widget_Material_SeekBar = 16974464; // 0x1030280
+    field public static final int Widget_Material_SegmentedButton = 16974465; // 0x1030281
+    field public static final int Widget_Material_Spinner = 16974467; // 0x1030283
+    field public static final int Widget_Material_Spinner_Underlined = 16974468; // 0x1030284
+    field public static final int Widget_Material_StackView = 16974466; // 0x1030282
+    field public static final int Widget_Material_Tab = 16974469; // 0x1030285
+    field public static final int Widget_Material_TabWidget = 16974470; // 0x1030286
+    field public static final int Widget_Material_TextView = 16974471; // 0x1030287
+    field public static final int Widget_Material_TextView_SpinnerItem = 16974472; // 0x1030288
+    field public static final int Widget_Material_TimePicker = 16974473; // 0x1030289
+    field public static final int Widget_Material_Toolbar = 16974474; // 0x103028a
+    field public static final int Widget_Material_Toolbar_Button_Navigation = 16974475; // 0x103028b
+    field public static final int Widget_Material_WebTextView = 16974476; // 0x103028c
+    field public static final int Widget_Material_WebView = 16974477; // 0x103028d
     field public static final int Widget_PopupMenu = 16973958; // 0x1030086
     field public static final int Widget_PopupWindow = 16973878; // 0x1030036
     field public static final int Widget_ProgressBar = 16973852; // 0x103001c
@@ -2093,13 +2524,28 @@
     field public static final int Widget_SeekBar = 16973856; // 0x1030020
     field public static final int Widget_Spinner = 16973864; // 0x1030028
     field public static final int Widget_Spinner_DropDown = 16973955; // 0x1030083
+    field public static final int Widget_StackView = 16974310; // 0x10301e6
     field public static final int Widget_TabWidget = 16973876; // 0x1030034
     field public static final int Widget_TextView = 16973858; // 0x1030022
     field public static final int Widget_TextView_PopupMenu = 16973865; // 0x1030029
     field public static final int Widget_TextView_SpinnerItem = 16973866; // 0x103002a
+    field public static final int Widget_Toolbar = 16974311; // 0x10301e7
+    field public static final int Widget_Toolbar_Button_Navigation = 16974312; // 0x10301e8
     field public static final int Widget_WebView = 16973875; // 0x1030033
   }
 
+  public static final class R.transition {
+    ctor public R.transition();
+    field public static final int explode = 17760259; // 0x10f0003
+    field public static final int fade = 17760258; // 0x10f0002
+    field public static final int move = 17760257; // 0x10f0001
+    field public static final int no_transition = 17760256; // 0x10f0000
+    field public static final int slide_bottom = 17760260; // 0x10f0004
+    field public static final int slide_left = 17760263; // 0x10f0007
+    field public static final int slide_right = 17760262; // 0x10f0006
+    field public static final int slide_top = 17760261; // 0x10f0005
+  }
+
   public static final class R.xml {
     ctor public R.xml();
   }
@@ -2110,8 +2556,10 @@
 
   public abstract class AccessibilityService extends android.app.Service {
     ctor public AccessibilityService();
+    method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
     method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
+    method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
     method public abstract void onAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
     method public final android.os.IBinder onBind(android.content.Intent);
     method protected boolean onGesture(int);
@@ -2139,6 +2587,7 @@
     field public static final int GLOBAL_ACTION_BACK = 1; // 0x1
     field public static final int GLOBAL_ACTION_HOME = 2; // 0x2
     field public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; // 0x4
+    field public static final int GLOBAL_ACTION_POWER_DIALOG = 6; // 0x6
     field public static final int GLOBAL_ACTION_QUICK_SETTINGS = 5; // 0x5
     field public static final int GLOBAL_ACTION_RECENTS = 3; // 0x3
     field public static final java.lang.String SERVICE_INTERFACE = "android.accessibilityservice.AccessibilityService";
@@ -2177,6 +2626,7 @@
     field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
     field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
+    field public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 64; // 0x40
     field public int eventTypes;
     field public int feedbackType;
     field public int flags;
@@ -2247,6 +2697,7 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
     method public java.lang.String getPassword(android.accounts.Account);
+    method public java.lang.String getPreviousName(android.accounts.Account);
     method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
     method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public void invalidateAuthToken(java.lang.String, java.lang.String);
@@ -2254,6 +2705,7 @@
     method public java.lang.String peekAuthToken(android.accounts.Account, java.lang.String);
     method public android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
+    method public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
     method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
     method public void setPassword(android.accounts.Account, java.lang.String);
     method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String);
@@ -2397,6 +2849,7 @@
   public class AnimatorInflater {
     ctor public AnimatorInflater();
     method public static android.animation.Animator loadAnimator(android.content.Context, int) throws android.content.res.Resources.NotFoundException;
+    method public static android.animation.StateListAnimator loadStateListAnimator(android.content.Context, int) throws android.content.res.Resources.NotFoundException;
   }
 
   public abstract class AnimatorListenerAdapter implements android.animation.Animator.AnimatorListener android.animation.Animator.AnimatorPauseListener {
@@ -2437,11 +2890,29 @@
     method public java.lang.Object evaluate(float, java.lang.Object, java.lang.Object);
   }
 
+  public abstract class BidirectionalTypeConverter extends android.animation.TypeConverter {
+    ctor public BidirectionalTypeConverter(java.lang.Class<T>, java.lang.Class<V>);
+    method public abstract T convertBack(V);
+    method public android.animation.BidirectionalTypeConverter<V, T> invert();
+  }
+
+  public class FloatArrayEvaluator implements android.animation.TypeEvaluator {
+    ctor public FloatArrayEvaluator();
+    ctor public FloatArrayEvaluator(float[]);
+    method public float[] evaluate(float, float[], float[]);
+  }
+
   public class FloatEvaluator implements android.animation.TypeEvaluator {
     ctor public FloatEvaluator();
     method public java.lang.Float evaluate(float, java.lang.Number, java.lang.Number);
   }
 
+  public class IntArrayEvaluator implements android.animation.TypeEvaluator {
+    ctor public IntArrayEvaluator();
+    ctor public IntArrayEvaluator(int[]);
+    method public int[] evaluate(float, int[], int[]);
+  }
+
   public class IntEvaluator implements android.animation.TypeEvaluator {
     ctor public IntEvaluator();
     method public java.lang.Integer evaluate(float, java.lang.Integer, java.lang.Integer);
@@ -2510,18 +2981,39 @@
     ctor public ObjectAnimator();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
+    method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
+    method public static android.animation.ObjectAnimator ofArgb(T, android.util.Property<T, java.lang.Integer>, int...);
     method public static android.animation.ObjectAnimator ofFloat(java.lang.Object, java.lang.String, float...);
+    method public static android.animation.ObjectAnimator ofFloat(java.lang.Object, java.lang.String, java.lang.String, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofFloat(T, android.util.Property<T, java.lang.Float>, float...);
+    method public static android.animation.ObjectAnimator ofFloat(T, android.util.Property<T, java.lang.Float>, android.util.Property<T, java.lang.Float>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofInt(java.lang.Object, java.lang.String, int...);
+    method public static android.animation.ObjectAnimator ofInt(java.lang.Object, java.lang.String, java.lang.String, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofInt(T, android.util.Property<T, java.lang.Integer>, int...);
+    method public static android.animation.ObjectAnimator ofInt(T, android.util.Property<T, java.lang.Integer>, android.util.Property<T, java.lang.Integer>, android.graphics.Path);
+    method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, float[][]);
+    method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, android.graphics.Path);
+    method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, android.animation.TypeConverter<T, float[]>, android.animation.TypeEvaluator<T>, T...);
+    method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, int[][]);
+    method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, android.graphics.Path);
+    method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, android.animation.TypeConverter<T, int[]>, android.animation.TypeEvaluator<T>, T...);
     method public static android.animation.ObjectAnimator ofObject(java.lang.Object, java.lang.String, android.animation.TypeEvaluator, java.lang.Object...);
+    method public static android.animation.ObjectAnimator ofObject(java.lang.Object, java.lang.String, android.animation.TypeConverter<android.graphics.PointF, ?>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, P>, android.animation.TypeConverter<V, P>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
 
+  public class PointFEvaluator implements android.animation.TypeEvaluator {
+    ctor public PointFEvaluator();
+    ctor public PointFEvaluator(android.graphics.PointF);
+    method public android.graphics.PointF evaluate(float, android.graphics.PointF, android.graphics.PointF);
+  }
+
   public class PropertyValuesHolder implements java.lang.Cloneable {
     method public android.animation.PropertyValuesHolder clone();
     method public java.lang.String getPropertyName();
@@ -2531,8 +3023,20 @@
     method public static android.animation.PropertyValuesHolder ofInt(android.util.Property<?, java.lang.Integer>, int...);
     method public static android.animation.PropertyValuesHolder ofKeyframe(java.lang.String, android.animation.Keyframe...);
     method public static android.animation.PropertyValuesHolder ofKeyframe(android.util.Property, android.animation.Keyframe...);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, float[][]);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.graphics.Path);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.animation.TypeConverter<V, float[]>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.animation.TypeConverter<T, float[]>, android.animation.TypeEvaluator<T>, android.animation.Keyframe...);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, int[][]);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.graphics.Path);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.animation.TypeConverter<V, int[]>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.animation.TypeConverter<T, int[]>, android.animation.TypeEvaluator<T>, android.animation.Keyframe...);
     method public static android.animation.PropertyValuesHolder ofObject(java.lang.String, android.animation.TypeEvaluator, java.lang.Object...);
+    method public static android.animation.PropertyValuesHolder ofObject(java.lang.String, android.animation.TypeConverter<android.graphics.PointF, ?>, android.graphics.Path);
     method public static android.animation.PropertyValuesHolder ofObject(android.util.Property, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.PropertyValuesHolder ofObject(android.util.Property<?, V>, android.animation.TypeConverter<T, V>, android.animation.TypeEvaluator<T>, T...);
+    method public static android.animation.PropertyValuesHolder ofObject(android.util.Property<?, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
+    method public void setConverter(android.animation.TypeConverter);
     method public void setEvaluator(android.animation.TypeEvaluator);
     method public void setFloatValues(float...);
     method public void setIntValues(int...);
@@ -2544,9 +3048,16 @@
 
   public class RectEvaluator implements android.animation.TypeEvaluator {
     ctor public RectEvaluator();
+    ctor public RectEvaluator(android.graphics.Rect);
     method public android.graphics.Rect evaluate(float, android.graphics.Rect, android.graphics.Rect);
   }
 
+  public class StateListAnimator {
+    ctor public StateListAnimator();
+    method public void addState(int[], android.animation.Animator);
+    method public void jumpToCurrentState();
+  }
+
   public class TimeAnimator extends android.animation.ValueAnimator {
     ctor public TimeAnimator();
     method public void setTimeListener(android.animation.TimeAnimator.TimeListener);
@@ -2560,6 +3071,11 @@
     method public abstract float getInterpolation(float);
   }
 
+  public abstract class TypeConverter {
+    ctor public TypeConverter(java.lang.Class<T>, java.lang.Class<V>);
+    method public abstract V convert(T);
+  }
+
   public abstract interface TypeEvaluator {
     method public abstract T evaluate(float, T, T);
   }
@@ -2578,6 +3094,7 @@
     method public long getStartDelay();
     method public android.animation.PropertyValuesHolder[] getValues();
     method public boolean isRunning();
+    method public static android.animation.ValueAnimator ofArgb(int...);
     method public static android.animation.ValueAnimator ofFloat(float...);
     method public static android.animation.ValueAnimator ofInt(int...);
     method public static android.animation.ValueAnimator ofObject(android.animation.TypeEvaluator, java.lang.Object...);
@@ -2623,30 +3140,33 @@
   public abstract class ActionBar {
     ctor public ActionBar();
     method public abstract void addOnMenuVisibilityListener(android.app.ActionBar.OnMenuVisibilityListener);
-    method public abstract void addTab(android.app.ActionBar.Tab);
-    method public abstract void addTab(android.app.ActionBar.Tab, boolean);
-    method public abstract void addTab(android.app.ActionBar.Tab, int);
-    method public abstract void addTab(android.app.ActionBar.Tab, int, boolean);
+    method public abstract deprecated void addTab(android.app.ActionBar.Tab);
+    method public abstract deprecated void addTab(android.app.ActionBar.Tab, boolean);
+    method public abstract deprecated void addTab(android.app.ActionBar.Tab, int);
+    method public abstract deprecated void addTab(android.app.ActionBar.Tab, int, boolean);
     method public abstract android.view.View getCustomView();
     method public abstract int getDisplayOptions();
+    method public float getElevation();
     method public abstract int getHeight();
-    method public abstract int getNavigationItemCount();
-    method public abstract int getNavigationMode();
-    method public abstract int getSelectedNavigationIndex();
-    method public abstract android.app.ActionBar.Tab getSelectedTab();
+    method public int getHideOffset();
+    method public abstract deprecated int getNavigationItemCount();
+    method public abstract deprecated int getNavigationMode();
+    method public abstract deprecated int getSelectedNavigationIndex();
+    method public abstract deprecated android.app.ActionBar.Tab getSelectedTab();
     method public abstract java.lang.CharSequence getSubtitle();
-    method public abstract android.app.ActionBar.Tab getTabAt(int);
-    method public abstract int getTabCount();
+    method public abstract deprecated android.app.ActionBar.Tab getTabAt(int);
+    method public abstract deprecated int getTabCount();
     method public android.content.Context getThemedContext();
     method public abstract java.lang.CharSequence getTitle();
     method public abstract void hide();
+    method public boolean isHideOnContentScrollEnabled();
     method public abstract boolean isShowing();
-    method public abstract android.app.ActionBar.Tab newTab();
-    method public abstract void removeAllTabs();
+    method public abstract deprecated android.app.ActionBar.Tab newTab();
+    method public abstract deprecated void removeAllTabs();
     method public abstract void removeOnMenuVisibilityListener(android.app.ActionBar.OnMenuVisibilityListener);
-    method public abstract void removeTab(android.app.ActionBar.Tab);
-    method public abstract void removeTabAt(int);
-    method public abstract void selectTab(android.app.ActionBar.Tab);
+    method public abstract deprecated void removeTab(android.app.ActionBar.Tab);
+    method public abstract deprecated void removeTabAt(int);
+    method public abstract deprecated void selectTab(android.app.ActionBar.Tab);
     method public abstract void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public abstract void setCustomView(android.view.View);
     method public abstract void setCustomView(android.view.View, android.app.ActionBar.LayoutParams);
@@ -2658,6 +3178,9 @@
     method public abstract void setDisplayShowHomeEnabled(boolean);
     method public abstract void setDisplayShowTitleEnabled(boolean);
     method public abstract void setDisplayUseLogoEnabled(boolean);
+    method public void setElevation(float);
+    method public void setHideOffset(int);
+    method public void setHideOnContentScrollEnabled(boolean);
     method public void setHomeActionContentDescription(java.lang.CharSequence);
     method public void setHomeActionContentDescription(int);
     method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
@@ -2665,11 +3188,11 @@
     method public void setHomeButtonEnabled(boolean);
     method public abstract void setIcon(int);
     method public abstract void setIcon(android.graphics.drawable.Drawable);
-    method public abstract void setListNavigationCallbacks(android.widget.SpinnerAdapter, android.app.ActionBar.OnNavigationListener);
+    method public abstract deprecated void setListNavigationCallbacks(android.widget.SpinnerAdapter, android.app.ActionBar.OnNavigationListener);
     method public abstract void setLogo(int);
     method public abstract void setLogo(android.graphics.drawable.Drawable);
-    method public abstract void setNavigationMode(int);
-    method public abstract void setSelectedNavigationItem(int);
+    method public abstract deprecated void setNavigationMode(int);
+    method public abstract deprecated void setSelectedNavigationItem(int);
     method public void setSplitBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setStackedBackgroundDrawable(android.graphics.drawable.Drawable);
     method public abstract void setSubtitle(java.lang.CharSequence);
@@ -2682,9 +3205,9 @@
     field public static final int DISPLAY_SHOW_HOME = 2; // 0x2
     field public static final int DISPLAY_SHOW_TITLE = 8; // 0x8
     field public static final int DISPLAY_USE_LOGO = 1; // 0x1
-    field public static final int NAVIGATION_MODE_LIST = 1; // 0x1
-    field public static final int NAVIGATION_MODE_STANDARD = 0; // 0x0
-    field public static final int NAVIGATION_MODE_TABS = 2; // 0x2
+    field public static final deprecated int NAVIGATION_MODE_LIST = 1; // 0x1
+    field public static final deprecated int NAVIGATION_MODE_STANDARD = 0; // 0x0
+    field public static final deprecated int NAVIGATION_MODE_TABS = 2; // 0x2
   }
 
   public static class ActionBar.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
@@ -2701,11 +3224,11 @@
     method public abstract void onMenuVisibilityChanged(boolean);
   }
 
-  public static abstract interface ActionBar.OnNavigationListener {
+  public static abstract deprecated interface ActionBar.OnNavigationListener {
     method public abstract boolean onNavigationItemSelected(int, long);
   }
 
-  public static abstract class ActionBar.Tab {
+  public static abstract deprecated class ActionBar.Tab {
     ctor public ActionBar.Tab();
     method public abstract java.lang.CharSequence getContentDescription();
     method public abstract android.view.View getCustomView();
@@ -2727,7 +3250,7 @@
     field public static final int INVALID_POSITION = -1; // 0xffffffff
   }
 
-  public static abstract interface ActionBar.TabListener {
+  public static abstract deprecated interface ActionBar.TabListener {
     method public abstract void onTabReselected(android.app.ActionBar.Tab, android.app.FragmentTransaction);
     method public abstract void onTabSelected(android.app.ActionBar.Tab, android.app.FragmentTransaction);
     method public abstract void onTabUnselected(android.app.ActionBar.Tab, android.app.FragmentTransaction);
@@ -2752,6 +3275,8 @@
     method public void finishActivity(int);
     method public void finishActivityFromChild(android.app.Activity, int);
     method public void finishAffinity();
+    method public void finishAfterTransition();
+    method public void finishAndRemoveTask();
     method public void finishFromChild(android.app.Activity);
     method public android.app.ActionBar getActionBar();
     method public final android.app.Application getApplication();
@@ -2759,6 +3284,8 @@
     method public java.lang.String getCallingPackage();
     method public int getChangingConfigurations();
     method public android.content.ComponentName getComponentName();
+    method public android.transition.Scene getContentScene();
+    method public android.transition.TransitionManager getContentTransitionManager();
     method public android.view.View getCurrentFocus();
     method public android.app.FragmentManager getFragmentManager();
     method public android.content.Intent getIntent();
@@ -2766,6 +3293,7 @@
     method public android.view.LayoutInflater getLayoutInflater();
     method public android.app.LoaderManager getLoaderManager();
     method public java.lang.String getLocalClassName();
+    method public final android.media.session.MediaController getMediaController();
     method public android.view.MenuInflater getMenuInflater();
     method public final android.app.Activity getParent();
     method public android.content.Intent getParentActivityIntent();
@@ -2791,6 +3319,7 @@
     method public boolean navigateUpToFromChild(android.app.Activity, android.content.Intent);
     method public void onActionModeFinished(android.view.ActionMode);
     method public void onActionModeStarted(android.view.ActionMode);
+    method public void onActivityReenter(int, android.content.Intent);
     method protected void onActivityResult(int, int, android.content.Intent);
     method public void onAttachFragment(android.app.Fragment);
     method public void onAttachedToWindow();
@@ -2801,6 +3330,7 @@
     method public boolean onContextItemSelected(android.view.MenuItem);
     method public void onContextMenuClosed(android.view.Menu);
     method protected void onCreate(android.os.Bundle);
+    method public void onCreate(android.os.Bundle, android.os.PersistableBundle);
     method public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo);
     method public java.lang.CharSequence onCreateDescription();
     method protected deprecated android.app.Dialog onCreateDialog(int);
@@ -2814,6 +3344,7 @@
     method public android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
     method protected void onDestroy();
     method public void onDetachedFromWindow();
+    method public void onEnterAnimationComplete();
     method public boolean onGenericMotionEvent(android.view.MotionEvent);
     method public boolean onKeyDown(int, android.view.KeyEvent);
     method public boolean onKeyLongPress(int, android.view.KeyEvent);
@@ -2831,6 +3362,7 @@
     method public void onPanelClosed(int, android.view.Menu);
     method protected void onPause();
     method protected void onPostCreate(android.os.Bundle);
+    method public void onPostCreate(android.os.Bundle, android.os.PersistableBundle);
     method protected void onPostResume();
     method protected deprecated void onPrepareDialog(int, android.app.Dialog);
     method protected deprecated void onPrepareDialog(int, android.app.Dialog, android.os.Bundle);
@@ -2840,9 +3372,11 @@
     method public void onProvideAssistData(android.os.Bundle);
     method protected void onRestart();
     method protected void onRestoreInstanceState(android.os.Bundle);
+    method public void onRestoreInstanceState(android.os.Bundle, android.os.PersistableBundle);
     method protected void onResume();
     method public deprecated java.lang.Object onRetainNonConfigurationInstance();
     method protected void onSaveInstanceState(android.os.Bundle);
+    method public void onSaveInstanceState(android.os.Bundle, android.os.PersistableBundle);
     method public boolean onSearchRequested();
     method protected void onStart();
     method protected void onStop();
@@ -2852,22 +3386,30 @@
     method public void onTrimMemory(int);
     method public void onUserInteraction();
     method protected void onUserLeaveHint();
+    method public void onVisibleBehindCanceled();
     method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
     method public void onWindowFocusChanged(boolean);
     method public android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback);
     method public void openContextMenu(android.view.View);
     method public void openOptionsMenu();
     method public void overridePendingTransition(int, int);
+    method public void postponeEnterTransition();
     method public void recreate();
     method public void registerForContextMenu(android.view.View);
+    method public boolean releaseInstance();
     method public final deprecated void removeDialog(int);
     method public void reportFullyDrawn();
+    method public boolean requestVisibleBehind(boolean);
     method public final boolean requestWindowFeature(int);
     method public final void runOnUiThread(java.lang.Runnable);
+    method public void setActionBar(android.widget.Toolbar);
+    method public void setContentTransitionManager(android.transition.TransitionManager);
     method public void setContentView(int);
     method public void setContentView(android.view.View);
     method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public final void setDefaultKeyMode(int);
+    method public void setEnterSharedElementCallback(android.app.SharedElementCallback);
+    method public void setExitSharedElementCallback(android.app.SharedElementCallback);
     method public final void setFeatureDrawable(int, android.graphics.drawable.Drawable);
     method public final void setFeatureDrawableAlpha(int, int);
     method public final void setFeatureDrawableResource(int, int);
@@ -2875,6 +3417,7 @@
     method public void setFinishOnTouchOutside(boolean);
     method public void setImmersive(boolean);
     method public void setIntent(android.content.Intent);
+    method public final void setMediaController(android.media.session.MediaController);
     method public final void setProgress(int);
     method public final void setProgressBarIndeterminate(boolean);
     method public final void setProgressBarIndeterminateVisibility(boolean);
@@ -2883,9 +3426,10 @@
     method public final void setResult(int);
     method public final void setResult(int, android.content.Intent);
     method public final void setSecondaryProgress(int);
+    method public void setTaskDescription(android.app.ActivityManager.TaskDescription);
     method public void setTitle(java.lang.CharSequence);
     method public void setTitle(int);
-    method public void setTitleColor(int);
+    method public deprecated void setTitleColor(int);
     method public void setVisible(boolean);
     method public final void setVolumeControlStream(int);
     method public boolean shouldUpRecreateTask(android.content.Intent);
@@ -2904,10 +3448,13 @@
     method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSenderFromChild(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSenderFromChild(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public void startLockTask();
     method public deprecated void startManagingCursor(android.database.Cursor);
     method public boolean startNextMatchingActivity(android.content.Intent);
     method public boolean startNextMatchingActivity(android.content.Intent, android.os.Bundle);
+    method public void startPostponedEnterTransition();
     method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean);
+    method public void stopLockTask();
     method public deprecated void stopManagingCursor(android.database.Cursor);
     method public void takeKeyEvents(boolean);
     method public void triggerSearch(java.lang.String, android.os.Bundle);
@@ -2931,8 +3478,11 @@
   }
 
   public class ActivityManager {
+    method public int addAppTask(android.app.Activity, android.content.Intent, android.app.ActivityManager.TaskDescription, android.graphics.Bitmap);
     method public boolean clearApplicationUserData();
     method public void dumpPackageState(java.io.FileDescriptor, java.lang.String);
+    method public android.util.Size getAppTaskThumbnailSize();
+    method public java.util.List<android.app.ActivityManager.AppTask> getAppTasks();
     method public android.content.pm.ConfigurationInfo getDeviceConfigurationInfo();
     method public int getLargeMemoryClass();
     method public int getLauncherLargeIconDensity();
@@ -2942,11 +3492,12 @@
     method public static void getMyMemoryState(android.app.ActivityManager.RunningAppProcessInfo);
     method public android.os.Debug.MemoryInfo[] getProcessMemoryInfo(int[]);
     method public java.util.List<android.app.ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState();
-    method public java.util.List<android.app.ActivityManager.RecentTaskInfo> getRecentTasks(int, int) throws java.lang.SecurityException;
+    method public deprecated java.util.List<android.app.ActivityManager.RecentTaskInfo> getRecentTasks(int, int) throws java.lang.SecurityException;
     method public java.util.List<android.app.ActivityManager.RunningAppProcessInfo> getRunningAppProcesses();
     method public android.app.PendingIntent getRunningServiceControlPanel(android.content.ComponentName) throws java.lang.SecurityException;
     method public java.util.List<android.app.ActivityManager.RunningServiceInfo> getRunningServices(int) throws java.lang.SecurityException;
-    method public java.util.List<android.app.ActivityManager.RunningTaskInfo> getRunningTasks(int) throws java.lang.SecurityException;
+    method public deprecated java.util.List<android.app.ActivityManager.RunningTaskInfo> getRunningTasks(int) throws java.lang.SecurityException;
+    method public boolean isInLockTaskMode();
     method public boolean isLowRamDevice();
     method public static boolean isRunningInTestHarness();
     method public static boolean isUserAMonkey();
@@ -2961,6 +3512,14 @@
     field public static final int RECENT_WITH_EXCLUDED = 1; // 0x1
   }
 
+  public static class ActivityManager.AppTask {
+    method public void finishAndRemoveTask();
+    method public android.app.ActivityManager.RecentTaskInfo getTaskInfo();
+    method public void moveToFront();
+    method public void setExcludeFromRecents(boolean);
+    method public void startActivity(android.content.Context, android.content.Intent, android.os.Bundle);
+  }
+
   public static class ActivityManager.MemoryInfo implements android.os.Parcelable {
     ctor public ActivityManager.MemoryInfo();
     method public int describeContents();
@@ -2999,11 +3558,13 @@
     method public void readFromParcel(android.os.Parcel);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
+    field public int affiliatedTaskId;
     field public android.content.Intent baseIntent;
     field public java.lang.CharSequence description;
     field public int id;
     field public android.content.ComponentName origActivity;
     field public int persistentId;
+    field public android.app.ActivityManager.TaskDescription taskDescription;
   }
 
   public static class ActivityManager.RunningAppProcessInfo implements android.os.Parcelable {
@@ -3016,6 +3577,7 @@
     field public static final int IMPORTANCE_BACKGROUND = 400; // 0x190
     field public static final int IMPORTANCE_EMPTY = 500; // 0x1f4
     field public static final int IMPORTANCE_FOREGROUND = 100; // 0x64
+    field public static final int IMPORTANCE_GONE = 1000; // 0x3e8
     field public static final int IMPORTANCE_PERCEPTIBLE = 130; // 0x82
     field public static final int IMPORTANCE_SERVICE = 300; // 0x12c
     field public static final int IMPORTANCE_VISIBLE = 200; // 0xc8
@@ -3075,9 +3637,27 @@
     field public android.content.ComponentName topActivity;
   }
 
+  public static class ActivityManager.TaskDescription implements android.os.Parcelable {
+    ctor public ActivityManager.TaskDescription(java.lang.String, android.graphics.Bitmap, int);
+    ctor public ActivityManager.TaskDescription(java.lang.String, android.graphics.Bitmap);
+    ctor public ActivityManager.TaskDescription(java.lang.String);
+    ctor public ActivityManager.TaskDescription();
+    ctor public ActivityManager.TaskDescription(android.app.ActivityManager.TaskDescription);
+    method public int describeContents();
+    method public android.graphics.Bitmap getIcon();
+    method public java.lang.String getLabel();
+    method public int getPrimaryColor();
+    method public void readFromParcel(android.os.Parcel);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public class ActivityOptions {
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
     method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int);
+    method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.view.View, java.lang.String);
+    method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...);
+    method public static android.app.ActivityOptions makeTaskLaunchBehind();
     method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
@@ -3085,13 +3665,16 @@
 
   public class AlarmManager {
     method public void cancel(android.app.PendingIntent);
+    method public android.app.AlarmManager.AlarmClockInfo getNextAlarmClock();
     method public void set(int, long, android.app.PendingIntent);
+    method public void setAlarmClock(android.app.AlarmManager.AlarmClockInfo, android.app.PendingIntent);
     method public void setExact(int, long, android.app.PendingIntent);
     method public void setInexactRepeating(int, long, long, android.app.PendingIntent);
     method public void setRepeating(int, long, long, android.app.PendingIntent);
     method public void setTime(long);
     method public void setTimeZone(java.lang.String);
     method public void setWindow(int, long, long, android.app.PendingIntent);
+    field public static final java.lang.String ACTION_NEXT_ALARM_CLOCK_CHANGED = "android.app.action.NEXT_ALARM_CLOCK_CHANGED";
     field public static final int ELAPSED_REALTIME = 3; // 0x3
     field public static final int ELAPSED_REALTIME_WAKEUP = 2; // 0x2
     field public static final long INTERVAL_DAY = 86400000L; // 0x5265c00L
@@ -3103,6 +3686,15 @@
     field public static final int RTC_WAKEUP = 0; // 0x0
   }
 
+  public static final class AlarmManager.AlarmClockInfo implements android.os.Parcelable {
+    ctor public AlarmManager.AlarmClockInfo(long, android.app.PendingIntent);
+    method public int describeContents();
+    method public android.app.PendingIntent getShowIntent();
+    method public long getTriggerTime();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public class AlertDialog extends android.app.Dialog implements android.content.DialogInterface {
     ctor protected AlertDialog(android.content.Context);
     ctor protected AlertDialog(android.content.Context, int);
@@ -3168,6 +3760,7 @@
     method public android.app.AlertDialog.Builder setSingleChoiceItems(android.widget.ListAdapter, int, android.content.DialogInterface.OnClickListener);
     method public android.app.AlertDialog.Builder setTitle(int);
     method public android.app.AlertDialog.Builder setTitle(java.lang.CharSequence);
+    method public android.app.AlertDialog.Builder setView(int);
     method public android.app.AlertDialog.Builder setView(android.view.View);
     method public android.app.AlertDialog show();
   }
@@ -3188,10 +3781,12 @@
     method public void startWatchingMode(java.lang.String, java.lang.String, android.app.AppOpsManager.OnOpChangedListener);
     method public void stopWatchingMode(android.app.AppOpsManager.OnOpChangedListener);
     field public static final int MODE_ALLOWED = 0; // 0x0
+    field public static final int MODE_DEFAULT = 3; // 0x3
     field public static final int MODE_ERRORED = 2; // 0x2
     field public static final int MODE_IGNORED = 1; // 0x1
     field public static final java.lang.String OPSTR_COARSE_LOCATION = "android:coarse_location";
     field public static final java.lang.String OPSTR_FINE_LOCATION = "android:fine_location";
+    field public static final java.lang.String OPSTR_GET_USAGE_STATS = "android:get_usage_stats";
     field public static final java.lang.String OPSTR_MONITOR_HIGH_POWER_LOCATION = "android:monitor_location_high_power";
     field public static final java.lang.String OPSTR_MONITOR_LOCATION = "android:monitor_location";
   }
@@ -3317,6 +3912,7 @@
     method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void cancel();
     method public void closeOptionsMenu();
+    method public void create();
     method public void dismiss();
     method public boolean dispatchGenericMotionEvent(android.view.MotionEvent);
     method public boolean dispatchKeyEvent(android.view.KeyEvent);
@@ -3519,14 +4115,22 @@
     method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public final boolean equals(java.lang.Object);
     method public final android.app.Activity getActivity();
+    method public boolean getAllowEnterTransitionOverlap();
+    method public boolean getAllowReturnTransitionOverlap();
     method public final android.os.Bundle getArguments();
     method public final android.app.FragmentManager getChildFragmentManager();
+    method public android.transition.Transition getEnterTransition();
+    method public android.transition.Transition getExitTransition();
     method public final android.app.FragmentManager getFragmentManager();
     method public final int getId();
     method public android.app.LoaderManager getLoaderManager();
     method public final android.app.Fragment getParentFragment();
+    method public android.transition.Transition getReenterTransition();
     method public final android.content.res.Resources getResources();
     method public final boolean getRetainInstance();
+    method public android.transition.Transition getReturnTransition();
+    method public android.transition.Transition getSharedElementEnterTransition();
+    method public android.transition.Transition getSharedElementReturnTransition();
     method public final java.lang.String getString(int);
     method public final java.lang.String getString(int, java.lang.Object...);
     method public final java.lang.String getTag();
@@ -3575,11 +4179,21 @@
     method public void onViewCreated(android.view.View, android.os.Bundle);
     method public void onViewStateRestored(android.os.Bundle);
     method public void registerForContextMenu(android.view.View);
+    method public void setAllowEnterTransitionOverlap(boolean);
+    method public void setAllowReturnTransitionOverlap(boolean);
     method public void setArguments(android.os.Bundle);
+    method public void setEnterSharedElementCallback(android.app.SharedElementCallback);
+    method public void setEnterTransition(android.transition.Transition);
+    method public void setExitSharedElementCallback(android.app.SharedElementCallback);
+    method public void setExitTransition(android.transition.Transition);
     method public void setHasOptionsMenu(boolean);
     method public void setInitialSavedState(android.app.Fragment.SavedState);
     method public void setMenuVisibility(boolean);
+    method public void setReenterTransition(android.transition.Transition);
     method public void setRetainInstance(boolean);
+    method public void setReturnTransition(android.transition.Transition);
+    method public void setSharedElementEnterTransition(android.transition.Transition);
+    method public void setSharedElementReturnTransition(android.transition.Transition);
     method public void setTargetFragment(android.app.Fragment, int);
     method public void setUserVisibleHint(boolean);
     method public void startActivity(android.content.Intent);
@@ -3599,7 +4213,7 @@
     field public static final android.os.Parcelable.ClassLoaderCreator CREATOR;
   }
 
-  public class FragmentBreadCrumbs extends android.view.ViewGroup implements android.app.FragmentManager.OnBackStackChangedListener {
+  public deprecated class FragmentBreadCrumbs extends android.view.ViewGroup implements android.app.FragmentManager.OnBackStackChangedListener {
     ctor public FragmentBreadCrumbs(android.content.Context);
     ctor public FragmentBreadCrumbs(android.content.Context, android.util.AttributeSet);
     ctor public FragmentBreadCrumbs(android.content.Context, android.util.AttributeSet, int);
@@ -3660,6 +4274,7 @@
     method public abstract android.app.FragmentTransaction add(android.app.Fragment, java.lang.String);
     method public abstract android.app.FragmentTransaction add(int, android.app.Fragment);
     method public abstract android.app.FragmentTransaction add(int, android.app.Fragment, java.lang.String);
+    method public abstract android.app.FragmentTransaction addSharedElement(android.view.View, java.lang.String);
     method public abstract android.app.FragmentTransaction addToBackStack(java.lang.String);
     method public abstract android.app.FragmentTransaction attach(android.app.Fragment);
     method public abstract int commit();
@@ -3696,14 +4311,18 @@
     method public android.app.Instrumentation.ActivityMonitor addMonitor(android.content.IntentFilter, android.app.Instrumentation.ActivityResult, boolean);
     method public android.app.Instrumentation.ActivityMonitor addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean);
     method public void callActivityOnCreate(android.app.Activity, android.os.Bundle);
+    method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
     method public void callActivityOnDestroy(android.app.Activity);
     method public void callActivityOnNewIntent(android.app.Activity, android.content.Intent);
     method public void callActivityOnPause(android.app.Activity);
     method public void callActivityOnPostCreate(android.app.Activity, android.os.Bundle);
+    method public void callActivityOnPostCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
     method public void callActivityOnRestart(android.app.Activity);
     method public void callActivityOnRestoreInstanceState(android.app.Activity, android.os.Bundle);
+    method public void callActivityOnRestoreInstanceState(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
     method public void callActivityOnResume(android.app.Activity);
     method public void callActivityOnSaveInstanceState(android.app.Activity, android.os.Bundle);
+    method public void callActivityOnSaveInstanceState(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
     method public void callActivityOnStart(android.app.Activity);
     method public void callActivityOnStop(android.app.Activity);
     method public void callActivityOnUserLeaving(android.app.Activity);
@@ -3780,6 +4399,7 @@
   }
 
   public class KeyguardManager {
+    method public android.content.Intent createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence);
     method public deprecated void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult);
     method public boolean inKeyguardRestrictedInputMode();
     method public boolean isKeyguardLocked();
@@ -3889,6 +4509,7 @@
     ctor public MediaRouteButton(android.content.Context);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int, int);
     method public int getRouteTypes();
     method public void onAttachedToWindow();
     method public void onDetachedFromWindow();
@@ -3920,14 +4541,34 @@
     method public java.lang.String getSortKey();
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
+    field public static final java.lang.String CATEGORY_ALARM = "alarm";
+    field public static final java.lang.String CATEGORY_CALL = "call";
+    field public static final java.lang.String CATEGORY_EMAIL = "email";
+    field public static final java.lang.String CATEGORY_ERROR = "err";
+    field public static final java.lang.String CATEGORY_EVENT = "event";
+    field public static final java.lang.String CATEGORY_MESSAGE = "msg";
+    field public static final java.lang.String CATEGORY_PROGRESS = "progress";
+    field public static final java.lang.String CATEGORY_PROMO = "promo";
+    field public static final java.lang.String CATEGORY_RECOMMENDATION = "recommendation";
+    field public static final java.lang.String CATEGORY_SERVICE = "service";
+    field public static final java.lang.String CATEGORY_SOCIAL = "social";
+    field public static final java.lang.String CATEGORY_STATUS = "status";
+    field public static final java.lang.String CATEGORY_SYSTEM = "sys";
+    field public static final java.lang.String CATEGORY_TRANSPORT = "transport";
+    field public static final int COLOR_DEFAULT = 0; // 0x0
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int DEFAULT_ALL = -1; // 0xffffffff
     field public static final int DEFAULT_LIGHTS = 4; // 0x4
     field public static final int DEFAULT_SOUND = 1; // 0x1
     field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
+    field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
+    field public static final java.lang.String EXTRA_COMPACT_ACTIONS = "android.compactActions";
     field public static final java.lang.String EXTRA_INFO_TEXT = "android.infoText";
     field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
     field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
+    field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
     field public static final java.lang.String EXTRA_PEOPLE = "android.people";
     field public static final java.lang.String EXTRA_PICTURE = "android.picture";
     field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
@@ -3938,6 +4579,7 @@
     field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
     field public static final java.lang.String EXTRA_SUB_TEXT = "android.subText";
     field public static final java.lang.String EXTRA_SUMMARY_TEXT = "android.summaryText";
+    field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
     field public static final java.lang.String EXTRA_TEXT = "android.text";
     field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
     field public static final java.lang.String EXTRA_TITLE = "android.title";
@@ -3952,15 +4594,22 @@
     field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
     field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
     field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final java.lang.String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
     field public static final int PRIORITY_DEFAULT = 0; // 0x0
     field public static final int PRIORITY_HIGH = 1; // 0x1
     field public static final int PRIORITY_LOW = -1; // 0xffffffff
     field public static final int PRIORITY_MAX = 2; // 0x2
     field public static final int PRIORITY_MIN = -2; // 0xfffffffe
-    field public static final int STREAM_DEFAULT = -1; // 0xffffffff
+    field public static final deprecated int STREAM_DEFAULT = -1; // 0xffffffff
+    field public static final int VISIBILITY_PRIVATE = 0; // 0x0
+    field public static final int VISIBILITY_PUBLIC = 1; // 0x1
+    field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
     field public android.app.Notification.Action[] actions;
-    field public int audioStreamType;
+    field public android.media.AudioAttributes audioAttributes;
+    field public deprecated int audioStreamType;
     field public android.widget.RemoteViews bigContentView;
+    field public java.lang.String category;
+    field public int color;
     field public android.app.PendingIntent contentIntent;
     field public android.widget.RemoteViews contentView;
     field public int defaults;
@@ -3968,6 +4617,7 @@
     field public android.os.Bundle extras;
     field public int flags;
     field public android.app.PendingIntent fullScreenIntent;
+    field public android.widget.RemoteViews headsUpContentView;
     field public int icon;
     field public int iconLevel;
     field public android.graphics.Bitmap largeIcon;
@@ -3976,10 +4626,12 @@
     field public int ledOnMS;
     field public int number;
     field public int priority;
+    field public android.app.Notification publicVersion;
     field public android.net.Uri sound;
     field public java.lang.CharSequence tickerText;
-    field public android.widget.RemoteViews tickerView;
+    field public deprecated android.widget.RemoteViews tickerView;
     field public long[] vibrate;
+    field public int visibility;
     field public long when;
   }
 
@@ -4041,11 +4693,14 @@
     method public android.app.Notification.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent);
     method public android.app.Notification.Builder addAction(android.app.Notification.Action);
     method public android.app.Notification.Builder addExtras(android.os.Bundle);
+    method public android.app.Notification.Builder addPerson(java.lang.String);
     method public android.app.Notification build();
     method public android.app.Notification.Builder extend(android.app.Notification.Extender);
     method public android.os.Bundle getExtras();
     method public deprecated android.app.Notification getNotification();
     method public android.app.Notification.Builder setAutoCancel(boolean);
+    method public android.app.Notification.Builder setCategory(java.lang.String);
+    method public android.app.Notification.Builder setColor(int);
     method public android.app.Notification.Builder setContent(android.widget.RemoteViews);
     method public android.app.Notification.Builder setContentInfo(java.lang.CharSequence);
     method public android.app.Notification.Builder setContentIntent(android.app.PendingIntent);
@@ -4065,18 +4720,21 @@
     method public android.app.Notification.Builder setOnlyAlertOnce(boolean);
     method public android.app.Notification.Builder setPriority(int);
     method public android.app.Notification.Builder setProgress(int, int, boolean);
+    method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
     method public android.app.Notification.Builder setShowWhen(boolean);
     method public android.app.Notification.Builder setSmallIcon(int);
     method public android.app.Notification.Builder setSmallIcon(int, int);
     method public android.app.Notification.Builder setSortKey(java.lang.String);
     method public android.app.Notification.Builder setSound(android.net.Uri);
-    method public android.app.Notification.Builder setSound(android.net.Uri, int);
+    method public deprecated android.app.Notification.Builder setSound(android.net.Uri, int);
+    method public android.app.Notification.Builder setSound(android.net.Uri, android.media.AudioAttributes);
     method public android.app.Notification.Builder setStyle(android.app.Notification.Style);
     method public android.app.Notification.Builder setSubText(java.lang.CharSequence);
     method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
-    method public android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
+    method public deprecated android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
     method public android.app.Notification.Builder setUsesChronometer(boolean);
     method public android.app.Notification.Builder setVibrate(long[]);
+    method public android.app.Notification.Builder setVisibility(int);
     method public android.app.Notification.Builder setWhen(long);
   }
 
@@ -4092,6 +4750,13 @@
     method public android.app.Notification.InboxStyle setSummaryText(java.lang.CharSequence);
   }
 
+  public static class Notification.MediaStyle extends android.app.Notification.Style {
+    ctor public Notification.MediaStyle();
+    ctor public Notification.MediaStyle(android.app.Notification.Builder);
+    method public android.app.Notification.MediaStyle setMediaSession(android.media.session.MediaSession.Token);
+    method public android.app.Notification.MediaStyle setShowActionsInCompactView(int...);
+  }
+
   public static abstract class Notification.Style {
     ctor public Notification.Style();
     method public android.app.Notification build();
@@ -4288,6 +4953,9 @@
     field public static final int MENU_KEYCODE = 47; // 0x2f
     field public static final java.lang.String QUERY = "query";
     field public static final java.lang.String SHORTCUT_MIME_TYPE = "vnd.android.cursor.item/vnd.android.search.suggest";
+    field public static final java.lang.String SUGGEST_COLUMN_AUDIO_CHANNEL_CONFIG = "suggest_audio_channel_config";
+    field public static final java.lang.String SUGGEST_COLUMN_CONTENT_TYPE = "suggest_content_type";
+    field public static final java.lang.String SUGGEST_COLUMN_DURATION = "suggest_duration";
     field public static final java.lang.String SUGGEST_COLUMN_FLAGS = "suggest_flags";
     field public static final java.lang.String SUGGEST_COLUMN_FORMAT = "suggest_format";
     field public static final java.lang.String SUGGEST_COLUMN_ICON_1 = "suggest_icon_1";
@@ -4296,13 +4964,22 @@
     field public static final java.lang.String SUGGEST_COLUMN_INTENT_DATA = "suggest_intent_data";
     field public static final java.lang.String SUGGEST_COLUMN_INTENT_DATA_ID = "suggest_intent_data_id";
     field public static final java.lang.String SUGGEST_COLUMN_INTENT_EXTRA_DATA = "suggest_intent_extra_data";
+    field public static final java.lang.String SUGGEST_COLUMN_IS_LIVE = "suggest_is_live";
     field public static final java.lang.String SUGGEST_COLUMN_LAST_ACCESS_HINT = "suggest_last_access_hint";
+    field public static final java.lang.String SUGGEST_COLUMN_PRODUCTION_YEAR = "suggest_production_year";
+    field public static final java.lang.String SUGGEST_COLUMN_PURCHASE_PRICE = "suggest_purchase_price";
     field public static final java.lang.String SUGGEST_COLUMN_QUERY = "suggest_intent_query";
+    field public static final java.lang.String SUGGEST_COLUMN_RATING_SCORE = "suggest_rating_score";
+    field public static final java.lang.String SUGGEST_COLUMN_RATING_STYLE = "suggest_rating_style";
+    field public static final java.lang.String SUGGEST_COLUMN_RENTAL_PRICE = "suggest_rental_price";
+    field public static final java.lang.String SUGGEST_COLUMN_RESULT_CARD_IMAGE = "suggest_result_card_image";
     field public static final java.lang.String SUGGEST_COLUMN_SHORTCUT_ID = "suggest_shortcut_id";
     field public static final java.lang.String SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING = "suggest_spinner_while_refreshing";
     field public static final java.lang.String SUGGEST_COLUMN_TEXT_1 = "suggest_text_1";
     field public static final java.lang.String SUGGEST_COLUMN_TEXT_2 = "suggest_text_2";
     field public static final java.lang.String SUGGEST_COLUMN_TEXT_2_URL = "suggest_text_2_url";
+    field public static final java.lang.String SUGGEST_COLUMN_VIDEO_HEIGHT = "suggest_video_height";
+    field public static final java.lang.String SUGGEST_COLUMN_VIDEO_WIDTH = "suggest_video_width";
     field public static final java.lang.String SUGGEST_MIME_TYPE = "vnd.android.cursor.dir/vnd.android.search.suggest";
     field public static final java.lang.String SUGGEST_NEVER_MAKE_SHORTCUT = "_-1";
     field public static final java.lang.String SUGGEST_PARAMETER_LIMIT = "limit";
@@ -4378,6 +5055,16 @@
     field public static final int START_STICKY_COMPATIBILITY = 0; // 0x0
   }
 
+  public abstract class SharedElementCallback {
+    ctor public SharedElementCallback();
+    method public android.os.Parcelable onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF);
+    method public android.view.View onCreateSnapshotView(android.content.Context, android.os.Parcelable);
+    method public void onMapSharedElements(java.util.List<java.lang.String>, java.util.Map<java.lang.String, android.view.View>);
+    method public void onRejectSharedElements(java.util.List<android.view.View>);
+    method public void onSharedElementEnd(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
+    method public void onSharedElementStart(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
+  }
+
   public deprecated class TabActivity extends android.app.ActivityGroup {
     ctor public TabActivity();
     method public android.widget.TabHost getTabHost();
@@ -4415,9 +5102,16 @@
   }
 
   public final class UiAutomation {
+    method public void clearWindowAnimationFrameStats();
+    method public boolean clearWindowContentFrameStats(int);
     method public android.view.accessibility.AccessibilityEvent executeAndWaitForEvent(java.lang.Runnable, android.app.UiAutomation.AccessibilityEventFilter, long) throws java.util.concurrent.TimeoutException;
+    method public android.os.ParcelFileDescriptor executeShellCommand(java.lang.String);
+    method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
     method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
+    method public android.view.WindowAnimationFrameStats getWindowAnimationFrameStats();
+    method public android.view.WindowContentFrameStats getWindowContentFrameStats(int);
+    method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
     method public boolean injectInputEvent(android.view.InputEvent, boolean);
     method public final boolean performGlobalAction(int);
     method public void setOnAccessibilityEventListener(android.app.UiAutomation.OnAccessibilityEventListener);
@@ -4453,6 +5147,7 @@
     field public static java.lang.String ACTION_EXIT_CAR_MODE;
     field public static java.lang.String ACTION_EXIT_DESK_MODE;
     field public static final int DISABLE_CAR_MODE_GO_HOME = 1; // 0x1
+    field public static final int ENABLE_CAR_MODE_ALLOW_SLEEP = 2; // 0x2
     field public static final int ENABLE_CAR_MODE_GO_CAR_HOME = 1; // 0x1
     field public static final int MODE_NIGHT_AUTO = 0; // 0x0
     field public static final int MODE_NIGHT_NO = 1; // 0x1
@@ -4548,26 +5243,51 @@
     method public java.lang.CharSequence onDisableRequested(android.content.Context, android.content.Intent);
     method public void onDisabled(android.content.Context, android.content.Intent);
     method public void onEnabled(android.content.Context, android.content.Intent);
+    method public void onLockTaskModeEntering(android.content.Context, android.content.Intent, java.lang.String);
+    method public void onLockTaskModeExiting(android.content.Context, android.content.Intent);
     method public void onPasswordChanged(android.content.Context, android.content.Intent);
     method public void onPasswordExpiring(android.content.Context, android.content.Intent);
     method public void onPasswordFailed(android.content.Context, android.content.Intent);
     method public void onPasswordSucceeded(android.content.Context, android.content.Intent);
+    method public void onProfileProvisioningComplete(android.content.Context, android.content.Intent);
     method public void onReceive(android.content.Context, android.content.Intent);
     field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED";
     field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
     field public static final java.lang.String ACTION_DEVICE_ADMIN_ENABLED = "android.app.action.DEVICE_ADMIN_ENABLED";
+    field public static final java.lang.String ACTION_LOCK_TASK_ENTERING = "android.app.action.LOCK_TASK_ENTERING";
+    field public static final java.lang.String ACTION_LOCK_TASK_EXITING = "android.app.action.LOCK_TASK_EXITING";
     field public static final java.lang.String ACTION_PASSWORD_CHANGED = "android.app.action.ACTION_PASSWORD_CHANGED";
     field public static final java.lang.String ACTION_PASSWORD_EXPIRING = "android.app.action.ACTION_PASSWORD_EXPIRING";
     field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED";
     field public static final java.lang.String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
+    field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.PROFILE_PROVISIONING_COMPLETE";
     field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
     field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
+    field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
   }
 
   public class DevicePolicyManager {
+    method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
+    method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
+    method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
+    method public void addUserRestriction(android.content.ComponentName, java.lang.String);
+    method public void clearCrossProfileIntentFilters(android.content.ComponentName);
+    method public void clearDeviceOwnerApp(java.lang.String);
+    method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
+    method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
+    method public android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+    method public android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
+    method public void enableSystemApp(android.content.ComponentName, java.lang.String);
+    method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
+    method public java.lang.String[] getAccountTypesWithManagementDisabled();
     method public java.util.List<android.content.ComponentName> getActiveAdmins();
+    method public android.os.Bundle getApplicationRestrictions(android.content.ComponentName, java.lang.String);
+    method public boolean getAutoTimeRequired();
     method public boolean getCameraDisabled(android.content.ComponentName);
+    method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
+    method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
     method public int getCurrentFailedPasswordAttempts();
+    method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
     method public int getKeyguardDisabledFeatures(android.content.ComponentName);
     method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
     method public long getMaximumTimeToLock(android.content.ComponentName);
@@ -4583,17 +5303,38 @@
     method public int getPasswordMinimumSymbols(android.content.ComponentName);
     method public int getPasswordMinimumUpperCase(android.content.ComponentName);
     method public int getPasswordQuality(android.content.ComponentName);
+    method public java.util.List<java.lang.String> getPermittedAccessibilityServices(android.content.ComponentName);
+    method public java.util.List<java.lang.String> getPermittedInputMethods(android.content.ComponentName);
+    method public boolean getScreenCaptureDisabled(android.content.ComponentName);
     method public boolean getStorageEncryption(android.content.ComponentName);
     method public int getStorageEncryptionStatus();
+    method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
     method public boolean hasGrantedPolicy(android.content.ComponentName, int);
+    method public boolean installCaCert(android.content.ComponentName, byte[]);
+    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
     method public boolean isActivePasswordSufficient();
     method public boolean isAdminActive(android.content.ComponentName);
+    method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String);
     method public boolean isDeviceOwnerApp(java.lang.String);
+    method public boolean isLockTaskPermitted(java.lang.String);
+    method public boolean isMasterVolumeMuted(android.content.ComponentName);
+    method public boolean isProfileOwnerApp(java.lang.String);
+    method public boolean isUninstallBlocked(android.content.ComponentName, java.lang.String);
     method public void lockNow();
     method public void removeActiveAdmin(android.content.ComponentName);
+    method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
+    method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
     method public boolean resetPassword(java.lang.String, int);
+    method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
+    method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
+    method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
+    method public void setAutoTimeRequired(android.content.ComponentName, boolean);
     method public void setCameraDisabled(android.content.ComponentName, boolean);
+    method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
+    method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
     method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
+    method public void setLockTaskPackages(android.content.ComponentName, java.lang.String[]) throws java.lang.SecurityException;
+    method public void setMasterVolumeMuted(android.content.ComponentName, boolean);
     method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
     method public void setMaximumTimeToLock(android.content.ComponentName, long);
     method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
@@ -4606,9 +5347,22 @@
     method public void setPasswordMinimumSymbols(android.content.ComponentName, int);
     method public void setPasswordMinimumUpperCase(android.content.ComponentName, int);
     method public void setPasswordQuality(android.content.ComponentName, int);
+    method public boolean setPermittedAccessibilityServices(android.content.ComponentName, java.util.List<java.lang.String>);
+    method public boolean setPermittedInputMethods(android.content.ComponentName, java.util.List<java.lang.String>);
+    method public void setProfileEnabled(android.content.ComponentName);
+    method public void setProfileName(android.content.ComponentName, java.lang.String);
+    method public void setRecommendedGlobalProxy(android.content.ComponentName, android.net.ProxyInfo);
+    method public void setRestrictionsProvider(android.content.ComponentName, android.content.ComponentName);
+    method public void setScreenCaptureDisabled(android.content.ComponentName, boolean);
+    method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String);
     method public int setStorageEncryption(android.content.ComponentName, boolean);
+    method public void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
+    method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
+    method public void uninstallAllUserCaCerts(android.content.ComponentName);
+    method public void uninstallCaCert(android.content.ComponentName, byte[]);
     method public void wipeData(int);
     field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
+    field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE";
     field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
     field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
     field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
@@ -4617,15 +5371,40 @@
     field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0
     field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
     field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
+    field public static final java.lang.String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE = "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
+    field public static final java.lang.String EXTRA_PROVISIONING_EMAIL_ADDRESS = "android.app.extra.PROVISIONING_EMAIL_ADDRESS";
+    field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
+    field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME";
+    field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PAC_URL = "android.app.extra.PROVISIONING_WIFI_PAC_URL";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PASSWORD = "android.app.extra.PROVISIONING_WIFI_PASSWORD";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PROXY_BYPASS = "android.app.extra.PROVISIONING_WIFI_PROXY_BYPASS";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PROXY_HOST = "android.app.extra.PROVISIONING_WIFI_PROXY_HOST";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PROXY_PORT = "android.app.extra.PROVISIONING_WIFI_PROXY_PORT";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE = "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_SSID = "android.app.extra.PROVISIONING_WIFI_SSID";
+    field public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 2; // 0x2
+    field public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 1; // 0x1
     field public static final int KEYGUARD_DISABLE_FEATURES_ALL = 2147483647; // 0x7fffffff
     field public static final int KEYGUARD_DISABLE_FEATURES_NONE = 0; // 0x0
+    field public static final int KEYGUARD_DISABLE_FINGERPRINT = 32; // 0x20
     field public static final int KEYGUARD_DISABLE_SECURE_CAMERA = 2; // 0x2
+    field public static final int KEYGUARD_DISABLE_SECURE_NOTIFICATIONS = 4; // 0x4
+    field public static final int KEYGUARD_DISABLE_TRUST_AGENTS = 16; // 0x10
+    field public static final int KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS = 8; // 0x8
     field public static final int KEYGUARD_DISABLE_WIDGETS_ALL = 1; // 0x1
+    field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning";
     field public static final int PASSWORD_QUALITY_ALPHABETIC = 262144; // 0x40000
     field public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680; // 0x50000
     field public static final int PASSWORD_QUALITY_BIOMETRIC_WEAK = 32768; // 0x8000
     field public static final int PASSWORD_QUALITY_COMPLEX = 393216; // 0x60000
     field public static final int PASSWORD_QUALITY_NUMERIC = 131072; // 0x20000
+    field public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 196608; // 0x30000
     field public static final int PASSWORD_QUALITY_SOMETHING = 65536; // 0x10000
     field public static final int PASSWORD_QUALITY_UNSPECIFIED = 0; // 0x0
     field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
@@ -4645,6 +5424,7 @@
     method public void onFullBackup(android.app.backup.FullBackupDataOutput) throws java.io.IOException;
     method public abstract void onRestore(android.app.backup.BackupDataInput, int, android.os.ParcelFileDescriptor) throws java.io.IOException;
     method public void onRestoreFile(android.os.ParcelFileDescriptor, long, java.io.File, int, long, long) throws java.io.IOException;
+    method public void onRestoreFinished();
     field public static final int TYPE_DIRECTORY = 2; // 0x2
     field public static final int TYPE_FILE = 1; // 0x1
   }
@@ -4716,6 +5496,142 @@
 
 }
 
+package android.app.job {
+
+  public class JobInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getBackoffPolicy();
+    method public android.os.PersistableBundle getExtras();
+    method public int getId();
+    method public long getInitialBackoffMillis();
+    method public long getIntervalMillis();
+    method public long getMaxExecutionDelayMillis();
+    method public long getMinLatencyMillis();
+    method public int getNetworkType();
+    method public android.content.ComponentName getService();
+    method public boolean isPeriodic();
+    method public boolean isPersisted();
+    method public boolean isRequireCharging();
+    method public boolean isRequireDeviceIdle();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int BACKOFF_POLICY_EXPONENTIAL = 1; // 0x1
+    field public static final int BACKOFF_POLICY_LINEAR = 0; // 0x0
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final long DEFAULT_INITIAL_BACKOFF_MILLIS = 30000L; // 0x7530L
+    field public static final long MAX_BACKOFF_DELAY_MILLIS = 18000000L; // 0x112a880L
+    field public static final int NETWORK_TYPE_ANY = 1; // 0x1
+    field public static final int NETWORK_TYPE_NONE = 0; // 0x0
+    field public static final int NETWORK_TYPE_UNMETERED = 2; // 0x2
+  }
+
+  public static final class JobInfo.Builder {
+    ctor public JobInfo.Builder(int, android.content.ComponentName);
+    method public android.app.job.JobInfo build();
+    method public android.app.job.JobInfo.Builder setBackoffCriteria(long, int);
+    method public android.app.job.JobInfo.Builder setExtras(android.os.PersistableBundle);
+    method public android.app.job.JobInfo.Builder setMinimumLatency(long);
+    method public android.app.job.JobInfo.Builder setOverrideDeadline(long);
+    method public android.app.job.JobInfo.Builder setPeriodic(long);
+    method public android.app.job.JobInfo.Builder setPersisted(boolean);
+    method public android.app.job.JobInfo.Builder setRequiredNetworkType(int);
+    method public android.app.job.JobInfo.Builder setRequiresCharging(boolean);
+    method public android.app.job.JobInfo.Builder setRequiresDeviceIdle(boolean);
+  }
+
+  public class JobParameters implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.os.PersistableBundle getExtras();
+    method public int getJobId();
+    method public boolean isOverrideDeadlineExpired();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public abstract class JobScheduler {
+    ctor public JobScheduler();
+    method public abstract void cancel(int);
+    method public abstract void cancelAll();
+    method public abstract java.util.List<android.app.job.JobInfo> getAllPendingJobs();
+    method public abstract int schedule(android.app.job.JobInfo);
+    field public static final int RESULT_FAILURE = 0; // 0x0
+    field public static final int RESULT_SUCCESS = 1; // 0x1
+  }
+
+  public abstract class JobService extends android.app.Service {
+    ctor public JobService();
+    method public final void jobFinished(android.app.job.JobParameters, boolean);
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public abstract boolean onStartJob(android.app.job.JobParameters);
+    method public abstract boolean onStopJob(android.app.job.JobParameters);
+    field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_JOB_SERVICE";
+  }
+
+}
+
+package android.app.usage {
+
+  public final class ConfigurationStats implements android.os.Parcelable {
+    ctor public ConfigurationStats(android.app.usage.ConfigurationStats);
+    method public int describeContents();
+    method public int getActivationCount();
+    method public android.content.res.Configuration getConfiguration();
+    method public long getFirstTimeStamp();
+    method public long getLastTimeActive();
+    method public long getLastTimeStamp();
+    method public long getTotalTimeActive();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public final class UsageEvents implements android.os.Parcelable {
+    method public int describeContents();
+    method public boolean getNextEvent(android.app.usage.UsageEvents.Event);
+    method public boolean hasNextEvent();
+    method public void resetToStart();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static final class UsageEvents.Event {
+    ctor public UsageEvents.Event();
+    method public java.lang.String getClassName();
+    method public android.content.res.Configuration getConfiguration();
+    method public int getEventType();
+    method public java.lang.String getPackageName();
+    method public long getTimeStamp();
+    field public static final int CONFIGURATION_CHANGE = 5; // 0x5
+    field public static final int MOVE_TO_BACKGROUND = 2; // 0x2
+    field public static final int MOVE_TO_FOREGROUND = 1; // 0x1
+    field public static final int NONE = 0; // 0x0
+  }
+
+  public final class UsageStats implements android.os.Parcelable {
+    ctor public UsageStats(android.app.usage.UsageStats);
+    method public void add(android.app.usage.UsageStats);
+    method public int describeContents();
+    method public long getFirstTimeStamp();
+    method public long getLastTimeStamp();
+    method public long getLastTimeUsed();
+    method public java.lang.String getPackageName();
+    method public long getTotalTimeInForeground();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public final class UsageStatsManager {
+    method public java.util.Map<java.lang.String, android.app.usage.UsageStats> queryAndAggregateUsageStats(long, long);
+    method public java.util.List<android.app.usage.ConfigurationStats> queryConfigurations(int, long, long);
+    method public android.app.usage.UsageEvents queryEvents(long, long);
+    method public java.util.List<android.app.usage.UsageStats> queryUsageStats(int, long, long);
+    field public static final int INTERVAL_BEST = 4; // 0x4
+    field public static final int INTERVAL_DAILY = 0; // 0x0
+    field public static final int INTERVAL_MONTHLY = 2; // 0x2
+    field public static final int INTERVAL_WEEKLY = 1; // 0x1
+    field public static final int INTERVAL_YEARLY = 3; // 0x3
+  }
+
+}
+
 package android.appwidget {
 
   public class AppWidgetHost {
@@ -4729,6 +5645,7 @@
     method protected android.appwidget.AppWidgetHostView onCreateView(android.content.Context, int, android.appwidget.AppWidgetProviderInfo);
     method protected void onProviderChanged(int, android.appwidget.AppWidgetProviderInfo);
     method protected void onProvidersChanged();
+    method public final void startAppWidgetConfigureActivityForResult(android.app.Activity, int, int, int, android.os.Bundle);
     method public void startListening();
     method public void stopListening();
   }
@@ -4751,10 +5668,12 @@
   public class AppWidgetManager {
     method public boolean bindAppWidgetIdIfAllowed(int, android.content.ComponentName);
     method public boolean bindAppWidgetIdIfAllowed(int, android.content.ComponentName, android.os.Bundle);
+    method public boolean bindAppWidgetIdIfAllowed(int, android.os.UserHandle, android.content.ComponentName, android.os.Bundle);
     method public int[] getAppWidgetIds(android.content.ComponentName);
     method public android.appwidget.AppWidgetProviderInfo getAppWidgetInfo(int);
     method public android.os.Bundle getAppWidgetOptions(int);
     method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProviders();
+    method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProvidersForProfile(android.os.UserHandle);
     method public static android.appwidget.AppWidgetManager getInstance(android.content.Context);
     method public void notifyAppWidgetViewDataChanged(int[], int);
     method public void notifyAppWidgetViewDataChanged(int, int);
@@ -4769,15 +5688,20 @@
     field public static final java.lang.String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
     field public static final java.lang.String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
     field public static final java.lang.String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
+    field public static final java.lang.String ACTION_APPWIDGET_HOST_RESTORED = "android.appwidget.action.APPWIDGET_HOST_RESTORED";
     field public static final java.lang.String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
     field public static final java.lang.String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
+    field public static final java.lang.String ACTION_APPWIDGET_RESTORED = "android.appwidget.action.APPWIDGET_RESTORED";
     field public static final java.lang.String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
     field public static final java.lang.String EXTRA_APPWIDGET_ID = "appWidgetId";
     field public static final java.lang.String EXTRA_APPWIDGET_IDS = "appWidgetIds";
+    field public static final java.lang.String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
     field public static final java.lang.String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions";
     field public static final java.lang.String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider";
+    field public static final java.lang.String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile";
     field public static final java.lang.String EXTRA_CUSTOM_EXTRAS = "customExtras";
     field public static final java.lang.String EXTRA_CUSTOM_INFO = "customInfo";
+    field public static final java.lang.String EXTRA_HOST_ID = "hostId";
     field public static final int INVALID_APPWIDGET_ID = 0; // 0x0
     field public static final java.lang.String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
     field public static final java.lang.String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
@@ -4794,6 +5718,7 @@
     method public void onDisabled(android.content.Context);
     method public void onEnabled(android.content.Context);
     method public void onReceive(android.content.Context, android.content.Intent);
+    method public void onRestored(android.content.Context, int[], int[]);
     method public void onUpdate(android.content.Context, android.appwidget.AppWidgetManager, int[]);
   }
 
@@ -4802,6 +5727,10 @@
     ctor public AppWidgetProviderInfo(android.os.Parcel);
     method public android.appwidget.AppWidgetProviderInfo clone();
     method public int describeContents();
+    method public final android.os.UserHandle getProfile();
+    method public final android.graphics.drawable.Drawable loadIcon(android.content.Context, int);
+    method public final java.lang.String loadLabel(android.content.pm.PackageManager);
+    method public final android.graphics.drawable.Drawable loadPreviewImage(android.content.Context, int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int RESIZE_BOTH = 3; // 0x3
@@ -4810,12 +5739,13 @@
     field public static final int RESIZE_VERTICAL = 2; // 0x2
     field public static final int WIDGET_CATEGORY_HOME_SCREEN = 1; // 0x1
     field public static final int WIDGET_CATEGORY_KEYGUARD = 2; // 0x2
+    field public static final int WIDGET_CATEGORY_SEARCHBOX = 4; // 0x4
     field public int autoAdvanceViewId;
     field public android.content.ComponentName configure;
     field public int icon;
     field public int initialKeyguardLayout;
     field public int initialLayout;
-    field public java.lang.String label;
+    field public deprecated java.lang.String label;
     field public int minHeight;
     field public int minResizeHeight;
     field public int minResizeWidth;
@@ -4850,6 +5780,8 @@
     method public boolean disable();
     method public boolean enable();
     method public java.lang.String getAddress();
+    method public android.bluetooth.le.BluetoothLeAdvertiser getBluetoothLeAdvertiser();
+    method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
     method public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices();
     method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
     method public java.lang.String getName();
@@ -4861,13 +5793,16 @@
     method public int getState();
     method public boolean isDiscovering();
     method public boolean isEnabled();
+    method public boolean isMultipleAdvertisementSupported();
+    method public boolean isOffloadedFilteringSupported();
+    method public boolean isOffloadedScanBatchingSupported();
     method public android.bluetooth.BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(java.lang.String, java.util.UUID) throws java.io.IOException;
     method public android.bluetooth.BluetoothServerSocket listenUsingRfcommWithServiceRecord(java.lang.String, java.util.UUID) throws java.io.IOException;
     method public boolean setName(java.lang.String);
     method public boolean startDiscovery();
-    method public boolean startLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback);
-    method public boolean startLeScan(java.util.UUID[], android.bluetooth.BluetoothAdapter.LeScanCallback);
-    method public void stopLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback);
+    method public deprecated boolean startLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback);
+    method public deprecated boolean startLeScan(java.util.UUID[], android.bluetooth.BluetoothAdapter.LeScanCallback);
+    method public deprecated void stopLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback);
     field public static final java.lang.String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";
     field public static final java.lang.String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED";
     field public static final java.lang.String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";
@@ -5288,9 +6223,15 @@
     method public boolean readCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
     method public boolean readDescriptor(android.bluetooth.BluetoothGattDescriptor);
     method public boolean readRemoteRssi();
+    method public boolean requestConnectionPriority(int);
+    method public boolean requestMtu(int);
     method public boolean setCharacteristicNotification(android.bluetooth.BluetoothGattCharacteristic, boolean);
     method public boolean writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
     method public boolean writeDescriptor(android.bluetooth.BluetoothGattDescriptor);
+    field public static final int CONNECTION_PRIORITY_BALANCED = 0; // 0x0
+    field public static final int CONNECTION_PRIORITY_HIGH = 1; // 0x1
+    field public static final int CONNECTION_PRIORITY_LOW_POWER = 2; // 0x2
+    field public static final int GATT_CONNECTION_CONGESTED = 143; // 0x8f
     field public static final int GATT_FAILURE = 257; // 0x101
     field public static final int GATT_INSUFFICIENT_AUTHENTICATION = 5; // 0x5
     field public static final int GATT_INSUFFICIENT_ENCRYPTION = 15; // 0xf
@@ -5310,6 +6251,7 @@
     method public void onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int);
     method public void onDescriptorRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
     method public void onDescriptorWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
+    method public void onMtuChanged(android.bluetooth.BluetoothGatt, int, int);
     method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int);
     method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int);
     method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int);
@@ -5409,6 +6351,7 @@
     method public void onDescriptorReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattDescriptor);
     method public void onDescriptorWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattDescriptor, boolean, boolean, int, byte[]);
     method public void onExecuteWrite(android.bluetooth.BluetoothDevice, int, boolean);
+    method public void onNotificationSent(android.bluetooth.BluetoothDevice, int);
     method public void onServiceAdded(int, android.bluetooth.BluetoothGattService);
   }
 
@@ -5539,6 +6482,166 @@
 
 }
 
+package android.bluetooth.le {
+
+  public abstract class AdvertiseCallback {
+    ctor public AdvertiseCallback();
+    method public void onStartFailure(int);
+    method public void onStartSuccess(android.bluetooth.le.AdvertiseSettings);
+    field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
+    field public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1; // 0x1
+    field public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; // 0x5
+    field public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; // 0x4
+    field public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; // 0x2
+  }
+
+  public final class AdvertiseData implements android.os.Parcelable {
+    method public int describeContents();
+    method public boolean getIncludeDeviceName();
+    method public boolean getIncludeTxPowerLevel();
+    method public android.util.SparseArray<byte[]> getManufacturerSpecificData();
+    method public java.util.Map<android.os.ParcelUuid, byte[]> getServiceData();
+    method public java.util.List<android.os.ParcelUuid> getServiceUuids();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static final class AdvertiseData.Builder {
+    ctor public AdvertiseData.Builder();
+    method public android.bluetooth.le.AdvertiseData.Builder addManufacturerData(int, byte[]);
+    method public android.bluetooth.le.AdvertiseData.Builder addServiceData(android.os.ParcelUuid, byte[]);
+    method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid);
+    method public android.bluetooth.le.AdvertiseData build();
+    method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean);
+    method public android.bluetooth.le.AdvertiseData.Builder setIncludeTxPowerLevel(boolean);
+  }
+
+  public final class AdvertiseSettings implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getMode();
+    method public int getTimeout();
+    method public int getTxPowerLevel();
+    method public boolean isConnectable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int ADVERTISE_MODE_BALANCED = 1; // 0x1
+    field public static final int ADVERTISE_MODE_LOW_LATENCY = 2; // 0x2
+    field public static final int ADVERTISE_MODE_LOW_POWER = 0; // 0x0
+    field public static final int ADVERTISE_TX_POWER_HIGH = 3; // 0x3
+    field public static final int ADVERTISE_TX_POWER_LOW = 1; // 0x1
+    field public static final int ADVERTISE_TX_POWER_MEDIUM = 2; // 0x2
+    field public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0; // 0x0
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static final class AdvertiseSettings.Builder {
+    ctor public AdvertiseSettings.Builder();
+    method public android.bluetooth.le.AdvertiseSettings build();
+    method public android.bluetooth.le.AdvertiseSettings.Builder setAdvertiseMode(int);
+    method public android.bluetooth.le.AdvertiseSettings.Builder setConnectable(boolean);
+    method public android.bluetooth.le.AdvertiseSettings.Builder setTimeout(int);
+    method public android.bluetooth.le.AdvertiseSettings.Builder setTxPowerLevel(int);
+  }
+
+  public final class BluetoothLeAdvertiser {
+    method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
+    method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
+    method public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
+  }
+
+  public final class BluetoothLeScanner {
+    method public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
+    method public void startScan(android.bluetooth.le.ScanCallback);
+    method public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
+    method public void stopScan(android.bluetooth.le.ScanCallback);
+  }
+
+  public abstract class ScanCallback {
+    ctor public ScanCallback();
+    method public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult>);
+    method public void onScanFailed(int);
+    method public void onScanResult(int, android.bluetooth.le.ScanResult);
+    field public static final int SCAN_FAILED_ALREADY_STARTED = 1; // 0x1
+    field public static final int SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = 2; // 0x2
+    field public static final int SCAN_FAILED_FEATURE_UNSUPPORTED = 4; // 0x4
+    field public static final int SCAN_FAILED_INTERNAL_ERROR = 3; // 0x3
+  }
+
+  public final class ScanFilter implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.lang.String getDeviceAddress();
+    method public java.lang.String getDeviceName();
+    method public byte[] getManufacturerData();
+    method public byte[] getManufacturerDataMask();
+    method public int getManufacturerId();
+    method public byte[] getServiceData();
+    method public byte[] getServiceDataMask();
+    method public android.os.ParcelUuid getServiceDataUuid();
+    method public android.os.ParcelUuid getServiceUuid();
+    method public android.os.ParcelUuid getServiceUuidMask();
+    method public boolean matches(android.bluetooth.le.ScanResult);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static final class ScanFilter.Builder {
+    ctor public ScanFilter.Builder();
+    method public android.bluetooth.le.ScanFilter build();
+    method public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(java.lang.String);
+    method public android.bluetooth.le.ScanFilter.Builder setDeviceName(java.lang.String);
+    method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[]);
+    method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[], byte[]);
+    method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[]);
+    method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[], byte[]);
+    method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid);
+    method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
+  }
+
+  public final class ScanRecord {
+    method public int getAdvertiseFlags();
+    method public byte[] getBytes();
+    method public java.lang.String getDeviceName();
+    method public android.util.SparseArray<byte[]> getManufacturerSpecificData();
+    method public byte[] getManufacturerSpecificData(int);
+    method public java.util.Map<android.os.ParcelUuid, byte[]> getServiceData();
+    method public byte[] getServiceData(android.os.ParcelUuid);
+    method public java.util.List<android.os.ParcelUuid> getServiceUuids();
+    method public int getTxPowerLevel();
+  }
+
+  public final class ScanResult implements android.os.Parcelable {
+    ctor public ScanResult(android.bluetooth.BluetoothDevice, android.bluetooth.le.ScanRecord, int, long);
+    method public int describeContents();
+    method public android.bluetooth.BluetoothDevice getDevice();
+    method public int getRssi();
+    method public android.bluetooth.le.ScanRecord getScanRecord();
+    method public long getTimestampNanos();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public final class ScanSettings implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getCallbackType();
+    method public long getReportDelayMillis();
+    method public int getScanMode();
+    method public int getScanResultType();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CALLBACK_TYPE_ALL_MATCHES = 1; // 0x1
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int SCAN_MODE_BALANCED = 1; // 0x1
+    field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
+    field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
+  }
+
+  public static final class ScanSettings.Builder {
+    ctor public ScanSettings.Builder();
+    method public android.bluetooth.le.ScanSettings build();
+    method public android.bluetooth.le.ScanSettings.Builder setReportDelay(long);
+    method public android.bluetooth.le.ScanSettings.Builder setScanMode(int);
+  }
+
+}
+
 package android.content {
 
   public abstract class AbstractThreadedSyncAdapter {
@@ -5868,6 +6971,7 @@
     method public final android.os.Bundle call(android.net.Uri, java.lang.String, java.lang.String, android.os.Bundle);
     method public deprecated void cancelSync(android.net.Uri);
     method public static void cancelSync(android.accounts.Account, java.lang.String);
+    method public static void cancelSync(android.content.SyncRequest);
     method public final android.net.Uri canonicalize(android.net.Uri);
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public static deprecated android.content.SyncInfo getCurrentSync();
@@ -5912,8 +7016,10 @@
     method public final void unregisterContentObserver(android.database.ContentObserver);
     method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
     method public static void validateSyncExtrasBundle(android.os.Bundle);
+    field public static final java.lang.String ANY_CURSOR_ITEM_TYPE = "vnd.android.cursor.item/*";
     field public static final java.lang.String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir";
     field public static final java.lang.String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item";
+    field public static final java.lang.String EXTRA_SIZE = "android.content.extra.SIZE";
     field public static final java.lang.String SCHEME_ANDROID_RESOURCE = "android.resource";
     field public static final java.lang.String SCHEME_CONTENT = "content";
     field public static final java.lang.String SCHEME_FILE = "file";
@@ -6007,16 +7113,20 @@
     method public abstract android.content.res.AssetManager getAssets();
     method public abstract java.io.File getCacheDir();
     method public abstract java.lang.ClassLoader getClassLoader();
+    method public abstract java.io.File getCodeCacheDir();
     method public abstract android.content.ContentResolver getContentResolver();
     method public abstract java.io.File getDatabasePath(java.lang.String);
     method public abstract java.io.File getDir(java.lang.String, int);
+    method public final android.graphics.drawable.Drawable getDrawable(int);
     method public abstract java.io.File getExternalCacheDir();
     method public abstract java.io.File[] getExternalCacheDirs();
     method public abstract java.io.File getExternalFilesDir(java.lang.String);
     method public abstract java.io.File[] getExternalFilesDirs(java.lang.String);
+    method public abstract java.io.File[] getExternalMediaDirs();
     method public abstract java.io.File getFileStreamPath(java.lang.String);
     method public abstract java.io.File getFilesDir();
     method public abstract android.os.Looper getMainLooper();
+    method public abstract java.io.File getNoBackupFilesDir();
     method public abstract java.io.File getObbDir();
     method public abstract java.io.File[] getObbDirs();
     method public abstract java.lang.String getPackageCodePath();
@@ -6047,8 +7157,8 @@
     method public void registerComponentCallbacks(android.content.ComponentCallbacks);
     method public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter);
     method public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter, java.lang.String, android.os.Handler);
-    method public abstract void removeStickyBroadcast(android.content.Intent);
-    method public abstract void removeStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
+    method public abstract deprecated void removeStickyBroadcast(android.content.Intent);
+    method public abstract deprecated void removeStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
     method public abstract void revokeUriPermission(android.net.Uri, int);
     method public abstract void sendBroadcast(android.content.Intent);
     method public abstract void sendBroadcast(android.content.Intent, java.lang.String);
@@ -6057,10 +7167,10 @@
     method public abstract void sendOrderedBroadcast(android.content.Intent, java.lang.String);
     method public abstract void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
     method public abstract void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
-    method public abstract void sendStickyBroadcast(android.content.Intent);
-    method public abstract void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
-    method public abstract void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
-    method public abstract void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
+    method public abstract deprecated void sendStickyBroadcast(android.content.Intent);
+    method public abstract deprecated void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
+    method public abstract deprecated void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
+    method public abstract deprecated void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
     method public abstract void setTheme(int);
     method public abstract deprecated void setWallpaper(android.graphics.Bitmap) throws java.io.IOException;
     method public abstract deprecated void setWallpaper(java.io.InputStream) throws java.io.IOException;
@@ -6080,8 +7190,10 @@
     field public static final java.lang.String ACCOUNT_SERVICE = "account";
     field public static final java.lang.String ACTIVITY_SERVICE = "activity";
     field public static final java.lang.String ALARM_SERVICE = "alarm";
+    field public static final java.lang.String APPWIDGET_SERVICE = "appwidget";
     field public static final java.lang.String APP_OPS_SERVICE = "appops";
     field public static final java.lang.String AUDIO_SERVICE = "audio";
+    field public static final java.lang.String BATTERY_SERVICE = "batterymanager";
     field public static final int BIND_ABOVE_CLIENT = 8; // 0x8
     field public static final int BIND_ADJUST_WITH_ACTIVITY = 128; // 0x80
     field public static final int BIND_ALLOW_OOM_MANAGEMENT = 16; // 0x10
@@ -6091,6 +7203,7 @@
     field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
     field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
     field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
+    field public static final java.lang.String CAMERA_SERVICE = "camera";
     field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
     field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
     field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
@@ -6104,10 +7217,14 @@
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
+    field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
+    field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
     field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";
     field public static final java.lang.String LOCATION_SERVICE = "location";
+    field public static final java.lang.String MEDIA_PROJECTION_SERVICE = "media_projection";
     field public static final java.lang.String MEDIA_ROUTER_SERVICE = "media_router";
+    field public static final java.lang.String MEDIA_SESSION_SERVICE = "media_session";
     field public static final int MODE_APPEND = 32768; // 0x8000
     field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8
     field public static final int MODE_MULTI_PROCESS = 4; // 0x4
@@ -6119,11 +7236,14 @@
     field public static final java.lang.String NSD_SERVICE = "servicediscovery";
     field public static final java.lang.String POWER_SERVICE = "power";
     field public static final java.lang.String PRINT_SERVICE = "print";
+    field public static final java.lang.String RESTRICTIONS_SERVICE = "restrictions";
     field public static final java.lang.String SEARCH_SERVICE = "search";
     field public static final java.lang.String SENSOR_SERVICE = "sensor";
     field public static final java.lang.String STORAGE_SERVICE = "storage";
+    field public static final java.lang.String TELECOM_SERVICE = "telecom";
     field public static final java.lang.String TELEPHONY_SERVICE = "phone";
     field public static final java.lang.String TEXT_SERVICES_MANAGER_SERVICE = "textservices";
+    field public static final java.lang.String TV_INPUT_SERVICE = "tv_input";
     field public static final java.lang.String UI_MODE_SERVICE = "uimode";
     field public static final java.lang.String USB_SERVICE = "usb";
     field public static final java.lang.String USER_SERVICE = "user";
@@ -6166,6 +7286,7 @@
     method public android.content.Context getBaseContext();
     method public java.io.File getCacheDir();
     method public java.lang.ClassLoader getClassLoader();
+    method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
     method public java.io.File getDatabasePath(java.lang.String);
     method public java.io.File getDir(java.lang.String, int);
@@ -6173,9 +7294,11 @@
     method public java.io.File[] getExternalCacheDirs();
     method public java.io.File getExternalFilesDir(java.lang.String);
     method public java.io.File[] getExternalFilesDirs(java.lang.String);
+    method public java.io.File[] getExternalMediaDirs();
     method public java.io.File getFileStreamPath(java.lang.String);
     method public java.io.File getFilesDir();
     method public android.os.Looper getMainLooper();
+    method public java.io.File getNoBackupFilesDir();
     method public java.io.File getObbDir();
     method public java.io.File[] getObbDirs();
     method public java.lang.String getPackageCodePath();
@@ -6429,6 +7552,7 @@
     field public static final java.lang.String ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE";
     field public static final java.lang.String ACTION_ALL_APPS = "android.intent.action.ALL_APPS";
     field public static final java.lang.String ACTION_ANSWER = "android.intent.action.ANSWER";
+    field public static final java.lang.String ACTION_APPLICATION_RESTRICTIONS_CHANGED = "android.intent.action.APPLICATION_RESTRICTIONS_CHANGED";
     field public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
     field public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST";
     field public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
@@ -6469,6 +7593,8 @@
     field public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
     field public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
     field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN";
+    field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
+    field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
     field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
     field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
     field public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";
@@ -6487,6 +7613,7 @@
     field public static final java.lang.String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED";
     field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
+    field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
     field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
     field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
     field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
@@ -6557,6 +7684,7 @@
     field public static final java.lang.String CATEGORY_HOME = "android.intent.category.HOME";
     field public static final java.lang.String CATEGORY_INFO = "android.intent.category.INFO";
     field public static final java.lang.String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER";
+    field public static final java.lang.String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
     field public static final java.lang.String CATEGORY_LE_DESK_DOCK = "android.intent.category.LE_DESK_DOCK";
     field public static final java.lang.String CATEGORY_MONKEY = "android.intent.category.MONKEY";
     field public static final java.lang.String CATEGORY_OPENABLE = "android.intent.category.OPENABLE";
@@ -6571,6 +7699,7 @@
     field public static final java.lang.String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
     field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
     field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
+    field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
     field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
     field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
     field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
@@ -6600,6 +7729,7 @@
     field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
     field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
     field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token";
+    field public static final java.lang.String EXTRA_REPLACEMENT_EXTRAS = "android.intent.extra.REPLACEMENT_EXTRAS";
     field public static final java.lang.String EXTRA_REPLACING = "android.intent.extra.REPLACING";
     field public static final java.lang.String EXTRA_RESTRICTIONS_BUNDLE = "android.intent.extra.restrictions_bundle";
     field public static final java.lang.String EXTRA_RESTRICTIONS_INTENT = "android.intent.extra.restrictions_intent";
@@ -6616,6 +7746,7 @@
     field public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT";
     field public static final java.lang.String EXTRA_TITLE = "android.intent.extra.TITLE";
     field public static final java.lang.String EXTRA_UID = "android.intent.extra.UID";
+    field public static final java.lang.String EXTRA_USER = "android.intent.extra.USER";
     field public static final int FILL_IN_ACTION = 1; // 0x1
     field public static final int FILL_IN_CATEGORIES = 4; // 0x4
     field public static final int FILL_IN_CLIP_DATA = 128; // 0x80
@@ -6627,11 +7758,12 @@
     field public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 4194304; // 0x400000
     field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
     field public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864; // 0x4000000
-    field public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; // 0x80000
+    field public static final deprecated int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288; // 0x80000
     field public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608; // 0x800000
     field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
     field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
     field public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; // 0x8000000
+    field public static final int FLAG_ACTIVITY_NEW_DOCUMENT = 524288; // 0x80000
     field public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; // 0x10000000
     field public static final int FLAG_ACTIVITY_NO_ANIMATION = 65536; // 0x10000
     field public static final int FLAG_ACTIVITY_NO_HISTORY = 1073741824; // 0x40000000
@@ -6639,12 +7771,14 @@
     field public static final int FLAG_ACTIVITY_PREVIOUS_IS_TOP = 16777216; // 0x1000000
     field public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 131072; // 0x20000
     field public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 2097152; // 0x200000
+    field public static final int FLAG_ACTIVITY_RETAIN_IN_RECENTS = 8192; // 0x2000
     field public static final int FLAG_ACTIVITY_SINGLE_TOP = 536870912; // 0x20000000
     field public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384; // 0x4000
     field public static final int FLAG_DEBUG_LOG_RESOLUTION = 8; // 0x8
     field public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 16; // 0x10
     field public static final int FLAG_FROM_BACKGROUND = 4; // 0x4
     field public static final int FLAG_GRANT_PERSISTABLE_URI_PERMISSION = 64; // 0x40
+    field public static final int FLAG_GRANT_PREFIX_URI_PERMISSION = 128; // 0x80
     field public static final int FLAG_GRANT_READ_URI_PERMISSION = 1; // 0x1
     field public static final int FLAG_GRANT_WRITE_URI_PERMISSION = 2; // 0x2
     field public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 32; // 0x20
@@ -6856,15 +7990,18 @@
   }
 
   public class RestrictionEntry implements android.os.Parcelable {
+    ctor public RestrictionEntry(int, java.lang.String);
     ctor public RestrictionEntry(java.lang.String, java.lang.String);
     ctor public RestrictionEntry(java.lang.String, boolean);
     ctor public RestrictionEntry(java.lang.String, java.lang.String[]);
+    ctor public RestrictionEntry(java.lang.String, int);
     ctor public RestrictionEntry(android.os.Parcel);
     method public int describeContents();
     method public java.lang.String[] getAllSelectedStrings();
     method public java.lang.String[] getChoiceEntries();
     method public java.lang.String[] getChoiceValues();
     method public java.lang.String getDescription();
+    method public int getIntValue();
     method public java.lang.String getKey();
     method public boolean getSelectedState();
     method public java.lang.String getSelectedString();
@@ -6876,6 +8013,7 @@
     method public void setChoiceValues(java.lang.String[]);
     method public void setChoiceValues(android.content.Context, int);
     method public void setDescription(java.lang.String);
+    method public void setIntValue(int);
     method public void setSelectedState(boolean);
     method public void setSelectedString(java.lang.String);
     method public void setTitle(java.lang.String);
@@ -6884,8 +8022,49 @@
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int TYPE_BOOLEAN = 1; // 0x1
     field public static final int TYPE_CHOICE = 2; // 0x2
+    field public static final int TYPE_INTEGER = 5; // 0x5
     field public static final int TYPE_MULTI_SELECT = 4; // 0x4
     field public static final int TYPE_NULL = 0; // 0x0
+    field public static final int TYPE_STRING = 6; // 0x6
+  }
+
+  public class RestrictionsManager {
+    method public android.content.Intent createLocalApprovalIntent();
+    method public android.os.Bundle getApplicationRestrictions();
+    method public java.util.List<android.content.RestrictionEntry> getManifestRestrictions(java.lang.String);
+    method public boolean hasRestrictionsProvider();
+    method public void notifyPermissionResponse(java.lang.String, android.os.PersistableBundle);
+    method public void requestPermission(java.lang.String, java.lang.String, android.os.PersistableBundle);
+    field public static final java.lang.String ACTION_PERMISSION_RESPONSE_RECEIVED = "android.content.action.PERMISSION_RESPONSE_RECEIVED";
+    field public static final java.lang.String ACTION_REQUEST_LOCAL_APPROVAL = "android.content.action.REQUEST_LOCAL_APPROVAL";
+    field public static final java.lang.String ACTION_REQUEST_PERMISSION = "android.content.action.REQUEST_PERMISSION";
+    field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.extra.PACKAGE_NAME";
+    field public static final java.lang.String EXTRA_REQUEST_BUNDLE = "android.content.extra.REQUEST_BUNDLE";
+    field public static final java.lang.String EXTRA_REQUEST_ID = "android.content.extra.REQUEST_ID";
+    field public static final java.lang.String EXTRA_REQUEST_TYPE = "android.content.extra.REQUEST_TYPE";
+    field public static final java.lang.String EXTRA_RESPONSE_BUNDLE = "android.content.extra.RESPONSE_BUNDLE";
+    field public static final java.lang.String META_DATA_APP_RESTRICTIONS = "android.content.APP_RESTRICTIONS";
+    field public static final java.lang.String REQUEST_KEY_APPROVE_LABEL = "android.request.approve_label";
+    field public static final java.lang.String REQUEST_KEY_DATA = "android.request.data";
+    field public static final java.lang.String REQUEST_KEY_DENY_LABEL = "android.request.deny_label";
+    field public static final java.lang.String REQUEST_KEY_ICON = "android.request.icon";
+    field public static final java.lang.String REQUEST_KEY_ID = "android.request.id";
+    field public static final java.lang.String REQUEST_KEY_MESSAGE = "android.request.mesg";
+    field public static final java.lang.String REQUEST_KEY_NEW_REQUEST = "android.request.new_request";
+    field public static final java.lang.String REQUEST_KEY_TITLE = "android.request.title";
+    field public static final java.lang.String REQUEST_TYPE_APPROVAL = "android.request.type.approval";
+    field public static final java.lang.String RESPONSE_KEY_ERROR_CODE = "android.response.errorcode";
+    field public static final java.lang.String RESPONSE_KEY_MESSAGE = "android.response.msg";
+    field public static final java.lang.String RESPONSE_KEY_RESPONSE_TIMESTAMP = "android.response.timestamp";
+    field public static final java.lang.String RESPONSE_KEY_RESULT = "android.response.result";
+    field public static final int RESULT_APPROVED = 1; // 0x1
+    field public static final int RESULT_DENIED = 2; // 0x2
+    field public static final int RESULT_ERROR = 5; // 0x5
+    field public static final int RESULT_ERROR_BAD_REQUEST = 1; // 0x1
+    field public static final int RESULT_ERROR_INTERNAL = 3; // 0x3
+    field public static final int RESULT_ERROR_NETWORK = 2; // 0x2
+    field public static final int RESULT_NO_RESPONSE = 3; // 0x3
+    field public static final int RESULT_UNKNOWN_REQUEST = 4; // 0x4
   }
 
   public class SearchRecentSuggestionsProvider extends android.content.ContentProvider {
@@ -7077,8 +8256,13 @@
     field public static final int CONFIG_TOUCHSCREEN = 8; // 0x8
     field public static final int CONFIG_UI_MODE = 512; // 0x200
     field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int DOCUMENT_LAUNCH_ALWAYS = 2; // 0x2
+    field public static final int DOCUMENT_LAUNCH_INTO_EXISTING = 1; // 0x1
+    field public static final int DOCUMENT_LAUNCH_NEVER = 3; // 0x3
+    field public static final int DOCUMENT_LAUNCH_NONE = 0; // 0x0
     field public static final int FLAG_ALLOW_TASK_REPARENTING = 64; // 0x40
     field public static final int FLAG_ALWAYS_RETAIN_TASK_STATE = 8; // 0x8
+    field public static final int FLAG_AUTO_REMOVE_FROM_RECENTS = 8192; // 0x2000
     field public static final int FLAG_CLEAR_TASK_ON_LAUNCH = 4; // 0x4
     field public static final int FLAG_EXCLUDE_FROM_RECENTS = 32; // 0x20
     field public static final int FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS = 256; // 0x100
@@ -7087,12 +8271,17 @@
     field public static final int FLAG_IMMERSIVE = 2048; // 0x800
     field public static final int FLAG_MULTIPROCESS = 1; // 0x1
     field public static final int FLAG_NO_HISTORY = 128; // 0x80
+    field public static final int FLAG_RELINQUISH_TASK_IDENTITY = 4096; // 0x1000
+    field public static final int FLAG_RESUME_WHILE_PAUSING = 16384; // 0x4000
     field public static final int FLAG_SINGLE_USER = 1073741824; // 0x40000000
     field public static final int FLAG_STATE_NOT_NEEDED = 16; // 0x10
     field public static final int LAUNCH_MULTIPLE = 0; // 0x0
     field public static final int LAUNCH_SINGLE_INSTANCE = 3; // 0x3
     field public static final int LAUNCH_SINGLE_TASK = 2; // 0x2
     field public static final int LAUNCH_SINGLE_TOP = 1; // 0x1
+    field public static final int PERSIST_ACROSS_REBOOTS = 2; // 0x2
+    field public static final int PERSIST_NEVER = 1; // 0x1
+    field public static final int PERSIST_ROOT_ONLY = 0; // 0x0
     field public static final int SCREEN_ORIENTATION_BEHIND = 3; // 0x3
     field public static final int SCREEN_ORIENTATION_FULL_SENSOR = 10; // 0xa
     field public static final int SCREEN_ORIENTATION_FULL_USER = 13; // 0xd
@@ -7111,10 +8300,13 @@
     field public static final int SCREEN_ORIENTATION_USER_PORTRAIT = 12; // 0xc
     field public static final int UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = 1; // 0x1
     field public int configChanges;
+    field public int documentLaunchMode;
     field public int flags;
     field public int launchMode;
+    field public int maxRecents;
     field public java.lang.String parentActivityName;
     field public java.lang.String permission;
+    field public int persistableMode;
     field public int screenOrientation;
     field public int softInputMode;
     field public java.lang.String targetActivity;
@@ -7136,11 +8328,14 @@
     field public static final int FLAG_DEBUGGABLE = 2; // 0x2
     field public static final int FLAG_EXTERNAL_STORAGE = 262144; // 0x40000
     field public static final int FLAG_FACTORY_TEST = 16; // 0x10
+    field public static final int FLAG_FULL_BACKUP_ONLY = 67108864; // 0x4000000
     field public static final int FLAG_HAS_CODE = 4; // 0x4
     field public static final int FLAG_INSTALLED = 8388608; // 0x800000
     field public static final int FLAG_IS_DATA_ONLY = 16777216; // 0x1000000
+    field public static final int FLAG_IS_GAME = 33554432; // 0x2000000
     field public static final int FLAG_KILL_AFTER_RESTORE = 65536; // 0x10000
     field public static final int FLAG_LARGE_HEAP = 1048576; // 0x100000
+    field public static final int FLAG_MULTIARCH = -2147483648; // 0x80000000
     field public static final int FLAG_PERSISTENT = 8; // 0x8
     field public static final int FLAG_RESIZEABLE_FOR_SCREENS = 4096; // 0x1000
     field public static final int FLAG_RESTORE_ANY_VERSION = 131072; // 0x20000
@@ -7171,6 +8366,8 @@
     field public int requiresSmallestWidthDp;
     field public java.lang.String[] sharedLibraryFiles;
     field public java.lang.String sourceDir;
+    field public java.lang.String[] splitPublicSourceDirs;
+    field public java.lang.String[] splitSourceDirs;
     field public int targetSdkVersion;
     field public java.lang.String taskAffinity;
     field public int theme;
@@ -7215,6 +8412,15 @@
     field public int reqTouchScreen;
   }
 
+  public final class FeatureGroupInfo implements android.os.Parcelable {
+    ctor public FeatureGroupInfo();
+    ctor public FeatureGroupInfo(android.content.pm.FeatureGroupInfo);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public android.content.pm.FeatureInfo[] features;
+  }
+
   public class FeatureInfo implements android.os.Parcelable {
     ctor public FeatureInfo();
     ctor public FeatureInfo(android.content.pm.FeatureInfo);
@@ -7239,6 +8445,8 @@
     field public boolean handleProfiling;
     field public java.lang.String publicSourceDir;
     field public java.lang.String sourceDir;
+    field public java.lang.String[] splitPublicSourceDirs;
+    field public java.lang.String[] splitSourceDirs;
     field public java.lang.String targetPackage;
   }
 
@@ -7256,18 +8464,55 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
+  public class LauncherActivityInfo {
+    method public android.content.pm.ApplicationInfo getApplicationInfo();
+    method public android.graphics.drawable.Drawable getBadgedIcon(int);
+    method public android.content.ComponentName getComponentName();
+    method public long getFirstInstallTime();
+    method public android.graphics.drawable.Drawable getIcon(int);
+    method public java.lang.CharSequence getLabel();
+    method public java.lang.String getName();
+    method public android.os.UserHandle getUser();
+  }
+
+  public class LauncherApps {
+    method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
+    method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle);
+    method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle);
+    method public void registerCallback(android.content.pm.LauncherApps.Callback);
+    method public void registerCallback(android.content.pm.LauncherApps.Callback, android.os.Handler);
+    method public android.content.pm.LauncherActivityInfo resolveActivity(android.content.Intent, android.os.UserHandle);
+    method public void startAppDetailsActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
+    method public void startMainActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
+    method public void unregisterCallback(android.content.pm.LauncherApps.Callback);
+  }
+
+  public static abstract class LauncherApps.Callback {
+    ctor public LauncherApps.Callback();
+    method public abstract void onPackageAdded(java.lang.String, android.os.UserHandle);
+    method public abstract void onPackageChanged(java.lang.String, android.os.UserHandle);
+    method public abstract void onPackageRemoved(java.lang.String, android.os.UserHandle);
+    method public abstract void onPackagesAvailable(java.lang.String[], android.os.UserHandle, boolean);
+    method public abstract void onPackagesUnavailable(java.lang.String[], android.os.UserHandle, boolean);
+  }
+
   public class PackageInfo implements android.os.Parcelable {
     ctor public PackageInfo();
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int INSTALL_LOCATION_AUTO = 0; // 0x0
+    field public static final int INSTALL_LOCATION_INTERNAL_ONLY = 1; // 0x1
+    field public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2; // 0x2
     field public static final int REQUESTED_PERMISSION_GRANTED = 2; // 0x2
     field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
     field public android.content.pm.ActivityInfo[] activities;
     field public android.content.pm.ApplicationInfo applicationInfo;
     field public android.content.pm.ConfigurationInfo[] configPreferences;
+    field public android.content.pm.FeatureGroupInfo[] featureGroups;
     field public long firstInstallTime;
     field public int[] gids;
+    field public int installLocation;
     field public android.content.pm.InstrumentationInfo[] instrumentation;
     field public long lastUpdateTime;
     field public java.lang.String packageName;
@@ -7281,10 +8526,92 @@
     field public java.lang.String sharedUserId;
     field public int sharedUserLabel;
     field public android.content.pm.Signature[] signatures;
+    field public java.lang.String[] splitNames;
     field public int versionCode;
     field public java.lang.String versionName;
   }
 
+  public class PackageInstaller {
+    method public void abandonSession(int);
+    method public int createSession(android.content.pm.PackageInstaller.SessionParams) throws java.io.IOException;
+    method public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getAllSessions();
+    method public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getMySessions();
+    method public android.content.pm.PackageInstaller.SessionInfo getSessionInfo(int);
+    method public android.content.pm.PackageInstaller.Session openSession(int) throws java.io.IOException;
+    method public void registerSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
+    method public void registerSessionCallback(android.content.pm.PackageInstaller.SessionCallback, android.os.Handler);
+    method public void uninstall(java.lang.String, android.content.IntentSender);
+    method public void unregisterSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
+    method public void updateSessionAppIcon(int, android.graphics.Bitmap);
+    method public void updateSessionAppLabel(int, java.lang.CharSequence);
+    field public static final java.lang.String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
+    field public static final java.lang.String EXTRA_OTHER_PACKAGE_NAME = "android.content.pm.extra.OTHER_PACKAGE_NAME";
+    field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
+    field public static final java.lang.String EXTRA_SESSION_ID = "android.content.pm.extra.SESSION_ID";
+    field public static final java.lang.String EXTRA_STATUS = "android.content.pm.extra.STATUS";
+    field public static final java.lang.String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
+    field public static final java.lang.String EXTRA_STORAGE_PATH = "android.content.pm.extra.STORAGE_PATH";
+    field public static final int STATUS_FAILURE = 1; // 0x1
+    field public static final int STATUS_FAILURE_ABORTED = 3; // 0x3
+    field public static final int STATUS_FAILURE_BLOCKED = 2; // 0x2
+    field public static final int STATUS_FAILURE_CONFLICT = 5; // 0x5
+    field public static final int STATUS_FAILURE_INCOMPATIBLE = 7; // 0x7
+    field public static final int STATUS_FAILURE_INVALID = 4; // 0x4
+    field public static final int STATUS_FAILURE_STORAGE = 6; // 0x6
+    field public static final int STATUS_PENDING_USER_ACTION = -1; // 0xffffffff
+    field public static final int STATUS_SUCCESS = 0; // 0x0
+  }
+
+  public static class PackageInstaller.Session implements java.io.Closeable {
+    method public void abandon();
+    method public void close();
+    method public void commit(android.content.IntentSender);
+    method public void fsync(java.io.OutputStream) throws java.io.IOException;
+    method public java.lang.String[] getNames() throws java.io.IOException;
+    method public java.io.InputStream openRead(java.lang.String) throws java.io.IOException;
+    method public java.io.OutputStream openWrite(java.lang.String, long, long) throws java.io.IOException;
+    method public void setStagingProgress(float);
+  }
+
+  public static abstract class PackageInstaller.SessionCallback {
+    ctor public PackageInstaller.SessionCallback();
+    method public abstract void onActiveChanged(int, boolean);
+    method public abstract void onBadgingChanged(int);
+    method public abstract void onCreated(int);
+    method public abstract void onFinished(int, boolean);
+    method public abstract void onProgressChanged(int, float);
+  }
+
+  public static class PackageInstaller.SessionInfo implements android.os.Parcelable {
+    method public android.content.Intent createDetailsIntent();
+    method public int describeContents();
+    method public android.graphics.Bitmap getAppIcon();
+    method public java.lang.CharSequence getAppLabel();
+    method public java.lang.String getAppPackageName();
+    method public java.lang.String getInstallerPackageName();
+    method public float getProgress();
+    method public int getSessionId();
+    method public boolean isActive();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static class PackageInstaller.SessionParams implements android.os.Parcelable {
+    ctor public PackageInstaller.SessionParams(int);
+    method public int describeContents();
+    method public void setAppIcon(android.graphics.Bitmap);
+    method public void setAppLabel(java.lang.CharSequence);
+    method public void setAppPackageName(java.lang.String);
+    method public void setInstallLocation(int);
+    method public void setOriginatingUri(android.net.Uri);
+    method public void setReferrerUri(android.net.Uri);
+    method public void setSize(long);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int MODE_FULL_INSTALL = 1; // 0x1
+    field public static final int MODE_INHERIT_EXISTING = 2; // 0x2
+  }
+
   public class PackageItemInfo {
     ctor public PackageItemInfo();
     ctor public PackageItemInfo(android.content.pm.PackageItemInfo);
@@ -7350,10 +8677,12 @@
     method public abstract java.lang.String getInstallerPackageName(java.lang.String);
     method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract android.content.Intent getLaunchIntentForPackage(java.lang.String);
+    method public abstract android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
     method public abstract java.lang.String getNameForUid(int);
     method public android.content.pm.PackageInfo getPackageArchiveInfo(java.lang.String, int);
     method public abstract int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public abstract android.content.pm.PackageInstaller getPackageInstaller();
     method public abstract java.lang.String[] getPackagesForUid(int);
     method public abstract java.util.List<android.content.pm.PackageInfo> getPackagesHoldingPermissions(java.lang.String[], int);
     method public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -7369,6 +8698,9 @@
     method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
     method public abstract java.lang.String[] getSystemSharedLibraryNames();
     method public abstract java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
+    method public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(android.graphics.drawable.Drawable, android.os.UserHandle, android.graphics.Rect, int);
+    method public abstract android.graphics.drawable.Drawable getUserBadgedIcon(android.graphics.drawable.Drawable, android.os.UserHandle);
+    method public abstract java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public abstract boolean hasSystemFeature(java.lang.String);
     method public abstract boolean isSafeMode();
@@ -7399,39 +8731,54 @@
     field public static final java.lang.String EXTRA_VERIFICATION_RESULT = "android.content.pm.extra.VERIFICATION_RESULT";
     field public static final java.lang.String FEATURE_APP_WIDGETS = "android.software.app_widgets";
     field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
+    field public static final java.lang.String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
     field public static final java.lang.String FEATURE_BACKUP = "android.software.backup";
     field public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
     field public static final java.lang.String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
     field public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera";
     field public static final java.lang.String FEATURE_CAMERA_ANY = "android.hardware.camera.any";
     field public static final java.lang.String FEATURE_CAMERA_AUTOFOCUS = "android.hardware.camera.autofocus";
+    field public static final java.lang.String FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING = "android.hardware.camera.capability.manual_post_processing";
+    field public static final java.lang.String FEATURE_CAMERA_CAPABILITY_MANUAL_SENSOR = "android.hardware.camera.capability.manual_sensor";
+    field public static final java.lang.String FEATURE_CAMERA_CAPABILITY_RAW = "android.hardware.camera.capability.raw";
     field public static final java.lang.String FEATURE_CAMERA_EXTERNAL = "android.hardware.camera.external";
     field public static final java.lang.String FEATURE_CAMERA_FLASH = "android.hardware.camera.flash";
     field public static final java.lang.String FEATURE_CAMERA_FRONT = "android.hardware.camera.front";
+    field public static final java.lang.String FEATURE_CAMERA_LEVEL_FULL = "android.hardware.camera.level.full";
+    field public static final java.lang.String FEATURE_CONNECTION_SERVICE = "android.software.connectionservice";
     field public static final java.lang.String FEATURE_CONSUMER_IR = "android.hardware.consumerir";
     field public static final java.lang.String FEATURE_DEVICE_ADMIN = "android.software.device_admin";
     field public static final java.lang.String FEATURE_FAKETOUCH = "android.hardware.faketouch";
     field public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT = "android.hardware.faketouch.multitouch.distinct";
     field public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = "android.hardware.faketouch.multitouch.jazzhand";
+    field public static final java.lang.String FEATURE_GAMEPAD = "android.hardware.gamepad";
     field public static final java.lang.String FEATURE_HOME_SCREEN = "android.software.home_screen";
     field public static final java.lang.String FEATURE_INPUT_METHODS = "android.software.input_methods";
+    field public static final java.lang.String FEATURE_LEANBACK = "android.software.leanback";
+    field public static final java.lang.String FEATURE_LIVE_TV = "android.software.live_tv";
     field public static final java.lang.String FEATURE_LIVE_WALLPAPER = "android.software.live_wallpaper";
     field public static final java.lang.String FEATURE_LOCATION = "android.hardware.location";
     field public static final java.lang.String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
     field public static final java.lang.String FEATURE_LOCATION_NETWORK = "android.hardware.location.network";
+    field public static final java.lang.String FEATURE_MANAGED_USERS = "android.software.managed_users";
     field public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone";
     field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
     field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
+    field public static final java.lang.String FEATURE_OPENGLES_EXTENSION_PACK = "android.hardware.opengles.aep";
     field public static final java.lang.String FEATURE_PRINTING = "android.software.print";
     field public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape";
     field public static final java.lang.String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait";
+    field public static final java.lang.String FEATURE_SECURELY_REMOVES_USERS = "android.software.securely_removes_users";
     field public static final java.lang.String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer";
+    field public static final java.lang.String FEATURE_SENSOR_AMBIENT_TEMPERATURE = "android.hardware.sensor.ambient_temperature";
     field public static final java.lang.String FEATURE_SENSOR_BAROMETER = "android.hardware.sensor.barometer";
     field public static final java.lang.String FEATURE_SENSOR_COMPASS = "android.hardware.sensor.compass";
     field public static final java.lang.String FEATURE_SENSOR_GYROSCOPE = "android.hardware.sensor.gyroscope";
     field public static final java.lang.String FEATURE_SENSOR_HEART_RATE = "android.hardware.sensor.heartrate";
+    field public static final java.lang.String FEATURE_SENSOR_HEART_RATE_ECG = "android.hardware.sensor.heartrate.ecg";
     field public static final java.lang.String FEATURE_SENSOR_LIGHT = "android.hardware.sensor.light";
     field public static final java.lang.String FEATURE_SENSOR_PROXIMITY = "android.hardware.sensor.proximity";
+    field public static final java.lang.String FEATURE_SENSOR_RELATIVE_HUMIDITY = "android.hardware.sensor.relative_humidity";
     field public static final java.lang.String FEATURE_SENSOR_STEP_COUNTER = "android.hardware.sensor.stepcounter";
     field public static final java.lang.String FEATURE_SENSOR_STEP_DETECTOR = "android.hardware.sensor.stepdetector";
     field public static final java.lang.String FEATURE_SIP = "android.software.sip";
@@ -7439,13 +8786,14 @@
     field public static final java.lang.String FEATURE_TELEPHONY = "android.hardware.telephony";
     field public static final java.lang.String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
     field public static final java.lang.String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
-    field public static final java.lang.String FEATURE_TELEVISION = "android.hardware.type.television";
+    field public static final deprecated java.lang.String FEATURE_TELEVISION = "android.hardware.type.television";
     field public static final java.lang.String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen";
     field public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch";
     field public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct";
     field public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND = "android.hardware.touchscreen.multitouch.jazzhand";
     field public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory";
     field public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host";
+    field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
     field public static final java.lang.String FEATURE_WATCH = "android.hardware.type.watch";
     field public static final java.lang.String FEATURE_WEBVIEW = "android.software.webview";
     field public static final java.lang.String FEATURE_WIFI = "android.hardware.wifi";
@@ -7533,6 +8881,7 @@
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int FLAG_COSTS_MONEY = 1; // 0x1
     field public static final int PROTECTION_DANGEROUS = 1; // 0x1
+    field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
     field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
     field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10
     field public static final int PROTECTION_MASK_BASE = 15; // 0xf
@@ -7651,7 +9000,7 @@
     ctor public AssetFileDescriptor.AutoCloseOutputStream(android.content.res.AssetFileDescriptor) throws java.io.IOException;
   }
 
-  public final class AssetManager {
+  public final class AssetManager implements java.lang.AutoCloseable {
     method public void close();
     method public final java.lang.String[] getLocales();
     method public final java.lang.String[] list(java.lang.String) throws java.io.IOException;
@@ -7671,7 +9020,6 @@
   public final class AssetManager.AssetInputStream extends java.io.InputStream {
     method public final int available() throws java.io.IOException;
     method public final void close() throws java.io.IOException;
-    method public final int getAssetInt();
     method public final void mark(int);
     method public final boolean markSupported();
     method public final int read() throws java.io.IOException;
@@ -7687,6 +9035,7 @@
     method public int describeContents();
     method public int getColorForState(int[], int);
     method public int getDefaultColor();
+    method public boolean isOpaque();
     method public boolean isStateful();
     method public static android.content.res.ColorStateList valueOf(int);
     method public android.content.res.ColorStateList withAlpha(int);
@@ -7820,7 +9169,9 @@
     method public int getDimensionPixelSize(int) throws android.content.res.Resources.NotFoundException;
     method public android.util.DisplayMetrics getDisplayMetrics();
     method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawable(int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
     method public android.graphics.drawable.Drawable getDrawableForDensity(int, int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawableForDensity(int, int, android.content.res.Resources.Theme);
     method public float getFraction(int, int, int);
     method public int getIdentifier(java.lang.String, java.lang.String, java.lang.String);
     method public int[] getIntArray(int) throws android.content.res.Resources.NotFoundException;
@@ -7864,6 +9215,8 @@
   public final class Resources.Theme {
     method public void applyStyle(int, boolean);
     method public void dump(int, java.lang.String, java.lang.String);
+    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
+    method public android.content.res.Resources getResources();
     method public android.content.res.TypedArray obtainStyledAttributes(int[]);
     method public android.content.res.TypedArray obtainStyledAttributes(int, int[]) throws android.content.res.Resources.NotFoundException;
     method public android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet, int[], int, int);
@@ -7873,6 +9226,7 @@
 
   public class TypedArray {
     method public boolean getBoolean(int, boolean);
+    method public int getChangingConfigurations();
     method public int getColor(int, int);
     method public android.content.res.ColorStateList getColorStateList(int);
     method public float getDimension(int, float);
@@ -7894,6 +9248,7 @@
     method public java.lang.String getString(int);
     method public java.lang.CharSequence getText(int);
     method public java.lang.CharSequence[] getTextArray(int);
+    method public int getType(int);
     method public boolean getValue(int, android.util.TypedValue);
     method public boolean hasValue(int);
     method public int length();
@@ -8877,6 +10232,7 @@
     ctor public GestureOverlayView(android.content.Context);
     ctor public GestureOverlayView(android.content.Context, android.util.AttributeSet);
     ctor public GestureOverlayView(android.content.Context, android.util.AttributeSet, int);
+    ctor public GestureOverlayView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addOnGestureListener(android.gesture.GestureOverlayView.OnGestureListener);
     method public void addOnGesturePerformedListener(android.gesture.GestureOverlayView.OnGesturePerformedListener);
     method public void addOnGesturingListener(android.gesture.GestureOverlayView.OnGesturingListener);
@@ -9118,13 +10474,13 @@
     field public android.graphics.Bitmap inBitmap;
     field public int inDensity;
     field public boolean inDither;
-    field public boolean inInputShareable;
+    field public deprecated boolean inInputShareable;
     field public boolean inJustDecodeBounds;
     field public boolean inMutable;
     field public boolean inPreferQualityOverSpeed;
     field public android.graphics.Bitmap.Config inPreferredConfig;
     field public boolean inPremultiplied;
-    field public boolean inPurgeable;
+    field public deprecated boolean inPurgeable;
     field public int inSampleSize;
     field public boolean inScaled;
     field public int inScreenDensity;
@@ -9195,16 +10551,17 @@
     method public boolean clipRect(float, float, float, float, android.graphics.Region.Op);
     method public boolean clipRect(float, float, float, float);
     method public boolean clipRect(int, int, int, int);
-    method public boolean clipRegion(android.graphics.Region, android.graphics.Region.Op);
-    method public boolean clipRegion(android.graphics.Region);
+    method public deprecated boolean clipRegion(android.graphics.Region, android.graphics.Region.Op);
+    method public deprecated boolean clipRegion(android.graphics.Region);
     method public void concat(android.graphics.Matrix);
     method public void drawARGB(int, int, int, int);
     method public void drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint);
+    method public void drawArc(float, float, float, float, float, float, boolean, android.graphics.Paint);
     method public void drawBitmap(android.graphics.Bitmap, float, float, android.graphics.Paint);
     method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.RectF, android.graphics.Paint);
     method public void drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.Rect, android.graphics.Paint);
-    method public void drawBitmap(int[], int, int, float, float, int, int, boolean, android.graphics.Paint);
-    method public void drawBitmap(int[], int, int, int, int, int, int, boolean, android.graphics.Paint);
+    method public deprecated void drawBitmap(int[], int, int, float, float, int, int, boolean, android.graphics.Paint);
+    method public deprecated void drawBitmap(int[], int, int, int, int, int, int, boolean, android.graphics.Paint);
     method public void drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint);
     method public void drawBitmapMesh(android.graphics.Bitmap, int, int, float[], int, int[], int, android.graphics.Paint);
     method public void drawCircle(float, float, float, android.graphics.Paint);
@@ -9214,6 +10571,7 @@
     method public void drawLines(float[], int, int, android.graphics.Paint);
     method public void drawLines(float[], android.graphics.Paint);
     method public void drawOval(android.graphics.RectF, android.graphics.Paint);
+    method public void drawOval(float, float, float, float, android.graphics.Paint);
     method public void drawPaint(android.graphics.Paint);
     method public void drawPath(android.graphics.Path, android.graphics.Paint);
     method public void drawPicture(android.graphics.Picture);
@@ -9229,6 +10587,7 @@
     method public void drawRect(android.graphics.Rect, android.graphics.Paint);
     method public void drawRect(float, float, float, float, android.graphics.Paint);
     method public void drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint);
+    method public void drawRoundRect(float, float, float, float, float, float, android.graphics.Paint);
     method public void drawText(char[], int, int, float, float, android.graphics.Paint);
     method public void drawText(java.lang.String, float, float, android.graphics.Paint);
     method public void drawText(java.lang.String, int, int, float, float, android.graphics.Paint);
@@ -9259,9 +10618,13 @@
     method public int save();
     method public int save(int);
     method public int saveLayer(android.graphics.RectF, android.graphics.Paint, int);
+    method public int saveLayer(android.graphics.RectF, android.graphics.Paint);
     method public int saveLayer(float, float, float, float, android.graphics.Paint, int);
+    method public int saveLayer(float, float, float, float, android.graphics.Paint);
     method public int saveLayerAlpha(android.graphics.RectF, int, int);
+    method public int saveLayerAlpha(android.graphics.RectF, int);
     method public int saveLayerAlpha(float, float, float, float, int, int);
+    method public int saveLayerAlpha(float, float, float, float, int);
     method public void scale(float, float);
     method public final void scale(float, float, float, float);
     method public void setBitmap(android.graphics.Bitmap);
@@ -9382,6 +10745,8 @@
     field public static final int JPEG = 256; // 0x100
     field public static final int NV16 = 16; // 0x10
     field public static final int NV21 = 17; // 0x11
+    field public static final int RAW10 = 37; // 0x25
+    field public static final int RAW_SENSOR = 32; // 0x20
     field public static final int RGB_565 = 4; // 0x4
     field public static final int UNKNOWN = 0; // 0x0
     field public static final int YUV_420_888 = 35; // 0x23
@@ -9411,7 +10776,7 @@
     enum_constant public static final android.graphics.Interpolator.Result NORMAL;
   }
 
-  public class LayerRasterizer extends android.graphics.Rasterizer {
+  public deprecated class LayerRasterizer extends android.graphics.Rasterizer {
     ctor public LayerRasterizer();
     method public void addLayer(android.graphics.Paint, float, float);
     method public void addLayer(android.graphics.Paint);
@@ -9435,6 +10800,7 @@
     ctor public Matrix(android.graphics.Matrix);
     method public void getValues(float[]);
     method public boolean invert(android.graphics.Matrix);
+    method public boolean isAffine();
     method public boolean isIdentity();
     method public void mapPoints(float[], int, float[], int, int);
     method public void mapPoints(float[], float[]);
@@ -9529,6 +10895,24 @@
     method public void setPaint(android.graphics.Paint);
   }
 
+  public final class Outline {
+    ctor public Outline();
+    ctor public Outline(android.graphics.Outline);
+    method public boolean canClip();
+    method public float getAlpha();
+    method public boolean isEmpty();
+    method public void set(android.graphics.Outline);
+    method public void setAlpha(float);
+    method public void setConvexPath(android.graphics.Path);
+    method public void setEmpty();
+    method public void setOval(int, int, int, int);
+    method public void setOval(android.graphics.Rect);
+    method public void setRect(int, int, int, int);
+    method public void setRect(android.graphics.Rect);
+    method public void setRoundRect(int, int, int, int, float);
+    method public void setRoundRect(android.graphics.Rect, float);
+  }
+
   public class Paint {
     ctor public Paint();
     ctor public Paint(int);
@@ -9544,15 +10928,17 @@
     method public android.graphics.ColorFilter getColorFilter();
     method public boolean getFillPath(android.graphics.Path, android.graphics.Path);
     method public int getFlags();
+    method public java.lang.String getFontFeatureSettings();
     method public float getFontMetrics(android.graphics.Paint.FontMetrics);
     method public android.graphics.Paint.FontMetrics getFontMetrics();
     method public int getFontMetricsInt(android.graphics.Paint.FontMetricsInt);
     method public android.graphics.Paint.FontMetricsInt getFontMetricsInt();
     method public float getFontSpacing();
     method public int getHinting();
+    method public float getLetterSpacing();
     method public android.graphics.MaskFilter getMaskFilter();
     method public android.graphics.PathEffect getPathEffect();
-    method public android.graphics.Rasterizer getRasterizer();
+    method public deprecated android.graphics.Rasterizer getRasterizer();
     method public android.graphics.Shader getShader();
     method public android.graphics.Paint.Cap getStrokeCap();
     method public android.graphics.Paint.Join getStrokeJoin();
@@ -9576,6 +10962,7 @@
     method public android.graphics.Xfermode getXfermode();
     method public final boolean isAntiAlias();
     method public final boolean isDither();
+    method public boolean isElegantTextHeight();
     method public final boolean isFakeBoldText();
     method public final boolean isFilterBitmap();
     method public final boolean isLinearText();
@@ -9594,14 +10981,17 @@
     method public void setColor(int);
     method public android.graphics.ColorFilter setColorFilter(android.graphics.ColorFilter);
     method public void setDither(boolean);
+    method public void setElegantTextHeight(boolean);
     method public void setFakeBoldText(boolean);
     method public void setFilterBitmap(boolean);
     method public void setFlags(int);
+    method public void setFontFeatureSettings(java.lang.String);
     method public void setHinting(int);
+    method public void setLetterSpacing(float);
     method public void setLinearText(boolean);
     method public android.graphics.MaskFilter setMaskFilter(android.graphics.MaskFilter);
     method public android.graphics.PathEffect setPathEffect(android.graphics.PathEffect);
-    method public android.graphics.Rasterizer setRasterizer(android.graphics.Rasterizer);
+    method public deprecated android.graphics.Rasterizer setRasterizer(android.graphics.Rasterizer);
     method public android.graphics.Shader setShader(android.graphics.Shader);
     method public void setShadowLayer(float, float, float, int);
     method public void setStrikeThruText(boolean);
@@ -9691,22 +11081,28 @@
     ctor public Path();
     ctor public Path(android.graphics.Path);
     method public void addArc(android.graphics.RectF, float, float);
+    method public void addArc(float, float, float, float, float, float);
     method public void addCircle(float, float, float, android.graphics.Path.Direction);
     method public void addOval(android.graphics.RectF, android.graphics.Path.Direction);
+    method public void addOval(float, float, float, float, android.graphics.Path.Direction);
     method public void addPath(android.graphics.Path, float, float);
     method public void addPath(android.graphics.Path);
     method public void addPath(android.graphics.Path, android.graphics.Matrix);
     method public void addRect(android.graphics.RectF, android.graphics.Path.Direction);
     method public void addRect(float, float, float, float, android.graphics.Path.Direction);
     method public void addRoundRect(android.graphics.RectF, float, float, android.graphics.Path.Direction);
+    method public void addRoundRect(float, float, float, float, float, float, android.graphics.Path.Direction);
     method public void addRoundRect(android.graphics.RectF, float[], android.graphics.Path.Direction);
+    method public void addRoundRect(float, float, float, float, float[], android.graphics.Path.Direction);
     method public void arcTo(android.graphics.RectF, float, float, boolean);
     method public void arcTo(android.graphics.RectF, float, float);
+    method public void arcTo(float, float, float, float, float, float, boolean);
     method public void close();
     method public void computeBounds(android.graphics.RectF, boolean);
     method public void cubicTo(float, float, float, float, float, float);
     method public android.graphics.Path.FillType getFillType();
     method public void incReserve(int);
+    method public boolean isConvex();
     method public boolean isEmpty();
     method public boolean isInverseFillType();
     method public boolean isRect(android.graphics.RectF);
@@ -9904,7 +11300,7 @@
     ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
-  public class Rasterizer {
+  public deprecated class Rasterizer {
     ctor public Rasterizer();
   }
 
@@ -10073,6 +11469,7 @@
     method public void releaseTexImage();
     method public void setDefaultBufferSize(int, int);
     method public void setOnFrameAvailableListener(android.graphics.SurfaceTexture.OnFrameAvailableListener);
+    method public void setOnFrameAvailableListener(android.graphics.SurfaceTexture.OnFrameAvailableListener, android.os.Handler);
     method public void updateTexImage();
   }
 
@@ -10135,6 +11532,23 @@
     method public abstract void stop();
   }
 
+  public class AnimatedStateListDrawable extends android.graphics.drawable.StateListDrawable {
+    ctor public AnimatedStateListDrawable();
+    method public void addState(int[], android.graphics.drawable.Drawable, int);
+    method public void addTransition(int, int, T, boolean);
+  }
+
+  public class AnimatedVectorDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable {
+    ctor public AnimatedVectorDrawable();
+    method public void draw(android.graphics.Canvas);
+    method public int getOpacity();
+    method public boolean isRunning();
+    method public void setAlpha(int);
+    method public void setColorFilter(android.graphics.ColorFilter);
+    method public void start();
+    method public void stop();
+  }
+
   public class AnimationDrawable extends android.graphics.drawable.DrawableContainer implements android.graphics.drawable.Animatable java.lang.Runnable {
     ctor public AnimationDrawable();
     method public void addFrame(android.graphics.drawable.Drawable, int);
@@ -10208,6 +11622,8 @@
 
   public abstract class Drawable {
     ctor public Drawable();
+    method public void applyTheme(android.content.res.Resources.Theme);
+    method public boolean canApplyTheme();
     method public void clearColorFilter();
     method public final void copyBounds(android.graphics.Rect);
     method public final android.graphics.Rect copyBounds();
@@ -10216,24 +11632,30 @@
     method public static android.graphics.drawable.Drawable createFromResourceStream(android.content.res.Resources, android.util.TypedValue, java.io.InputStream, java.lang.String, android.graphics.BitmapFactory.Options);
     method public static android.graphics.drawable.Drawable createFromStream(java.io.InputStream, java.lang.String);
     method public static android.graphics.drawable.Drawable createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static android.graphics.drawable.Drawable createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static android.graphics.drawable.Drawable createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static android.graphics.drawable.Drawable createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public abstract void draw(android.graphics.Canvas);
     method public int getAlpha();
     method public final android.graphics.Rect getBounds();
     method public android.graphics.drawable.Drawable.Callback getCallback();
     method public int getChangingConfigurations();
+    method public android.graphics.ColorFilter getColorFilter();
     method public android.graphics.drawable.Drawable.ConstantState getConstantState();
     method public android.graphics.drawable.Drawable getCurrent();
+    method public android.graphics.Rect getDirtyBounds();
     method public int getIntrinsicHeight();
     method public int getIntrinsicWidth();
     method public final int getLevel();
     method public int getMinimumHeight();
     method public int getMinimumWidth();
     method public abstract int getOpacity();
+    method public void getOutline(android.graphics.Outline);
     method public boolean getPadding(android.graphics.Rect);
     method public int[] getState();
     method public android.graphics.Region getTransparentRegion();
     method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public void invalidateSelf();
     method public boolean isAutoMirrored();
     method public boolean isStateful();
@@ -10255,8 +11677,13 @@
     method public void setColorFilter(int, android.graphics.PorterDuff.Mode);
     method public void setDither(boolean);
     method public void setFilterBitmap(boolean);
+    method public void setHotspot(float, float);
+    method public void setHotspotBounds(int, int, int, int);
     method public final boolean setLevel(int);
     method public boolean setState(int[]);
+    method public void setTint(int);
+    method public void setTintList(android.content.res.ColorStateList);
+    method public void setTintMode(android.graphics.PorterDuff.Mode);
     method public boolean setVisible(boolean, boolean);
     method public void unscheduleSelf(java.lang.Runnable);
   }
@@ -10269,9 +11696,11 @@
 
   public static abstract class Drawable.ConstantState {
     ctor public Drawable.ConstantState();
+    method public boolean canApplyTheme();
     method public abstract int getChangingConfigurations();
     method public abstract android.graphics.drawable.Drawable newDrawable();
     method public android.graphics.drawable.Drawable newDrawable(android.content.res.Resources);
+    method public android.graphics.drawable.Drawable newDrawable(android.content.res.Resources, android.content.res.Resources.Theme);
   }
 
   public class DrawableContainer extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
@@ -10318,10 +11747,12 @@
     ctor public GradientDrawable();
     ctor public GradientDrawable(android.graphics.drawable.GradientDrawable.Orientation, int[]);
     method public void draw(android.graphics.Canvas);
+    method public float getGradientRadius();
     method public int getOpacity();
     method public android.graphics.drawable.GradientDrawable.Orientation getOrientation();
     method public void setAlpha(int);
     method public void setColor(int);
+    method public void setColor(android.content.res.ColorStateList);
     method public void setColorFilter(android.graphics.ColorFilter);
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
@@ -10333,7 +11764,9 @@
     method public void setShape(int);
     method public void setSize(int, int);
     method public void setStroke(int, int);
+    method public void setStroke(int, android.content.res.ColorStateList);
     method public void setStroke(int, int, float, float);
+    method public void setStroke(int, android.content.res.ColorStateList, float, float);
     method public void setUseLevel(boolean);
     field public static final int LINE = 2; // 0x2
     field public static final int LINEAR_GRADIENT = 0; // 0x0
@@ -10378,6 +11811,7 @@
     method public int getId(int);
     method public int getNumberOfLayers();
     method public int getOpacity();
+    method public int getPaddingMode();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
@@ -10386,7 +11820,10 @@
     method public void setId(int, int);
     method public void setLayerInset(int, int, int, int, int);
     method public void setOpacity(int);
+    method public void setPaddingMode(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
+    field public static final int PADDING_MODE_NEST = 0; // 0x0
+    field public static final int PADDING_MODE_STACK = 1; // 0x1
   }
 
   public class LevelListDrawable extends android.graphics.drawable.DrawableContainer {
@@ -10426,15 +11863,33 @@
     method public void setPicture(android.graphics.Picture);
   }
 
+  public class RippleDrawable extends android.graphics.drawable.LayerDrawable {
+    ctor public RippleDrawable(android.content.res.ColorStateList, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+    method public void setColor(android.content.res.ColorStateList);
+  }
+
   public class RotateDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
     ctor public RotateDrawable();
     method public void draw(android.graphics.Canvas);
     method public android.graphics.drawable.Drawable getDrawable();
+    method public float getFromDegrees();
     method public int getOpacity();
+    method public float getPivotX();
+    method public float getPivotY();
+    method public float getToDegrees();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
+    method public boolean isPivotXRelative();
+    method public boolean isPivotYRelative();
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setFromDegrees(float);
+    method public void setPivotX(float);
+    method public void setPivotXRelative(boolean);
+    method public void setPivotY(float);
+    method public void setPivotYRelative(boolean);
+    method public void setToDegrees(float);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
 
@@ -10489,6 +11944,14 @@
     method public void startTransition(int);
   }
 
+  public class VectorDrawable extends android.graphics.drawable.Drawable {
+    ctor public VectorDrawable();
+    method public void draw(android.graphics.Canvas);
+    method public int getOpacity();
+    method public void setAlpha(int);
+    method public void setColorFilter(android.graphics.ColorFilter);
+  }
+
 }
 
 package android.graphics.drawable.shapes {
@@ -10521,6 +11984,7 @@
     method public android.graphics.drawable.shapes.Shape clone() throws java.lang.CloneNotSupportedException;
     method public abstract void draw(android.graphics.Canvas, android.graphics.Paint);
     method public final float getHeight();
+    method public void getOutline(android.graphics.Outline);
     method public final float getWidth();
     method public boolean hasAlpha();
     method protected void onResize(float, float);
@@ -10558,11 +12022,29 @@
     method public android.graphics.pdf.PdfDocument.PageInfo.Builder setContentRect(android.graphics.Rect);
   }
 
+  public final class PdfRenderer implements java.lang.AutoCloseable {
+    ctor public PdfRenderer(android.os.ParcelFileDescriptor) throws java.io.IOException;
+    method public void close();
+    method public int getPageCount();
+    method public android.graphics.pdf.PdfRenderer.Page openPage(int);
+    method public boolean shouldScaleForPrinting();
+  }
+
+  public final class PdfRenderer.Page implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getHeight();
+    method public int getIndex();
+    method public int getWidth();
+    method public void render(android.graphics.Bitmap, android.graphics.Rect, android.graphics.Matrix, int);
+    field public static final int RENDER_MODE_FOR_DISPLAY = 1; // 0x1
+    field public static final int RENDER_MODE_FOR_PRINT = 2; // 0x2
+  }
+
 }
 
 package android.hardware {
 
-  public class Camera {
+  public deprecated class Camera {
     method public final void addCallbackBuffer(byte[]);
     method public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
     method public final void cancelAutoFocus();
@@ -10601,21 +12083,21 @@
     field public static final int CAMERA_ERROR_UNKNOWN = 1; // 0x1
   }
 
-  public static class Camera.Area {
+  public static deprecated class Camera.Area {
     ctor public Camera.Area(android.graphics.Rect, int);
     field public android.graphics.Rect rect;
     field public int weight;
   }
 
-  public static abstract interface Camera.AutoFocusCallback {
+  public static abstract deprecated interface Camera.AutoFocusCallback {
     method public abstract void onAutoFocus(boolean, android.hardware.Camera);
   }
 
-  public static abstract interface Camera.AutoFocusMoveCallback {
+  public static abstract deprecated interface Camera.AutoFocusMoveCallback {
     method public abstract void onAutoFocusMoving(boolean, android.hardware.Camera);
   }
 
-  public static class Camera.CameraInfo {
+  public static deprecated class Camera.CameraInfo {
     ctor public Camera.CameraInfo();
     field public static final int CAMERA_FACING_BACK = 0; // 0x0
     field public static final int CAMERA_FACING_FRONT = 1; // 0x1
@@ -10624,11 +12106,11 @@
     field public int orientation;
   }
 
-  public static abstract interface Camera.ErrorCallback {
+  public static abstract deprecated interface Camera.ErrorCallback {
     method public abstract void onError(int, android.hardware.Camera);
   }
 
-  public static class Camera.Face {
+  public static deprecated class Camera.Face {
     ctor public Camera.Face();
     field public int id;
     field public android.graphics.Point leftEye;
@@ -10638,15 +12120,15 @@
     field public int score;
   }
 
-  public static abstract interface Camera.FaceDetectionListener {
+  public static abstract deprecated interface Camera.FaceDetectionListener {
     method public abstract void onFaceDetection(android.hardware.Camera.Face[], android.hardware.Camera);
   }
 
-  public static abstract interface Camera.OnZoomChangeListener {
+  public static abstract deprecated interface Camera.OnZoomChangeListener {
     method public abstract void onZoomChange(int, boolean, android.hardware.Camera);
   }
 
-  public class Camera.Parameters {
+  public deprecated class Camera.Parameters {
     method public java.lang.String flatten();
     method public java.lang.String get(java.lang.String);
     method public java.lang.String getAntibanding();
@@ -10796,19 +12278,19 @@
     field public static final java.lang.String WHITE_BALANCE_WARM_FLUORESCENT = "warm-fluorescent";
   }
 
-  public static abstract interface Camera.PictureCallback {
+  public static abstract deprecated interface Camera.PictureCallback {
     method public abstract void onPictureTaken(byte[], android.hardware.Camera);
   }
 
-  public static abstract interface Camera.PreviewCallback {
+  public static abstract deprecated interface Camera.PreviewCallback {
     method public abstract void onPreviewFrame(byte[], android.hardware.Camera);
   }
 
-  public static abstract interface Camera.ShutterCallback {
+  public static abstract deprecated interface Camera.ShutterCallback {
     method public abstract void onShutter();
   }
 
-  public class Camera.Size {
+  public deprecated class Camera.Size {
     ctor public Camera.Size(int, int);
     field public int height;
     field public int width;
@@ -10840,15 +12322,22 @@
   public final class Sensor {
     method public int getFifoMaxEventCount();
     method public int getFifoReservedEventCount();
+    method public int getMaxDelay();
     method public float getMaximumRange();
     method public int getMinDelay();
     method public java.lang.String getName();
     method public float getPower();
+    method public int getReportingMode();
     method public float getResolution();
     method public java.lang.String getStringType();
     method public int getType();
     method public java.lang.String getVendor();
     method public int getVersion();
+    method public boolean isWakeUpSensor();
+    field public static final int REPORTING_MODE_CONTINUOUS = 0; // 0x0
+    field public static final int REPORTING_MODE_ONE_SHOT = 2; // 0x2
+    field public static final int REPORTING_MODE_ON_CHANGE = 1; // 0x1
+    field public static final int REPORTING_MODE_SPECIAL_TRIGGER = 3; // 0x3
     field public static final java.lang.String STRING_TYPE_ACCELEROMETER = "android.sensor.accelerometer";
     field public static final java.lang.String STRING_TYPE_AMBIENT_TEMPERATURE = "android.sensor.ambient_temperature";
     field public static final java.lang.String STRING_TYPE_GAME_ROTATION_VECTOR = "android.sensor.game_rotation_vector";
@@ -10921,6 +12410,7 @@
     method public static float getAltitude(float, float);
     method public static void getAngleChange(float[], float[], float[]);
     method public android.hardware.Sensor getDefaultSensor(int);
+    method public android.hardware.Sensor getDefaultSensor(int, boolean);
     method public static float getInclination(float[]);
     method public static float[] getOrientation(float[], float[]);
     method public static void getQuaternionFromVector(float[], float[]);
@@ -11013,16 +12503,640 @@
 
 }
 
+package android.hardware.camera2 {
+
+  public class CameraAccessException extends android.util.AndroidException {
+    ctor public CameraAccessException(int);
+    ctor public CameraAccessException(int, java.lang.String);
+    ctor public CameraAccessException(int, java.lang.String, java.lang.Throwable);
+    ctor public CameraAccessException(int, java.lang.Throwable);
+    method public final int getReason();
+    field public static final int CAMERA_DISABLED = 1; // 0x1
+    field public static final int CAMERA_DISCONNECTED = 2; // 0x2
+    field public static final int CAMERA_ERROR = 3; // 0x3
+  }
+
+  public abstract class CameraCaptureSession implements java.lang.AutoCloseable {
+    ctor public CameraCaptureSession();
+    method public abstract void abortCaptures() throws android.hardware.camera2.CameraAccessException;
+    method public abstract int capture(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract int captureBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void close();
+    method public abstract android.hardware.camera2.CameraDevice getDevice();
+    method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
+  }
+
+  public static abstract class CameraCaptureSession.CaptureCallback {
+    ctor public CameraCaptureSession.CaptureCallback();
+    method public void onCaptureCompleted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.TotalCaptureResult);
+    method public void onCaptureFailed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureFailure);
+    method public void onCaptureProgressed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult);
+    method public void onCaptureSequenceAborted(android.hardware.camera2.CameraCaptureSession, int);
+    method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraCaptureSession, int, long);
+    method public void onCaptureStarted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, long, long);
+  }
+
+  public static abstract class CameraCaptureSession.StateCallback {
+    ctor public CameraCaptureSession.StateCallback();
+    method public void onActive(android.hardware.camera2.CameraCaptureSession);
+    method public void onClosed(android.hardware.camera2.CameraCaptureSession);
+    method public abstract void onConfigureFailed(android.hardware.camera2.CameraCaptureSession);
+    method public abstract void onConfigured(android.hardware.camera2.CameraCaptureSession);
+    method public void onReady(android.hardware.camera2.CameraCaptureSession);
+  }
+
+  public final class CameraCharacteristics extends android.hardware.camera2.CameraMetadata {
+    method public T get(android.hardware.camera2.CameraCharacteristics.Key<T>);
+    method public java.util.List<android.hardware.camera2.CaptureRequest.Key<?>> getAvailableCaptureRequestKeys();
+    method public java.util.List<android.hardware.camera2.CaptureResult.Key<?>> getAvailableCaptureResultKeys();
+    field public static final android.hardware.camera2.CameraCharacteristics.Key COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AE_AVAILABLE_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AE_COMPENSATION_RANGE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AE_COMPENSATION_STEP;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AF_AVAILABLE_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AVAILABLE_EFFECTS;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AVAILABLE_SCENE_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_AWB_AVAILABLE_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_MAX_REGIONS_AE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_MAX_REGIONS_AF;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key CONTROL_MAX_REGIONS_AWB;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key EDGE_AVAILABLE_EDGE_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key FLASH_INFO_AVAILABLE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key INFO_SUPPORTED_HARDWARE_LEVEL;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key JPEG_AVAILABLE_THUMBNAIL_SIZES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_FACING;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_AVAILABLE_APERTURES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_AVAILABLE_FILTER_DENSITIES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_AVAILABLE_FOCAL_LENGTHS;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_FOCUS_DISTANCE_CALIBRATION;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_HYPERFOCAL_DISTANCE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key LENS_INFO_MINIMUM_FOCUS_DISTANCE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_AVAILABLE_CAPABILITIES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_PROC;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_PROC_STALLING;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_MAX_NUM_OUTPUT_RAW;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_PARTIAL_RESULT_COUNT;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key REQUEST_PIPELINE_MAX_DEPTH;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SCALER_AVAILABLE_MAX_DIGITAL_ZOOM;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SCALER_CROPPING_TYPE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SCALER_STREAM_CONFIGURATION_MAP;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_AVAILABLE_TEST_PATTERN_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_BLACK_LEVEL_PATTERN;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_CALIBRATION_TRANSFORM1;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_CALIBRATION_TRANSFORM2;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_COLOR_TRANSFORM1;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_COLOR_TRANSFORM2;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_FORWARD_MATRIX1;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_FORWARD_MATRIX2;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_ACTIVE_ARRAY_SIZE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_COLOR_FILTER_ARRANGEMENT;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_EXPOSURE_TIME_RANGE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_MAX_FRAME_DURATION;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_PHYSICAL_SIZE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_PIXEL_ARRAY_SIZE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_SENSITIVITY_RANGE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_TIMESTAMP_SOURCE;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_INFO_WHITE_LEVEL;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_MAX_ANALOG_SENSITIVITY;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_ORIENTATION;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_REFERENCE_ILLUMINANT1;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SENSOR_REFERENCE_ILLUMINANT2;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key STATISTICS_INFO_MAX_FACE_COUNT;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key SYNC_MAX_LATENCY;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key TONEMAP_AVAILABLE_TONE_MAP_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key TONEMAP_MAX_CURVE_POINTS;
+  }
+
+  public static final class CameraCharacteristics.Key {
+    method public final boolean equals(java.lang.Object);
+    method public java.lang.String getName();
+    method public final int hashCode();
+  }
+
+  public abstract class CameraDevice implements java.lang.AutoCloseable {
+    method public abstract void close();
+    method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract java.lang.String getId();
+    field public static final int TEMPLATE_MANUAL = 6; // 0x6
+    field public static final int TEMPLATE_PREVIEW = 1; // 0x1
+    field public static final int TEMPLATE_RECORD = 3; // 0x3
+    field public static final int TEMPLATE_STILL_CAPTURE = 2; // 0x2
+    field public static final int TEMPLATE_VIDEO_SNAPSHOT = 4; // 0x4
+    field public static final int TEMPLATE_ZERO_SHUTTER_LAG = 5; // 0x5
+  }
+
+  public static abstract class CameraDevice.StateCallback {
+    ctor public CameraDevice.StateCallback();
+    method public void onClosed(android.hardware.camera2.CameraDevice);
+    method public abstract void onDisconnected(android.hardware.camera2.CameraDevice);
+    method public abstract void onError(android.hardware.camera2.CameraDevice, int);
+    method public abstract void onOpened(android.hardware.camera2.CameraDevice);
+    field public static final int ERROR_CAMERA_DEVICE = 4; // 0x4
+    field public static final int ERROR_CAMERA_DISABLED = 3; // 0x3
+    field public static final int ERROR_CAMERA_IN_USE = 1; // 0x1
+    field public static final int ERROR_CAMERA_SERVICE = 5; // 0x5
+    field public static final int ERROR_MAX_CAMERAS_IN_USE = 2; // 0x2
+  }
+
+  public final class CameraManager {
+    method public android.hardware.camera2.CameraCharacteristics getCameraCharacteristics(java.lang.String) throws android.hardware.camera2.CameraAccessException;
+    method public java.lang.String[] getCameraIdList() throws android.hardware.camera2.CameraAccessException;
+    method public void openCamera(java.lang.String, android.hardware.camera2.CameraDevice.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public void registerAvailabilityCallback(android.hardware.camera2.CameraManager.AvailabilityCallback, android.os.Handler);
+    method public void unregisterAvailabilityCallback(android.hardware.camera2.CameraManager.AvailabilityCallback);
+  }
+
+  public static abstract class CameraManager.AvailabilityCallback {
+    ctor public CameraManager.AvailabilityCallback();
+    method public void onCameraAvailable(java.lang.String);
+    method public void onCameraUnavailable(java.lang.String);
+  }
+
+  public abstract class CameraMetadata {
+    method public java.util.List<TKey> getKeys();
+    field public static final int COLOR_CORRECTION_ABERRATION_MODE_FAST = 1; // 0x1
+    field public static final int COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int COLOR_CORRECTION_ABERRATION_MODE_OFF = 0; // 0x0
+    field public static final int COLOR_CORRECTION_MODE_FAST = 1; // 0x1
+    field public static final int COLOR_CORRECTION_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0; // 0x0
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_50HZ = 1; // 0x1
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_60HZ = 2; // 0x2
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_AUTO = 3; // 0x3
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AE_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AE_MODE_ON = 1; // 0x1
+    field public static final int CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3; // 0x3
+    field public static final int CONTROL_AE_MODE_ON_AUTO_FLASH = 2; // 0x2
+    field public static final int CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4; // 0x4
+    field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_IDLE = 0; // 0x0
+    field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_START = 1; // 0x1
+    field public static final int CONTROL_AE_STATE_CONVERGED = 2; // 0x2
+    field public static final int CONTROL_AE_STATE_FLASH_REQUIRED = 4; // 0x4
+    field public static final int CONTROL_AE_STATE_INACTIVE = 0; // 0x0
+    field public static final int CONTROL_AE_STATE_LOCKED = 3; // 0x3
+    field public static final int CONTROL_AE_STATE_PRECAPTURE = 5; // 0x5
+    field public static final int CONTROL_AE_STATE_SEARCHING = 1; // 0x1
+    field public static final int CONTROL_AF_MODE_AUTO = 1; // 0x1
+    field public static final int CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4; // 0x4
+    field public static final int CONTROL_AF_MODE_CONTINUOUS_VIDEO = 3; // 0x3
+    field public static final int CONTROL_AF_MODE_EDOF = 5; // 0x5
+    field public static final int CONTROL_AF_MODE_MACRO = 2; // 0x2
+    field public static final int CONTROL_AF_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AF_STATE_ACTIVE_SCAN = 3; // 0x3
+    field public static final int CONTROL_AF_STATE_FOCUSED_LOCKED = 4; // 0x4
+    field public static final int CONTROL_AF_STATE_INACTIVE = 0; // 0x0
+    field public static final int CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5; // 0x5
+    field public static final int CONTROL_AF_STATE_PASSIVE_FOCUSED = 2; // 0x2
+    field public static final int CONTROL_AF_STATE_PASSIVE_SCAN = 1; // 0x1
+    field public static final int CONTROL_AF_STATE_PASSIVE_UNFOCUSED = 6; // 0x6
+    field public static final int CONTROL_AF_TRIGGER_CANCEL = 2; // 0x2
+    field public static final int CONTROL_AF_TRIGGER_IDLE = 0; // 0x0
+    field public static final int CONTROL_AF_TRIGGER_START = 1; // 0x1
+    field public static final int CONTROL_AWB_MODE_AUTO = 1; // 0x1
+    field public static final int CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6; // 0x6
+    field public static final int CONTROL_AWB_MODE_DAYLIGHT = 5; // 0x5
+    field public static final int CONTROL_AWB_MODE_FLUORESCENT = 3; // 0x3
+    field public static final int CONTROL_AWB_MODE_INCANDESCENT = 2; // 0x2
+    field public static final int CONTROL_AWB_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AWB_MODE_SHADE = 8; // 0x8
+    field public static final int CONTROL_AWB_MODE_TWILIGHT = 7; // 0x7
+    field public static final int CONTROL_AWB_MODE_WARM_FLUORESCENT = 4; // 0x4
+    field public static final int CONTROL_AWB_STATE_CONVERGED = 2; // 0x2
+    field public static final int CONTROL_AWB_STATE_INACTIVE = 0; // 0x0
+    field public static final int CONTROL_AWB_STATE_LOCKED = 3; // 0x3
+    field public static final int CONTROL_AWB_STATE_SEARCHING = 1; // 0x1
+    field public static final int CONTROL_CAPTURE_INTENT_CUSTOM = 0; // 0x0
+    field public static final int CONTROL_CAPTURE_INTENT_MANUAL = 6; // 0x6
+    field public static final int CONTROL_CAPTURE_INTENT_PREVIEW = 1; // 0x1
+    field public static final int CONTROL_CAPTURE_INTENT_STILL_CAPTURE = 2; // 0x2
+    field public static final int CONTROL_CAPTURE_INTENT_VIDEO_RECORD = 3; // 0x3
+    field public static final int CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4; // 0x4
+    field public static final int CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5; // 0x5
+    field public static final int CONTROL_EFFECT_MODE_AQUA = 8; // 0x8
+    field public static final int CONTROL_EFFECT_MODE_BLACKBOARD = 7; // 0x7
+    field public static final int CONTROL_EFFECT_MODE_MONO = 1; // 0x1
+    field public static final int CONTROL_EFFECT_MODE_NEGATIVE = 2; // 0x2
+    field public static final int CONTROL_EFFECT_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_EFFECT_MODE_POSTERIZE = 5; // 0x5
+    field public static final int CONTROL_EFFECT_MODE_SEPIA = 4; // 0x4
+    field public static final int CONTROL_EFFECT_MODE_SOLARIZE = 3; // 0x3
+    field public static final int CONTROL_EFFECT_MODE_WHITEBOARD = 6; // 0x6
+    field public static final int CONTROL_MODE_AUTO = 1; // 0x1
+    field public static final int CONTROL_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_MODE_OFF_KEEP_STATE = 3; // 0x3
+    field public static final int CONTROL_MODE_USE_SCENE_MODE = 2; // 0x2
+    field public static final int CONTROL_SCENE_MODE_ACTION = 2; // 0x2
+    field public static final int CONTROL_SCENE_MODE_BARCODE = 16; // 0x10
+    field public static final int CONTROL_SCENE_MODE_BEACH = 8; // 0x8
+    field public static final int CONTROL_SCENE_MODE_CANDLELIGHT = 15; // 0xf
+    field public static final int CONTROL_SCENE_MODE_DISABLED = 0; // 0x0
+    field public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1; // 0x1
+    field public static final int CONTROL_SCENE_MODE_FIREWORKS = 12; // 0xc
+    field public static final int CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17; // 0x11
+    field public static final int CONTROL_SCENE_MODE_LANDSCAPE = 4; // 0x4
+    field public static final int CONTROL_SCENE_MODE_NIGHT = 5; // 0x5
+    field public static final int CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6; // 0x6
+    field public static final int CONTROL_SCENE_MODE_PARTY = 14; // 0xe
+    field public static final int CONTROL_SCENE_MODE_PORTRAIT = 3; // 0x3
+    field public static final int CONTROL_SCENE_MODE_SNOW = 9; // 0x9
+    field public static final int CONTROL_SCENE_MODE_SPORTS = 13; // 0xd
+    field public static final int CONTROL_SCENE_MODE_STEADYPHOTO = 11; // 0xb
+    field public static final int CONTROL_SCENE_MODE_SUNSET = 10; // 0xa
+    field public static final int CONTROL_SCENE_MODE_THEATRE = 7; // 0x7
+    field public static final int CONTROL_VIDEO_STABILIZATION_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_VIDEO_STABILIZATION_MODE_ON = 1; // 0x1
+    field public static final int EDGE_MODE_FAST = 1; // 0x1
+    field public static final int EDGE_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int EDGE_MODE_OFF = 0; // 0x0
+    field public static final int FLASH_MODE_OFF = 0; // 0x0
+    field public static final int FLASH_MODE_SINGLE = 1; // 0x1
+    field public static final int FLASH_MODE_TORCH = 2; // 0x2
+    field public static final int FLASH_STATE_CHARGING = 1; // 0x1
+    field public static final int FLASH_STATE_FIRED = 3; // 0x3
+    field public static final int FLASH_STATE_PARTIAL = 4; // 0x4
+    field public static final int FLASH_STATE_READY = 2; // 0x2
+    field public static final int FLASH_STATE_UNAVAILABLE = 0; // 0x0
+    field public static final int HOT_PIXEL_MODE_FAST = 1; // 0x1
+    field public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int HOT_PIXEL_MODE_OFF = 0; // 0x0
+    field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1
+    field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2; // 0x2
+    field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0
+    field public static final int LENS_FACING_BACK = 1; // 0x1
+    field public static final int LENS_FACING_FRONT = 0; // 0x0
+    field public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE = 1; // 0x1
+    field public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED = 2; // 0x2
+    field public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED = 0; // 0x0
+    field public static final int LENS_OPTICAL_STABILIZATION_MODE_OFF = 0; // 0x0
+    field public static final int LENS_OPTICAL_STABILIZATION_MODE_ON = 1; // 0x1
+    field public static final int LENS_STATE_MOVING = 1; // 0x1
+    field public static final int LENS_STATE_STATIONARY = 0; // 0x0
+    field public static final int NOISE_REDUCTION_MODE_FAST = 1; // 0x1
+    field public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int NOISE_REDUCTION_MODE_OFF = 0; // 0x0
+    field public static final int REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0; // 0x0
+    field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2
+    field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1
+    field public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3; // 0x3
+    field public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0; // 0x0
+    field public static final int SCALER_CROPPING_TYPE_FREEFORM = 1; // 0x1
+    field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR = 3; // 0x3
+    field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG = 2; // 0x2
+    field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG = 1; // 0x1
+    field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4; // 0x4
+    field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB = 0; // 0x0
+    field public static final int SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME = 1; // 0x1
+    field public static final int SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN = 0; // 0x0
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER = 10; // 0xa
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT = 14; // 0xe
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_D50 = 23; // 0x17
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_D55 = 20; // 0x14
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_D65 = 21; // 0x15
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_D75 = 22; // 0x16
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT = 1; // 0x1
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT = 12; // 0xc
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT = 13; // 0xd
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_FINE_WEATHER = 9; // 0x9
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_FLASH = 4; // 0x4
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT = 2; // 0x2
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN = 24; // 0x18
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_SHADE = 11; // 0xb
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A = 17; // 0x11
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B = 18; // 0x12
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C = 19; // 0x13
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN = 3; // 0x3
+    field public static final int SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT = 15; // 0xf
+    field public static final int SENSOR_TEST_PATTERN_MODE_COLOR_BARS = 2; // 0x2
+    field public static final int SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY = 3; // 0x3
+    field public static final int SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256; // 0x100
+    field public static final int SENSOR_TEST_PATTERN_MODE_OFF = 0; // 0x0
+    field public static final int SENSOR_TEST_PATTERN_MODE_PN9 = 4; // 0x4
+    field public static final int SENSOR_TEST_PATTERN_MODE_SOLID_COLOR = 1; // 0x1
+    field public static final int SHADING_MODE_FAST = 1; // 0x1
+    field public static final int SHADING_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int SHADING_MODE_OFF = 0; // 0x0
+    field public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2; // 0x2
+    field public static final int STATISTICS_FACE_DETECT_MODE_OFF = 0; // 0x0
+    field public static final int STATISTICS_FACE_DETECT_MODE_SIMPLE = 1; // 0x1
+    field public static final int STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0; // 0x0
+    field public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1; // 0x1
+    field public static final int STATISTICS_SCENE_FLICKER_50HZ = 1; // 0x1
+    field public static final int STATISTICS_SCENE_FLICKER_60HZ = 2; // 0x2
+    field public static final int STATISTICS_SCENE_FLICKER_NONE = 0; // 0x0
+    field public static final int SYNC_MAX_LATENCY_PER_FRAME_CONTROL = 0; // 0x0
+    field public static final int SYNC_MAX_LATENCY_UNKNOWN = -1; // 0xffffffff
+    field public static final int TONEMAP_MODE_CONTRAST_CURVE = 0; // 0x0
+    field public static final int TONEMAP_MODE_FAST = 1; // 0x1
+    field public static final int TONEMAP_MODE_HIGH_QUALITY = 2; // 0x2
+  }
+
+  public class CaptureFailure {
+    method public long getFrameNumber();
+    method public int getReason();
+    method public android.hardware.camera2.CaptureRequest getRequest();
+    method public int getSequenceId();
+    method public boolean wasImageCaptured();
+    field public static final int REASON_ERROR = 0; // 0x0
+    field public static final int REASON_FLUSHED = 1; // 0x1
+  }
+
+  public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
+    method public int describeContents();
+    method public T get(android.hardware.camera2.CaptureRequest.Key<T>);
+    method public java.lang.Object getTag();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.hardware.camera2.CaptureRequest.Key BLACK_LEVEL_LOCK;
+    field public static final android.hardware.camera2.CaptureRequest.Key COLOR_CORRECTION_ABERRATION_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key COLOR_CORRECTION_GAINS;
+    field public static final android.hardware.camera2.CaptureRequest.Key COLOR_CORRECTION_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key COLOR_CORRECTION_TRANSFORM;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_ANTIBANDING_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_EXPOSURE_COMPENSATION;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_LOCK;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_PRECAPTURE_TRIGGER;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_REGIONS;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AE_TARGET_FPS_RANGE;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AF_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AF_REGIONS;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AF_TRIGGER;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AWB_LOCK;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AWB_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_AWB_REGIONS;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_CAPTURE_INTENT;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_EFFECT_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_SCENE_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key CONTROL_VIDEO_STABILIZATION_MODE;
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final android.hardware.camera2.CaptureRequest.Key EDGE_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key FLASH_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key HOT_PIXEL_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key JPEG_GPS_LOCATION;
+    field public static final android.hardware.camera2.CaptureRequest.Key JPEG_ORIENTATION;
+    field public static final android.hardware.camera2.CaptureRequest.Key JPEG_QUALITY;
+    field public static final android.hardware.camera2.CaptureRequest.Key JPEG_THUMBNAIL_QUALITY;
+    field public static final android.hardware.camera2.CaptureRequest.Key JPEG_THUMBNAIL_SIZE;
+    field public static final android.hardware.camera2.CaptureRequest.Key LENS_APERTURE;
+    field public static final android.hardware.camera2.CaptureRequest.Key LENS_FILTER_DENSITY;
+    field public static final android.hardware.camera2.CaptureRequest.Key LENS_FOCAL_LENGTH;
+    field public static final android.hardware.camera2.CaptureRequest.Key LENS_FOCUS_DISTANCE;
+    field public static final android.hardware.camera2.CaptureRequest.Key LENS_OPTICAL_STABILIZATION_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key NOISE_REDUCTION_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key SCALER_CROP_REGION;
+    field public static final android.hardware.camera2.CaptureRequest.Key SENSOR_EXPOSURE_TIME;
+    field public static final android.hardware.camera2.CaptureRequest.Key SENSOR_FRAME_DURATION;
+    field public static final android.hardware.camera2.CaptureRequest.Key SENSOR_SENSITIVITY;
+    field public static final android.hardware.camera2.CaptureRequest.Key SENSOR_TEST_PATTERN_DATA;
+    field public static final android.hardware.camera2.CaptureRequest.Key SENSOR_TEST_PATTERN_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key SHADING_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key STATISTICS_FACE_DETECT_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key STATISTICS_HOT_PIXEL_MAP_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key STATISTICS_LENS_SHADING_MAP_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_CURVE;
+    field public static final android.hardware.camera2.CaptureRequest.Key TONEMAP_MODE;
+  }
+
+  public static final class CaptureRequest.Builder {
+    method public void addTarget(android.view.Surface);
+    method public android.hardware.camera2.CaptureRequest build();
+    method public T get(android.hardware.camera2.CaptureRequest.Key<T>);
+    method public void removeTarget(android.view.Surface);
+    method public void set(android.hardware.camera2.CaptureRequest.Key<T>, T);
+    method public void setTag(java.lang.Object);
+  }
+
+  public static final class CaptureRequest.Key {
+    method public final boolean equals(java.lang.Object);
+    method public java.lang.String getName();
+    method public final int hashCode();
+  }
+
+  public class CaptureResult extends android.hardware.camera2.CameraMetadata {
+    method public T get(android.hardware.camera2.CaptureResult.Key<T>);
+    method public long getFrameNumber();
+    method public android.hardware.camera2.CaptureRequest getRequest();
+    method public int getSequenceId();
+    field public static final android.hardware.camera2.CaptureResult.Key BLACK_LEVEL_LOCK;
+    field public static final android.hardware.camera2.CaptureResult.Key COLOR_CORRECTION_ABERRATION_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key COLOR_CORRECTION_GAINS;
+    field public static final android.hardware.camera2.CaptureResult.Key COLOR_CORRECTION_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key COLOR_CORRECTION_TRANSFORM;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_ANTIBANDING_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_EXPOSURE_COMPENSATION;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_LOCK;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_PRECAPTURE_TRIGGER;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_REGIONS;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_STATE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AE_TARGET_FPS_RANGE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AF_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AF_REGIONS;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AF_STATE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AF_TRIGGER;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AWB_LOCK;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AWB_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AWB_REGIONS;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_AWB_STATE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_CAPTURE_INTENT;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_EFFECT_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_SCENE_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key CONTROL_VIDEO_STABILIZATION_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key EDGE_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key FLASH_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key FLASH_STATE;
+    field public static final android.hardware.camera2.CaptureResult.Key HOT_PIXEL_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key JPEG_GPS_LOCATION;
+    field public static final android.hardware.camera2.CaptureResult.Key JPEG_ORIENTATION;
+    field public static final android.hardware.camera2.CaptureResult.Key JPEG_QUALITY;
+    field public static final android.hardware.camera2.CaptureResult.Key JPEG_THUMBNAIL_QUALITY;
+    field public static final android.hardware.camera2.CaptureResult.Key JPEG_THUMBNAIL_SIZE;
+    field public static final android.hardware.camera2.CaptureResult.Key LENS_APERTURE;
+    field public static final android.hardware.camera2.CaptureResult.Key LENS_FILTER_DENSITY;
+    field public static final android.hardware.camera2.CaptureResult.Key LENS_FOCAL_LENGTH;
+    field public static final android.hardware.camera2.CaptureResult.Key LENS_FOCUS_DISTANCE;
+    field public static final android.hardware.camera2.CaptureResult.Key LENS_FOCUS_RANGE;
+    field public static final android.hardware.camera2.CaptureResult.Key LENS_OPTICAL_STABILIZATION_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key LENS_STATE;
+    field public static final android.hardware.camera2.CaptureResult.Key NOISE_REDUCTION_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key REQUEST_PIPELINE_DEPTH;
+    field public static final android.hardware.camera2.CaptureResult.Key SCALER_CROP_REGION;
+    field public static final android.hardware.camera2.CaptureResult.Key SENSOR_EXPOSURE_TIME;
+    field public static final android.hardware.camera2.CaptureResult.Key SENSOR_FRAME_DURATION;
+    field public static final android.hardware.camera2.CaptureResult.Key SENSOR_GREEN_SPLIT;
+    field public static final android.hardware.camera2.CaptureResult.Key SENSOR_NEUTRAL_COLOR_POINT;
+    field public static final android.hardware.camera2.CaptureResult.Key SENSOR_NOISE_PROFILE;
+    field public static final android.hardware.camera2.CaptureResult.Key SENSOR_ROLLING_SHUTTER_SKEW;
+    field public static final android.hardware.camera2.CaptureResult.Key SENSOR_SENSITIVITY;
+    field public static final android.hardware.camera2.CaptureResult.Key SENSOR_TEST_PATTERN_DATA;
+    field public static final android.hardware.camera2.CaptureResult.Key SENSOR_TEST_PATTERN_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key SENSOR_TIMESTAMP;
+    field public static final android.hardware.camera2.CaptureResult.Key SHADING_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_FACES;
+    field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_FACE_DETECT_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_HOT_PIXEL_MAP;
+    field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_HOT_PIXEL_MAP_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_LENS_SHADING_CORRECTION_MAP;
+    field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_LENS_SHADING_MAP_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key STATISTICS_SCENE_FLICKER;
+    field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_CURVE;
+    field public static final android.hardware.camera2.CaptureResult.Key TONEMAP_MODE;
+  }
+
+  public static final class CaptureResult.Key {
+    method public final boolean equals(java.lang.Object);
+    method public java.lang.String getName();
+    method public final int hashCode();
+  }
+
+  public final class DngCreator implements java.lang.AutoCloseable {
+    ctor public DngCreator(android.hardware.camera2.CameraCharacteristics, android.hardware.camera2.CaptureResult);
+    method public void close();
+    method public android.hardware.camera2.DngCreator setDescription(java.lang.String);
+    method public android.hardware.camera2.DngCreator setLocation(android.location.Location);
+    method public android.hardware.camera2.DngCreator setOrientation(int);
+    method public android.hardware.camera2.DngCreator setThumbnail(android.graphics.Bitmap);
+    method public android.hardware.camera2.DngCreator setThumbnail(android.media.Image);
+    method public void writeByteBuffer(java.io.OutputStream, android.util.Size, java.nio.ByteBuffer, long) throws java.io.IOException;
+    method public void writeImage(java.io.OutputStream, android.media.Image) throws java.io.IOException;
+    method public void writeInputStream(java.io.OutputStream, android.util.Size, java.io.InputStream, long) throws java.io.IOException;
+    field public static final int MAX_THUMBNAIL_DIMENSION = 256; // 0x100
+  }
+
+  public final class TotalCaptureResult extends android.hardware.camera2.CaptureResult {
+    method public java.util.List<android.hardware.camera2.CaptureResult> getPartialResults();
+  }
+
+}
+
+package android.hardware.camera2.params {
+
+  public final class BlackLevelPattern {
+    method public void copyTo(int[], int);
+    method public int getOffsetForIndex(int, int);
+    field public static final int COUNT = 4; // 0x4
+  }
+
+  public final class ColorSpaceTransform {
+    ctor public ColorSpaceTransform(android.util.Rational[]);
+    ctor public ColorSpaceTransform(int[]);
+    method public void copyElements(android.util.Rational[], int);
+    method public void copyElements(int[], int);
+    method public android.util.Rational getElement(int, int);
+  }
+
+  public final class Face {
+    method public android.graphics.Rect getBounds();
+    method public int getId();
+    method public android.graphics.Point getLeftEyePosition();
+    method public android.graphics.Point getMouthPosition();
+    method public android.graphics.Point getRightEyePosition();
+    method public int getScore();
+    field public static final int ID_UNSUPPORTED = -1; // 0xffffffff
+    field public static final int SCORE_MAX = 100; // 0x64
+    field public static final int SCORE_MIN = 1; // 0x1
+  }
+
+  public final class LensShadingMap {
+    method public void copyGainFactors(float[], int);
+    method public int getColumnCount();
+    method public float getGainFactor(int, int, int);
+    method public int getGainFactorCount();
+    method public android.hardware.camera2.params.RggbChannelVector getGainFactorVector(int, int);
+    method public int getRowCount();
+    field public static final float MINIMUM_GAIN_FACTOR = 1.0f;
+  }
+
+  public final class MeteringRectangle {
+    ctor public MeteringRectangle(int, int, int, int, int);
+    ctor public MeteringRectangle(android.graphics.Point, android.util.Size, int);
+    ctor public MeteringRectangle(android.graphics.Rect, int);
+    method public boolean equals(android.hardware.camera2.params.MeteringRectangle);
+    method public int getHeight();
+    method public int getMeteringWeight();
+    method public android.graphics.Rect getRect();
+    method public android.util.Size getSize();
+    method public android.graphics.Point getUpperLeftPoint();
+    method public int getWidth();
+    method public int getX();
+    method public int getY();
+    field public static final int METERING_WEIGHT_DONT_CARE = 0; // 0x0
+    field public static final int METERING_WEIGHT_MAX = 1000; // 0x3e8
+    field public static final int METERING_WEIGHT_MIN = 0; // 0x0
+  }
+
+  public final class RggbChannelVector {
+    ctor public RggbChannelVector(float, float, float, float);
+    method public void copyTo(float[], int);
+    method public float getBlue();
+    method public float getComponent(int);
+    method public float getGreenEven();
+    method public float getGreenOdd();
+    method public final float getRed();
+    field public static final int BLUE = 3; // 0x3
+    field public static final int COUNT = 4; // 0x4
+    field public static final int GREEN_EVEN = 1; // 0x1
+    field public static final int GREEN_ODD = 2; // 0x2
+    field public static final int RED = 0; // 0x0
+  }
+
+  public final class StreamConfigurationMap {
+    method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRanges();
+    method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRangesFor(android.util.Size);
+    method public android.util.Size[] getHighSpeedVideoSizes();
+    method public android.util.Size[] getHighSpeedVideoSizesFor(android.util.Range<java.lang.Integer>);
+    method public final int[] getOutputFormats();
+    method public long getOutputMinFrameDuration(int, android.util.Size);
+    method public long getOutputMinFrameDuration(java.lang.Class<T>, android.util.Size);
+    method public android.util.Size[] getOutputSizes(java.lang.Class<T>);
+    method public android.util.Size[] getOutputSizes(int);
+    method public long getOutputStallDuration(int, android.util.Size);
+    method public long getOutputStallDuration(java.lang.Class<T>, android.util.Size);
+    method public boolean isOutputSupportedFor(int);
+    method public static boolean isOutputSupportedFor(java.lang.Class<T>);
+    method public boolean isOutputSupportedFor(android.view.Surface);
+  }
+
+  public final class TonemapCurve {
+    ctor public TonemapCurve(float[], float[], float[]);
+    method public void copyColorCurve(int, float[], int);
+    method public android.graphics.PointF getPoint(int, int);
+    method public int getPointCount(int);
+    field public static final int CHANNEL_BLUE = 2; // 0x2
+    field public static final int CHANNEL_GREEN = 1; // 0x1
+    field public static final int CHANNEL_RED = 0; // 0x0
+    field public static final float LEVEL_BLACK = 0.0f;
+    field public static final float LEVEL_WHITE = 1.0f;
+    field public static final int POINT_SIZE = 2; // 0x2
+  }
+
+}
+
 package android.hardware.display {
 
   public final class DisplayManager {
     method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, android.view.Surface, int);
+    method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, android.view.Surface, int, android.hardware.display.VirtualDisplay.Callback, android.os.Handler);
     method public android.view.Display getDisplay(int);
     method public android.view.Display[] getDisplays();
     method public android.view.Display[] getDisplays(java.lang.String);
     method public void registerDisplayListener(android.hardware.display.DisplayManager.DisplayListener, android.os.Handler);
     method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener);
     field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
+    field public static final int VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 16; // 0x10
     field public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 8; // 0x8
     field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2
     field public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1; // 0x1
@@ -11039,9 +13153,17 @@
     method public android.view.Display getDisplay();
     method public android.view.Surface getSurface();
     method public void release();
+    method public void resize(int, int, int);
     method public void setSurface(android.view.Surface);
   }
 
+  public static abstract class VirtualDisplay.Callback {
+    ctor public VirtualDisplay.Callback();
+    method public void onPaused();
+    method public void onResumed();
+    method public void onStopped();
+  }
+
 }
 
 package android.hardware.input {
@@ -11063,64 +13185,6 @@
 
 }
 
-package android.hardware.location {
-
-  public final class GeofenceHardware {
-    method public boolean addGeofence(int, int, android.hardware.location.GeofenceHardwareRequest, android.hardware.location.GeofenceHardwareCallback);
-    method public int[] getMonitoringTypes();
-    method public int getStatusOfMonitoringType(int);
-    method public boolean pauseGeofence(int, int);
-    method public boolean registerForMonitorStateChangeCallback(int, android.hardware.location.GeofenceHardwareMonitorCallback);
-    method public boolean removeGeofence(int, int);
-    method public boolean resumeGeofence(int, int, int);
-    method public boolean unregisterForMonitorStateChangeCallback(int, android.hardware.location.GeofenceHardwareMonitorCallback);
-    field public static final int GEOFENCE_ENTERED = 1; // 0x1
-    field public static final int GEOFENCE_ERROR_ID_EXISTS = 2; // 0x2
-    field public static final int GEOFENCE_ERROR_ID_UNKNOWN = 3; // 0x3
-    field public static final int GEOFENCE_ERROR_INVALID_TRANSITION = 4; // 0x4
-    field public static final int GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 1; // 0x1
-    field public static final int GEOFENCE_EXITED = 2; // 0x2
-    field public static final int GEOFENCE_FAILURE = 5; // 0x5
-    field public static final int GEOFENCE_SUCCESS = 0; // 0x0
-    field public static final int GEOFENCE_UNCERTAIN = 4; // 0x4
-    field public static final int MONITORING_TYPE_GPS_HARDWARE = 0; // 0x0
-    field public static final int MONITOR_CURRENTLY_AVAILABLE = 0; // 0x0
-    field public static final int MONITOR_CURRENTLY_UNAVAILABLE = 1; // 0x1
-    field public static final int MONITOR_UNSUPPORTED = 2; // 0x2
-  }
-
-  public abstract class GeofenceHardwareCallback {
-    ctor public GeofenceHardwareCallback();
-    method public void onGeofenceAdd(int, int);
-    method public void onGeofencePause(int, int);
-    method public void onGeofenceRemove(int, int);
-    method public void onGeofenceResume(int, int);
-    method public void onGeofenceTransition(int, int, android.location.Location, long, int);
-  }
-
-  public abstract class GeofenceHardwareMonitorCallback {
-    ctor public GeofenceHardwareMonitorCallback();
-    method public void onMonitoringSystemChange(int, boolean, android.location.Location);
-  }
-
-  public final class GeofenceHardwareRequest {
-    ctor public GeofenceHardwareRequest();
-    method public static android.hardware.location.GeofenceHardwareRequest createCircularGeofence(double, double, double);
-    method public int getLastTransition();
-    method public double getLatitude();
-    method public double getLongitude();
-    method public int getMonitorTransitions();
-    method public int getNotificationResponsiveness();
-    method public double getRadius();
-    method public int getUnknownTimer();
-    method public void setLastTransition(int);
-    method public void setMonitorTransitions(int);
-    method public void setNotificationResponsiveness(int);
-    method public void setUnknownTimer(int);
-  }
-
-}
-
 package android.hardware.usb {
 
   public class UsbAccessory implements android.os.Parcelable {
@@ -11135,6 +13199,19 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
+  public class UsbConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getId();
+    method public android.hardware.usb.UsbInterface getInterface(int);
+    method public int getInterfaceCount();
+    method public int getMaxPower();
+    method public java.lang.String getName();
+    method public boolean isRemoteWakeup();
+    method public boolean isSelfPowered();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public final class UsbConstants {
     ctor public UsbConstants();
     field public static final int USB_CLASS_APP_SPEC = 254; // 0xfe
@@ -11174,6 +13251,8 @@
 
   public class UsbDevice implements android.os.Parcelable {
     method public int describeContents();
+    method public android.hardware.usb.UsbConfiguration getConfiguration(int);
+    method public int getConfigurationCount();
     method public int getDeviceClass();
     method public int getDeviceId();
     method public static int getDeviceId(java.lang.String);
@@ -11183,7 +13262,10 @@
     method public int getDeviceSubclass();
     method public android.hardware.usb.UsbInterface getInterface(int);
     method public int getInterfaceCount();
+    method public java.lang.String getManufacturerName();
     method public int getProductId();
+    method public java.lang.String getProductName();
+    method public java.lang.String getSerialNumber();
     method public int getVendorId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
@@ -11201,6 +13283,8 @@
     method public java.lang.String getSerial();
     method public boolean releaseInterface(android.hardware.usb.UsbInterface);
     method public android.hardware.usb.UsbRequest requestWait();
+    method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
+    method public boolean setInterface(android.hardware.usb.UsbInterface);
   }
 
   public class UsbEndpoint implements android.os.Parcelable {
@@ -11218,12 +13302,14 @@
 
   public class UsbInterface implements android.os.Parcelable {
     method public int describeContents();
+    method public int getAlternateSetting();
     method public android.hardware.usb.UsbEndpoint getEndpoint(int);
     method public int getEndpointCount();
     method public int getId();
     method public int getInterfaceClass();
     method public int getInterfaceProtocol();
     method public int getInterfaceSubclass();
+    method public java.lang.String getName();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
@@ -11293,6 +13379,7 @@
     ctor public ExtractEditText(android.content.Context);
     ctor public ExtractEditText(android.content.Context, android.util.AttributeSet);
     ctor public ExtractEditText(android.content.Context, android.util.AttributeSet, int);
+    ctor public ExtractEditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void finishInternalChanges();
     method public boolean hasVerticalScrollBar();
     method public void startInternalChanges();
@@ -11300,13 +13387,14 @@
 
   public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
     ctor public InputMethodService();
-    method public boolean enableHardwareAcceleration();
+    method public deprecated boolean enableHardwareAcceleration();
     method public int getBackDisposition();
     method public int getCandidatesHiddenVisibility();
     method public android.view.inputmethod.InputBinding getCurrentInputBinding();
     method public android.view.inputmethod.InputConnection getCurrentInputConnection();
     method public android.view.inputmethod.EditorInfo getCurrentInputEditorInfo();
     method public boolean getCurrentInputStarted();
+    method public int getInputMethodWindowRecommendedHeight();
     method public android.view.LayoutInflater getLayoutInflater();
     method public int getMaxWidth();
     method public java.lang.CharSequence getTextForImeAction(int);
@@ -11348,7 +13436,8 @@
     method public void onStartInput(android.view.inputmethod.EditorInfo, boolean);
     method public void onStartInputView(android.view.inputmethod.EditorInfo, boolean);
     method public void onUnbindInput();
-    method public void onUpdateCursor(android.graphics.Rect);
+    method public deprecated void onUpdateCursor(android.graphics.Rect);
+    method public void onUpdateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo);
     method public void onUpdateExtractedText(int, android.view.inputmethod.ExtractedText);
     method public void onUpdateExtractingViews(android.view.inputmethod.EditorInfo);
     method public void onUpdateExtractingVisibility(android.view.inputmethod.EditorInfo);
@@ -11395,6 +13484,7 @@
     method public void finishInput();
     method public void toggleSoftInput(int, int);
     method public void updateCursor(android.graphics.Rect);
+    method public void updateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo);
     method public void updateExtractedText(int, android.view.inputmethod.ExtractedText);
     method public void updateSelection(int, int, int, int, int, int);
     method public void viewClicked(boolean);
@@ -11489,6 +13579,7 @@
   public class KeyboardView extends android.view.View implements android.view.View.OnClickListener {
     ctor public KeyboardView(android.content.Context, android.util.AttributeSet);
     ctor public KeyboardView(android.content.Context, android.util.AttributeSet, int);
+    ctor public KeyboardView(android.content.Context, android.util.AttributeSet, int, int);
     method public void closing();
     method public android.inputmethodservice.Keyboard getKeyboard();
     method protected android.inputmethodservice.KeyboardView.OnKeyboardActionListener getOnKeyboardActionListener();
@@ -11776,7 +13867,7 @@
     ctor public SettingInjectorService(java.lang.String);
     method public final android.os.IBinder onBind(android.content.Intent);
     method protected abstract boolean onGetEnabled();
-    method protected abstract java.lang.String onGetSummary();
+    method protected abstract deprecated java.lang.String onGetSummary();
     method public final void onStart(android.content.Intent, int);
     method public final int onStartCommand(android.content.Intent, int, int);
     field public static final java.lang.String ACTION_INJECTED_SETTING_CHANGED = "android.location.InjectedSettingChanged";
@@ -11795,8 +13886,51 @@
     method public void stop();
   }
 
+  public final class AudioAttributes implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getContentType();
+    method public int getFlags();
+    method public int getUsage();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
+    field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
+    field public static final int CONTENT_TYPE_SONIFICATION = 4; // 0x4
+    field public static final int CONTENT_TYPE_SPEECH = 1; // 0x1
+    field public static final int CONTENT_TYPE_UNKNOWN = 0; // 0x0
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int FLAG_AUDIBILITY_ENFORCED = 1; // 0x1
+    field public static final int FLAG_HW_AV_SYNC = 16; // 0x10
+    field public static final int USAGE_ALARM = 4; // 0x4
+    field public static final int USAGE_ASSISTANCE_ACCESSIBILITY = 11; // 0xb
+    field public static final int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12; // 0xc
+    field public static final int USAGE_ASSISTANCE_SONIFICATION = 13; // 0xd
+    field public static final int USAGE_GAME = 14; // 0xe
+    field public static final int USAGE_MEDIA = 1; // 0x1
+    field public static final int USAGE_NOTIFICATION = 5; // 0x5
+    field public static final int USAGE_NOTIFICATION_COMMUNICATION_DELAYED = 9; // 0x9
+    field public static final int USAGE_NOTIFICATION_COMMUNICATION_INSTANT = 8; // 0x8
+    field public static final int USAGE_NOTIFICATION_COMMUNICATION_REQUEST = 7; // 0x7
+    field public static final int USAGE_NOTIFICATION_EVENT = 10; // 0xa
+    field public static final int USAGE_NOTIFICATION_RINGTONE = 6; // 0x6
+    field public static final int USAGE_UNKNOWN = 0; // 0x0
+    field public static final int USAGE_VOICE_COMMUNICATION = 2; // 0x2
+    field public static final int USAGE_VOICE_COMMUNICATION_SIGNALLING = 3; // 0x3
+  }
+
+  public static class AudioAttributes.Builder {
+    ctor public AudioAttributes.Builder();
+    ctor public AudioAttributes.Builder(android.media.AudioAttributes);
+    method public android.media.AudioAttributes build();
+    method public android.media.AudioAttributes.Builder setContentType(int);
+    method public android.media.AudioAttributes.Builder setFlags(int);
+    method public android.media.AudioAttributes.Builder setLegacyStreamType(int);
+    method public android.media.AudioAttributes.Builder setUsage(int);
+  }
+
   public class AudioFormat {
-    ctor public AudioFormat();
+    method public int getChannelMask();
+    method public int getEncoding();
+    method public int getSampleRate();
     field public static final deprecated int CHANNEL_CONFIGURATION_DEFAULT = 1; // 0x1
     field public static final deprecated int CHANNEL_CONFIGURATION_INVALID = 0; // 0x0
     field public static final deprecated int CHANNEL_CONFIGURATION_MONO = 2; // 0x2
@@ -11833,12 +13967,26 @@
     field public static final int CHANNEL_OUT_LOW_FREQUENCY = 32; // 0x20
     field public static final int CHANNEL_OUT_MONO = 4; // 0x4
     field public static final int CHANNEL_OUT_QUAD = 204; // 0xcc
+    field public static final int CHANNEL_OUT_SIDE_LEFT = 2048; // 0x800
+    field public static final int CHANNEL_OUT_SIDE_RIGHT = 4096; // 0x1000
     field public static final int CHANNEL_OUT_STEREO = 12; // 0xc
     field public static final int CHANNEL_OUT_SURROUND = 1052; // 0x41c
+    field public static final int ENCODING_AC3 = 5; // 0x5
     field public static final int ENCODING_DEFAULT = 1; // 0x1
+    field public static final int ENCODING_E_AC3 = 6; // 0x6
     field public static final int ENCODING_INVALID = 0; // 0x0
     field public static final int ENCODING_PCM_16BIT = 2; // 0x2
     field public static final int ENCODING_PCM_8BIT = 3; // 0x3
+    field public static final int ENCODING_PCM_FLOAT = 4; // 0x4
+  }
+
+  public static class AudioFormat.Builder {
+    ctor public AudioFormat.Builder();
+    ctor public AudioFormat.Builder(android.media.AudioFormat);
+    method public android.media.AudioFormat build();
+    method public android.media.AudioFormat.Builder setChannelMask(int);
+    method public android.media.AudioFormat.Builder setEncoding(int) throws java.lang.IllegalArgumentException;
+    method public android.media.AudioFormat.Builder setSampleRate(int) throws java.lang.IllegalArgumentException;
   }
 
   public class AudioManager {
@@ -11847,6 +13995,7 @@
     method public void adjustSuggestedStreamVolume(int, int, int);
     method public void adjustVolume(int, int);
     method public void dispatchMediaKeyEvent(android.view.KeyEvent);
+    method public int generateAudioSessionId();
     method public int getMode();
     method public java.lang.String getParameters(java.lang.String);
     method public java.lang.String getProperty(java.lang.String);
@@ -11861,14 +14010,15 @@
     method public boolean isMicrophoneMute();
     method public boolean isMusicActive();
     method public boolean isSpeakerphoneOn();
+    method public boolean isVolumeFixed();
     method public deprecated boolean isWiredHeadsetOn();
     method public void loadSoundEffects();
     method public void playSoundEffect(int);
     method public void playSoundEffect(int, float);
-    method public void registerMediaButtonEventReceiver(android.content.ComponentName);
-    method public void registerMediaButtonEventReceiver(android.app.PendingIntent);
-    method public void registerRemoteControlClient(android.media.RemoteControlClient);
-    method public boolean registerRemoteController(android.media.RemoteController);
+    method public deprecated void registerMediaButtonEventReceiver(android.content.ComponentName);
+    method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent);
+    method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
+    method public deprecated boolean registerRemoteController(android.media.RemoteController);
     method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
     method public deprecated void setBluetoothA2dpOn(boolean);
     method public void setBluetoothScoOn(boolean);
@@ -11887,11 +14037,13 @@
     method public void startBluetoothSco();
     method public void stopBluetoothSco();
     method public void unloadSoundEffects();
-    method public void unregisterMediaButtonEventReceiver(android.content.ComponentName);
-    method public void unregisterMediaButtonEventReceiver(android.app.PendingIntent);
-    method public void unregisterRemoteControlClient(android.media.RemoteControlClient);
-    method public void unregisterRemoteController(android.media.RemoteController);
+    method public deprecated void unregisterMediaButtonEventReceiver(android.content.ComponentName);
+    method public deprecated void unregisterMediaButtonEventReceiver(android.app.PendingIntent);
+    method public deprecated void unregisterRemoteControlClient(android.media.RemoteControlClient);
+    method public deprecated void unregisterRemoteController(android.media.RemoteController);
     field public static final java.lang.String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY";
+    field public static final java.lang.String ACTION_HDMI_AUDIO_PLUG = "android.media.action.HDMI_AUDIO_PLUG";
+    field public static final java.lang.String ACTION_HEADSET_PLUG = "android.intent.action.HEADSET_PLUG";
     field public static final deprecated java.lang.String ACTION_SCO_AUDIO_STATE_CHANGED = "android.media.SCO_AUDIO_STATE_CHANGED";
     field public static final java.lang.String ACTION_SCO_AUDIO_STATE_UPDATED = "android.media.ACTION_SCO_AUDIO_STATE_UPDATED";
     field public static final int ADJUST_LOWER = -1; // 0xffffffff
@@ -11906,6 +14058,12 @@
     field public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = -3; // 0xfffffffd
     field public static final int AUDIOFOCUS_REQUEST_FAILED = 0; // 0x0
     field public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; // 0x1
+    field public static final int AUDIO_SESSION_ID_GENERATE = 0; // 0x0
+    field public static final int ERROR = -1; // 0xffffffff
+    field public static final int ERROR_DEAD_OBJECT = -6; // 0xfffffffa
+    field public static final java.lang.String EXTRA_AUDIO_PLUG_STATE = "android.media.extra.AUDIO_PLUG_STATE";
+    field public static final java.lang.String EXTRA_ENCODINGS = "android.media.extra.ENCODINGS";
+    field public static final java.lang.String EXTRA_MAX_CHANNEL_COUNT = "android.media.extra.MAX_CHANNEL_COUNT";
     field public static final java.lang.String EXTRA_RINGER_MODE = "android.media.EXTRA_RINGER_MODE";
     field public static final java.lang.String EXTRA_SCO_AUDIO_PREVIOUS_STATE = "android.media.extra.SCO_AUDIO_PREVIOUS_STATE";
     field public static final java.lang.String EXTRA_SCO_AUDIO_STATE = "android.media.extra.SCO_AUDIO_STATE";
@@ -12018,6 +14176,7 @@
   public class AudioTrack {
     ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
+    ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException;
     method public int attachAuxEffect(int);
     method public void flush();
     method public int getAudioFormat();
@@ -12051,10 +14210,13 @@
     method public int setPlaybackRate(int);
     method public int setPositionNotificationPeriod(int);
     method protected deprecated void setState(int);
-    method public int setStereoVolume(float, float);
+    method public deprecated int setStereoVolume(float, float);
+    method public int setVolume(float);
     method public void stop() throws java.lang.IllegalStateException;
     method public int write(byte[], int, int);
     method public int write(short[], int, int);
+    method public int write(float[], int, int, int);
+    method public int write(java.nio.ByteBuffer, int, int);
     field public static final int ERROR = -1; // 0xffffffff
     field public static final int ERROR_BAD_VALUE = -2; // 0xfffffffe
     field public static final int ERROR_INVALID_OPERATION = -3; // 0xfffffffd
@@ -12067,6 +14229,8 @@
     field public static final int STATE_NO_STATIC_DATA = 2; // 0x2
     field public static final int STATE_UNINITIALIZED = 0; // 0x0
     field public static final int SUCCESS = 0; // 0x0
+    field public static final int WRITE_BLOCKING = 0; // 0x0
+    field public static final int WRITE_NON_BLOCKING = 1; // 0x1
   }
 
   public static abstract interface AudioTrack.OnPlaybackPositionUpdateListener {
@@ -12080,14 +14244,22 @@
     method public static boolean hasProfile(int);
     method public static boolean hasProfile(int, int);
     field public static final int QUALITY_1080P = 6; // 0x6
+    field public static final int QUALITY_2160P = 8; // 0x8
     field public static final int QUALITY_480P = 4; // 0x4
     field public static final int QUALITY_720P = 5; // 0x5
     field public static final int QUALITY_CIF = 3; // 0x3
     field public static final int QUALITY_HIGH = 1; // 0x1
+    field public static final int QUALITY_HIGH_SPEED_1080P = 2004; // 0x7d4
+    field public static final int QUALITY_HIGH_SPEED_2160P = 2005; // 0x7d5
+    field public static final int QUALITY_HIGH_SPEED_480P = 2002; // 0x7d2
+    field public static final int QUALITY_HIGH_SPEED_720P = 2003; // 0x7d3
+    field public static final int QUALITY_HIGH_SPEED_HIGH = 2001; // 0x7d1
+    field public static final int QUALITY_HIGH_SPEED_LOW = 2000; // 0x7d0
     field public static final int QUALITY_LOW = 0; // 0x0
     field public static final int QUALITY_QCIF = 2; // 0x2
     field public static final int QUALITY_QVGA = 7; // 0x7
     field public static final int QUALITY_TIME_LAPSE_1080P = 1006; // 0x3ee
+    field public static final int QUALITY_TIME_LAPSE_2160P = 1008; // 0x3f0
     field public static final int QUALITY_TIME_LAPSE_480P = 1004; // 0x3ec
     field public static final int QUALITY_TIME_LAPSE_720P = 1005; // 0x3ed
     field public static final int QUALITY_TIME_LAPSE_CIF = 1003; // 0x3eb
@@ -12185,11 +14357,13 @@
 
   public abstract class Image implements java.lang.AutoCloseable {
     method public abstract void close();
+    method public android.graphics.Rect getCropRect();
     method public abstract int getFormat();
     method public abstract int getHeight();
     method public abstract android.media.Image.Plane[] getPlanes();
     method public abstract long getTimestamp();
     method public abstract int getWidth();
+    method public void setCropRect(android.graphics.Rect);
   }
 
   public static abstract class Image.Plane {
@@ -12256,22 +14430,31 @@
 
   public final class MediaCodec {
     method public void configure(android.media.MediaFormat, android.view.Surface, android.media.MediaCrypto, int);
-    method public static android.media.MediaCodec createByCodecName(java.lang.String);
-    method public static android.media.MediaCodec createDecoderByType(java.lang.String);
-    method public static android.media.MediaCodec createEncoderByType(java.lang.String);
+    method public static android.media.MediaCodec createByCodecName(java.lang.String) throws java.io.IOException;
+    method public static android.media.MediaCodec createDecoderByType(java.lang.String) throws java.io.IOException;
+    method public static android.media.MediaCodec createEncoderByType(java.lang.String) throws java.io.IOException;
     method public final android.view.Surface createInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
     method public final void flush();
     method public android.media.MediaCodecInfo getCodecInfo();
-    method public java.nio.ByteBuffer[] getInputBuffers();
+    method public java.nio.ByteBuffer getInputBuffer(int);
+    method public deprecated java.nio.ByteBuffer[] getInputBuffers();
+    method public final android.media.MediaFormat getInputFormat();
+    method public android.media.Image getInputImage(int);
     method public final java.lang.String getName();
-    method public java.nio.ByteBuffer[] getOutputBuffers();
+    method public java.nio.ByteBuffer getOutputBuffer(int);
+    method public deprecated java.nio.ByteBuffer[] getOutputBuffers();
     method public final android.media.MediaFormat getOutputFormat();
+    method public final android.media.MediaFormat getOutputFormat(int);
+    method public android.media.Image getOutputImage(int);
     method public final void queueInputBuffer(int, int, int, long, int) throws android.media.MediaCodec.CryptoException;
     method public final void queueSecureInputBuffer(int, int, android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException;
     method public final void release();
     method public final void releaseOutputBuffer(int, boolean);
+    method public final void releaseOutputBuffer(int, long);
+    method public final void reset();
+    method public void setCallback(android.media.MediaCodec.Callback);
     method public final void setParameters(android.os.Bundle);
     method public final void setVideoScalingMode(int);
     method public final void signalEndOfInputStream();
@@ -12279,11 +14462,12 @@
     method public final void stop();
     field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2
     field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4
-    field public static final int BUFFER_FLAG_SYNC_FRAME = 1; // 0x1
+    field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
+    field public static final deprecated int BUFFER_FLAG_SYNC_FRAME = 1; // 0x1
     field public static final int CONFIGURE_FLAG_ENCODE = 1; // 0x1
     field public static final int CRYPTO_MODE_AES_CTR = 1; // 0x1
     field public static final int CRYPTO_MODE_UNENCRYPTED = 0; // 0x0
-    field public static final int INFO_OUTPUT_BUFFERS_CHANGED = -3; // 0xfffffffd
+    field public static final deprecated int INFO_OUTPUT_BUFFERS_CHANGED = -3; // 0xfffffffd
     field public static final int INFO_OUTPUT_FORMAT_CHANGED = -2; // 0xfffffffe
     field public static final int INFO_TRY_AGAIN_LATER = -1; // 0xffffffff
     field public static final java.lang.String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
@@ -12302,9 +14486,24 @@
     field public int size;
   }
 
+  public static abstract class MediaCodec.Callback {
+    ctor public MediaCodec.Callback();
+    method public abstract void onError(android.media.MediaCodec, android.media.MediaCodec.CodecException);
+    method public abstract void onInputBufferAvailable(android.media.MediaCodec, int);
+    method public abstract void onOutputBufferAvailable(android.media.MediaCodec, int, android.media.MediaCodec.BufferInfo);
+    method public abstract void onOutputFormatChanged(android.media.MediaCodec, android.media.MediaFormat);
+  }
+
+  public static final class MediaCodec.CodecException extends java.lang.IllegalStateException {
+    method public java.lang.String getDiagnosticInfo();
+    method public boolean isRecoverable();
+    method public boolean isTransient();
+  }
+
   public static final class MediaCodec.CryptoException extends java.lang.RuntimeException {
     ctor public MediaCodec.CryptoException(int, java.lang.String);
     method public int getErrorCode();
+    field public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4
     field public static final int ERROR_KEY_EXPIRED = 2; // 0x2
     field public static final int ERROR_NO_KEY = 1; // 0x1
     field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
@@ -12328,9 +14527,25 @@
     method public final boolean isEncoder();
   }
 
+  public static final class MediaCodecInfo.AudioCapabilities {
+    method public android.util.Range<java.lang.Integer> getBitrateRange();
+    method public int getMaxInputChannelCount();
+    method public android.util.Range<java.lang.Integer>[] getSupportedSampleRateRanges();
+    method public int[] getSupportedSampleRates();
+    method public boolean isSampleRateSupported(int);
+  }
+
   public static final class MediaCodecInfo.CodecCapabilities {
     ctor public MediaCodecInfo.CodecCapabilities();
+    method public static android.media.MediaCodecInfo.CodecCapabilities createFromProfileLevel(java.lang.String, int, int);
+    method public android.media.MediaCodecInfo.AudioCapabilities getAudioCapabilities();
+    method public android.media.MediaFormat getDefaultFormat();
+    method public android.media.MediaCodecInfo.EncoderCapabilities getEncoderCapabilities();
+    method public java.lang.String getMimeType();
+    method public android.media.MediaCodecInfo.VideoCapabilities getVideoCapabilities();
+    method public final boolean isFeatureRequired(java.lang.String);
     method public final boolean isFeatureSupported(java.lang.String);
+    method public final boolean isFormatSupported(android.media.MediaFormat);
     field public static final int COLOR_Format12bitRGB444 = 3; // 0x3
     field public static final int COLOR_Format16bitARGB1555 = 5; // 0x5
     field public static final int COLOR_Format16bitARGB4444 = 4; // 0x4
@@ -12366,6 +14581,7 @@
     field public static final int COLOR_FormatYCrYCb = 26; // 0x1a
     field public static final int COLOR_FormatYUV411PackedPlanar = 18; // 0x12
     field public static final int COLOR_FormatYUV411Planar = 17; // 0x11
+    field public static final int COLOR_FormatYUV420Flexible = 2135033992; // 0x7f420888
     field public static final int COLOR_FormatYUV420PackedPlanar = 20; // 0x14
     field public static final int COLOR_FormatYUV420PackedSemiPlanar = 39; // 0x27
     field public static final int COLOR_FormatYUV420Planar = 19; // 0x13
@@ -12378,6 +14594,8 @@
     field public static final int COLOR_QCOM_FormatYUV420SemiPlanar = 2141391872; // 0x7fa30c00
     field public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
     field public static final java.lang.String FEATURE_AdaptivePlayback = "adaptive-playback";
+    field public static final java.lang.String FEATURE_SecurePlayback = "secure-playback";
+    field public static final java.lang.String FEATURE_TunneledPlayback = "tunneled-playback";
     field public int[] colorFormats;
     field public android.media.MediaCodecInfo.CodecProfileLevel[] profileLevels;
   }
@@ -12410,6 +14628,7 @@
     field public static final int AVCLevel42 = 8192; // 0x2000
     field public static final int AVCLevel5 = 16384; // 0x4000
     field public static final int AVCLevel51 = 32768; // 0x8000
+    field public static final int AVCLevel52 = 65536; // 0x10000
     field public static final int AVCProfileBaseline = 1; // 0x1
     field public static final int AVCProfileExtended = 4; // 0x4
     field public static final int AVCProfileHigh = 8; // 0x8
@@ -12434,6 +14653,34 @@
     field public static final int H263ProfileISWV3 = 16; // 0x10
     field public static final int H263ProfileInterlace = 128; // 0x80
     field public static final int H263ProfileInternet = 64; // 0x40
+    field public static final int HEVCHighTierLevel1 = 2; // 0x2
+    field public static final int HEVCHighTierLevel2 = 8; // 0x8
+    field public static final int HEVCHighTierLevel21 = 32; // 0x20
+    field public static final int HEVCHighTierLevel3 = 128; // 0x80
+    field public static final int HEVCHighTierLevel31 = 512; // 0x200
+    field public static final int HEVCHighTierLevel4 = 2048; // 0x800
+    field public static final int HEVCHighTierLevel41 = 8192; // 0x2000
+    field public static final int HEVCHighTierLevel5 = 32768; // 0x8000
+    field public static final int HEVCHighTierLevel51 = 131072; // 0x20000
+    field public static final int HEVCHighTierLevel52 = 524288; // 0x80000
+    field public static final int HEVCHighTierLevel6 = 2097152; // 0x200000
+    field public static final int HEVCHighTierLevel61 = 8388608; // 0x800000
+    field public static final int HEVCHighTierLevel62 = 33554432; // 0x2000000
+    field public static final int HEVCMainTierLevel1 = 1; // 0x1
+    field public static final int HEVCMainTierLevel2 = 4; // 0x4
+    field public static final int HEVCMainTierLevel21 = 16; // 0x10
+    field public static final int HEVCMainTierLevel3 = 64; // 0x40
+    field public static final int HEVCMainTierLevel31 = 256; // 0x100
+    field public static final int HEVCMainTierLevel4 = 1024; // 0x400
+    field public static final int HEVCMainTierLevel41 = 4096; // 0x1000
+    field public static final int HEVCMainTierLevel5 = 16384; // 0x4000
+    field public static final int HEVCMainTierLevel51 = 65536; // 0x10000
+    field public static final int HEVCMainTierLevel52 = 262144; // 0x40000
+    field public static final int HEVCMainTierLevel6 = 1048576; // 0x100000
+    field public static final int HEVCMainTierLevel61 = 4194304; // 0x400000
+    field public static final int HEVCMainTierLevel62 = 16777216; // 0x1000000
+    field public static final int HEVCProfileMain = 1; // 0x1
+    field public static final int HEVCProfileMain10 = 2; // 0x2
     field public static final int MPEG4Level0 = 1; // 0x1
     field public static final int MPEG4Level0b = 2; // 0x2
     field public static final int MPEG4Level1 = 4; // 0x4
@@ -12467,9 +14714,37 @@
     field public int profile;
   }
 
+  public static final class MediaCodecInfo.EncoderCapabilities {
+    method public android.util.Range<java.lang.Integer> getComplexityRange();
+    method public boolean isBitrateModeSupported(int);
+    field public static final int BITRATE_MODE_CBR = 2; // 0x2
+    field public static final int BITRATE_MODE_CQ = 0; // 0x0
+    field public static final int BITRATE_MODE_VBR = 1; // 0x1
+  }
+
+  public static final class MediaCodecInfo.VideoCapabilities {
+    method public boolean areSizeAndRateSupported(int, int, double);
+    method public android.util.Range<java.lang.Integer> getBitrateRange();
+    method public int getHeightAlignment();
+    method public android.util.Range<java.lang.Integer> getSupportedFrameRates();
+    method public android.util.Range<java.lang.Double> getSupportedFrameRatesFor(int, int);
+    method public android.util.Range<java.lang.Integer> getSupportedHeights();
+    method public android.util.Range<java.lang.Integer> getSupportedHeightsFor(int);
+    method public android.util.Range<java.lang.Integer> getSupportedWidths();
+    method public android.util.Range<java.lang.Integer> getSupportedWidthsFor(int);
+    method public int getWidthAlignment();
+    method public boolean isSizeSupported(int, int);
+  }
+
   public final class MediaCodecList {
-    method public static final int getCodecCount();
-    method public static final android.media.MediaCodecInfo getCodecInfoAt(int);
+    ctor public MediaCodecList(int);
+    method public final java.lang.String findDecoderForFormat(android.media.MediaFormat);
+    method public final java.lang.String findEncoderForFormat(android.media.MediaFormat);
+    method public static final deprecated int getCodecCount();
+    method public static final deprecated android.media.MediaCodecInfo getCodecInfoAt(int);
+    method public final android.media.MediaCodecInfo[] getCodecInfos();
+    field public static final int ALL_CODECS = 1; // 0x1
+    field public static final int REGULAR_CODECS = 0; // 0x0
   }
 
   public final class MediaCrypto {
@@ -12483,6 +14758,31 @@
     ctor public MediaCryptoException(java.lang.String);
   }
 
+  public class MediaDescription implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.lang.CharSequence getDescription();
+    method public android.os.Bundle getExtras();
+    method public android.graphics.Bitmap getIconBitmap();
+    method public android.net.Uri getIconUri();
+    method public java.lang.String getMediaId();
+    method public java.lang.CharSequence getSubtitle();
+    method public java.lang.CharSequence getTitle();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static class MediaDescription.Builder {
+    ctor public MediaDescription.Builder();
+    method public android.media.MediaDescription build();
+    method public android.media.MediaDescription.Builder setDescription(java.lang.CharSequence);
+    method public android.media.MediaDescription.Builder setExtras(android.os.Bundle);
+    method public android.media.MediaDescription.Builder setIconBitmap(android.graphics.Bitmap);
+    method public android.media.MediaDescription.Builder setIconUri(android.net.Uri);
+    method public android.media.MediaDescription.Builder setMediaId(java.lang.String);
+    method public android.media.MediaDescription.Builder setSubtitle(java.lang.CharSequence);
+    method public android.media.MediaDescription.Builder setTitle(java.lang.CharSequence);
+  }
+
   public final class MediaDrm {
     ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
     method public void closeSession(byte[]);
@@ -12494,7 +14794,7 @@
     method public java.util.List<byte[]> getSecureStops();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
     method public static final boolean isCryptoSchemeSupported(java.util.UUID, java.lang.String);
-    method public byte[] openSession() throws android.media.NotProvisionedException;
+    method public byte[] openSession() throws android.media.NotProvisionedException, android.media.ResourceBusyException;
     method public byte[] provideKeyResponse(byte[], byte[]) throws android.media.DeniedByServerException, android.media.NotProvisionedException;
     method public void provideProvisionResponse(byte[]) throws android.media.DeniedByServerException;
     method public java.util.HashMap<java.lang.String, java.lang.String> queryKeyStatus(byte[]);
@@ -12531,6 +14831,10 @@
     method public java.lang.String getDefaultUrl();
   }
 
+  public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
+    method public java.lang.String getDiagnosticInfo();
+  }
+
   public static abstract interface MediaDrm.OnEventListener {
     method public abstract void onEvent(android.media.MediaDrm, byte[], int, int, byte[]);
   }
@@ -12580,20 +14884,33 @@
     method public static final android.media.MediaFormat createSubtitleFormat(java.lang.String, java.lang.String);
     method public static final android.media.MediaFormat createVideoFormat(java.lang.String, int, int);
     method public final java.nio.ByteBuffer getByteBuffer(java.lang.String);
+    method public boolean getFeatureEnabled(java.lang.String);
     method public final float getFloat(java.lang.String);
     method public final int getInteger(java.lang.String);
     method public final long getLong(java.lang.String);
     method public final java.lang.String getString(java.lang.String);
     method public final void setByteBuffer(java.lang.String, java.nio.ByteBuffer);
+    method public void setFeatureEnabled(java.lang.String, boolean);
     method public final void setFloat(java.lang.String, float);
     method public final void setInteger(java.lang.String, int);
     method public final void setLong(java.lang.String, long);
     method public final void setString(java.lang.String, java.lang.String);
+    field public static final java.lang.String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
+    field public static final java.lang.String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level";
+    field public static final java.lang.String KEY_AAC_DRC_HEAVY_COMPRESSION = "aac-drc-heavy-compression";
+    field public static final java.lang.String KEY_AAC_DRC_TARGET_REFERENCE_LEVEL = "aac-target-ref-level";
+    field public static final java.lang.String KEY_AAC_ENCODED_TARGET_LEVEL = "aac-encoded-target-level";
+    field public static final java.lang.String KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT = "aac-max-output-channel_count";
     field public static final java.lang.String KEY_AAC_PROFILE = "aac-profile";
+    field public static final java.lang.String KEY_AAC_SBR_MODE = "aac-sbr-mode";
+    field public static final java.lang.String KEY_AUDIO_SESSION_ID = "audio-session-id";
+    field public static final java.lang.String KEY_BITRATE_MODE = "bitrate-mode";
     field public static final java.lang.String KEY_BIT_RATE = "bitrate";
+    field public static final java.lang.String KEY_CAPTURE_RATE = "capture-rate";
     field public static final java.lang.String KEY_CHANNEL_COUNT = "channel-count";
     field public static final java.lang.String KEY_CHANNEL_MASK = "channel-mask";
     field public static final java.lang.String KEY_COLOR_FORMAT = "color-format";
+    field public static final java.lang.String KEY_COMPLEXITY = "complexity";
     field public static final java.lang.String KEY_DURATION = "durationUs";
     field public static final java.lang.String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
     field public static final java.lang.String KEY_FRAME_RATE = "frame-rate";
@@ -12608,13 +14925,91 @@
     field public static final java.lang.String KEY_MAX_INPUT_SIZE = "max-input-size";
     field public static final java.lang.String KEY_MAX_WIDTH = "max-width";
     field public static final java.lang.String KEY_MIME = "mime";
+    field public static final java.lang.String KEY_PROFILE = "profile";
     field public static final java.lang.String KEY_PUSH_BLANK_BUFFERS_ON_STOP = "push-blank-buffers-on-shutdown";
     field public static final java.lang.String KEY_REPEAT_PREVIOUS_FRAME_AFTER = "repeat-previous-frame-after";
     field public static final java.lang.String KEY_SAMPLE_RATE = "sample-rate";
+    field public static final java.lang.String KEY_TEMPORAL_LAYERING = "ts-schema";
     field public static final java.lang.String KEY_WIDTH = "width";
+    field public static final java.lang.String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
+    field public static final java.lang.String MIMETYPE_AUDIO_AC3 = "audio/ac3";
+    field public static final java.lang.String MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
+    field public static final java.lang.String MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
+    field public static final java.lang.String MIMETYPE_AUDIO_FLAC = "audio/flac";
+    field public static final java.lang.String MIMETYPE_AUDIO_G711_ALAW = "audio/g711-alaw";
+    field public static final java.lang.String MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
+    field public static final java.lang.String MIMETYPE_AUDIO_MPEG = "audio/mpeg";
+    field public static final java.lang.String MIMETYPE_AUDIO_MSGSM = "audio/gsm";
+    field public static final java.lang.String MIMETYPE_AUDIO_OPUS = "audio/opus";
+    field public static final java.lang.String MIMETYPE_AUDIO_QCELP = "audio/qcelp";
+    field public static final java.lang.String MIMETYPE_AUDIO_RAW = "audio/raw";
+    field public static final java.lang.String MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
+    field public static final java.lang.String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
+    field public static final java.lang.String MIMETYPE_TEXT_VTT = "text/vtt";
+    field public static final java.lang.String MIMETYPE_VIDEO_AVC = "video/avc";
+    field public static final java.lang.String MIMETYPE_VIDEO_H263 = "video/3gpp";
+    field public static final java.lang.String MIMETYPE_VIDEO_HEVC = "video/hevc";
+    field public static final java.lang.String MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
+    field public static final java.lang.String MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
+    field public static final java.lang.String MIMETYPE_VIDEO_RAW = "video/raw";
+    field public static final java.lang.String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
+    field public static final java.lang.String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
   }
 
-  public abstract class MediaMetadataEditor {
+  public final class MediaMetadata implements android.os.Parcelable {
+    method public boolean containsKey(java.lang.String);
+    method public int describeContents();
+    method public android.graphics.Bitmap getBitmap(java.lang.String);
+    method public android.media.MediaDescription getDescription();
+    method public long getLong(java.lang.String);
+    method public android.media.Rating getRating(java.lang.String);
+    method public java.lang.String getString(java.lang.String);
+    method public java.lang.CharSequence getText(java.lang.String);
+    method public java.util.Set<java.lang.String> keySet();
+    method public int size();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final java.lang.String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
+    field public static final java.lang.String METADATA_KEY_ART = "android.media.metadata.ART";
+    field public static final java.lang.String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
+    field public static final java.lang.String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
+    field public static final java.lang.String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
+    field public static final java.lang.String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION";
+    field public static final java.lang.String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
+    field public static final java.lang.String METADATA_KEY_DATE = "android.media.metadata.DATE";
+    field public static final java.lang.String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_DESCRIPTION = "android.media.metadata.DISPLAY_DESCRIPTION";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_ICON = "android.media.metadata.DISPLAY_ICON";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_ICON_URI = "android.media.metadata.DISPLAY_ICON_URI";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_SUBTITLE = "android.media.metadata.DISPLAY_SUBTITLE";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE";
+    field public static final java.lang.String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
+    field public static final java.lang.String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+    field public static final java.lang.String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID";
+    field public static final java.lang.String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
+    field public static final java.lang.String METADATA_KEY_RATING = "android.media.metadata.RATING";
+    field public static final java.lang.String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
+    field public static final java.lang.String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+    field public static final java.lang.String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
+    field public static final java.lang.String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
+    field public static final java.lang.String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
+  }
+
+  public static final class MediaMetadata.Builder {
+    ctor public MediaMetadata.Builder();
+    ctor public MediaMetadata.Builder(android.media.MediaMetadata);
+    method public android.media.MediaMetadata build();
+    method public android.media.MediaMetadata.Builder putBitmap(java.lang.String, android.graphics.Bitmap);
+    method public android.media.MediaMetadata.Builder putLong(java.lang.String, long);
+    method public android.media.MediaMetadata.Builder putRating(java.lang.String, android.media.Rating);
+    method public android.media.MediaMetadata.Builder putString(java.lang.String, java.lang.String);
+    method public android.media.MediaMetadata.Builder putText(java.lang.String, java.lang.CharSequence);
+  }
+
+  public abstract deprecated class MediaMetadataEditor {
     method public synchronized void addEditableKey(int);
     method public abstract void apply();
     method public synchronized void clear();
@@ -12688,6 +15083,7 @@
 
   public static final class MediaMuxer.OutputFormat {
     field public static final int MUXER_OUTPUT_MPEG_4 = 0; // 0x0
+    field public static final int MUXER_OUTPUT_WEBM = 1; // 0x1
   }
 
   public class MediaPlayer {
@@ -12699,11 +15095,14 @@
     method public void attachAuxEffect(int);
     method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri);
     method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri, android.view.SurfaceHolder);
+    method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri, android.view.SurfaceHolder, android.media.AudioAttributes, int);
     method public static android.media.MediaPlayer create(android.content.Context, int);
+    method public static android.media.MediaPlayer create(android.content.Context, int, android.media.AudioAttributes, int);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
     method public int getAudioSessionId();
     method public int getCurrentPosition();
     method public int getDuration();
+    method public int getSelectedTrack(int) throws java.lang.IllegalStateException;
     method public android.media.MediaPlayer.TrackInfo[] getTrackInfo() throws java.lang.IllegalStateException;
     method public int getVideoHeight();
     method public int getVideoWidth();
@@ -12716,6 +15115,7 @@
     method public void reset();
     method public void seekTo(int) throws java.lang.IllegalStateException;
     method public void selectTrack(int) throws java.lang.IllegalStateException;
+    method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
     method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public void setAudioStreamType(int);
     method public void setAuxEffectSendLevel(float);
@@ -12803,6 +15203,7 @@
     method public int getTrackType();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int MEDIA_TRACK_TYPE_AUDIO = 2; // 0x2
+    field public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4; // 0x4
     field public static final int MEDIA_TRACK_TYPE_TIMEDTEXT = 3; // 0x3
     field public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0; // 0x0
     field public static final int MEDIA_TRACK_TYPE_VIDEO = 1; // 0x1
@@ -12812,6 +15213,7 @@
     ctor public MediaRecorder();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
+    method public android.view.Surface getSurface();
     method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
     method public void release();
     method public void reset();
@@ -12820,7 +15222,7 @@
     method public void setAudioEncodingBitRate(int);
     method public void setAudioSamplingRate(int);
     method public void setAudioSource(int) throws java.lang.IllegalStateException;
-    method public void setCamera(android.hardware.Camera);
+    method public deprecated void setCamera(android.hardware.Camera);
     method public void setCaptureRate(double);
     method public void setLocation(float, float);
     method public void setMaxDuration(int) throws java.lang.IllegalArgumentException;
@@ -12854,6 +15256,7 @@
     field public static final int AMR_WB = 2; // 0x2
     field public static final int DEFAULT = 0; // 0x0
     field public static final int HE_AAC = 4; // 0x4
+    field public static final int VORBIS = 6; // 0x6
   }
 
   public final class MediaRecorder.AudioSource {
@@ -12884,6 +15287,7 @@
     field public static final int MPEG_4 = 2; // 0x2
     field public static final deprecated int RAW_AMR = 3; // 0x3
     field public static final int THREE_GPP = 1; // 0x1
+    field public static final int WEBM = 9; // 0x9
   }
 
   public final class MediaRecorder.VideoEncoder {
@@ -12891,11 +15295,13 @@
     field public static final int H263 = 1; // 0x1
     field public static final int H264 = 2; // 0x2
     field public static final int MPEG_4_SP = 3; // 0x3
+    field public static final int VP8 = 4; // 0x4
   }
 
   public final class MediaRecorder.VideoSource {
     field public static final int CAMERA = 1; // 0x1
     field public static final int DEFAULT = 0; // 0x0
+    field public static final int SURFACE = 2; // 0x2
   }
 
   public class MediaRouter {
@@ -13068,14 +15474,16 @@
     field public static final int RATING_4_STARS = 4; // 0x4
     field public static final int RATING_5_STARS = 5; // 0x5
     field public static final int RATING_HEART = 1; // 0x1
+    field public static final int RATING_NONE = 0; // 0x0
     field public static final int RATING_PERCENTAGE = 6; // 0x6
     field public static final int RATING_THUMB_UP_DOWN = 2; // 0x2
   }
 
-  public class RemoteControlClient {
+  public deprecated class RemoteControlClient {
     ctor public RemoteControlClient(android.app.PendingIntent);
     ctor public RemoteControlClient(android.app.PendingIntent, android.os.Looper);
     method public android.media.RemoteControlClient.MetadataEditor editMetadata(boolean);
+    method public android.media.session.MediaSession getMediaSession();
     method public void setMetadataUpdateListener(android.media.RemoteControlClient.OnMetadataUpdateListener);
     method public void setOnGetPlaybackPositionListener(android.media.RemoteControlClient.OnGetPlaybackPositionListener);
     method public void setPlaybackPositionUpdateListener(android.media.RemoteControlClient.OnPlaybackPositionUpdateListener);
@@ -13103,7 +15511,7 @@
     field public static final int PLAYSTATE_STOPPED = 1; // 0x1
   }
 
-  public class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
+  public deprecated class RemoteControlClient.MetadataEditor extends android.media.MediaMetadataEditor {
     method public synchronized void apply();
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
   }
@@ -13120,7 +15528,7 @@
     method public abstract void onPlaybackPositionUpdate(long);
   }
 
-  public final class RemoteController {
+  public final deprecated class RemoteController {
     ctor public RemoteController(android.content.Context, android.media.RemoteController.OnClientUpdateListener) throws java.lang.IllegalArgumentException;
     ctor public RemoteController(android.content.Context, android.media.RemoteController.OnClientUpdateListener, android.os.Looper) throws java.lang.IllegalArgumentException;
     method public boolean clearArtworkConfiguration();
@@ -13151,11 +15559,13 @@
   }
 
   public class Ringtone {
-    method public int getStreamType();
+    method public android.media.AudioAttributes getAudioAttributes();
+    method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
     method public boolean isPlaying();
     method public void play();
-    method public void setStreamType(int);
+    method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
+    method public deprecated void setStreamType(int);
     method public void stop();
   }
 
@@ -13199,7 +15609,7 @@
   }
 
   public class SoundPool {
-    ctor public SoundPool(int, int, int);
+    ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
     method public final void autoResume();
     method public int load(java.lang.String, int);
@@ -13219,6 +15629,13 @@
     method public final boolean unload(int);
   }
 
+  public static class SoundPool.Builder {
+    ctor public SoundPool.Builder();
+    method public android.media.SoundPool build();
+    method public android.media.SoundPool.Builder setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
+    method public android.media.SoundPool.Builder setMaxStreams(int) throws java.lang.IllegalArgumentException;
+  }
+
   public static abstract interface SoundPool.OnLoadCompleteListener {
     method public abstract void onLoadComplete(android.media.SoundPool, int, int);
   }
@@ -13350,6 +15767,19 @@
     ctor public UnsupportedSchemeException(java.lang.String);
   }
 
+  public abstract class VolumeProvider {
+    ctor public VolumeProvider(int, int, int);
+    method public final int getCurrentVolume();
+    method public final int getMaxVolume();
+    method public final int getVolumeControl();
+    method public void onAdjustVolume(int);
+    method public void onSetVolumeTo(int);
+    method public final void setCurrentVolume(int);
+    field public static final int VOLUME_CONTROL_ABSOLUTE = 2; // 0x2
+    field public static final int VOLUME_CONTROL_FIXED = 0; // 0x0
+    field public static final int VOLUME_CONTROL_RELATIVE = 1; // 0x1
+  }
+
 }
 
 package android.media.audiofx {
@@ -13582,14 +16012,22 @@
 
   public class Virtualizer extends android.media.audiofx.AudioEffect {
     ctor public Virtualizer(int, int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.RuntimeException, java.lang.UnsupportedOperationException;
+    method public boolean canVirtualize(int, int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
+    method public boolean forceVirtualizationMode(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
     method public android.media.audiofx.Virtualizer.Settings getProperties() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
     method public short getRoundedStrength() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
+    method public boolean getSpeakerAngles(int, int, int[]) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
     method public boolean getStrengthSupported();
+    method public int getVirtualizationMode() throws java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
     method public void setParameterListener(android.media.audiofx.Virtualizer.OnParameterChangeListener);
     method public void setProperties(android.media.audiofx.Virtualizer.Settings) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
     method public void setStrength(short) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
     field public static final int PARAM_STRENGTH = 1; // 0x1
     field public static final int PARAM_STRENGTH_SUPPORTED = 0; // 0x0
+    field public static final int VIRTUALIZATION_MODE_AUTO = 1; // 0x1
+    field public static final int VIRTUALIZATION_MODE_BINAURAL = 2; // 0x2
+    field public static final int VIRTUALIZATION_MODE_OFF = 0; // 0x0
+    field public static final int VIRTUALIZATION_MODE_TRANSAURAL = 3; // 0x3
   }
 
   public static abstract interface Virtualizer.OnParameterChangeListener {
@@ -13650,6 +16088,50 @@
 
 }
 
+package android.media.browse {
+
+  public final class MediaBrowser {
+    ctor public MediaBrowser(android.content.Context, android.content.ComponentName, android.media.browse.MediaBrowser.ConnectionCallback, android.os.Bundle);
+    method public void connect();
+    method public void disconnect();
+    method public android.os.Bundle getExtras();
+    method public java.lang.String getRoot();
+    method public android.content.ComponentName getServiceComponent();
+    method public android.media.session.MediaSession.Token getSessionToken();
+    method public boolean isConnected();
+    method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
+    method public void unsubscribe(java.lang.String);
+  }
+
+  public static class MediaBrowser.ConnectionCallback {
+    ctor public MediaBrowser.ConnectionCallback();
+    method public void onConnected();
+    method public void onConnectionFailed();
+    method public void onConnectionSuspended();
+  }
+
+  public static class MediaBrowser.MediaItem implements android.os.Parcelable {
+    ctor public MediaBrowser.MediaItem(android.media.MediaDescription, int);
+    method public int describeContents();
+    method public android.media.MediaDescription getDescription();
+    method public int getFlags();
+    method public java.lang.String getMediaId();
+    method public boolean isBrowsable();
+    method public boolean isPlayable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int FLAG_BROWSABLE = 1; // 0x1
+    field public static final int FLAG_PLAYABLE = 2; // 0x2
+  }
+
+  public static abstract class MediaBrowser.SubscriptionCallback {
+    ctor public MediaBrowser.SubscriptionCallback();
+    method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
+    method public void onError(java.lang.String);
+  }
+
+}
+
 package android.media.effect {
 
   public abstract class Effect {
@@ -13705,6 +16187,540 @@
 
 }
 
+package android.media.projection {
+
+  public final class MediaProjection {
+    method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, int, android.view.Surface, android.hardware.display.VirtualDisplay.Callback, android.os.Handler);
+    method public void registerCallback(android.media.projection.MediaProjection.Callback, android.os.Handler);
+    method public void stop();
+    method public void unregisterCallback(android.media.projection.MediaProjection.Callback);
+  }
+
+  public static abstract class MediaProjection.Callback {
+    ctor public MediaProjection.Callback();
+    method public void onStop();
+  }
+
+  public final class MediaProjectionManager {
+    method public android.content.Intent createScreenCaptureIntent();
+    method public android.media.projection.MediaProjection getMediaProjection(int, android.content.Intent);
+  }
+
+}
+
+package android.media.session {
+
+  public final class MediaController {
+    ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
+    method public void adjustVolume(int, int);
+    method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
+    method public android.os.Bundle getExtras();
+    method public long getFlags();
+    method public android.media.MediaMetadata getMetadata();
+    method public java.lang.String getPackageName();
+    method public android.media.session.MediaController.PlaybackInfo getPlaybackInfo();
+    method public android.media.session.PlaybackState getPlaybackState();
+    method public java.util.List<android.media.session.MediaSession.QueueItem> getQueue();
+    method public java.lang.CharSequence getQueueTitle();
+    method public int getRatingType();
+    method public android.app.PendingIntent getSessionActivity();
+    method public android.media.session.MediaSession.Token getSessionToken();
+    method public android.media.session.MediaController.TransportControls getTransportControls();
+    method public void registerCallback(android.media.session.MediaController.Callback);
+    method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
+    method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+    method public void setVolumeTo(int, int);
+    method public void unregisterCallback(android.media.session.MediaController.Callback);
+  }
+
+  public static abstract class MediaController.Callback {
+    ctor public MediaController.Callback();
+    method public void onAudioInfoChanged(android.media.session.MediaController.PlaybackInfo);
+    method public void onExtrasChanged(android.os.Bundle);
+    method public void onMetadataChanged(android.media.MediaMetadata);
+    method public void onPlaybackStateChanged(android.media.session.PlaybackState);
+    method public void onQueueChanged(java.util.List<android.media.session.MediaSession.QueueItem>);
+    method public void onQueueTitleChanged(java.lang.CharSequence);
+    method public void onSessionDestroyed();
+    method public void onSessionEvent(java.lang.String, android.os.Bundle);
+  }
+
+  public static final class MediaController.PlaybackInfo {
+    method public android.media.AudioAttributes getAudioAttributes();
+    method public int getCurrentVolume();
+    method public int getMaxVolume();
+    method public int getPlaybackType();
+    method public int getVolumeControl();
+    field public static final int PLAYBACK_TYPE_LOCAL = 1; // 0x1
+    field public static final int PLAYBACK_TYPE_REMOTE = 2; // 0x2
+  }
+
+  public final class MediaController.TransportControls {
+    method public void fastForward();
+    method public void pause();
+    method public void play();
+    method public void playFromMediaId(java.lang.String, android.os.Bundle);
+    method public void playFromSearch(java.lang.String, android.os.Bundle);
+    method public void rewind();
+    method public void seekTo(long);
+    method public void sendCustomAction(android.media.session.PlaybackState.CustomAction, android.os.Bundle);
+    method public void sendCustomAction(java.lang.String, android.os.Bundle);
+    method public void setRating(android.media.Rating);
+    method public void skipToNext();
+    method public void skipToPrevious();
+    method public void skipToQueueItem(long);
+    method public void stop();
+  }
+
+  public final class MediaSession {
+    ctor public MediaSession(android.content.Context, java.lang.String);
+    method public android.media.session.MediaController getController();
+    method public android.media.session.MediaSession.Token getSessionToken();
+    method public boolean isActive();
+    method public void release();
+    method public void sendSessionEvent(java.lang.String, android.os.Bundle);
+    method public void setActive(boolean);
+    method public void setCallback(android.media.session.MediaSession.Callback);
+    method public void setCallback(android.media.session.MediaSession.Callback, android.os.Handler);
+    method public void setExtras(android.os.Bundle);
+    method public void setFlags(int);
+    method public void setMediaButtonReceiver(android.app.PendingIntent);
+    method public void setMetadata(android.media.MediaMetadata);
+    method public void setPlaybackState(android.media.session.PlaybackState);
+    method public void setPlaybackToLocal(android.media.AudioAttributes);
+    method public void setPlaybackToRemote(android.media.VolumeProvider);
+    method public void setQueue(java.util.List<android.media.session.MediaSession.QueueItem>);
+    method public void setQueueTitle(java.lang.CharSequence);
+    method public void setSessionActivity(android.app.PendingIntent);
+    field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+    field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
+  }
+
+  public static abstract class MediaSession.Callback {
+    ctor public MediaSession.Callback();
+    method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+    method public void onCustomAction(java.lang.String, android.os.Bundle);
+    method public void onFastForward();
+    method public boolean onMediaButtonEvent(android.content.Intent);
+    method public void onPause();
+    method public void onPlay();
+    method public void onPlayFromMediaId(java.lang.String, android.os.Bundle);
+    method public void onPlayFromSearch(java.lang.String, android.os.Bundle);
+    method public void onRewind();
+    method public void onSeekTo(long);
+    method public void onSetRating(android.media.Rating);
+    method public void onSkipToNext();
+    method public void onSkipToPrevious();
+    method public void onSkipToQueueItem(long);
+    method public void onStop();
+  }
+
+  public static final class MediaSession.QueueItem implements android.os.Parcelable {
+    ctor public MediaSession.QueueItem(android.media.MediaDescription, long);
+    method public int describeContents();
+    method public android.media.MediaDescription getDescription();
+    method public long getQueueId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int UNKNOWN_ID = -1; // 0xffffffff
+  }
+
+  public static final class MediaSession.Token implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public final class MediaSessionManager {
+    method public void addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName);
+    method public void addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName, android.os.Handler);
+    method public java.util.List<android.media.session.MediaController> getActiveSessions(android.content.ComponentName);
+    method public void removeOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener);
+  }
+
+  public static abstract interface MediaSessionManager.OnActiveSessionsChangedListener {
+    method public abstract void onActiveSessionsChanged(java.util.List<android.media.session.MediaController>);
+  }
+
+  public final class PlaybackState implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getActions();
+    method public long getActiveQueueItemId();
+    method public long getBufferedPosition();
+    method public java.util.List<android.media.session.PlaybackState.CustomAction> getCustomActions();
+    method public java.lang.CharSequence getErrorMessage();
+    method public long getLastPositionUpdateTime();
+    method public float getPlaybackSpeed();
+    method public long getPosition();
+    method public int getState();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final long ACTION_FAST_FORWARD = 64L; // 0x40L
+    field public static final long ACTION_PAUSE = 2L; // 0x2L
+    field public static final long ACTION_PLAY = 4L; // 0x4L
+    field public static final long ACTION_PLAY_FROM_MEDIA_ID = 1024L; // 0x400L
+    field public static final long ACTION_PLAY_FROM_SEARCH = 2048L; // 0x800L
+    field public static final long ACTION_PLAY_PAUSE = 512L; // 0x200L
+    field public static final long ACTION_REWIND = 8L; // 0x8L
+    field public static final long ACTION_SEEK_TO = 256L; // 0x100L
+    field public static final long ACTION_SET_RATING = 128L; // 0x80L
+    field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
+    field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
+    field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
+    field public static final long ACTION_STOP = 1L; // 0x1L
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
+    field public static final int STATE_BUFFERING = 6; // 0x6
+    field public static final int STATE_CONNECTING = 8; // 0x8
+    field public static final int STATE_ERROR = 7; // 0x7
+    field public static final int STATE_FAST_FORWARDING = 4; // 0x4
+    field public static final int STATE_NONE = 0; // 0x0
+    field public static final int STATE_PAUSED = 2; // 0x2
+    field public static final int STATE_PLAYING = 3; // 0x3
+    field public static final int STATE_REWINDING = 5; // 0x5
+    field public static final int STATE_SKIPPING_TO_NEXT = 10; // 0xa
+    field public static final int STATE_SKIPPING_TO_PREVIOUS = 9; // 0x9
+    field public static final int STATE_SKIPPING_TO_QUEUE_ITEM = 11; // 0xb
+    field public static final int STATE_STOPPED = 1; // 0x1
+  }
+
+  public static final class PlaybackState.Builder {
+    ctor public PlaybackState.Builder();
+    ctor public PlaybackState.Builder(android.media.session.PlaybackState);
+    method public android.media.session.PlaybackState.Builder addCustomAction(java.lang.String, java.lang.String, int);
+    method public android.media.session.PlaybackState.Builder addCustomAction(android.media.session.PlaybackState.CustomAction);
+    method public android.media.session.PlaybackState build();
+    method public android.media.session.PlaybackState.Builder setActions(long);
+    method public android.media.session.PlaybackState.Builder setActiveQueueItemId(long);
+    method public android.media.session.PlaybackState.Builder setBufferedPosition(long);
+    method public android.media.session.PlaybackState.Builder setErrorMessage(java.lang.CharSequence);
+    method public android.media.session.PlaybackState.Builder setState(int, long, float, long);
+    method public android.media.session.PlaybackState.Builder setState(int, long, float);
+  }
+
+  public static final class PlaybackState.CustomAction implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.lang.String getAction();
+    method public android.os.Bundle getExtras();
+    method public int getIcon();
+    method public java.lang.CharSequence getName();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static final class PlaybackState.CustomAction.Builder {
+    ctor public PlaybackState.CustomAction.Builder(java.lang.String, java.lang.CharSequence, int);
+    method public android.media.session.PlaybackState.CustomAction build();
+    method public android.media.session.PlaybackState.CustomAction.Builder setExtras(android.os.Bundle);
+  }
+
+}
+
+package android.media.tv {
+
+  public final class TvContentRating {
+    method public static android.media.tv.TvContentRating createRating(java.lang.String, java.lang.String, java.lang.String, java.lang.String...);
+    method public java.lang.String flattenToString();
+    method public java.lang.String getDomain();
+    method public java.lang.String getMainRating();
+    method public java.lang.String getRatingSystem();
+    method public java.util.List<java.lang.String> getSubRatings();
+    method public static android.media.tv.TvContentRating unflattenFromString(java.lang.String);
+  }
+
+  public final class TvContract {
+    method public static final android.net.Uri buildChannelLogoUri(long);
+    method public static final android.net.Uri buildChannelLogoUri(android.net.Uri);
+    method public static final android.net.Uri buildChannelUri(long);
+    method public static final android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
+    method public static final android.net.Uri buildChannelsUriForInput(java.lang.String);
+    method public static final java.lang.String buildInputId(android.content.ComponentName);
+    method public static final android.net.Uri buildProgramUri(long);
+    method public static final android.net.Uri buildProgramsUriForChannel(long);
+    method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
+    method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
+    method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+    field public static final java.lang.String AUTHORITY = "android.media.tv";
+  }
+
+  public static abstract interface TvContract.BaseTvColumns implements android.provider.BaseColumns {
+    field public static final java.lang.String COLUMN_PACKAGE_NAME = "package_name";
+  }
+
+  public static final class TvContract.Channels implements android.media.tv.TvContract.BaseTvColumns {
+    method public static final java.lang.String getVideoResolution(java.lang.String);
+    field public static final java.lang.String COLUMN_DESCRIPTION = "description";
+    field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
+    field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
+    field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_NETWORK_AFFILIATION = "network_affiliation";
+    field public static final java.lang.String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
+    field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type";
+    field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
+    field public static final java.lang.String COLUMN_TYPE = "type";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_FORMAT = "video_format";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/channel";
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
+    field public static final java.lang.String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO";
+    field public static final java.lang.String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER";
+    field public static final java.lang.String TYPE_1SEG = "TYPE_1SEG";
+    field public static final java.lang.String TYPE_ATSC_C = "TYPE_ATSC_C";
+    field public static final java.lang.String TYPE_ATSC_M_H = "TYPE_ATSC_M_H";
+    field public static final java.lang.String TYPE_ATSC_T = "TYPE_ATSC_T";
+    field public static final java.lang.String TYPE_CMMB = "TYPE_CMMB";
+    field public static final java.lang.String TYPE_DTMB = "TYPE_DTMB";
+    field public static final java.lang.String TYPE_DVB_C = "TYPE_DVB_C";
+    field public static final java.lang.String TYPE_DVB_C2 = "TYPE_DVB_C2";
+    field public static final java.lang.String TYPE_DVB_H = "TYPE_DVB_H";
+    field public static final java.lang.String TYPE_DVB_S = "TYPE_DVB_S";
+    field public static final java.lang.String TYPE_DVB_S2 = "TYPE_DVB_S2";
+    field public static final java.lang.String TYPE_DVB_SH = "TYPE_DVB_SH";
+    field public static final java.lang.String TYPE_DVB_T = "TYPE_DVB_T";
+    field public static final java.lang.String TYPE_DVB_T2 = "TYPE_DVB_T2";
+    field public static final java.lang.String TYPE_ISDB_C = "TYPE_ISDB_C";
+    field public static final java.lang.String TYPE_ISDB_S = "TYPE_ISDB_S";
+    field public static final java.lang.String TYPE_ISDB_T = "TYPE_ISDB_T";
+    field public static final java.lang.String TYPE_ISDB_TB = "TYPE_ISDB_TB";
+    field public static final java.lang.String TYPE_NTSC = "TYPE_NTSC";
+    field public static final java.lang.String TYPE_OTHER = "TYPE_OTHER";
+    field public static final java.lang.String TYPE_PAL = "TYPE_PAL";
+    field public static final java.lang.String TYPE_SECAM = "TYPE_SECAM";
+    field public static final java.lang.String TYPE_S_DMB = "TYPE_S_DMB";
+    field public static final java.lang.String TYPE_T_DMB = "TYPE_T_DMB";
+    field public static final java.lang.String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I";
+    field public static final java.lang.String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P";
+    field public static final java.lang.String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P";
+    field public static final java.lang.String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P";
+    field public static final java.lang.String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P";
+    field public static final java.lang.String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P";
+    field public static final java.lang.String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I";
+    field public static final java.lang.String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P";
+    field public static final java.lang.String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I";
+    field public static final java.lang.String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P";
+    field public static final java.lang.String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P";
+    field public static final java.lang.String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED";
+    field public static final java.lang.String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD";
+    field public static final java.lang.String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD";
+    field public static final java.lang.String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD";
+    field public static final java.lang.String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD";
+  }
+
+  public static final class TvContract.Channels.Logo {
+    field public static final java.lang.String CONTENT_DIRECTORY = "logo";
+  }
+
+  public static final class TvContract.Programs implements android.media.tv.TvContract.BaseTvColumns {
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+    field public static final java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
+    field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+    field public static final java.lang.String COLUMN_SEASON_NUMBER = "season_number";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
+    field public static final android.net.Uri CONTENT_URI;
+  }
+
+  public static final class TvContract.Programs.Genres {
+    method public static java.lang.String[] decode(java.lang.String);
+    method public static java.lang.String encode(java.lang.String...);
+    field public static final java.lang.String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE";
+    field public static final java.lang.String COMEDY = "COMEDY";
+    field public static final java.lang.String DRAMA = "DRAMA";
+    field public static final java.lang.String EDUCATION = "EDUCATION";
+    field public static final java.lang.String FAMILY_KIDS = "FAMILY_KIDS";
+    field public static final java.lang.String GAMING = "GAMING";
+    field public static final java.lang.String MOVIES = "MOVIES";
+    field public static final java.lang.String NEWS = "NEWS";
+    field public static final java.lang.String SHOPPING = "SHOPPING";
+    field public static final java.lang.String SPORTS = "SPORTS";
+    field public static final java.lang.String TRAVEL = "TRAVEL";
+  }
+
+  public final class TvInputInfo implements android.os.Parcelable {
+    method public android.content.Intent createSettingsIntent();
+    method public android.content.Intent createSetupIntent();
+    method public int describeContents();
+    method public java.lang.String getId();
+    method public java.lang.String getParentId();
+    method public android.content.pm.ServiceInfo getServiceInfo();
+    method public int getType();
+    method public boolean isPassthroughInput();
+    method public android.graphics.drawable.Drawable loadIcon(android.content.Context);
+    method public java.lang.CharSequence loadLabel(android.content.Context);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final java.lang.String EXTRA_INPUT_ID = "android.media.tv.extra.INPUT_ID";
+    field public static final int TYPE_COMPONENT = 1004; // 0x3ec
+    field public static final int TYPE_COMPOSITE = 1001; // 0x3e9
+    field public static final int TYPE_DISPLAY_PORT = 1008; // 0x3f0
+    field public static final int TYPE_DVI = 1006; // 0x3ee
+    field public static final int TYPE_HDMI = 1007; // 0x3ef
+    field public static final int TYPE_OTHER = 1000; // 0x3e8
+    field public static final int TYPE_SCART = 1003; // 0x3eb
+    field public static final int TYPE_SVIDEO = 1002; // 0x3ea
+    field public static final int TYPE_TUNER = 0; // 0x0
+    field public static final int TYPE_VGA = 1005; // 0x3ed
+  }
+
+  public final class TvInputManager {
+    method public int getInputState(java.lang.String);
+    method public android.media.tv.TvInputInfo getTvInputInfo(java.lang.String);
+    method public java.util.List<android.media.tv.TvInputInfo> getTvInputList();
+    method public boolean isParentalControlsEnabled();
+    method public boolean isRatingBlocked(android.media.tv.TvContentRating);
+    method public void registerCallback(android.media.tv.TvInputManager.TvInputCallback, android.os.Handler);
+    method public void unregisterCallback(android.media.tv.TvInputManager.TvInputCallback);
+    field public static final java.lang.String ACTION_BLOCKED_RATINGS_CHANGED = "android.media.tv.action.BLOCKED_RATINGS_CHANGED";
+    field public static final java.lang.String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED";
+    field public static final java.lang.String ACTION_QUERY_CONTENT_RATING_SYSTEMS = "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS";
+    field public static final int INPUT_STATE_CONNECTED = 0; // 0x0
+    field public static final int INPUT_STATE_CONNECTED_STANDBY = 1; // 0x1
+    field public static final int INPUT_STATE_DISCONNECTED = 2; // 0x2
+    field public static final java.lang.String META_DATA_CONTENT_RATING_SYSTEMS = "android.media.tv.metadata.CONTENT_RATING_SYSTEMS";
+    field public static final int VIDEO_UNAVAILABLE_REASON_BUFFERING = 3; // 0x3
+    field public static final int VIDEO_UNAVAILABLE_REASON_TUNING = 1; // 0x1
+    field public static final int VIDEO_UNAVAILABLE_REASON_UNKNOWN = 0; // 0x0
+    field public static final int VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 2; // 0x2
+  }
+
+  public static abstract class TvInputManager.TvInputCallback {
+    ctor public TvInputManager.TvInputCallback();
+    method public void onInputAdded(java.lang.String);
+    method public void onInputRemoved(java.lang.String);
+    method public void onInputStateChanged(java.lang.String, int);
+  }
+
+  public abstract class TvInputService extends android.app.Service {
+    ctor public TvInputService();
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public abstract android.media.tv.TvInputService.Session onCreateSession(java.lang.String);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.media.tv.TvInputService";
+    field public static final java.lang.String SERVICE_META_DATA = "android.media.tv.input";
+  }
+
+  public static abstract class TvInputService.HardwareSession extends android.media.tv.TvInputService.Session {
+    ctor public TvInputService.HardwareSession(android.content.Context);
+    method public abstract java.lang.String getHardwareInputId();
+    method public void onHardwareVideoAvailable();
+    method public void onHardwareVideoUnavailable(int);
+    method public final boolean onSetSurface(android.view.Surface);
+  }
+
+  public static abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
+    ctor public TvInputService.Session(android.content.Context);
+    method public void notifyChannelRetuned(android.net.Uri);
+    method public void notifyContentAllowed();
+    method public void notifyContentBlocked(android.media.tv.TvContentRating);
+    method public void notifyTrackSelected(int, java.lang.String);
+    method public void notifyTracksChanged(java.util.List<android.media.tv.TvTrackInfo>);
+    method public void notifyVideoAvailable();
+    method public void notifyVideoUnavailable(int);
+    method public android.view.View onCreateOverlayView();
+    method public boolean onGenericMotionEvent(android.view.MotionEvent);
+    method public boolean onKeyDown(int, android.view.KeyEvent);
+    method public boolean onKeyLongPress(int, android.view.KeyEvent);
+    method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
+    method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public abstract void onRelease();
+    method public boolean onSelectTrack(int, java.lang.String);
+    method public abstract void onSetCaptionEnabled(boolean);
+    method public abstract void onSetStreamVolume(float);
+    method public abstract boolean onSetSurface(android.view.Surface);
+    method public void onSurfaceChanged(int, int, int);
+    method public boolean onTouchEvent(android.view.MotionEvent);
+    method public boolean onTrackballEvent(android.view.MotionEvent);
+    method public abstract boolean onTune(android.net.Uri);
+    method public void onUnblockContent(android.media.tv.TvContentRating);
+    method public void setOverlayViewEnabled(boolean);
+  }
+
+  public final class TvTrackInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public final int getAudioChannelCount();
+    method public final int getAudioSampleRate();
+    method public final android.os.Bundle getExtra();
+    method public final java.lang.String getId();
+    method public final java.lang.String getLanguage();
+    method public final int getType();
+    method public final float getVideoFrameRate();
+    method public final int getVideoHeight();
+    method public final int getVideoWidth();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int TYPE_AUDIO = 0; // 0x0
+    field public static final int TYPE_SUBTITLE = 2; // 0x2
+    field public static final int TYPE_VIDEO = 1; // 0x1
+  }
+
+  public static final class TvTrackInfo.Builder {
+    ctor public TvTrackInfo.Builder(int, java.lang.String);
+    method public android.media.tv.TvTrackInfo build();
+    method public final android.media.tv.TvTrackInfo.Builder setAudioChannelCount(int);
+    method public final android.media.tv.TvTrackInfo.Builder setAudioSampleRate(int);
+    method public final android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle);
+    method public final android.media.tv.TvTrackInfo.Builder setLanguage(java.lang.String);
+    method public final android.media.tv.TvTrackInfo.Builder setVideoFrameRate(float);
+    method public final android.media.tv.TvTrackInfo.Builder setVideoHeight(int);
+    method public final android.media.tv.TvTrackInfo.Builder setVideoWidth(int);
+  }
+
+  public class TvView extends android.view.ViewGroup {
+    ctor public TvView(android.content.Context);
+    ctor public TvView(android.content.Context, android.util.AttributeSet);
+    ctor public TvView(android.content.Context, android.util.AttributeSet, int);
+    method public boolean dispatchUnhandledInputEvent(android.view.InputEvent);
+    method public java.lang.String getSelectedTrack(int);
+    method public java.util.List<android.media.tv.TvTrackInfo> getTracks(int);
+    method protected void onLayout(boolean, int, int, int, int);
+    method public boolean onUnhandledInputEvent(android.view.InputEvent);
+    method public void reset();
+    method public void selectTrack(int, java.lang.String);
+    method public void setCallback(android.media.tv.TvView.TvInputCallback);
+    method public void setCaptionEnabled(boolean);
+    method public void setOnUnhandledInputEventListener(android.media.tv.TvView.OnUnhandledInputEventListener);
+    method public void setStreamVolume(float);
+    method public void tune(java.lang.String, android.net.Uri);
+  }
+
+  public static abstract interface TvView.OnUnhandledInputEventListener {
+    method public abstract boolean onUnhandledInputEvent(android.view.InputEvent);
+  }
+
+  public static abstract class TvView.TvInputCallback {
+    ctor public TvView.TvInputCallback();
+    method public void onChannelRetuned(java.lang.String, android.net.Uri);
+    method public void onConnectionFailed(java.lang.String);
+    method public void onContentAllowed(java.lang.String);
+    method public void onContentBlocked(java.lang.String, android.media.tv.TvContentRating);
+    method public void onDisconnected(java.lang.String);
+    method public void onTrackSelected(java.lang.String, int, java.lang.String);
+    method public void onTracksChanged(java.lang.String, java.util.List<android.media.tv.TvTrackInfo>);
+    method public void onVideoAvailable(java.lang.String);
+    method public void onVideoSizeChanged(java.lang.String, int, int);
+    method public void onVideoUnavailable(java.lang.String, int);
+  }
+
+}
+
 package android.mtp {
 
   public final class MtpConstants {
@@ -13835,17 +16851,30 @@
 package android.net {
 
   public class ConnectivityManager {
+    method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
     method public android.net.NetworkInfo getActiveNetworkInfo();
     method public android.net.NetworkInfo[] getAllNetworkInfo();
+    method public android.net.Network[] getAllNetworks();
     method public deprecated boolean getBackgroundDataSetting();
+    method public android.net.LinkProperties getLinkProperties(android.net.Network);
+    method public android.net.NetworkCapabilities getNetworkCapabilities(android.net.Network);
     method public android.net.NetworkInfo getNetworkInfo(int);
-    method public int getNetworkPreference();
+    method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
+    method public deprecated int getNetworkPreference();
+    method public static android.net.Network getProcessDefaultNetwork();
     method public boolean isActiveNetworkMetered();
+    method public boolean isDefaultNetworkActive();
     method public static boolean isNetworkTypeValid(int);
-    method public boolean requestRouteToHost(int, int);
-    method public void setNetworkPreference(int);
-    method public int startUsingNetworkFeature(int, java.lang.String);
-    method public int stopUsingNetworkFeature(int, java.lang.String);
+    method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
+    method public void removeDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
+    method public void reportBadNetwork(android.net.Network);
+    method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
+    method public deprecated boolean requestRouteToHost(int, int);
+    method public deprecated void setNetworkPreference(int);
+    method public static boolean setProcessDefaultNetwork(android.net.Network);
+    method public deprecated int startUsingNetworkFeature(int, java.lang.String);
+    method public deprecated int stopUsingNetworkFeature(int, java.lang.String);
+    method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
     field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
     field public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
     field public static final deprecated int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
@@ -13864,10 +16893,24 @@
     field public static final int TYPE_MOBILE_HIPRI = 5; // 0x5
     field public static final int TYPE_MOBILE_MMS = 2; // 0x2
     field public static final int TYPE_MOBILE_SUPL = 3; // 0x3
+    field public static final int TYPE_VPN = 17; // 0x11
     field public static final int TYPE_WIFI = 1; // 0x1
     field public static final int TYPE_WIMAX = 6; // 0x6
   }
 
+  public static class ConnectivityManager.NetworkCallback {
+    ctor public ConnectivityManager.NetworkCallback();
+    method public void onAvailable(android.net.Network);
+    method public void onCapabilitiesChanged(android.net.Network, android.net.NetworkCapabilities);
+    method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
+    method public void onLosing(android.net.Network, int);
+    method public void onLost(android.net.Network);
+  }
+
+  public static abstract interface ConnectivityManager.OnNetworkActiveListener {
+    method public abstract void onNetworkActive();
+  }
+
   public class Credentials {
     ctor public Credentials(int, int, int);
     method public int getGid();
@@ -13888,6 +16931,37 @@
     field public int serverAddress;
   }
 
+  public final class IpPrefix implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.net.InetAddress getAddress();
+    method public int getPrefixLength();
+    method public byte[] getRawAddress();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public class LinkAddress implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.net.InetAddress getAddress();
+    method public int getFlags();
+    method public int getPrefixLength();
+    method public int getScope();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public final class LinkProperties implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.util.List<java.net.InetAddress> getDnsServers();
+    method public java.lang.String getDomains();
+    method public android.net.ProxyInfo getHttpProxy();
+    method public java.lang.String getInterfaceName();
+    method public java.util.List<android.net.LinkAddress> getLinkAddresses();
+    method public java.util.List<android.net.RouteInfo> getRoutes();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public class LocalServerSocket {
     ctor public LocalServerSocket(java.lang.String) throws java.io.IOException;
     ctor public LocalServerSocket(java.io.FileDescriptor) throws java.io.IOException;
@@ -13956,6 +17030,49 @@
     field public static final java.lang.String MAILTO_SCHEME = "mailto:";
   }
 
+  public class Network implements android.os.Parcelable {
+    method public void bindSocket(java.net.Socket) throws java.io.IOException;
+    method public int describeContents();
+    method public java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException;
+    method public java.net.InetAddress getByName(java.lang.String) throws java.net.UnknownHostException;
+    method public javax.net.SocketFactory getSocketFactory();
+    method public java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public final class NetworkCapabilities implements android.os.Parcelable {
+    ctor public NetworkCapabilities(android.net.NetworkCapabilities);
+    method public int describeContents();
+    method public int getLinkDownstreamBandwidthKbps();
+    method public int getLinkUpstreamBandwidthKbps();
+    method public boolean hasCapability(int);
+    method public boolean hasTransport(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int NET_CAPABILITY_CBS = 5; // 0x5
+    field public static final int NET_CAPABILITY_DUN = 2; // 0x2
+    field public static final int NET_CAPABILITY_EIMS = 10; // 0xa
+    field public static final int NET_CAPABILITY_FOTA = 3; // 0x3
+    field public static final int NET_CAPABILITY_IA = 7; // 0x7
+    field public static final int NET_CAPABILITY_IMS = 4; // 0x4
+    field public static final int NET_CAPABILITY_INTERNET = 12; // 0xc
+    field public static final int NET_CAPABILITY_MMS = 0; // 0x0
+    field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
+    field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
+    field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
+    field public static final int NET_CAPABILITY_RCS = 8; // 0x8
+    field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
+    field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe
+    field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6
+    field public static final int NET_CAPABILITY_XCAP = 9; // 0x9
+    field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2
+    field public static final int TRANSPORT_CELLULAR = 0; // 0x0
+    field public static final int TRANSPORT_ETHERNET = 3; // 0x3
+    field public static final int TRANSPORT_VPN = 4; // 0x4
+    field public static final int TRANSPORT_WIFI = 1; // 0x1
+  }
+
   public class NetworkInfo implements android.os.Parcelable {
     method public int describeContents();
     method public android.net.NetworkInfo.DetailedState getDetailedState();
@@ -14003,6 +17120,22 @@
     enum_constant public static final android.net.NetworkInfo.State UNKNOWN;
   }
 
+  public class NetworkRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static class NetworkRequest.Builder {
+    ctor public NetworkRequest.Builder();
+    method public android.net.NetworkRequest.Builder addCapability(int);
+    method public android.net.NetworkRequest.Builder addTransportType(int);
+    method public android.net.NetworkRequest build();
+    method public android.net.NetworkRequest.Builder removeCapability(int);
+    method public android.net.NetworkRequest.Builder removeTransportType(int);
+    method public android.net.NetworkRequest.Builder setNetworkSpecifier(java.lang.String);
+  }
+
   public class ParseException extends java.lang.RuntimeException {
     field public java.lang.String response;
   }
@@ -14013,9 +17146,47 @@
     method public static final deprecated int getDefaultPort();
     method public static final deprecated java.lang.String getHost(android.content.Context);
     method public static final deprecated int getPort(android.content.Context);
+    field public static final java.lang.String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO";
     field public static final java.lang.String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE";
   }
 
+  public class ProxyInfo implements android.os.Parcelable {
+    method public static android.net.ProxyInfo buildDirectProxy(java.lang.String, int);
+    method public static android.net.ProxyInfo buildDirectProxy(java.lang.String, int, java.util.List<java.lang.String>);
+    method public static android.net.ProxyInfo buildPacProxy(android.net.Uri);
+    method public int describeContents();
+    method public java.lang.String[] getExclusionList();
+    method public java.lang.String getHost();
+    method public android.net.Uri getPacFileUrl();
+    method public int getPort();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public abstract class PskKeyManager {
+    ctor public PskKeyManager();
+    method public java.lang.String chooseClientKeyIdentity(java.lang.String, java.net.Socket);
+    method public java.lang.String chooseClientKeyIdentity(java.lang.String, javax.net.ssl.SSLEngine);
+    method public java.lang.String chooseServerKeyIdentityHint(java.net.Socket);
+    method public java.lang.String chooseServerKeyIdentityHint(javax.net.ssl.SSLEngine);
+    method public javax.crypto.SecretKey getKey(java.lang.String, java.lang.String, java.net.Socket);
+    method public javax.crypto.SecretKey getKey(java.lang.String, java.lang.String, javax.net.ssl.SSLEngine);
+    field public static final int MAX_IDENTITY_HINT_LENGTH_BYTES = 128; // 0x80
+    field public static final int MAX_IDENTITY_LENGTH_BYTES = 128; // 0x80
+    field public static final int MAX_KEY_LENGTH_BYTES = 256; // 0x100
+  }
+
+  public final class RouteInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.net.IpPrefix getDestination();
+    method public java.net.InetAddress getGateway();
+    method public java.lang.String getInterface();
+    method public boolean isDefaultRoute();
+    method public boolean matches(java.net.InetAddress);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
     ctor public deprecated SSLCertificateSocketFactory(int);
     method public java.net.Socket createSocket(java.net.Socket, java.lang.String, int, boolean) throws java.io.IOException;
@@ -14224,12 +17395,17 @@
     ctor public VpnService.Builder();
     method public android.net.VpnService.Builder addAddress(java.net.InetAddress, int);
     method public android.net.VpnService.Builder addAddress(java.lang.String, int);
+    method public android.net.VpnService.Builder addAllowedApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public android.net.VpnService.Builder addDisallowedApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.net.VpnService.Builder addDnsServer(java.net.InetAddress);
     method public android.net.VpnService.Builder addDnsServer(java.lang.String);
     method public android.net.VpnService.Builder addRoute(java.net.InetAddress, int);
     method public android.net.VpnService.Builder addRoute(java.lang.String, int);
     method public android.net.VpnService.Builder addSearchDomain(java.lang.String);
+    method public android.net.VpnService.Builder allowBypass();
+    method public android.net.VpnService.Builder allowFamily(int);
     method public android.os.ParcelFileDescriptor establish();
+    method public android.net.VpnService.Builder setBlocking(boolean);
     method public android.net.VpnService.Builder setConfigureIntent(android.app.PendingIntent);
     method public android.net.VpnService.Builder setMtu(int);
     method public android.net.VpnService.Builder setSession(java.lang.String);
@@ -14322,6 +17498,7 @@
   public class X509TrustManagerExtensions {
     ctor public X509TrustManagerExtensions(javax.net.ssl.X509TrustManager) throws java.lang.IllegalArgumentException;
     method public java.util.List<java.security.cert.X509Certificate> checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String, java.lang.String) throws java.security.cert.CertificateException;
+    method public boolean isUserAddedCertificate(java.security.cert.X509Certificate);
   }
 
 }
@@ -14368,10 +17545,13 @@
   public final class NsdServiceInfo implements android.os.Parcelable {
     ctor public NsdServiceInfo();
     method public int describeContents();
+    method public java.util.Map<java.lang.String, byte[]> getAttributes();
     method public java.net.InetAddress getHost();
     method public int getPort();
     method public java.lang.String getServiceName();
     method public java.lang.String getServiceType();
+    method public void removeAttribute(java.lang.String);
+    method public void setAttribute(java.lang.String, java.lang.String);
     method public void setHost(java.net.InetAddress);
     method public void setPort(int);
     method public void setServiceName(java.lang.String);
@@ -14655,6 +17835,7 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public java.lang.String BSSID;
+    field public java.lang.String FQDN;
     field public java.lang.String SSID;
     field public java.util.BitSet allowedAuthAlgorithms;
     field public java.util.BitSet allowedGroupCiphers;
@@ -14744,9 +17925,11 @@
   }
 
   public static final class WifiEnterpriseConfig.Eap {
+    field public static final int AKA = 5; // 0x5
     field public static final int NONE = -1; // 0xffffffff
     field public static final int PEAP = 0; // 0x0
     field public static final int PWD = 3; // 0x3
+    field public static final int SIM = 4; // 0x4
     field public static final int TLS = 1; // 0x1
     field public static final int TTLS = 2; // 0x2
   }
@@ -14763,6 +17946,7 @@
     method public int describeContents();
     method public java.lang.String getBSSID();
     method public static android.net.NetworkInfo.DetailedState getDetailedStateOf(android.net.wifi.SupplicantState);
+    method public int getFrequency();
     method public boolean getHiddenSSID();
     method public int getIpAddress();
     method public int getLinkSpeed();
@@ -14772,12 +17956,14 @@
     method public java.lang.String getSSID();
     method public android.net.wifi.SupplicantState getSupplicantState();
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String FREQUENCY_UNITS = "MHz";
     field public static final java.lang.String LINK_SPEED_UNITS = "Mbps";
   }
 
   public class WifiManager {
     method public int addNetwork(android.net.wifi.WifiConfiguration);
     method public static int calculateSignalLevel(int, int);
+    method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
     method public static int compareSignalLevel(int, int);
     method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String);
     method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, java.lang.String);
@@ -14790,7 +17976,13 @@
     method public android.net.DhcpInfo getDhcpInfo();
     method public java.util.List<android.net.wifi.ScanResult> getScanResults();
     method public int getWifiState();
+    method public boolean is5GHzBandSupported();
+    method public boolean isDeviceToApRttSupported();
+    method public boolean isEnhancedPowerReportingSupported();
+    method public boolean isP2pSupported();
+    method public boolean isPreferredNetworkOffloadSupported();
     method public boolean isScanAlwaysAvailable();
+    method public boolean isTdlsSupported();
     method public boolean isWifiEnabled();
     method public boolean pingSupplicant();
     method public boolean reassociate();
@@ -14801,6 +17993,7 @@
     method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
     method public boolean setWifiEnabled(boolean);
     method public boolean startScan();
+    method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
     method public int updateNetwork(android.net.wifi.WifiConfiguration);
     field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
     field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
@@ -14829,6 +18022,11 @@
     field public static final int WIFI_STATE_ENABLED = 3; // 0x3
     field public static final int WIFI_STATE_ENABLING = 2; // 0x2
     field public static final int WIFI_STATE_UNKNOWN = 4; // 0x4
+    field public static final int WPS_AUTH_FAILURE = 6; // 0x6
+    field public static final int WPS_OVERLAP_ERROR = 3; // 0x3
+    field public static final int WPS_TIMED_OUT = 7; // 0x7
+    field public static final int WPS_TKIP_ONLY_PROHIBITED = 5; // 0x5
+    field public static final int WPS_WEP_PROHIBITED = 4; // 0x4
   }
 
   public class WifiManager.MulticastLock {
@@ -14846,11 +18044,19 @@
     method public void setWorkSource(android.os.WorkSource);
   }
 
+  public static abstract class WifiManager.WpsCallback {
+    ctor public WifiManager.WpsCallback();
+    method public abstract void onFailed(int);
+    method public abstract void onStarted(java.lang.String);
+    method public abstract void onSucceeded();
+  }
+
   public class WpsInfo implements android.os.Parcelable {
     ctor public WpsInfo();
     ctor public WpsInfo(android.net.wifi.WpsInfo);
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
+    field public java.lang.String BSSID;
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int DISPLAY = 1; // 0x1
     field public static final int INVALID = 4; // 0x4
@@ -15084,6 +18290,7 @@
     method public static android.nfc.NdefRecord createApplicationRecord(java.lang.String);
     method public static android.nfc.NdefRecord createExternal(java.lang.String, java.lang.String, byte[]);
     method public static android.nfc.NdefRecord createMime(java.lang.String, byte[]);
+    method public static android.nfc.NdefRecord createTextRecord(java.lang.String, java.lang.String);
     method public static android.nfc.NdefRecord createUri(android.net.Uri);
     method public static android.nfc.NdefRecord createUri(java.lang.String);
     method public int describeContents();
@@ -15120,6 +18327,7 @@
     method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
     method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
     method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
+    method public boolean invokeBeam(android.app.Activity);
     method public boolean isEnabled();
     method public boolean isNdefPushEnabled();
     method public void setBeamPushUris(android.net.Uri[], android.app.Activity);
@@ -15191,10 +18399,17 @@
 package android.nfc.cardemulation {
 
   public final class CardEmulation {
+    method public boolean categoryAllowsForegroundPreference(java.lang.String);
+    method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, java.lang.String);
     method public static synchronized android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
     method public int getSelectionModeForCategory(java.lang.String);
     method public boolean isDefaultServiceForAid(android.content.ComponentName, java.lang.String);
     method public boolean isDefaultServiceForCategory(android.content.ComponentName, java.lang.String);
+    method public boolean registerAidsForService(android.content.ComponentName, java.lang.String, java.util.List<java.lang.String>);
+    method public boolean removeAidsForService(android.content.ComponentName, java.lang.String);
+    method public boolean setPreferredService(android.app.Activity, android.content.ComponentName);
+    method public boolean supportsAidPrefixRegistration();
+    method public boolean unsetPreferredService(android.app.Activity);
     field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
     field public static final java.lang.String CATEGORY_OTHER = "other";
     field public static final java.lang.String CATEGORY_PAYMENT = "payment";
@@ -15545,8 +18760,10 @@
   }
 
   public abstract class EGLObjectHandle {
-    ctor protected EGLObjectHandle(int);
-    method public int getHandle();
+    ctor protected deprecated EGLObjectHandle(int);
+    ctor protected EGLObjectHandle(long);
+    method public deprecated int getHandle();
+    method public long getNativeHandle();
   }
 
   public class EGLSurface extends android.opengl.EGLObjectHandle {
@@ -16458,11 +19675,9 @@
     method public static void glGenTextures(int, java.nio.IntBuffer);
     method public static void glGenerateMipmap(int);
     method public static void glGetActiveAttrib(int, int, int, int[], int, int[], int, int[], int, byte[], int);
-    method public static void glGetActiveAttrib(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, byte);
     method public static java.lang.String glGetActiveAttrib(int, int, int[], int, int[], int);
     method public static java.lang.String glGetActiveAttrib(int, int, java.nio.IntBuffer, java.nio.IntBuffer);
     method public static void glGetActiveUniform(int, int, int, int[], int, int[], int, int[], int, byte[], int);
-    method public static void glGetActiveUniform(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, byte);
     method public static java.lang.String glGetActiveUniform(int, int, int[], int, int[], int);
     method public static java.lang.String glGetActiveUniform(int, int, java.nio.IntBuffer, java.nio.IntBuffer);
     method public static void glGetAttachedShaders(int, int, int[], int, int[], int);
@@ -16488,7 +19703,6 @@
     method public static void glGetShaderPrecisionFormat(int, int, int[], int, int[], int);
     method public static void glGetShaderPrecisionFormat(int, int, java.nio.IntBuffer, java.nio.IntBuffer);
     method public static void glGetShaderSource(int, int, int[], int, byte[], int);
-    method public static void glGetShaderSource(int, int, java.nio.IntBuffer, byte);
     method public static java.lang.String glGetShaderSource(int);
     method public static void glGetShaderiv(int, int, int[], int);
     method public static void glGetShaderiv(int, int, java.nio.IntBuffer);
@@ -17361,6 +20575,532 @@
     field public static final int GL_WAIT_FAILED = 37149; // 0x911d
   }
 
+  public class GLES31 extends android.opengl.GLES30 {
+    method public static void glActiveShaderProgram(int, int);
+    method public static void glBindImageTexture(int, int, int, boolean, int, int, int);
+    method public static void glBindProgramPipeline(int);
+    method public static void glBindVertexBuffer(int, int, long, int);
+    method public static int glCreateShaderProgramv(int, java.lang.String[]);
+    method public static void glDeleteProgramPipelines(int, int[], int);
+    method public static void glDeleteProgramPipelines(int, java.nio.IntBuffer);
+    method public static void glDispatchCompute(int, int, int);
+    method public static void glDispatchComputeIndirect(long);
+    method public static void glDrawArraysIndirect(int, long);
+    method public static void glDrawElementsIndirect(int, int, long);
+    method public static void glFramebufferParameteri(int, int, int);
+    method public static void glGenProgramPipelines(int, int[], int);
+    method public static void glGenProgramPipelines(int, java.nio.IntBuffer);
+    method public static void glGetBooleani_v(int, int, boolean[], int);
+    method public static void glGetBooleani_v(int, int, java.nio.IntBuffer);
+    method public static void glGetFramebufferParameteriv(int, int, int[], int);
+    method public static void glGetFramebufferParameteriv(int, int, java.nio.IntBuffer);
+    method public static void glGetMultisamplefv(int, int, float[], int);
+    method public static void glGetMultisamplefv(int, int, java.nio.FloatBuffer);
+    method public static void glGetProgramInterfaceiv(int, int, int, int[], int);
+    method public static void glGetProgramInterfaceiv(int, int, int, java.nio.IntBuffer);
+    method public static java.lang.String glGetProgramPipelineInfoLog(int);
+    method public static void glGetProgramPipelineiv(int, int, int[], int);
+    method public static void glGetProgramPipelineiv(int, int, java.nio.IntBuffer);
+    method public static int glGetProgramResourceIndex(int, int, java.lang.String);
+    method public static int glGetProgramResourceLocation(int, int, java.lang.String);
+    method public static java.lang.String glGetProgramResourceName(int, int, int);
+    method public static void glGetProgramResourceiv(int, int, int, int, int[], int, int, int[], int, int[], int);
+    method public static void glGetProgramResourceiv(int, int, int, int, java.nio.IntBuffer, int, java.nio.IntBuffer, java.nio.IntBuffer);
+    method public static void glGetTexLevelParameterfv(int, int, int, float[], int);
+    method public static void glGetTexLevelParameterfv(int, int, int, java.nio.FloatBuffer);
+    method public static void glGetTexLevelParameteriv(int, int, int, int[], int);
+    method public static void glGetTexLevelParameteriv(int, int, int, java.nio.IntBuffer);
+    method public static boolean glIsProgramPipeline(int);
+    method public static void glMemoryBarrier(int);
+    method public static void glMemoryBarrierByRegion(int);
+    method public static void glProgramUniform1f(int, int, float);
+    method public static void glProgramUniform1fv(int, int, int, float[], int);
+    method public static void glProgramUniform1fv(int, int, int, java.nio.FloatBuffer);
+    method public static void glProgramUniform1i(int, int, int);
+    method public static void glProgramUniform1iv(int, int, int, int[], int);
+    method public static void glProgramUniform1iv(int, int, int, java.nio.IntBuffer);
+    method public static void glProgramUniform1ui(int, int, int);
+    method public static void glProgramUniform1uiv(int, int, int, int[], int);
+    method public static void glProgramUniform1uiv(int, int, int, java.nio.IntBuffer);
+    method public static void glProgramUniform2f(int, int, float, float);
+    method public static void glProgramUniform2fv(int, int, int, float[], int);
+    method public static void glProgramUniform2fv(int, int, int, java.nio.FloatBuffer);
+    method public static void glProgramUniform2i(int, int, int, int);
+    method public static void glProgramUniform2iv(int, int, int, int[], int);
+    method public static void glProgramUniform2iv(int, int, int, java.nio.IntBuffer);
+    method public static void glProgramUniform2ui(int, int, int, int);
+    method public static void glProgramUniform2uiv(int, int, int, int[], int);
+    method public static void glProgramUniform2uiv(int, int, int, java.nio.IntBuffer);
+    method public static void glProgramUniform3f(int, int, float, float, float);
+    method public static void glProgramUniform3fv(int, int, int, float[], int);
+    method public static void glProgramUniform3fv(int, int, int, java.nio.FloatBuffer);
+    method public static void glProgramUniform3i(int, int, int, int, int);
+    method public static void glProgramUniform3iv(int, int, int, int[], int);
+    method public static void glProgramUniform3iv(int, int, int, java.nio.IntBuffer);
+    method public static void glProgramUniform3ui(int, int, int, int, int);
+    method public static void glProgramUniform3uiv(int, int, int, int[], int);
+    method public static void glProgramUniform3uiv(int, int, int, java.nio.IntBuffer);
+    method public static void glProgramUniform4f(int, int, float, float, float, float);
+    method public static void glProgramUniform4fv(int, int, int, float[], int);
+    method public static void glProgramUniform4fv(int, int, int, java.nio.FloatBuffer);
+    method public static void glProgramUniform4i(int, int, int, int, int, int);
+    method public static void glProgramUniform4iv(int, int, int, int[], int);
+    method public static void glProgramUniform4iv(int, int, int, java.nio.IntBuffer);
+    method public static void glProgramUniform4ui(int, int, int, int, int, int);
+    method public static void glProgramUniform4uiv(int, int, int, int[], int);
+    method public static void glProgramUniform4uiv(int, int, int, java.nio.IntBuffer);
+    method public static void glProgramUniformMatrix2fv(int, int, int, boolean, float[], int);
+    method public static void glProgramUniformMatrix2fv(int, int, int, boolean, java.nio.FloatBuffer);
+    method public static void glProgramUniformMatrix2x3fv(int, int, int, boolean, float[], int);
+    method public static void glProgramUniformMatrix2x3fv(int, int, int, boolean, java.nio.FloatBuffer);
+    method public static void glProgramUniformMatrix2x4fv(int, int, int, boolean, float[], int);
+    method public static void glProgramUniformMatrix2x4fv(int, int, int, boolean, java.nio.FloatBuffer);
+    method public static void glProgramUniformMatrix3fv(int, int, int, boolean, float[], int);
+    method public static void glProgramUniformMatrix3fv(int, int, int, boolean, java.nio.FloatBuffer);
+    method public static void glProgramUniformMatrix3x2fv(int, int, int, boolean, float[], int);
+    method public static void glProgramUniformMatrix3x2fv(int, int, int, boolean, java.nio.FloatBuffer);
+    method public static void glProgramUniformMatrix3x4fv(int, int, int, boolean, float[], int);
+    method public static void glProgramUniformMatrix3x4fv(int, int, int, boolean, java.nio.FloatBuffer);
+    method public static void glProgramUniformMatrix4fv(int, int, int, boolean, float[], int);
+    method public static void glProgramUniformMatrix4fv(int, int, int, boolean, java.nio.FloatBuffer);
+    method public static void glProgramUniformMatrix4x2fv(int, int, int, boolean, float[], int);
+    method public static void glProgramUniformMatrix4x2fv(int, int, int, boolean, java.nio.FloatBuffer);
+    method public static void glProgramUniformMatrix4x3fv(int, int, int, boolean, float[], int);
+    method public static void glProgramUniformMatrix4x3fv(int, int, int, boolean, java.nio.FloatBuffer);
+    method public static void glSampleMaski(int, int);
+    method public static void glTexStorage2DMultisample(int, int, int, int, int, boolean);
+    method public static void glUseProgramStages(int, int, int);
+    method public static void glValidateProgramPipeline(int);
+    method public static void glVertexAttribBinding(int, int);
+    method public static void glVertexAttribFormat(int, int, int, boolean, int);
+    method public static void glVertexAttribIFormat(int, int, int, int);
+    method public static void glVertexBindingDivisor(int, int);
+    field public static final int GL_ACTIVE_ATOMIC_COUNTER_BUFFERS = 37593; // 0x92d9
+    field public static final int GL_ACTIVE_PROGRAM = 33369; // 0x8259
+    field public static final int GL_ACTIVE_RESOURCES = 37621; // 0x92f5
+    field public static final int GL_ACTIVE_VARIABLES = 37637; // 0x9305
+    field public static final int GL_ALL_SHADER_BITS = -1; // 0xffffffff
+    field public static final int GL_ARRAY_SIZE = 37627; // 0x92fb
+    field public static final int GL_ARRAY_STRIDE = 37630; // 0x92fe
+    field public static final int GL_ATOMIC_COUNTER_BARRIER_BIT = 4096; // 0x1000
+    field public static final int GL_ATOMIC_COUNTER_BUFFER = 37568; // 0x92c0
+    field public static final int GL_ATOMIC_COUNTER_BUFFER_BINDING = 37569; // 0x92c1
+    field public static final int GL_ATOMIC_COUNTER_BUFFER_INDEX = 37633; // 0x9301
+    field public static final int GL_ATOMIC_COUNTER_BUFFER_SIZE = 37571; // 0x92c3
+    field public static final int GL_ATOMIC_COUNTER_BUFFER_START = 37570; // 0x92c2
+    field public static final int GL_BLOCK_INDEX = 37629; // 0x92fd
+    field public static final int GL_BUFFER_BINDING = 37634; // 0x9302
+    field public static final int GL_BUFFER_DATA_SIZE = 37635; // 0x9303
+    field public static final int GL_BUFFER_UPDATE_BARRIER_BIT = 512; // 0x200
+    field public static final int GL_BUFFER_VARIABLE = 37605; // 0x92e5
+    field public static final int GL_COMMAND_BARRIER_BIT = 64; // 0x40
+    field public static final int GL_COMPUTE_SHADER = 37305; // 0x91b9
+    field public static final int GL_COMPUTE_SHADER_BIT = 32; // 0x20
+    field public static final int GL_COMPUTE_WORK_GROUP_SIZE = 33383; // 0x8267
+    field public static final int GL_DEPTH_STENCIL_TEXTURE_MODE = 37098; // 0x90ea
+    field public static final int GL_DISPATCH_INDIRECT_BUFFER = 37102; // 0x90ee
+    field public static final int GL_DISPATCH_INDIRECT_BUFFER_BINDING = 37103; // 0x90ef
+    field public static final int GL_DRAW_INDIRECT_BUFFER = 36671; // 0x8f3f
+    field public static final int GL_DRAW_INDIRECT_BUFFER_BINDING = 36675; // 0x8f43
+    field public static final int GL_FRAGMENT_SHADER_BIT = 2; // 0x2
+    field public static final int GL_FRAMEBUFFER_BARRIER_BIT = 1024; // 0x400
+    field public static final int GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS = 37652; // 0x9314
+    field public static final int GL_FRAMEBUFFER_DEFAULT_HEIGHT = 37649; // 0x9311
+    field public static final int GL_FRAMEBUFFER_DEFAULT_SAMPLES = 37651; // 0x9313
+    field public static final int GL_FRAMEBUFFER_DEFAULT_WIDTH = 37648; // 0x9310
+    field public static final int GL_IMAGE_2D = 36941; // 0x904d
+    field public static final int GL_IMAGE_2D_ARRAY = 36947; // 0x9053
+    field public static final int GL_IMAGE_3D = 36942; // 0x904e
+    field public static final int GL_IMAGE_BINDING_ACCESS = 36670; // 0x8f3e
+    field public static final int GL_IMAGE_BINDING_FORMAT = 36974; // 0x906e
+    field public static final int GL_IMAGE_BINDING_LAYER = 36669; // 0x8f3d
+    field public static final int GL_IMAGE_BINDING_LAYERED = 36668; // 0x8f3c
+    field public static final int GL_IMAGE_BINDING_LEVEL = 36667; // 0x8f3b
+    field public static final int GL_IMAGE_BINDING_NAME = 36666; // 0x8f3a
+    field public static final int GL_IMAGE_CUBE = 36944; // 0x9050
+    field public static final int GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS = 37065; // 0x90c9
+    field public static final int GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE = 37064; // 0x90c8
+    field public static final int GL_IMAGE_FORMAT_COMPATIBILITY_TYPE = 37063; // 0x90c7
+    field public static final int GL_INT_IMAGE_2D = 36952; // 0x9058
+    field public static final int GL_INT_IMAGE_2D_ARRAY = 36958; // 0x905e
+    field public static final int GL_INT_IMAGE_3D = 36953; // 0x9059
+    field public static final int GL_INT_IMAGE_CUBE = 36955; // 0x905b
+    field public static final int GL_INT_SAMPLER_2D_MULTISAMPLE = 37129; // 0x9109
+    field public static final int GL_IS_ROW_MAJOR = 37632; // 0x9300
+    field public static final int GL_LOCATION = 37646; // 0x930e
+    field public static final int GL_MATRIX_STRIDE = 37631; // 0x92ff
+    field public static final int GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS = 37596; // 0x92dc
+    field public static final int GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE = 37592; // 0x92d8
+    field public static final int GL_MAX_COLOR_TEXTURE_SAMPLES = 37134; // 0x910e
+    field public static final int GL_MAX_COMBINED_ATOMIC_COUNTERS = 37591; // 0x92d7
+    field public static final int GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS = 37585; // 0x92d1
+    field public static final int GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS = 33382; // 0x8266
+    field public static final int GL_MAX_COMBINED_IMAGE_UNIFORMS = 37071; // 0x90cf
+    field public static final int GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES = 36665; // 0x8f39
+    field public static final int GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS = 37084; // 0x90dc
+    field public static final int GL_MAX_COMPUTE_ATOMIC_COUNTERS = 33381; // 0x8265
+    field public static final int GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS = 33380; // 0x8264
+    field public static final int GL_MAX_COMPUTE_IMAGE_UNIFORMS = 37309; // 0x91bd
+    field public static final int GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS = 37083; // 0x90db
+    field public static final int GL_MAX_COMPUTE_SHARED_MEMORY_SIZE = 33378; // 0x8262
+    field public static final int GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS = 37308; // 0x91bc
+    field public static final int GL_MAX_COMPUTE_UNIFORM_BLOCKS = 37307; // 0x91bb
+    field public static final int GL_MAX_COMPUTE_UNIFORM_COMPONENTS = 33379; // 0x8263
+    field public static final int GL_MAX_COMPUTE_WORK_GROUP_COUNT = 37310; // 0x91be
+    field public static final int GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS = 37099; // 0x90eb
+    field public static final int GL_MAX_COMPUTE_WORK_GROUP_SIZE = 37311; // 0x91bf
+    field public static final int GL_MAX_DEPTH_TEXTURE_SAMPLES = 37135; // 0x910f
+    field public static final int GL_MAX_FRAGMENT_ATOMIC_COUNTERS = 37590; // 0x92d6
+    field public static final int GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS = 37584; // 0x92d0
+    field public static final int GL_MAX_FRAGMENT_IMAGE_UNIFORMS = 37070; // 0x90ce
+    field public static final int GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS = 37082; // 0x90da
+    field public static final int GL_MAX_FRAMEBUFFER_HEIGHT = 37654; // 0x9316
+    field public static final int GL_MAX_FRAMEBUFFER_SAMPLES = 37656; // 0x9318
+    field public static final int GL_MAX_FRAMEBUFFER_WIDTH = 37653; // 0x9315
+    field public static final int GL_MAX_IMAGE_UNITS = 36664; // 0x8f38
+    field public static final int GL_MAX_INTEGER_SAMPLES = 37136; // 0x9110
+    field public static final int GL_MAX_NAME_LENGTH = 37622; // 0x92f6
+    field public static final int GL_MAX_NUM_ACTIVE_VARIABLES = 37623; // 0x92f7
+    field public static final int GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET = 36447; // 0x8e5f
+    field public static final int GL_MAX_SAMPLE_MASK_WORDS = 36441; // 0x8e59
+    field public static final int GL_MAX_SHADER_STORAGE_BLOCK_SIZE = 37086; // 0x90de
+    field public static final int GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS = 37085; // 0x90dd
+    field public static final int GL_MAX_UNIFORM_LOCATIONS = 33390; // 0x826e
+    field public static final int GL_MAX_VERTEX_ATOMIC_COUNTERS = 37586; // 0x92d2
+    field public static final int GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS = 37580; // 0x92cc
+    field public static final int GL_MAX_VERTEX_ATTRIB_BINDINGS = 33498; // 0x82da
+    field public static final int GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET = 33497; // 0x82d9
+    field public static final int GL_MAX_VERTEX_ATTRIB_STRIDE = 33509; // 0x82e5
+    field public static final int GL_MAX_VERTEX_IMAGE_UNIFORMS = 37066; // 0x90ca
+    field public static final int GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS = 37078; // 0x90d6
+    field public static final int GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET = 36446; // 0x8e5e
+    field public static final int GL_NAME_LENGTH = 37625; // 0x92f9
+    field public static final int GL_NUM_ACTIVE_VARIABLES = 37636; // 0x9304
+    field public static final int GL_OFFSET = 37628; // 0x92fc
+    field public static final int GL_PIXEL_BUFFER_BARRIER_BIT = 128; // 0x80
+    field public static final int GL_PROGRAM_INPUT = 37603; // 0x92e3
+    field public static final int GL_PROGRAM_OUTPUT = 37604; // 0x92e4
+    field public static final int GL_PROGRAM_PIPELINE_BINDING = 33370; // 0x825a
+    field public static final int GL_PROGRAM_SEPARABLE = 33368; // 0x8258
+    field public static final int GL_READ_ONLY = 35000; // 0x88b8
+    field public static final int GL_READ_WRITE = 35002; // 0x88ba
+    field public static final int GL_REFERENCED_BY_COMPUTE_SHADER = 37643; // 0x930b
+    field public static final int GL_REFERENCED_BY_FRAGMENT_SHADER = 37642; // 0x930a
+    field public static final int GL_REFERENCED_BY_VERTEX_SHADER = 37638; // 0x9306
+    field public static final int GL_SAMPLER_2D_MULTISAMPLE = 37128; // 0x9108
+    field public static final int GL_SAMPLE_MASK = 36433; // 0x8e51
+    field public static final int GL_SAMPLE_MASK_VALUE = 36434; // 0x8e52
+    field public static final int GL_SAMPLE_POSITION = 36432; // 0x8e50
+    field public static final int GL_SHADER_STORAGE_BARRIER_BIT = 8192; // 0x2000
+    field public static final int GL_SHADER_STORAGE_BLOCK = 37606; // 0x92e6
+    field public static final int GL_SHADER_STORAGE_BUFFER = 37074; // 0x90d2
+    field public static final int GL_SHADER_STORAGE_BUFFER_BINDING = 37075; // 0x90d3
+    field public static final int GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT = 37087; // 0x90df
+    field public static final int GL_SHADER_STORAGE_BUFFER_SIZE = 37077; // 0x90d5
+    field public static final int GL_SHADER_STORAGE_BUFFER_START = 37076; // 0x90d4
+    field public static final int GL_STENCIL_INDEX = 6401; // 0x1901
+    field public static final int GL_TEXTURE_2D_MULTISAMPLE = 37120; // 0x9100
+    field public static final int GL_TEXTURE_ALPHA_SIZE = 32863; // 0x805f
+    field public static final int GL_TEXTURE_ALPHA_TYPE = 35859; // 0x8c13
+    field public static final int GL_TEXTURE_BINDING_2D_MULTISAMPLE = 37124; // 0x9104
+    field public static final int GL_TEXTURE_BLUE_SIZE = 32862; // 0x805e
+    field public static final int GL_TEXTURE_BLUE_TYPE = 35858; // 0x8c12
+    field public static final int GL_TEXTURE_COMPRESSED = 34465; // 0x86a1
+    field public static final int GL_TEXTURE_DEPTH = 32881; // 0x8071
+    field public static final int GL_TEXTURE_DEPTH_SIZE = 34890; // 0x884a
+    field public static final int GL_TEXTURE_DEPTH_TYPE = 35862; // 0x8c16
+    field public static final int GL_TEXTURE_FETCH_BARRIER_BIT = 8; // 0x8
+    field public static final int GL_TEXTURE_FIXED_SAMPLE_LOCATIONS = 37127; // 0x9107
+    field public static final int GL_TEXTURE_GREEN_SIZE = 32861; // 0x805d
+    field public static final int GL_TEXTURE_GREEN_TYPE = 35857; // 0x8c11
+    field public static final int GL_TEXTURE_HEIGHT = 4097; // 0x1001
+    field public static final int GL_TEXTURE_INTERNAL_FORMAT = 4099; // 0x1003
+    field public static final int GL_TEXTURE_RED_SIZE = 32860; // 0x805c
+    field public static final int GL_TEXTURE_RED_TYPE = 35856; // 0x8c10
+    field public static final int GL_TEXTURE_SAMPLES = 37126; // 0x9106
+    field public static final int GL_TEXTURE_SHARED_SIZE = 35903; // 0x8c3f
+    field public static final int GL_TEXTURE_STENCIL_SIZE = 35057; // 0x88f1
+    field public static final int GL_TEXTURE_UPDATE_BARRIER_BIT = 256; // 0x100
+    field public static final int GL_TEXTURE_WIDTH = 4096; // 0x1000
+    field public static final int GL_TOP_LEVEL_ARRAY_SIZE = 37644; // 0x930c
+    field public static final int GL_TOP_LEVEL_ARRAY_STRIDE = 37645; // 0x930d
+    field public static final int GL_TRANSFORM_FEEDBACK_BARRIER_BIT = 2048; // 0x800
+    field public static final int GL_TRANSFORM_FEEDBACK_VARYING = 37620; // 0x92f4
+    field public static final int GL_TYPE = 37626; // 0x92fa
+    field public static final int GL_UNIFORM = 37601; // 0x92e1
+    field public static final int GL_UNIFORM_BARRIER_BIT = 4; // 0x4
+    field public static final int GL_UNIFORM_BLOCK = 37602; // 0x92e2
+    field public static final int GL_UNSIGNED_INT_ATOMIC_COUNTER = 37595; // 0x92db
+    field public static final int GL_UNSIGNED_INT_IMAGE_2D = 36963; // 0x9063
+    field public static final int GL_UNSIGNED_INT_IMAGE_2D_ARRAY = 36969; // 0x9069
+    field public static final int GL_UNSIGNED_INT_IMAGE_3D = 36964; // 0x9064
+    field public static final int GL_UNSIGNED_INT_IMAGE_CUBE = 36966; // 0x9066
+    field public static final int GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = 37130; // 0x910a
+    field public static final int GL_VERTEX_ATTRIB_BINDING = 33492; // 0x82d4
+    field public static final int GL_VERTEX_ATTRIB_RELATIVE_OFFSET = 33493; // 0x82d5
+    field public static final int GL_VERTEX_BINDING_BUFFER = 36687; // 0x8f4f
+    field public static final int GL_VERTEX_BINDING_DIVISOR = 33494; // 0x82d6
+    field public static final int GL_VERTEX_BINDING_OFFSET = 33495; // 0x82d7
+    field public static final int GL_VERTEX_BINDING_STRIDE = 33496; // 0x82d8
+    field public static final int GL_VERTEX_SHADER_BIT = 1; // 0x1
+    field public static final int GL_WRITE_ONLY = 35001; // 0x88b9
+  }
+
+  public class GLES31Ext {
+    method public static void glBlendBarrierKHR();
+    method public static void glBlendEquationSeparateiEXT(int, int, int);
+    method public static void glBlendEquationiEXT(int, int);
+    method public static void glBlendFuncSeparateiEXT(int, int, int, int, int);
+    method public static void glBlendFunciEXT(int, int, int);
+    method public static void glColorMaskiEXT(int, boolean, boolean, boolean, boolean);
+    method public static void glCopyImageSubDataEXT(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int);
+    method public static void glDebugMessageCallbackKHR(android.opengl.GLES31Ext.DebugProcKHR);
+    method public static void glDebugMessageControlKHR(int, int, int, int, int[], int, boolean);
+    method public static void glDebugMessageControlKHR(int, int, int, int, java.nio.IntBuffer, boolean);
+    method public static void glDebugMessageInsertKHR(int, int, int, int, java.lang.String);
+    method public static void glDisableiEXT(int, int);
+    method public static void glEnableiEXT(int, int);
+    method public static void glFramebufferTextureEXT(int, int, int, int);
+    method public static android.opengl.GLES31Ext.DebugProcKHR glGetDebugMessageCallbackKHR();
+    method public static int glGetDebugMessageLogKHR(int, int, int[], int, int[], int, int[], int, int[], int, int[], int, byte[], int);
+    method public static int glGetDebugMessageLogKHR(int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.ByteBuffer);
+    method public static java.lang.String[] glGetDebugMessageLogKHR(int, int[], int, int[], int, int[], int, int[], int);
+    method public static java.lang.String[] glGetDebugMessageLogKHR(int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer);
+    method public static java.lang.String glGetObjectLabelKHR(int, int);
+    method public static java.lang.String glGetObjectPtrLabelKHR(long);
+    method public static void glGetSamplerParameterIivEXT(int, int, int[], int);
+    method public static void glGetSamplerParameterIivEXT(int, int, java.nio.IntBuffer);
+    method public static void glGetSamplerParameterIuivEXT(int, int, int[], int);
+    method public static void glGetSamplerParameterIuivEXT(int, int, java.nio.IntBuffer);
+    method public static void glGetTexParameterIivEXT(int, int, int[], int);
+    method public static void glGetTexParameterIivEXT(int, int, java.nio.IntBuffer);
+    method public static void glGetTexParameterIuivEXT(int, int, int[], int);
+    method public static void glGetTexParameterIuivEXT(int, int, java.nio.IntBuffer);
+    method public static boolean glIsEnablediEXT(int, int);
+    method public static void glMinSampleShadingOES(float);
+    method public static void glObjectLabelKHR(int, int, int, java.lang.String);
+    method public static void glObjectPtrLabelKHR(long, java.lang.String);
+    method public static void glPatchParameteriEXT(int, int);
+    method public static void glPopDebugGroupKHR();
+    method public static void glPrimitiveBoundingBoxEXT(float, float, float, float, float, float, float, float);
+    method public static void glPushDebugGroupKHR(int, int, int, java.lang.String);
+    method public static void glSamplerParameterIivEXT(int, int, int[], int);
+    method public static void glSamplerParameterIivEXT(int, int, java.nio.IntBuffer);
+    method public static void glSamplerParameterIuivEXT(int, int, int[], int);
+    method public static void glSamplerParameterIuivEXT(int, int, java.nio.IntBuffer);
+    method public static void glTexBufferEXT(int, int, int);
+    method public static void glTexBufferRangeEXT(int, int, int, int, int);
+    method public static void glTexParameterIivEXT(int, int, int[], int);
+    method public static void glTexParameterIivEXT(int, int, java.nio.IntBuffer);
+    method public static void glTexParameterIuivEXT(int, int, int[], int);
+    method public static void glTexParameterIuivEXT(int, int, java.nio.IntBuffer);
+    method public static void glTexStorage3DMultisampleOES(int, int, int, int, int, int, boolean);
+    field public static final int GL_BLEND_ADVANCED_COHERENT_KHR = 37509; // 0x9285
+    field public static final int GL_BUFFER_KHR = 33504; // 0x82e0
+    field public static final int GL_CLAMP_TO_BORDER_EXT = 33069; // 0x812d
+    field public static final int GL_COLORBURN_KHR = 37530; // 0x929a
+    field public static final int GL_COLORDODGE_KHR = 37529; // 0x9299
+    field public static final int GL_COMPRESSED_RGBA_ASTC_10x10_KHR = 37819; // 0x93bb
+    field public static final int GL_COMPRESSED_RGBA_ASTC_10x5_KHR = 37816; // 0x93b8
+    field public static final int GL_COMPRESSED_RGBA_ASTC_10x6_KHR = 37817; // 0x93b9
+    field public static final int GL_COMPRESSED_RGBA_ASTC_10x8_KHR = 37818; // 0x93ba
+    field public static final int GL_COMPRESSED_RGBA_ASTC_12x10_KHR = 37820; // 0x93bc
+    field public static final int GL_COMPRESSED_RGBA_ASTC_12x12_KHR = 37821; // 0x93bd
+    field public static final int GL_COMPRESSED_RGBA_ASTC_4x4_KHR = 37808; // 0x93b0
+    field public static final int GL_COMPRESSED_RGBA_ASTC_5x4_KHR = 37809; // 0x93b1
+    field public static final int GL_COMPRESSED_RGBA_ASTC_5x5_KHR = 37810; // 0x93b2
+    field public static final int GL_COMPRESSED_RGBA_ASTC_6x5_KHR = 37811; // 0x93b3
+    field public static final int GL_COMPRESSED_RGBA_ASTC_6x6_KHR = 37812; // 0x93b4
+    field public static final int GL_COMPRESSED_RGBA_ASTC_8x5_KHR = 37813; // 0x93b5
+    field public static final int GL_COMPRESSED_RGBA_ASTC_8x6_KHR = 37814; // 0x93b6
+    field public static final int GL_COMPRESSED_RGBA_ASTC_8x8_KHR = 37815; // 0x93b7
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 37851; // 0x93db
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 37848; // 0x93d8
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 37849; // 0x93d9
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 37850; // 0x93da
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 37852; // 0x93dc
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 37853; // 0x93dd
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 37840; // 0x93d0
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 37841; // 0x93d1
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 37842; // 0x93d2
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 37843; // 0x93d3
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 37844; // 0x93d4
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 37845; // 0x93d5
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 37846; // 0x93d6
+    field public static final int GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 37847; // 0x93d7
+    field public static final int GL_CONTEXT_FLAG_DEBUG_BIT_KHR = 2; // 0x2
+    field public static final int GL_DARKEN_KHR = 37527; // 0x9297
+    field public static final int GL_DEBUG_CALLBACK_FUNCTION_KHR = 33348; // 0x8244
+    field public static final int GL_DEBUG_CALLBACK_USER_PARAM_KHR = 33349; // 0x8245
+    field public static final int GL_DEBUG_GROUP_STACK_DEPTH_KHR = 33389; // 0x826d
+    field public static final int GL_DEBUG_LOGGED_MESSAGES_KHR = 37189; // 0x9145
+    field public static final int GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR = 33347; // 0x8243
+    field public static final int GL_DEBUG_OUTPUT_KHR = 37600; // 0x92e0
+    field public static final int GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR = 33346; // 0x8242
+    field public static final int GL_DEBUG_SEVERITY_HIGH_KHR = 37190; // 0x9146
+    field public static final int GL_DEBUG_SEVERITY_LOW_KHR = 37192; // 0x9148
+    field public static final int GL_DEBUG_SEVERITY_MEDIUM_KHR = 37191; // 0x9147
+    field public static final int GL_DEBUG_SEVERITY_NOTIFICATION_KHR = 33387; // 0x826b
+    field public static final int GL_DEBUG_SOURCE_API_KHR = 33350; // 0x8246
+    field public static final int GL_DEBUG_SOURCE_APPLICATION_KHR = 33354; // 0x824a
+    field public static final int GL_DEBUG_SOURCE_OTHER_KHR = 33355; // 0x824b
+    field public static final int GL_DEBUG_SOURCE_SHADER_COMPILER_KHR = 33352; // 0x8248
+    field public static final int GL_DEBUG_SOURCE_THIRD_PARTY_KHR = 33353; // 0x8249
+    field public static final int GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR = 33351; // 0x8247
+    field public static final int GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR = 33357; // 0x824d
+    field public static final int GL_DEBUG_TYPE_ERROR_KHR = 33356; // 0x824c
+    field public static final int GL_DEBUG_TYPE_MARKER_KHR = 33384; // 0x8268
+    field public static final int GL_DEBUG_TYPE_OTHER_KHR = 33361; // 0x8251
+    field public static final int GL_DEBUG_TYPE_PERFORMANCE_KHR = 33360; // 0x8250
+    field public static final int GL_DEBUG_TYPE_POP_GROUP_KHR = 33386; // 0x826a
+    field public static final int GL_DEBUG_TYPE_PORTABILITY_KHR = 33359; // 0x824f
+    field public static final int GL_DEBUG_TYPE_PUSH_GROUP_KHR = 33385; // 0x8269
+    field public static final int GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR = 33358; // 0x824e
+    field public static final int GL_DECODE_EXT = 35401; // 0x8a49
+    field public static final int GL_DIFFERENCE_KHR = 37534; // 0x929e
+    field public static final int GL_EXCLUSION_KHR = 37536; // 0x92a0
+    field public static final int GL_FIRST_VERTEX_CONVENTION_EXT = 36429; // 0x8e4d
+    field public static final int GL_FRACTIONAL_EVEN_EXT = 36476; // 0x8e7c
+    field public static final int GL_FRACTIONAL_ODD_EXT = 36475; // 0x8e7b
+    field public static final int GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES = 36445; // 0x8e5d
+    field public static final int GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT = 36263; // 0x8da7
+    field public static final int GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT = 37650; // 0x9312
+    field public static final int GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT = 36264; // 0x8da8
+    field public static final int GL_GEOMETRY_LINKED_INPUT_TYPE_EXT = 35095; // 0x8917
+    field public static final int GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT = 35096; // 0x8918
+    field public static final int GL_GEOMETRY_LINKED_VERTICES_OUT_EXT = 35094; // 0x8916
+    field public static final int GL_GEOMETRY_SHADER_BIT_EXT = 4; // 0x4
+    field public static final int GL_GEOMETRY_SHADER_EXT = 36313; // 0x8dd9
+    field public static final int GL_GEOMETRY_SHADER_INVOCATIONS_EXT = 34943; // 0x887f
+    field public static final int GL_HARDLIGHT_KHR = 37531; // 0x929b
+    field public static final int GL_HSL_COLOR_KHR = 37551; // 0x92af
+    field public static final int GL_HSL_HUE_KHR = 37549; // 0x92ad
+    field public static final int GL_HSL_LUMINOSITY_KHR = 37552; // 0x92b0
+    field public static final int GL_HSL_SATURATION_KHR = 37550; // 0x92ae
+    field public static final int GL_IMAGE_BUFFER_EXT = 36945; // 0x9051
+    field public static final int GL_IMAGE_CUBE_MAP_ARRAY_EXT = 36948; // 0x9054
+    field public static final int GL_INT_IMAGE_BUFFER_EXT = 36956; // 0x905c
+    field public static final int GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT = 36959; // 0x905f
+    field public static final int GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES = 37132; // 0x910c
+    field public static final int GL_INT_SAMPLER_BUFFER_EXT = 36304; // 0x8dd0
+    field public static final int GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT = 36878; // 0x900e
+    field public static final int GL_ISOLINES_EXT = 36474; // 0x8e7a
+    field public static final int GL_IS_PER_PATCH_EXT = 37607; // 0x92e7
+    field public static final int GL_LAST_VERTEX_CONVENTION_EXT = 36430; // 0x8e4e
+    field public static final int GL_LAYER_PROVOKING_VERTEX_EXT = 33374; // 0x825e
+    field public static final int GL_LIGHTEN_KHR = 37528; // 0x9298
+    field public static final int GL_LINES_ADJACENCY_EXT = 10; // 0xa
+    field public static final int GL_LINE_STRIP_ADJACENCY_EXT = 11; // 0xb
+    field public static final int GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT = 35378; // 0x8a32
+    field public static final int GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT = 36382; // 0x8e1e
+    field public static final int GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT = 36383; // 0x8e1f
+    field public static final int GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR = 33388; // 0x826c
+    field public static final int GL_MAX_DEBUG_LOGGED_MESSAGES_KHR = 37188; // 0x9144
+    field public static final int GL_MAX_DEBUG_MESSAGE_LENGTH_KHR = 37187; // 0x9143
+    field public static final int GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES = 36444; // 0x8e5c
+    field public static final int GL_MAX_FRAMEBUFFER_LAYERS_EXT = 37655; // 0x9317
+    field public static final int GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT = 37589; // 0x92d5
+    field public static final int GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT = 37583; // 0x92cf
+    field public static final int GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT = 37069; // 0x90cd
+    field public static final int GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT = 37155; // 0x9123
+    field public static final int GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT = 37156; // 0x9124
+    field public static final int GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT = 36320; // 0x8de0
+    field public static final int GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT = 36442; // 0x8e5a
+    field public static final int GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT = 37079; // 0x90d7
+    field public static final int GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT = 35881; // 0x8c29
+    field public static final int GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT = 36321; // 0x8de1
+    field public static final int GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT = 35372; // 0x8a2c
+    field public static final int GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT = 36319; // 0x8ddf
+    field public static final int GL_MAX_LABEL_LENGTH_KHR = 33512; // 0x82e8
+    field public static final int GL_MAX_PATCH_VERTICES_EXT = 36477; // 0x8e7d
+    field public static final int GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT = 37587; // 0x92d3
+    field public static final int GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT = 37581; // 0x92cd
+    field public static final int GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT = 37067; // 0x90cb
+    field public static final int GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT = 34924; // 0x886c
+    field public static final int GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT = 36483; // 0x8e83
+    field public static final int GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT = 37080; // 0x90d8
+    field public static final int GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT = 36481; // 0x8e81
+    field public static final int GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT = 36485; // 0x8e85
+    field public static final int GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT = 36489; // 0x8e89
+    field public static final int GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT = 36479; // 0x8e7f
+    field public static final int GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT = 37588; // 0x92d4
+    field public static final int GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT = 37582; // 0x92ce
+    field public static final int GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT = 37068; // 0x90cc
+    field public static final int GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT = 34925; // 0x886d
+    field public static final int GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT = 36486; // 0x8e86
+    field public static final int GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT = 37081; // 0x90d9
+    field public static final int GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT = 36482; // 0x8e82
+    field public static final int GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT = 36490; // 0x8e8a
+    field public static final int GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT = 36480; // 0x8e80
+    field public static final int GL_MAX_TESS_GEN_LEVEL_EXT = 36478; // 0x8e7e
+    field public static final int GL_MAX_TESS_PATCH_COMPONENTS_EXT = 36484; // 0x8e84
+    field public static final int GL_MAX_TEXTURE_BUFFER_SIZE_EXT = 35883; // 0x8c2b
+    field public static final int GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES = 36443; // 0x8e5b
+    field public static final int GL_MIN_SAMPLE_SHADING_VALUE_OES = 35895; // 0x8c37
+    field public static final int GL_MULTIPLY_KHR = 37524; // 0x9294
+    field public static final int GL_OVERLAY_KHR = 37526; // 0x9296
+    field public static final int GL_PATCHES_EXT = 14; // 0xe
+    field public static final int GL_PATCH_VERTICES_EXT = 36466; // 0x8e72
+    field public static final int GL_PRIMITIVES_GENERATED_EXT = 35975; // 0x8c87
+    field public static final int GL_PRIMITIVE_BOUNDING_BOX_EXT = 37566; // 0x92be
+    field public static final int GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED = 33313; // 0x8221
+    field public static final int GL_PROGRAM_KHR = 33506; // 0x82e2
+    field public static final int GL_QUADS_EXT = 7; // 0x7
+    field public static final int GL_QUERY_KHR = 33507; // 0x82e3
+    field public static final int GL_REFERENCED_BY_GEOMETRY_SHADER_EXT = 37641; // 0x9309
+    field public static final int GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT = 37639; // 0x9307
+    field public static final int GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT = 37640; // 0x9308
+    field public static final int GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES = 37131; // 0x910b
+    field public static final int GL_SAMPLER_BUFFER_EXT = 36290; // 0x8dc2
+    field public static final int GL_SAMPLER_CUBE_MAP_ARRAY_EXT = 36876; // 0x900c
+    field public static final int GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT = 36877; // 0x900d
+    field public static final int GL_SAMPLER_KHR = 33510; // 0x82e6
+    field public static final int GL_SAMPLE_SHADING_OES = 35894; // 0x8c36
+    field public static final int GL_SCREEN_KHR = 37525; // 0x9295
+    field public static final int GL_SHADER_KHR = 33505; // 0x82e1
+    field public static final int GL_SKIP_DECODE_EXT = 35402; // 0x8a4a
+    field public static final int GL_SOFTLIGHT_KHR = 37532; // 0x929c
+    field public static final int GL_STACK_OVERFLOW_KHR = 1283; // 0x503
+    field public static final int GL_STACK_UNDERFLOW_KHR = 1284; // 0x504
+    field public static final int GL_STENCIL_INDEX8_OES = 36168; // 0x8d48
+    field public static final int GL_STENCIL_INDEX_OES = 6401; // 0x1901
+    field public static final int GL_TESS_CONTROL_OUTPUT_VERTICES_EXT = 36469; // 0x8e75
+    field public static final int GL_TESS_CONTROL_SHADER_BIT_EXT = 8; // 0x8
+    field public static final int GL_TESS_CONTROL_SHADER_EXT = 36488; // 0x8e88
+    field public static final int GL_TESS_EVALUATION_SHADER_BIT_EXT = 16; // 0x10
+    field public static final int GL_TESS_EVALUATION_SHADER_EXT = 36487; // 0x8e87
+    field public static final int GL_TESS_GEN_MODE_EXT = 36470; // 0x8e76
+    field public static final int GL_TESS_GEN_POINT_MODE_EXT = 36473; // 0x8e79
+    field public static final int GL_TESS_GEN_SPACING_EXT = 36471; // 0x8e77
+    field public static final int GL_TESS_GEN_VERTEX_ORDER_EXT = 36472; // 0x8e78
+    field public static final int GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES = 37122; // 0x9102
+    field public static final int GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES = 37125; // 0x9105
+    field public static final int GL_TEXTURE_BINDING_BUFFER_EXT = 35884; // 0x8c2c
+    field public static final int GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT = 36874; // 0x900a
+    field public static final int GL_TEXTURE_BORDER_COLOR_EXT = 4100; // 0x1004
+    field public static final int GL_TEXTURE_BUFFER_BINDING_EXT = 35882; // 0x8c2a
+    field public static final int GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT = 35885; // 0x8c2d
+    field public static final int GL_TEXTURE_BUFFER_EXT = 35882; // 0x8c2a
+    field public static final int GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT = 37279; // 0x919f
+    field public static final int GL_TEXTURE_BUFFER_OFFSET_EXT = 37277; // 0x919d
+    field public static final int GL_TEXTURE_BUFFER_SIZE_EXT = 37278; // 0x919e
+    field public static final int GL_TEXTURE_CUBE_MAP_ARRAY_EXT = 36873; // 0x9009
+    field public static final int GL_TEXTURE_SRGB_DECODE_EXT = 35400; // 0x8a48
+    field public static final int GL_TRIANGLES_ADJACENCY_EXT = 12; // 0xc
+    field public static final int GL_TRIANGLE_STRIP_ADJACENCY_EXT = 13; // 0xd
+    field public static final int GL_UNDEFINED_VERTEX_EXT = 33376; // 0x8260
+    field public static final int GL_UNSIGNED_INT_IMAGE_BUFFER_EXT = 36967; // 0x9067
+    field public static final int GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT = 36970; // 0x906a
+    field public static final int GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES = 37133; // 0x910d
+    field public static final int GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT = 36312; // 0x8dd8
+    field public static final int GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT = 36879; // 0x900f
+    field public static final int GL_VERTEX_ARRAY_KHR = 32884; // 0x8074
+  }
+
+  public static abstract interface GLES31Ext.DebugProcKHR {
+    method public abstract void onMessage(int, int, int, int, java.lang.String);
+  }
+
   public class GLException extends java.lang.RuntimeException {
     ctor public GLException(int);
     ctor public GLException(int, java.lang.String);
@@ -17508,8 +21248,41 @@
     ctor public BadParcelableException(java.lang.Exception);
   }
 
+  public class BaseBundle {
+    method public void clear();
+    method public boolean containsKey(java.lang.String);
+    method public java.lang.Object get(java.lang.String);
+    method public double getDouble(java.lang.String);
+    method public double getDouble(java.lang.String, double);
+    method public double[] getDoubleArray(java.lang.String);
+    method public int getInt(java.lang.String);
+    method public int getInt(java.lang.String, int);
+    method public int[] getIntArray(java.lang.String);
+    method public long getLong(java.lang.String);
+    method public long getLong(java.lang.String, long);
+    method public long[] getLongArray(java.lang.String);
+    method public java.lang.String getString(java.lang.String);
+    method public java.lang.String getString(java.lang.String, java.lang.String);
+    method public java.lang.String[] getStringArray(java.lang.String);
+    method public boolean isEmpty();
+    method public java.util.Set<java.lang.String> keySet();
+    method public void putAll(android.os.PersistableBundle);
+    method public void putDouble(java.lang.String, double);
+    method public void putDoubleArray(java.lang.String, double[]);
+    method public void putInt(java.lang.String, int);
+    method public void putIntArray(java.lang.String, int[]);
+    method public void putLong(java.lang.String, long);
+    method public void putLongArray(java.lang.String, long[]);
+    method public void putString(java.lang.String, java.lang.String);
+    method public void putStringArray(java.lang.String, java.lang.String[]);
+    method public void remove(java.lang.String);
+    method public int size();
+  }
+
   public class BatteryManager {
     ctor public BatteryManager();
+    method public int getIntProperty(int);
+    method public long getLongProperty(int);
     field public static final int BATTERY_HEALTH_COLD = 7; // 0x7
     field public static final int BATTERY_HEALTH_DEAD = 4; // 0x4
     field public static final int BATTERY_HEALTH_GOOD = 2; // 0x2
@@ -17520,6 +21293,11 @@
     field public static final int BATTERY_PLUGGED_AC = 1; // 0x1
     field public static final int BATTERY_PLUGGED_USB = 2; // 0x2
     field public static final int BATTERY_PLUGGED_WIRELESS = 4; // 0x4
+    field public static final int BATTERY_PROPERTY_CAPACITY = 4; // 0x4
+    field public static final int BATTERY_PROPERTY_CHARGE_COUNTER = 1; // 0x1
+    field public static final int BATTERY_PROPERTY_CURRENT_AVERAGE = 3; // 0x3
+    field public static final int BATTERY_PROPERTY_CURRENT_NOW = 2; // 0x2
+    field public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5; // 0x5
     field public static final int BATTERY_STATUS_CHARGING = 2; // 0x2
     field public static final int BATTERY_STATUS_DISCHARGING = 3; // 0x3
     field public static final int BATTERY_STATUS_FULL = 5; // 0x5
@@ -17566,8 +21344,8 @@
     field public static final java.lang.String BOARD;
     field public static final java.lang.String BOOTLOADER;
     field public static final java.lang.String BRAND;
-    field public static final java.lang.String CPU_ABI;
-    field public static final java.lang.String CPU_ABI2;
+    field public static final deprecated java.lang.String CPU_ABI;
+    field public static final deprecated java.lang.String CPU_ABI2;
     field public static final java.lang.String DEVICE;
     field public static final java.lang.String DISPLAY;
     field public static final java.lang.String FINGERPRINT;
@@ -17579,6 +21357,9 @@
     field public static final java.lang.String PRODUCT;
     field public static final deprecated java.lang.String RADIO;
     field public static final java.lang.String SERIAL;
+    field public static final java.lang.String[] SUPPORTED_32_BIT_ABIS;
+    field public static final java.lang.String[] SUPPORTED_64_BIT_ABIS;
+    field public static final java.lang.String[] SUPPORTED_ABIS;
     field public static final java.lang.String TAGS;
     field public static final long TIME;
     field public static final java.lang.String TYPE;
@@ -17618,18 +21399,17 @@
     field public static final int JELLY_BEAN_MR2 = 18; // 0x12
     field public static final int KITKAT = 19; // 0x13
     field public static final int KITKAT_WATCH = 20; // 0x14
+    field public static final int L = 21; // 0x15
   }
 
-  public final class Bundle implements java.lang.Cloneable android.os.Parcelable {
+  public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
     ctor public Bundle();
     ctor public Bundle(java.lang.ClassLoader);
     ctor public Bundle(int);
     ctor public Bundle(android.os.Bundle);
-    method public void clear();
+    ctor public Bundle(android.os.PersistableBundle);
     method public java.lang.Object clone();
-    method public boolean containsKey(java.lang.String);
     method public int describeContents();
-    method public java.lang.Object get(java.lang.String);
     method public android.os.IBinder getBinder(java.lang.String);
     method public boolean getBoolean(java.lang.String);
     method public boolean getBoolean(java.lang.String, boolean);
@@ -17646,19 +21426,10 @@
     method public java.lang.CharSequence[] getCharSequenceArray(java.lang.String);
     method public java.util.ArrayList<java.lang.CharSequence> getCharSequenceArrayList(java.lang.String);
     method public java.lang.ClassLoader getClassLoader();
-    method public double getDouble(java.lang.String);
-    method public double getDouble(java.lang.String, double);
-    method public double[] getDoubleArray(java.lang.String);
     method public float getFloat(java.lang.String);
     method public float getFloat(java.lang.String, float);
     method public float[] getFloatArray(java.lang.String);
-    method public int getInt(java.lang.String);
-    method public int getInt(java.lang.String, int);
-    method public int[] getIntArray(java.lang.String);
     method public java.util.ArrayList<java.lang.Integer> getIntegerArrayList(java.lang.String);
-    method public long getLong(java.lang.String);
-    method public long getLong(java.lang.String, long);
-    method public long[] getLongArray(java.lang.String);
     method public T getParcelable(java.lang.String);
     method public android.os.Parcelable[] getParcelableArray(java.lang.String);
     method public java.util.ArrayList<T> getParcelableArrayList(java.lang.String);
@@ -17666,14 +21437,11 @@
     method public short getShort(java.lang.String);
     method public short getShort(java.lang.String, short);
     method public short[] getShortArray(java.lang.String);
+    method public android.util.Size getSize(java.lang.String);
+    method public android.util.SizeF getSizeF(java.lang.String);
     method public android.util.SparseArray<T> getSparseParcelableArray(java.lang.String);
-    method public java.lang.String getString(java.lang.String);
-    method public java.lang.String getString(java.lang.String, java.lang.String);
-    method public java.lang.String[] getStringArray(java.lang.String);
     method public java.util.ArrayList<java.lang.String> getStringArrayList(java.lang.String);
     method public boolean hasFileDescriptors();
-    method public boolean isEmpty();
-    method public java.util.Set<java.lang.String> keySet();
     method public void putAll(android.os.Bundle);
     method public void putBinder(java.lang.String, android.os.IBinder);
     method public void putBoolean(java.lang.String, boolean);
@@ -17686,29 +21454,21 @@
     method public void putCharSequence(java.lang.String, java.lang.CharSequence);
     method public void putCharSequenceArray(java.lang.String, java.lang.CharSequence[]);
     method public void putCharSequenceArrayList(java.lang.String, java.util.ArrayList<java.lang.CharSequence>);
-    method public void putDouble(java.lang.String, double);
-    method public void putDoubleArray(java.lang.String, double[]);
     method public void putFloat(java.lang.String, float);
     method public void putFloatArray(java.lang.String, float[]);
-    method public void putInt(java.lang.String, int);
-    method public void putIntArray(java.lang.String, int[]);
     method public void putIntegerArrayList(java.lang.String, java.util.ArrayList<java.lang.Integer>);
-    method public void putLong(java.lang.String, long);
-    method public void putLongArray(java.lang.String, long[]);
     method public void putParcelable(java.lang.String, android.os.Parcelable);
     method public void putParcelableArray(java.lang.String, android.os.Parcelable[]);
     method public void putParcelableArrayList(java.lang.String, java.util.ArrayList<? extends android.os.Parcelable>);
     method public void putSerializable(java.lang.String, java.io.Serializable);
     method public void putShort(java.lang.String, short);
     method public void putShortArray(java.lang.String, short[]);
+    method public void putSize(java.lang.String, android.util.Size);
+    method public void putSizeF(java.lang.String, android.util.SizeF);
     method public void putSparseParcelableArray(java.lang.String, android.util.SparseArray<? extends android.os.Parcelable>);
-    method public void putString(java.lang.String, java.lang.String);
-    method public void putStringArray(java.lang.String, java.lang.String[]);
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
     method public void readFromParcel(android.os.Parcel);
-    method public void remove(java.lang.String);
     method public void setClassLoader(java.lang.ClassLoader);
-    method public int size();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final android.os.Bundle EMPTY;
@@ -17737,7 +21497,7 @@
 
   public abstract class CountDownTimer {
     ctor public CountDownTimer(long, long);
-    method public final void cancel();
+    method public final synchronized void cancel();
     method public abstract void onFinish();
     method public abstract void onTick(long);
     method public final synchronized android.os.CountDownTimer start();
@@ -17805,6 +21565,7 @@
     method public static void startMethodTracing(java.lang.String);
     method public static void startMethodTracing(java.lang.String, int);
     method public static void startMethodTracing(java.lang.String, int, int);
+    method public static void startMethodTracingSampling(java.lang.String, int, int);
     method public static void startNativeTracing();
     method public static deprecated void stopAllocCounting();
     method public static void stopMethodTracing();
@@ -17888,10 +21649,13 @@
     method public static java.io.File getExternalStorageDirectory();
     method public static java.io.File getExternalStoragePublicDirectory(java.lang.String);
     method public static java.lang.String getExternalStorageState();
+    method public static java.lang.String getExternalStorageState(java.io.File);
     method public static java.io.File getRootDirectory();
-    method public static java.lang.String getStorageState(java.io.File);
+    method public static deprecated java.lang.String getStorageState(java.io.File);
     method public static boolean isExternalStorageEmulated();
+    method public static boolean isExternalStorageEmulated(java.io.File);
     method public static boolean isExternalStorageRemovable();
+    method public static boolean isExternalStorageRemovable(java.io.File);
     field public static java.lang.String DIRECTORY_ALARMS;
     field public static java.lang.String DIRECTORY_DCIM;
     field public static java.lang.String DIRECTORY_DOCUMENTS;
@@ -18066,6 +21830,7 @@
     field public int arg2;
     field public java.lang.Object obj;
     field public android.os.Messenger replyTo;
+    field public int sendingUid;
     field public int what;
   }
 
@@ -18122,7 +21887,6 @@
     method public final boolean hasFileDescriptors();
     method public final byte[] marshall();
     method public static android.os.Parcel obtain();
-    method protected static final android.os.Parcel obtain(int);
     method public final java.lang.Object[] readArray(java.lang.ClassLoader);
     method public final java.util.ArrayList readArrayList(java.lang.ClassLoader);
     method public final void readBinderArray(android.os.IBinder[]);
@@ -18149,7 +21913,11 @@
     method public final void readMap(java.util.Map, java.lang.ClassLoader);
     method public final T readParcelable(java.lang.ClassLoader);
     method public final android.os.Parcelable[] readParcelableArray(java.lang.ClassLoader);
+    method public final android.os.PersistableBundle readPersistableBundle();
+    method public final android.os.PersistableBundle readPersistableBundle(java.lang.ClassLoader);
     method public final java.io.Serializable readSerializable();
+    method public final android.util.Size readSize();
+    method public final android.util.SizeF readSizeF();
     method public final android.util.SparseArray readSparseArray(java.lang.ClassLoader);
     method public final android.util.SparseBooleanArray readSparseBooleanArray();
     method public final java.lang.String readString();
@@ -18189,7 +21957,10 @@
     method public final void writeNoException();
     method public final void writeParcelable(android.os.Parcelable, int);
     method public final void writeParcelableArray(T[], int);
+    method public final void writePersistableBundle(android.os.PersistableBundle);
     method public final void writeSerializable(java.io.Serializable);
+    method public final void writeSize(android.util.Size);
+    method public final void writeSizeF(android.util.SizeF);
     method public final void writeSparseArray(android.util.SparseArray<java.lang.Object>);
     method public final void writeSparseBooleanArray(android.util.SparseBooleanArray);
     method public final void writeString(java.lang.String);
@@ -18299,18 +22070,33 @@
     field public static final int PATTERN_SIMPLE_GLOB = 2; // 0x2
   }
 
+  public final class PersistableBundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
+    ctor public PersistableBundle();
+    ctor public PersistableBundle(int);
+    ctor public PersistableBundle(android.os.PersistableBundle);
+    method public java.lang.Object clone();
+    method public int describeContents();
+    method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
+    method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final android.os.PersistableBundle EMPTY;
+  }
+
   public final class PowerManager {
-    method public void goToSleep(long);
     method public boolean isInteractive();
+    method public boolean isPowerSaveMode();
     method public deprecated boolean isScreenOn();
+    method public boolean isWakeLockLevelSupported(int);
     method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String);
     method public void reboot(java.lang.String);
-    method public void userActivity(long, boolean);
-    method public void wakeUp(long);
     field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
+    field public static final java.lang.String ACTION_POWER_SAVE_MODE_CHANGED = "android.os.action.POWER_SAVE_MODE_CHANGED";
     field public static final deprecated int FULL_WAKE_LOCK = 26; // 0x1a
     field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
     field public static final int PARTIAL_WAKE_LOCK = 1; // 0x1
+    field public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32; // 0x20
+    field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1
     field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
     field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
   }
@@ -18320,6 +22106,7 @@
     method public void acquire(long);
     method public boolean isHeld();
     method public void release();
+    method public void release(int);
     method public void setReferenceCounted(boolean);
     method public void setWorkSource(android.os.WorkSource);
   }
@@ -18517,32 +22304,53 @@
     method public int getUserCount();
     method public android.os.UserHandle getUserForSerialNumber(long);
     method public java.lang.String getUserName();
+    method public java.util.List<android.os.UserHandle> getUserProfiles();
     method public android.os.Bundle getUserRestrictions();
     method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
+    method public boolean hasUserRestriction(java.lang.String);
     method public boolean isUserAGoat();
     method public boolean isUserRunning(android.os.UserHandle);
     method public boolean isUserRunningOrStopping(android.os.UserHandle);
     method public boolean setRestrictionsChallenge(java.lang.String);
-    method public void setUserRestriction(java.lang.String, boolean);
-    method public void setUserRestrictions(android.os.Bundle);
-    method public void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
+    method public deprecated void setUserRestriction(java.lang.String, boolean);
+    method public deprecated void setUserRestrictions(android.os.Bundle);
+    method public deprecated void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
+    field public static final java.lang.String DISALLOW_ADD_USER = "no_add_user";
+    field public static final java.lang.String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";
+    field public static final java.lang.String DISALLOW_APPS_CONTROL = "no_control_apps";
     field public static final java.lang.String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
+    field public static final java.lang.String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts";
     field public static final java.lang.String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials";
+    field public static final java.lang.String DISALLOW_CONFIG_MOBILE_NETWORKS = "no_config_mobile_networks";
+    field public static final java.lang.String DISALLOW_CONFIG_TETHERING = "no_config_tethering";
+    field public static final java.lang.String DISALLOW_CONFIG_VPN = "no_config_vpn";
     field public static final java.lang.String DISALLOW_CONFIG_WIFI = "no_config_wifi";
+    field public static final java.lang.String DISALLOW_CREATE_WINDOWS = "no_create_windows";
+    field public static final java.lang.String DISALLOW_CROSS_PROFILE_COPY_PASTE = "no_cross_profile_copy_paste";
+    field public static final java.lang.String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";
+    field public static final java.lang.String DISALLOW_FACTORY_RESET = "no_factory_reset";
     field public static final java.lang.String DISALLOW_INSTALL_APPS = "no_install_apps";
     field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
     field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
+    field public static final java.lang.String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
+    field public static final java.lang.String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam";
+    field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
     field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user";
     field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
+    field public static final java.lang.String DISALLOW_SMS = "no_sms";
     field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
+    field public static final java.lang.String DISALLOW_UNMUTE_MICROPHONE = "no_unmute_microphone";
     field public static final java.lang.String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer";
+    field public static final java.lang.String ENSURE_VERIFY_APPS = "ensure_verify_apps";
   }
 
   public abstract class Vibrator {
     method public abstract void cancel();
     method public abstract boolean hasVibrator();
-    method public abstract void vibrate(long);
-    method public abstract void vibrate(long[], int);
+    method public void vibrate(long);
+    method public void vibrate(long, android.media.AudioAttributes);
+    method public void vibrate(long[], int);
+    method public void vibrate(long[], int, android.media.AudioAttributes);
   }
 
   public class WorkSource implements android.os.Parcelable {
@@ -18588,13 +22396,16 @@
 
   public class CheckBoxPreference extends android.preference.TwoStatePreference {
     ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet);
     ctor public CheckBoxPreference(android.content.Context);
   }
 
   public abstract class DialogPreference extends android.preference.Preference implements android.content.DialogInterface.OnClickListener android.content.DialogInterface.OnDismissListener android.preference.PreferenceManager.OnActivityDestroyListener {
+    ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public DialogPreference(android.content.Context, android.util.AttributeSet);
+    ctor public DialogPreference(android.content.Context);
     method public android.app.Dialog getDialog();
     method public android.graphics.drawable.Drawable getDialogIcon();
     method public int getDialogLayoutResource();
@@ -18624,6 +22435,7 @@
   }
 
   public class EditTextPreference extends android.preference.DialogPreference {
+    ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public EditTextPreference(android.content.Context, android.util.AttributeSet);
     ctor public EditTextPreference(android.content.Context);
@@ -18634,6 +22446,8 @@
   }
 
   public class ListPreference extends android.preference.DialogPreference {
+    ctor public ListPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public ListPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public ListPreference(android.content.Context, android.util.AttributeSet);
     ctor public ListPreference(android.content.Context);
     method public int findIndexOfValue(java.lang.String);
@@ -18650,6 +22464,8 @@
   }
 
   public class MultiSelectListPreference extends android.preference.DialogPreference {
+    ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet);
     ctor public MultiSelectListPreference(android.content.Context);
     method public int findIndexOfValue(java.lang.String);
@@ -18664,6 +22480,7 @@
   }
 
   public class Preference implements java.lang.Comparable {
+    ctor public Preference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public Preference(android.content.Context, android.util.AttributeSet, int);
     ctor public Preference(android.content.Context, android.util.AttributeSet);
     ctor public Preference(android.content.Context);
@@ -18829,6 +22646,7 @@
   }
 
   public class PreferenceCategory extends android.preference.PreferenceGroup {
+    ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int, int);
     ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int);
     ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet);
     ctor public PreferenceCategory(android.content.Context);
@@ -18850,6 +22668,7 @@
   }
 
   public abstract class PreferenceGroup extends android.preference.Preference {
+    ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int, int);
     ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int);
     ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet);
     method public void addItemFromInflater(android.preference.Preference);
@@ -18904,6 +22723,7 @@
   }
 
   public class RingtonePreference extends android.preference.Preference implements android.preference.PreferenceManager.OnActivityResultListener {
+    ctor public RingtonePreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public RingtonePreference(android.content.Context, android.util.AttributeSet, int);
     ctor public RingtonePreference(android.content.Context, android.util.AttributeSet);
     ctor public RingtonePreference(android.content.Context);
@@ -18920,6 +22740,7 @@
   }
 
   public class SwitchPreference extends android.preference.TwoStatePreference {
+    ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public SwitchPreference(android.content.Context, android.util.AttributeSet);
     ctor public SwitchPreference(android.content.Context);
@@ -18932,6 +22753,7 @@
   }
 
   public abstract class TwoStatePreference extends android.preference.Preference {
+    ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int);
     ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet);
     ctor public TwoStatePreference(android.content.Context);
@@ -19295,6 +23117,7 @@
     method protected void onDisconnected();
     method protected abstract void onPrintJobQueued(android.printservice.PrintJob);
     method protected abstract void onRequestCancelPrintJob(android.printservice.PrintJob);
+    field public static final java.lang.String EXTRA_PRINTER_INFO = "android.intent.extra.print.EXTRA_PRINTER_INFO";
     field public static final java.lang.String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO";
     field public static final java.lang.String SERVICE_INTERFACE = "android.printservice.PrintService";
     field public static final java.lang.String SERVICE_META_DATA = "android.printservice";
@@ -19687,16 +23510,28 @@
   public static class CallLog.Calls implements android.provider.BaseColumns {
     ctor public CallLog.Calls();
     method public static java.lang.String getLastOutgoingCall(android.content.Context);
+    field public static final java.lang.String CACHED_FORMATTED_NUMBER = "formatted_number";
+    field public static final java.lang.String CACHED_LOOKUP_URI = "lookup_uri";
+    field public static final java.lang.String CACHED_MATCHED_NUMBER = "matched_number";
     field public static final java.lang.String CACHED_NAME = "name";
+    field public static final java.lang.String CACHED_NORMALIZED_NUMBER = "normalized_number";
     field public static final java.lang.String CACHED_NUMBER_LABEL = "numberlabel";
     field public static final java.lang.String CACHED_NUMBER_TYPE = "numbertype";
+    field public static final java.lang.String CACHED_PHOTO_ID = "photo_id";
     field public static final android.net.Uri CONTENT_FILTER_URI;
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/calls";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/calls";
     field public static final android.net.Uri CONTENT_URI;
+    field public static final android.net.Uri CONTENT_URI_WITH_VOICEMAIL;
+    field public static final java.lang.String COUNTRY_ISO = "countryiso";
+    field public static final java.lang.String DATA_USAGE = "data_usage";
     field public static final java.lang.String DATE = "date";
     field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
     field public static final java.lang.String DURATION = "duration";
+    field public static final java.lang.String EXTRA_CALL_TYPE_FILTER = "android.provider.extra.CALL_TYPE_FILTER";
+    field public static final java.lang.String FEATURES = "features";
+    field public static final int FEATURES_VIDEO = 1; // 0x1
+    field public static final java.lang.String GEOCODED_LOCATION = "geocoded_location";
     field public static final int INCOMING_TYPE = 1; // 0x1
     field public static final java.lang.String IS_READ = "is_read";
     field public static final java.lang.String LIMIT_PARAM_KEY = "limit";
@@ -19706,11 +23541,16 @@
     field public static final java.lang.String NUMBER_PRESENTATION = "presentation";
     field public static final java.lang.String OFFSET_PARAM_KEY = "offset";
     field public static final int OUTGOING_TYPE = 2; // 0x2
+    field public static final java.lang.String PHONE_ACCOUNT_COMPONENT_NAME = "subscription_component_name";
+    field public static final java.lang.String PHONE_ACCOUNT_ID = "subscription_id";
     field public static final int PRESENTATION_ALLOWED = 1; // 0x1
     field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
     field public static final int PRESENTATION_RESTRICTED = 2; // 0x2
     field public static final int PRESENTATION_UNKNOWN = 3; // 0x3
+    field public static final java.lang.String TRANSCRIPTION = "transcription";
     field public static final java.lang.String TYPE = "type";
+    field public static final int VOICEMAIL_TYPE = 4; // 0x4
+    field public static final java.lang.String VOICEMAIL_URI = "voicemail_uri";
   }
 
   public deprecated class Contacts {
@@ -20013,10 +23853,14 @@
     field public static final java.lang.String AUTHORITY = "com.android.contacts";
     field public static final android.net.Uri AUTHORITY_URI;
     field public static final java.lang.String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
+    field public static final java.lang.String DEFERRED_SNIPPETING = "deferred_snippeting";
+    field public static final java.lang.String DEFERRED_SNIPPETING_QUERY = "deferred_snippeting_query";
     field public static final java.lang.String DIRECTORY_PARAM_KEY = "directory";
     field public static final java.lang.String LIMIT_PARAM_KEY = "limit";
     field public static final java.lang.String PRIMARY_ACCOUNT_NAME = "name_for_primary_account";
     field public static final java.lang.String PRIMARY_ACCOUNT_TYPE = "type_for_primary_account";
+    field public static final java.lang.String REMOVE_DUPLICATE_ENTRIES = "remove_duplicate_entries";
+    field public static final java.lang.String STREQUENT_PHONE_ONLY = "strequent_phone_only";
   }
 
   public static final class ContactsContract.AggregationExceptions implements android.provider.BaseColumns {
@@ -20045,6 +23889,15 @@
     field public static final int TYPE_CUSTOM = 0; // 0x0
   }
 
+  public static final class ContactsContract.CommonDataKinds.Callable implements android.provider.ContactsContract.CommonDataKinds.CommonColumns android.provider.ContactsContract.DataColumnsWithJoins {
+    ctor public ContactsContract.CommonDataKinds.Callable();
+    field public static final android.net.Uri CONTENT_FILTER_URI;
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
+  }
+
   protected static abstract interface ContactsContract.CommonDataKinds.CommonColumns implements android.provider.ContactsContract.CommonDataKinds.BaseTypes {
     field public static final java.lang.String DATA = "data1";
     field public static final java.lang.String LABEL = "data3";
@@ -20055,6 +23908,9 @@
     ctor public ContactsContract.CommonDataKinds.Contactables();
     field public static final android.net.Uri CONTENT_FILTER_URI;
     field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String VISIBLE_CONTACTS_ONLY = "visible_contacts_only";
   }
 
@@ -20068,6 +23924,9 @@
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/email_v2";
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String DISPLAY_NAME = "data4";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final int TYPE_HOME = 1; // 0x1
     field public static final int TYPE_MOBILE = 4; // 0x4
     field public static final int TYPE_OTHER = 3; // 0x3
@@ -20075,8 +23934,12 @@
   }
 
   public static final class ContactsContract.CommonDataKinds.Event implements android.provider.ContactsContract.CommonDataKinds.CommonColumns android.provider.ContactsContract.DataColumnsWithJoins {
+    method public static final java.lang.CharSequence getTypeLabel(android.content.res.Resources, int, java.lang.CharSequence);
     method public static int getTypeResource(java.lang.Integer);
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_event";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String START_DATE = "data1";
     field public static final int TYPE_ANNIVERSARY = 1; // 0x1
     field public static final int TYPE_BIRTHDAY = 3; // 0x3
@@ -20085,12 +23948,18 @@
 
   public static final class ContactsContract.CommonDataKinds.GroupMembership implements android.provider.ContactsContract.DataColumnsWithJoins {
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/group_membership";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String GROUP_ROW_ID = "data1";
     field public static final java.lang.String GROUP_SOURCE_ID = "group_sourceid";
   }
 
   public static final class ContactsContract.CommonDataKinds.Identity implements android.provider.ContactsContract.DataColumnsWithJoins {
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/identity";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String IDENTITY = "data1";
     field public static final java.lang.String NAMESPACE = "data2";
   }
@@ -20102,6 +23971,9 @@
     method public static final int getTypeLabelResource(int);
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/im";
     field public static final java.lang.String CUSTOM_PROTOCOL = "data6";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String PROTOCOL = "data5";
     field public static final int PROTOCOL_AIM = 0; // 0x0
     field public static final int PROTOCOL_CUSTOM = -1; // 0xffffffff
@@ -20120,6 +23992,9 @@
 
   public static final class ContactsContract.CommonDataKinds.Nickname implements android.provider.ContactsContract.CommonDataKinds.CommonColumns android.provider.ContactsContract.DataColumnsWithJoins {
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/nickname";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String NAME = "data1";
     field public static final int TYPE_DEFAULT = 1; // 0x1
     field public static final int TYPE_INITIALS = 5; // 0x5
@@ -20131,6 +24006,9 @@
 
   public static final class ContactsContract.CommonDataKinds.Note implements android.provider.ContactsContract.DataColumnsWithJoins {
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/note";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String NOTE = "data1";
   }
 
@@ -20140,6 +24018,9 @@
     field public static final java.lang.String COMPANY = "data1";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/organization";
     field public static final java.lang.String DEPARTMENT = "data5";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String JOB_DESCRIPTION = "data6";
     field public static final java.lang.String OFFICE_LOCATION = "data9";
     field public static final java.lang.String PHONETIC_NAME = "data8";
@@ -20156,6 +24037,9 @@
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone_v2";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/phone_v2";
     field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String NORMALIZED_NUMBER = "data4";
     field public static final java.lang.String NUMBER = "data1";
     field public static final java.lang.String SEARCH_DISPLAY_NAME_KEY = "search_display_name";
@@ -20184,6 +24068,9 @@
 
   public static final class ContactsContract.CommonDataKinds.Photo implements android.provider.ContactsContract.DataColumnsWithJoins {
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/photo";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String PHOTO = "data15";
     field public static final java.lang.String PHOTO_FILE_ID = "data14";
   }
@@ -20192,6 +24079,9 @@
     method public static final java.lang.CharSequence getTypeLabel(android.content.res.Resources, int, java.lang.CharSequence);
     method public static final int getTypeLabelResource(int);
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/relation";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String NAME = "data1";
     field public static final int TYPE_ASSISTANT = 1; // 0x1
     field public static final int TYPE_BROTHER = 2; // 0x2
@@ -20213,6 +24103,9 @@
     method public static final java.lang.CharSequence getTypeLabel(android.content.res.Resources, int, java.lang.CharSequence);
     method public static final int getTypeLabelResource(int);
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/sip_address";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String SIP_ADDRESS = "data1";
     field public static final int TYPE_HOME = 1; // 0x1
     field public static final int TYPE_OTHER = 3; // 0x3
@@ -20222,7 +24115,11 @@
   public static final class ContactsContract.CommonDataKinds.StructuredName implements android.provider.ContactsContract.DataColumnsWithJoins {
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/name";
     field public static final java.lang.String DISPLAY_NAME = "data1";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String FAMILY_NAME = "data3";
+    field public static final java.lang.String FULL_NAME_STYLE = "data10";
     field public static final java.lang.String GIVEN_NAME = "data2";
     field public static final java.lang.String MIDDLE_NAME = "data5";
     field public static final java.lang.String PHONETIC_FAMILY_NAME = "data9";
@@ -20240,6 +24137,9 @@
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/postal-address_v2";
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String COUNTRY = "data10";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String FORMATTED_ADDRESS = "data1";
     field public static final java.lang.String NEIGHBORHOOD = "data6";
     field public static final java.lang.String POBOX = "data5";
@@ -20253,6 +24153,9 @@
 
   public static final class ContactsContract.CommonDataKinds.Website implements android.provider.ContactsContract.CommonDataKinds.CommonColumns android.provider.ContactsContract.DataColumnsWithJoins {
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/website";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final int TYPE_BLOG = 2; // 0x2
     field public static final int TYPE_FTP = 6; // 0x6
     field public static final int TYPE_HOME = 4; // 0x4
@@ -20276,6 +24179,7 @@
   protected static abstract interface ContactsContract.ContactOptionsColumns {
     field public static final java.lang.String CUSTOM_RINGTONE = "custom_ringtone";
     field public static final java.lang.String LAST_TIME_CONTACTED = "last_time_contacted";
+    field public static final java.lang.String PINNED = "pinned";
     field public static final java.lang.String SEND_TO_VOICEMAIL = "send_to_voicemail";
     field public static final java.lang.String STARRED = "starred";
     field public static final java.lang.String TIMES_CONTACTED = "times_contacted";
@@ -20294,20 +24198,26 @@
   public static class ContactsContract.Contacts implements android.provider.BaseColumns android.provider.ContactsContract.ContactNameColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactStatusColumns android.provider.ContactsContract.ContactsColumns {
     method public static android.net.Uri getLookupUri(android.content.ContentResolver, android.net.Uri);
     method public static android.net.Uri getLookupUri(long, java.lang.String);
+    method public static boolean isEnterpriseContactId(long);
     method public static android.net.Uri lookupContact(android.content.ContentResolver, android.net.Uri);
     method public static deprecated void markAsContacted(android.content.ContentResolver, long);
     method public static java.io.InputStream openContactPhotoInputStream(android.content.ContentResolver, android.net.Uri, boolean);
     method public static java.io.InputStream openContactPhotoInputStream(android.content.ContentResolver, android.net.Uri);
     field public static final android.net.Uri CONTENT_FILTER_URI;
+    field public static final android.net.Uri CONTENT_FREQUENT_URI;
     field public static final android.net.Uri CONTENT_GROUP_URI;
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact";
     field public static final android.net.Uri CONTENT_LOOKUP_URI;
+    field public static final android.net.Uri CONTENT_MULTI_VCARD_URI;
     field public static final android.net.Uri CONTENT_STREQUENT_FILTER_URI;
     field public static final android.net.Uri CONTENT_STREQUENT_URI;
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/contact";
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String CONTENT_VCARD_TYPE = "text/x-vcard";
     field public static final android.net.Uri CONTENT_VCARD_URI;
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
   }
 
   public static final class ContactsContract.Contacts.AggregationSuggestions implements android.provider.BaseColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactStatusColumns android.provider.ContactsContract.ContactsColumns {
@@ -20318,7 +24228,7 @@
     field public static final java.lang.String CONTENT_DIRECTORY = "data";
   }
 
-  public static final class ContactsContract.Contacts.Entity implements android.provider.BaseColumns android.provider.ContactsContract.BaseSyncColumns android.provider.ContactsContract.ContactNameColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactStatusColumns android.provider.ContactsContract.ContactsColumns android.provider.ContactsContract.DataColumns android.provider.ContactsContract.RawContactsColumns android.provider.ContactsContract.StatusColumns android.provider.ContactsContract.SyncColumns {
+  public static final class ContactsContract.Contacts.Entity implements android.provider.BaseColumns android.provider.ContactsContract.BaseSyncColumns android.provider.ContactsContract.ContactNameColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactStatusColumns android.provider.ContactsContract.ContactsColumns android.provider.ContactsContract.DataColumns android.provider.ContactsContract.DataUsageStatColumns android.provider.ContactsContract.RawContactsColumns android.provider.ContactsContract.StatusColumns android.provider.ContactsContract.SyncColumns {
     field public static final java.lang.String CONTENT_DIRECTORY = "entities";
     field public static final java.lang.String DATA_ID = "data_id";
     field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
@@ -20331,17 +24241,19 @@
     field public static final java.lang.String PHOTO_FILE_ID = "data14";
   }
 
-  public static final class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
+  public static final deprecated class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
+    field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items";
   }
 
   protected static abstract interface ContactsContract.ContactsColumns {
     field public static final java.lang.String CONTACT_LAST_UPDATED_TIMESTAMP = "contact_last_updated_timestamp";
     field public static final java.lang.String DISPLAY_NAME = "display_name";
     field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number";
+    field public static final java.lang.String IN_DEFAULT_DIRECTORY = "in_default_directory";
     field public static final java.lang.String IN_VISIBLE_GROUP = "in_visible_group";
     field public static final java.lang.String IS_USER_PROFILE = "is_user_profile";
     field public static final java.lang.String LOOKUP_KEY = "lookup";
+    field public static final java.lang.String NAME_RAW_CONTACT_ID = "name_raw_contact_id";
     field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
     field public static final java.lang.String PHOTO_ID = "photo_id";
     field public static final java.lang.String PHOTO_THUMBNAIL_URI = "photo_thumb_uri";
@@ -20352,6 +24264,9 @@
     method public static android.net.Uri getContactLookupUri(android.content.ContentResolver, android.net.Uri);
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/data";
     field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
+    field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
     field public static final java.lang.String VISIBLE_CONTACTS_ONLY = "visible_contacts_only";
   }
 
@@ -20377,6 +24292,7 @@
     field public static final java.lang.String IS_SUPER_PRIMARY = "is_super_primary";
     field public static final java.lang.String MIMETYPE = "mimetype";
     field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
+    field public static final java.lang.String RES_PACKAGE = "res_package";
     field public static final java.lang.String SYNC1 = "data_sync1";
     field public static final java.lang.String SYNC2 = "data_sync2";
     field public static final java.lang.String SYNC3 = "data_sync3";
@@ -20480,11 +24396,13 @@
     field public static final java.lang.String GROUP_IS_READ_ONLY = "group_is_read_only";
     field public static final java.lang.String GROUP_VISIBLE = "group_visible";
     field public static final java.lang.String NOTES = "notes";
+    field public static final java.lang.String RES_PACKAGE = "res_package";
     field public static final java.lang.String SHOULD_SYNC = "should_sync";
     field public static final java.lang.String SUMMARY_COUNT = "summ_count";
     field public static final java.lang.String SUMMARY_WITH_PHONES = "summ_phones";
     field public static final java.lang.String SYSTEM_ID = "system_id";
     field public static final java.lang.String TITLE = "title";
+    field public static final java.lang.String TITLE_RES = "title_res";
   }
 
   public static final class ContactsContract.Intents {
@@ -20534,6 +24452,8 @@
 
   public static final class ContactsContract.PhoneLookup implements android.provider.BaseColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactsColumns android.provider.ContactsContract.PhoneLookupColumns {
     field public static final android.net.Uri CONTENT_FILTER_URI;
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
+    field public static final java.lang.String QUERY_PARAMETER_SIP_ADDRESS = "sip";
   }
 
   protected static abstract interface ContactsContract.PhoneLookupColumns {
@@ -20550,6 +24470,14 @@
     field public static final int UNDEFINED = 0; // 0x0
   }
 
+  public static final class ContactsContract.PinnedPositions {
+    ctor public ContactsContract.PinnedPositions();
+    method public static void pin(android.content.ContentResolver, long, int);
+    method public static void undemote(android.content.ContentResolver, long);
+    field public static final int DEMOTED = -1; // 0xffffffff
+    field public static final int UNPINNED = 0; // 0x0
+  }
+
   public static final deprecated class ContactsContract.Presence extends android.provider.ContactsContract.StatusUpdates {
     ctor public ContactsContract.Presence();
   }
@@ -20582,6 +24510,8 @@
     ctor public ContactsContract.QuickContact();
     method public static void showQuickContact(android.content.Context, android.view.View, android.net.Uri, int, java.lang.String[]);
     method public static void showQuickContact(android.content.Context, android.graphics.Rect, android.net.Uri, int, java.lang.String[]);
+    field public static final java.lang.String ACTION_QUICK_CONTACT = "android.provider.action.QUICK_CONTACT";
+    field public static final java.lang.String EXTRA_EXCLUDE_MIMES = "android.provider.extra.EXCLUDE_MIMES";
     field public static final int MODE_LARGE = 3; // 0x3
     field public static final int MODE_MEDIUM = 2; // 0x2
     field public static final int MODE_SMALL = 1; // 0x1
@@ -20612,11 +24542,12 @@
     field public static final java.lang.String DATA_ID = "data_id";
   }
 
-  public static final class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
+  public static final deprecated class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
+    field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items";
   }
 
   protected static abstract interface ContactsContract.RawContactsColumns {
+    field public static final java.lang.String ACCOUNT_TYPE_AND_DATA_SET = "account_type_and_data_set";
     field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
     field public static final java.lang.String CONTACT_ID = "contact_id";
     field public static final java.lang.String DATA_SET = "data_set";
@@ -20632,6 +24563,12 @@
     field public static final android.net.Uri PROFILE_CONTENT_URI;
   }
 
+  public static class ContactsContract.SearchSnippets {
+    ctor public ContactsContract.SearchSnippets();
+    field public static final java.lang.String DEFERRED_SNIPPETING_KEY = "deferred_snippeting";
+    field public static final java.lang.String SNIPPET = "snippet";
+  }
+
   public static final class ContactsContract.Settings implements android.provider.ContactsContract.SettingsColumns {
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/setting";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/setting";
@@ -20679,54 +24616,54 @@
     field public static final android.net.Uri PROFILE_CONTENT_URI;
   }
 
-  public static final class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String PHOTO = "photo";
+  public static final deprecated class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
+    field public static final deprecated java.lang.String PHOTO = "photo";
   }
 
-  protected static abstract interface ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
-    field public static final java.lang.String PHOTO_URI = "photo_uri";
-    field public static final java.lang.String SORT_INDEX = "sort_index";
-    field public static final java.lang.String STREAM_ITEM_ID = "stream_item_id";
-    field public static final java.lang.String SYNC1 = "stream_item_photo_sync1";
-    field public static final java.lang.String SYNC2 = "stream_item_photo_sync2";
-    field public static final java.lang.String SYNC3 = "stream_item_photo_sync3";
-    field public static final java.lang.String SYNC4 = "stream_item_photo_sync4";
+  protected static abstract deprecated interface ContactsContract.StreamItemPhotosColumns {
+    field public static final deprecated java.lang.String PHOTO_FILE_ID = "photo_file_id";
+    field public static final deprecated java.lang.String PHOTO_URI = "photo_uri";
+    field public static final deprecated java.lang.String SORT_INDEX = "sort_index";
+    field public static final deprecated java.lang.String STREAM_ITEM_ID = "stream_item_id";
+    field public static final deprecated java.lang.String SYNC1 = "stream_item_photo_sync1";
+    field public static final deprecated java.lang.String SYNC2 = "stream_item_photo_sync2";
+    field public static final deprecated java.lang.String SYNC3 = "stream_item_photo_sync3";
+    field public static final deprecated java.lang.String SYNC4 = "stream_item_photo_sync4";
   }
 
-  public static final class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
-    field public static final android.net.Uri CONTENT_LIMIT_URI;
-    field public static final android.net.Uri CONTENT_PHOTO_URI;
-    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
-    field public static final android.net.Uri CONTENT_URI;
-    field public static final java.lang.String MAX_ITEMS = "max_items";
+  public static final deprecated class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
+    field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
+    field public static final deprecated android.net.Uri CONTENT_LIMIT_URI;
+    field public static final deprecated android.net.Uri CONTENT_PHOTO_URI;
+    field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
+    field public static final deprecated android.net.Uri CONTENT_URI;
+    field public static final deprecated java.lang.String MAX_ITEMS = "max_items";
   }
 
-  public static final class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "photo";
-    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
-    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
+  public static final deprecated class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
+    field public static final deprecated java.lang.String CONTENT_DIRECTORY = "photo";
+    field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
+    field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
   }
 
-  protected static abstract interface ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String ACCOUNT_NAME = "account_name";
-    field public static final java.lang.String ACCOUNT_TYPE = "account_type";
-    field public static final java.lang.String COMMENTS = "comments";
-    field public static final java.lang.String CONTACT_ID = "contact_id";
-    field public static final java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
-    field public static final java.lang.String DATA_SET = "data_set";
-    field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
-    field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
-    field public static final java.lang.String RES_ICON = "icon";
-    field public static final java.lang.String RES_LABEL = "label";
-    field public static final java.lang.String RES_PACKAGE = "res_package";
-    field public static final java.lang.String SYNC1 = "stream_item_sync1";
-    field public static final java.lang.String SYNC2 = "stream_item_sync2";
-    field public static final java.lang.String SYNC3 = "stream_item_sync3";
-    field public static final java.lang.String SYNC4 = "stream_item_sync4";
-    field public static final java.lang.String TEXT = "text";
-    field public static final java.lang.String TIMESTAMP = "timestamp";
+  protected static abstract deprecated interface ContactsContract.StreamItemsColumns {
+    field public static final deprecated java.lang.String ACCOUNT_NAME = "account_name";
+    field public static final deprecated java.lang.String ACCOUNT_TYPE = "account_type";
+    field public static final deprecated java.lang.String COMMENTS = "comments";
+    field public static final deprecated java.lang.String CONTACT_ID = "contact_id";
+    field public static final deprecated java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
+    field public static final deprecated java.lang.String DATA_SET = "data_set";
+    field public static final deprecated java.lang.String RAW_CONTACT_ID = "raw_contact_id";
+    field public static final deprecated java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
+    field public static final deprecated java.lang.String RES_ICON = "icon";
+    field public static final deprecated java.lang.String RES_LABEL = "label";
+    field public static final deprecated java.lang.String RES_PACKAGE = "res_package";
+    field public static final deprecated java.lang.String SYNC1 = "stream_item_sync1";
+    field public static final deprecated java.lang.String SYNC2 = "stream_item_sync2";
+    field public static final deprecated java.lang.String SYNC3 = "stream_item_sync3";
+    field public static final deprecated java.lang.String SYNC4 = "stream_item_sync4";
+    field public static final deprecated java.lang.String TEXT = "text";
+    field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
   }
 
   protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
@@ -20748,17 +24685,23 @@
 
   public final class DocumentsContract {
     method public static android.net.Uri buildChildDocumentsUri(java.lang.String, java.lang.String);
+    method public static android.net.Uri buildChildDocumentsUriUsingTree(android.net.Uri, java.lang.String);
     method public static android.net.Uri buildDocumentUri(java.lang.String, java.lang.String);
+    method public static android.net.Uri buildDocumentUriUsingTree(android.net.Uri, java.lang.String);
     method public static android.net.Uri buildRecentDocumentsUri(java.lang.String, java.lang.String);
     method public static android.net.Uri buildRootUri(java.lang.String, java.lang.String);
     method public static android.net.Uri buildRootsUri(java.lang.String);
     method public static android.net.Uri buildSearchDocumentsUri(java.lang.String, java.lang.String, java.lang.String);
+    method public static android.net.Uri buildTreeDocumentUri(java.lang.String, java.lang.String);
+    method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
     method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
     method public static java.lang.String getDocumentId(android.net.Uri);
     method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal);
     method public static java.lang.String getRootId(android.net.Uri);
     method public static java.lang.String getSearchDocumentsQuery(android.net.Uri);
+    method public static java.lang.String getTreeDocumentId(android.net.Uri);
     method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
+    method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
     field public static final java.lang.String EXTRA_ERROR = "error";
     field public static final java.lang.String EXTRA_INFO = "info";
     field public static final java.lang.String EXTRA_LOADING = "loading";
@@ -20778,6 +24721,7 @@
     field public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 32; // 0x20
     field public static final int FLAG_DIR_SUPPORTS_CREATE = 8; // 0x8
     field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4
+    field public static final int FLAG_SUPPORTS_RENAME = 64; // 0x40
     field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1
     field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2
     field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.document/directory";
@@ -20794,6 +24738,7 @@
     field public static final java.lang.String COLUMN_TITLE = "title";
     field public static final int FLAG_LOCAL_ONLY = 2; // 0x2
     field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1
+    field public static final int FLAG_SUPPORTS_IS_CHILD = 16; // 0x10
     field public static final int FLAG_SUPPORTS_RECENTS = 4; // 0x4
     field public static final int FLAG_SUPPORTS_SEARCH = 8; // 0x8
   }
@@ -20806,6 +24751,9 @@
     method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
     method public final java.lang.String getType(android.net.Uri);
     method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
+    method public boolean isChildDocument(java.lang.String, java.lang.String);
+    method public final android.content.res.AssetFileDescriptor openAssetFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
+    method public final android.content.res.AssetFileDescriptor openAssetFile(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public abstract android.os.ParcelFileDescriptor openDocument(java.lang.String, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public android.content.res.AssetFileDescriptor openDocumentThumbnail(java.lang.String, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public final android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
@@ -20818,6 +24766,8 @@
     method public android.database.Cursor queryRecentDocuments(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor queryRoots(java.lang.String[]) throws java.io.FileNotFoundException;
     method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
+    method public java.lang.String renameDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
+    method public final void revokeDocumentPermission(java.lang.String);
     method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
 
@@ -20851,6 +24801,9 @@
     field public static final java.lang.String EXTRA_MEDIA_ALBUM = "android.intent.extra.album";
     field public static final java.lang.String EXTRA_MEDIA_ARTIST = "android.intent.extra.artist";
     field public static final java.lang.String EXTRA_MEDIA_FOCUS = "android.intent.extra.focus";
+    field public static final java.lang.String EXTRA_MEDIA_GENRE = "android.intent.extra.genre";
+    field public static final java.lang.String EXTRA_MEDIA_PLAYLIST = "android.intent.extra.playlist";
+    field public static final java.lang.String EXTRA_MEDIA_RADIO_CHANNEL = "android.intent.extra.radio_channel";
     field public static final java.lang.String EXTRA_MEDIA_TITLE = "android.intent.extra.title";
     field public static final java.lang.String EXTRA_OUTPUT = "output";
     field public static final java.lang.String EXTRA_SCREEN_ORIENTATION = "android.intent.extra.screenOrientation";
@@ -20969,6 +24922,7 @@
     method public static android.net.Uri getContentUriForPath(java.lang.String);
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/audio";
     field public static final java.lang.String DEFAULT_SORT_ORDER = "title_key";
+    field public static final java.lang.String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/audio";
     field public static final android.net.Uri EXTERNAL_CONTENT_URI;
     field public static final java.lang.String EXTRA_MAX_BYTES = "android.provider.MediaStore.extra.MAX_BYTES";
     field public static final android.net.Uri INTERNAL_CONTENT_URI;
@@ -21004,6 +24958,10 @@
     field public static final java.lang.String NAME = "name";
   }
 
+  public static final class MediaStore.Audio.Radio {
+    field public static final java.lang.String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/radio";
+  }
+
   public static final class MediaStore.Files {
     ctor public MediaStore.Files();
     method public static android.net.Uri getContentUri(java.lang.String);
@@ -21173,11 +25131,13 @@
     field public static final java.lang.String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
     field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
     field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
+    field public static final java.lang.String ACTION_CAST_SETTINGS = "android.settings.CAST_SETTINGS";
     field public static final java.lang.String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
     field public static final java.lang.String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
     field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
     field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS";
     field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS";
+    field public static final java.lang.String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS";
     field public static final java.lang.String ACTION_INPUT_METHOD_SETTINGS = "android.settings.INPUT_METHOD_SETTINGS";
     field public static final java.lang.String ACTION_INPUT_METHOD_SUBTYPE_SETTINGS = "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS";
     field public static final java.lang.String ACTION_INTERNAL_STORAGE_SETTINGS = "android.settings.INTERNAL_STORAGE_SETTINGS";
@@ -21196,9 +25156,12 @@
     field public static final java.lang.String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
     field public static final java.lang.String ACTION_SECURITY_SETTINGS = "android.settings.SECURITY_SETTINGS";
     field public static final java.lang.String ACTION_SETTINGS = "android.settings.SETTINGS";
+    field public static final java.lang.String ACTION_SHOW_REGULATORY_INFO = "android.settings.SHOW_REGULATORY_INFO";
     field public static final java.lang.String ACTION_SOUND_SETTINGS = "android.settings.SOUND_SETTINGS";
     field public static final java.lang.String ACTION_SYNC_SETTINGS = "android.settings.SYNC_SETTINGS";
+    field public static final java.lang.String ACTION_USAGE_ACCESS_SETTINGS = "android.settings.USAGE_ACCESS_SETTINGS";
     field public static final java.lang.String ACTION_USER_DICTIONARY_SETTINGS = "android.settings.USER_DICTIONARY_SETTINGS";
+    field public static final java.lang.String ACTION_VOICE_INPUT_SETTINGS = "android.settings.VOICE_INPUT_SETTINGS";
     field public static final java.lang.String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS";
     field public static final java.lang.String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS";
     field public static final java.lang.String ACTION_WIRELESS_SETTINGS = "android.settings.WIRELESS_SETTINGS";
@@ -21236,7 +25199,7 @@
     field public static final java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
     field public static final java.lang.String DEVICE_PROVISIONED = "device_provisioned";
     field public static final java.lang.String HTTP_PROXY = "http_proxy";
-    field public static final java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
+    field public static final deprecated java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
     field public static final java.lang.String MODE_RINGER = "mode_ringer";
     field public static final java.lang.String NETWORK_PREFERENCE = "network_preference";
     field public static final java.lang.String RADIO_BLUETOOTH = "bluetooth";
@@ -21288,6 +25251,7 @@
     method public static boolean putLong(android.content.ContentResolver, java.lang.String, long);
     method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String);
     method public static final deprecated void setLocationProviderEnabled(android.content.ContentResolver, java.lang.String, boolean);
+    field public static final java.lang.String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED = "accessibility_display_inversion_enabled";
     field public static final java.lang.String ACCESSIBILITY_ENABLED = "accessibility_enabled";
     field public static final java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
     field public static final deprecated java.lang.String ADB_ENABLED = "adb_enabled";
@@ -21305,7 +25269,7 @@
     field public static final java.lang.String ENABLED_INPUT_METHODS = "enabled_input_methods";
     field public static final deprecated java.lang.String HTTP_PROXY = "http_proxy";
     field public static final java.lang.String INPUT_METHOD_SELECTOR_VISIBILITY = "input_method_selector_visibility";
-    field public static final deprecated java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
+    field public static final java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
     field public static final java.lang.String LOCATION_MODE = "location_mode";
     field public static final int LOCATION_MODE_BATTERY_SAVING = 2; // 0x2
     field public static final int LOCATION_MODE_HIGH_ACCURACY = 3; // 0x3
@@ -21322,6 +25286,7 @@
     field public static final java.lang.String PARENTAL_CONTROL_REDIRECT_URL = "parental_control_redirect_url";
     field public static final java.lang.String SELECTED_INPUT_METHOD_SUBTYPE = "selected_input_method_subtype";
     field public static final java.lang.String SETTINGS_CLASSNAME = "settings_classname";
+    field public static final java.lang.String SKIP_FIRST_USE_HINTS = "skip_first_use_hints";
     field public static final java.lang.String SYS_PROP_SETTING_VERSION = "sys.settings_secure_version";
     field public static final java.lang.String TOUCH_EXPLORATION_ENABLED = "touch_exploration_enabled";
     field public static final deprecated java.lang.String TTS_DEFAULT_COUNTRY = "tts_default_country";
@@ -21414,7 +25379,7 @@
     field public static final java.lang.String MODE_RINGER_STREAMS_AFFECTED = "mode_ringer_streams_affected";
     field public static final java.lang.String MUTE_STREAMS_AFFECTED = "mute_streams_affected";
     field public static final deprecated java.lang.String NETWORK_PREFERENCE = "network_preference";
-    field public static final java.lang.String NEXT_ALARM_FORMATTED = "next_alarm_formatted";
+    field public static final deprecated java.lang.String NEXT_ALARM_FORMATTED = "next_alarm_formatted";
     field public static final java.lang.String NOTIFICATION_SOUND = "notification_sound";
     field public static final deprecated java.lang.String PARENTAL_CONTROL_ENABLED = "parental_control_enabled";
     field public static final deprecated java.lang.String PARENTAL_CONTROL_LAST_UPDATE = "parental_control_last_update";
@@ -21520,6 +25485,7 @@
     field public static final java.lang.String CONTENT_CLASS = "ct_cls";
     field public static final java.lang.String CONTENT_LOCATION = "ct_l";
     field public static final java.lang.String CONTENT_TYPE = "ct_t";
+    field public static final java.lang.String CREATOR = "creator";
     field public static final java.lang.String DATE = "date";
     field public static final java.lang.String DATE_SENT = "date_sent";
     field public static final java.lang.String DELIVERY_REPORT = "d_rpt";
@@ -21529,6 +25495,7 @@
     field public static final java.lang.String MESSAGE_BOX = "msg_box";
     field public static final int MESSAGE_BOX_ALL = 0; // 0x0
     field public static final int MESSAGE_BOX_DRAFTS = 3; // 0x3
+    field public static final int MESSAGE_BOX_FAILED = 5; // 0x5
     field public static final int MESSAGE_BOX_INBOX = 1; // 0x1
     field public static final int MESSAGE_BOX_OUTBOX = 4; // 0x4
     field public static final int MESSAGE_BOX_SENT = 2; // 0x2
@@ -21738,6 +25705,7 @@
   public static abstract interface Telephony.TextBasedSmsColumns {
     field public static final java.lang.String ADDRESS = "address";
     field public static final java.lang.String BODY = "body";
+    field public static final java.lang.String CREATOR = "creator";
     field public static final java.lang.String DATE = "date";
     field public static final java.lang.String DATE_SENT = "date_sent";
     field public static final java.lang.String ERROR_CODE = "error_code";
@@ -21773,6 +25741,7 @@
   }
 
   public static abstract interface Telephony.ThreadsColumns implements android.provider.BaseColumns {
+    field public static final java.lang.String ARCHIVED = "archived";
     field public static final java.lang.String DATE = "date";
     field public static final java.lang.String ERROR = "error";
     field public static final java.lang.String HAS_ATTACHMENT = "has_attachment";
@@ -21850,6 +25819,7 @@
     field public static final java.lang.String NUMBER = "number";
     field public static final java.lang.String SOURCE_DATA = "source_data";
     field public static final java.lang.String SOURCE_PACKAGE = "source_package";
+    field public static final java.lang.String TRANSCRIPTION = "transcription";
   }
 
 }
@@ -21857,15 +25827,18 @@
 package android.renderscript {
 
   public class Allocation extends android.renderscript.BaseObj {
+    method public void copy1DRangeFrom(int, int, java.lang.Object);
     method public void copy1DRangeFrom(int, int, int[]);
     method public void copy1DRangeFrom(int, int, short[]);
     method public void copy1DRangeFrom(int, int, byte[]);
     method public void copy1DRangeFrom(int, int, float[]);
     method public void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
+    method public void copy1DRangeFromUnchecked(int, int, java.lang.Object);
     method public void copy1DRangeFromUnchecked(int, int, int[]);
     method public void copy1DRangeFromUnchecked(int, int, short[]);
     method public void copy1DRangeFromUnchecked(int, int, byte[]);
     method public void copy1DRangeFromUnchecked(int, int, float[]);
+    method public void copy2DRangeFrom(int, int, int, int, java.lang.Object);
     method public void copy2DRangeFrom(int, int, int, int, byte[]);
     method public void copy2DRangeFrom(int, int, int, int, short[]);
     method public void copy2DRangeFrom(int, int, int, int, int[]);
@@ -21873,17 +25846,20 @@
     method public void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
     method public void copy2DRangeFrom(int, int, android.graphics.Bitmap);
     method public void copyFrom(android.renderscript.BaseObj[]);
+    method public void copyFrom(java.lang.Object);
     method public void copyFrom(int[]);
     method public void copyFrom(short[]);
     method public void copyFrom(byte[]);
     method public void copyFrom(float[]);
     method public void copyFrom(android.graphics.Bitmap);
     method public void copyFrom(android.renderscript.Allocation);
+    method public void copyFromUnchecked(java.lang.Object);
     method public void copyFromUnchecked(int[]);
     method public void copyFromUnchecked(short[]);
     method public void copyFromUnchecked(byte[]);
     method public void copyFromUnchecked(float[]);
     method public void copyTo(android.graphics.Bitmap);
+    method public void copyTo(java.lang.Object);
     method public void copyTo(byte[]);
     method public void copyTo(short[]);
     method public void copyTo(int[]);
@@ -22376,6 +26352,7 @@
     method public void contextDump();
     method public static android.renderscript.RenderScript create(android.content.Context);
     method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType);
+    method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType, int);
     method public void destroy();
     method public void finish();
     method public final android.content.Context getApplicationContext();
@@ -22385,6 +26362,9 @@
     method public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
     method public void setMessageHandler(android.renderscript.RenderScript.RSMessageHandler);
     method public void setPriority(android.renderscript.RenderScript.Priority);
+    field public static final int CREATE_FLAG_LOW_LATENCY = 2; // 0x2
+    field public static final int CREATE_FLAG_LOW_POWER = 4; // 0x4
+    field public static final int CREATE_FLAG_NONE = 0; // 0x0
   }
 
   public static final class RenderScript.ContextType extends java.lang.Enum {
@@ -22517,7 +26497,9 @@
 
   public class ScriptC extends android.renderscript.Script {
     ctor protected ScriptC(int, android.renderscript.RenderScript);
+    ctor protected ScriptC(long, android.renderscript.RenderScript);
     ctor protected ScriptC(android.renderscript.RenderScript, android.content.res.Resources, int);
+    ctor protected ScriptC(android.renderscript.RenderScript, java.lang.String, byte[], byte[]);
   }
 
   public final class ScriptGroup extends android.renderscript.BaseObj {
@@ -22540,6 +26522,7 @@
   public final class ScriptIntrinsic3DLUT extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsic3DLUT create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setLUT(android.renderscript.Allocation);
   }
@@ -22547,20 +26530,35 @@
   public class ScriptIntrinsicBlend extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicBlend create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.KernelID getKernelIDAdd();
     method public android.renderscript.Script.KernelID getKernelIDClear();
     method public android.renderscript.Script.KernelID getKernelIDDst();
@@ -22581,6 +26579,7 @@
   public final class ScriptIntrinsicBlur extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicBlur create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.FieldID getFieldID_Input();
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setInput(android.renderscript.Allocation);
@@ -22591,6 +26590,7 @@
     method public static deprecated android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript, android.renderscript.Element);
     method public static android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript);
     method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setAdd(android.renderscript.Float4);
     method public void setAdd(float, float, float, float);
@@ -22604,6 +26604,7 @@
   public final class ScriptIntrinsicConvolve3x3 extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicConvolve3x3 create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.FieldID getFieldID_Input();
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setCoefficients(float[]);
@@ -22613,6 +26614,7 @@
   public final class ScriptIntrinsicConvolve5x5 extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicConvolve5x5 create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.FieldID getFieldID_Input();
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setCoefficients(float[]);
@@ -22622,7 +26624,9 @@
   public final class ScriptIntrinsicHistogram extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicHistogram create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEach_Dot(android.renderscript.Allocation);
+    method public void forEach_Dot(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.FieldID getFieldID_Input();
     method public android.renderscript.Script.KernelID getKernelID_Separate();
     method public void setDotCoefficients(float, float, float, float);
@@ -22632,6 +26636,7 @@
   public final class ScriptIntrinsicLUT extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicLUT create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setAlpha(int, int);
     method public void setBlue(int, int);
@@ -22681,6 +26686,9 @@
   }
 
   public class Type extends android.renderscript.BaseObj {
+    method public static android.renderscript.Type createX(android.renderscript.RenderScript, android.renderscript.Element, int);
+    method public static android.renderscript.Type createXY(android.renderscript.RenderScript, android.renderscript.Element, int, int);
+    method public static android.renderscript.Type createXYZ(android.renderscript.RenderScript, android.renderscript.Element, int, int, int);
     method public int getCount();
     method public android.renderscript.Element getElement();
     method public int getX();
@@ -22857,6 +26865,7 @@
     method public void onPanelClosed(int, android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
     method public boolean onSearchRequested();
+    method public void onWakeUp();
     method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
     method public void onWindowFocusChanged(boolean);
     method public android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback);
@@ -22866,37 +26875,101 @@
     method public void setFullscreen(boolean);
     method public void setInteractive(boolean);
     method public void setScreenBright(boolean);
+    method public final void wakeUp();
     field public static final java.lang.String DREAM_META_DATA = "android.service.dream";
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.dreams.DreamService";
   }
 
 }
 
+package android.service.media {
+
+  public abstract class MediaBrowserService extends android.app.Service {
+    ctor public MediaBrowserService();
+    method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+    method public android.media.session.MediaSession.Token getSessionToken();
+    method public void notifyChildrenChanged(java.lang.String);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public abstract android.service.media.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
+    method public abstract void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
+    method public void setSessionToken(android.media.session.MediaSession.Token);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
+  }
+
+  public static final class MediaBrowserService.BrowserRoot {
+    ctor public MediaBrowserService.BrowserRoot(java.lang.String, android.os.Bundle);
+    method public android.os.Bundle getExtras();
+    method public java.lang.String getRootId();
+  }
+
+  public class MediaBrowserService.Result {
+    method public void detach();
+    method public void sendResult(T);
+  }
+
+}
+
 package android.service.notification {
 
   public abstract class NotificationListenerService extends android.app.Service {
     ctor public NotificationListenerService();
     method public final void cancelAllNotifications();
-    method public final void cancelNotification(java.lang.String, java.lang.String, int);
+    method public final deprecated void cancelNotification(java.lang.String, java.lang.String, int);
+    method public final void cancelNotification(java.lang.String);
+    method public final void cancelNotifications(java.lang.String[]);
     method public android.service.notification.StatusBarNotification[] getActiveNotifications();
+    method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[]);
+    method public final int getCurrentInterruptionFilter();
+    method public final int getCurrentListenerHints();
+    method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking();
     method public android.os.IBinder onBind(android.content.Intent);
-    method public abstract void onNotificationPosted(android.service.notification.StatusBarNotification);
-    method public abstract void onNotificationRemoved(android.service.notification.StatusBarNotification);
+    method public void onInterruptionFilterChanged(int);
+    method public void onListenerConnected();
+    method public void onListenerHintsChanged(int);
+    method public void onNotificationPosted(android.service.notification.StatusBarNotification);
+    method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
+    method public void onNotificationRankingUpdate(android.service.notification.NotificationListenerService.RankingMap);
+    method public void onNotificationRemoved(android.service.notification.StatusBarNotification);
+    method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
+    method public final void requestInterruptionFilter(int);
+    method public final void requestListenerHints(int);
+    field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
+    field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
+    field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
+    field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
   }
 
+  public static class NotificationListenerService.Ranking {
+    ctor public NotificationListenerService.Ranking();
+    method public java.lang.String getKey();
+    method public int getRank();
+    method public boolean isAmbient();
+    method public boolean matchesInterruptionFilter();
+  }
+
+  public static class NotificationListenerService.RankingMap implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.lang.String[] getOrderedKeys();
+    method public boolean getRanking(java.lang.String, android.service.notification.NotificationListenerService.Ranking);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public class StatusBarNotification implements android.os.Parcelable {
     ctor public StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long);
     ctor public StatusBarNotification(android.os.Parcel);
     method public android.service.notification.StatusBarNotification clone();
     method public int describeContents();
+    method public java.lang.String getGroupKey();
     method public int getId();
     method public java.lang.String getKey();
     method public android.app.Notification getNotification();
     method public java.lang.String getPackageName();
     method public long getPostTime();
     method public java.lang.String getTag();
-    method public int getUserId();
+    method public android.os.UserHandle getUser();
+    method public deprecated int getUserId();
     method public boolean isClearable();
     method public boolean isOngoing();
     method public void writeToParcel(android.os.Parcel, int);
@@ -22905,6 +26978,16 @@
 
 }
 
+package android.service.restrictions {
+
+  public abstract class RestrictionsReceiver extends android.content.BroadcastReceiver {
+    ctor public RestrictionsReceiver();
+    method public void onReceive(android.content.Context, android.content.Intent);
+    method public abstract void onRequestPermission(android.content.Context, java.lang.String, java.lang.String, java.lang.String, android.os.PersistableBundle);
+  }
+
+}
+
 package android.service.textservice {
 
   public abstract class SpellCheckerService extends android.app.Service {
@@ -22928,6 +27011,73 @@
 
 }
 
+package android.service.voice {
+
+  public class AlwaysOnHotwordDetector {
+    method public android.content.Intent createEnrollIntent();
+    method public android.content.Intent createReEnrollIntent();
+    method public android.content.Intent createUnEnrollIntent();
+    method public int getSupportedRecognitionModes();
+    method public boolean startRecognition(int);
+    method public boolean stopRecognition();
+    field public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 2; // 0x2
+    field public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 1; // 0x1
+    field public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 2; // 0x2
+    field public static final int RECOGNITION_MODE_VOICE_TRIGGER = 1; // 0x1
+    field public static final int STATE_HARDWARE_UNAVAILABLE = -2; // 0xfffffffe
+    field public static final int STATE_KEYPHRASE_ENROLLED = 2; // 0x2
+    field public static final int STATE_KEYPHRASE_UNENROLLED = 1; // 0x1
+    field public static final int STATE_KEYPHRASE_UNSUPPORTED = -1; // 0xffffffff
+  }
+
+  public static abstract class AlwaysOnHotwordDetector.Callback {
+    ctor public AlwaysOnHotwordDetector.Callback();
+    method public abstract void onAvailabilityChanged(int);
+    method public abstract void onDetected(android.service.voice.AlwaysOnHotwordDetector.EventPayload);
+    method public abstract void onError();
+    method public abstract void onRecognitionPaused();
+    method public abstract void onRecognitionResumed();
+  }
+
+  public static class AlwaysOnHotwordDetector.EventPayload {
+    method public android.media.AudioFormat getCaptureAudioFormat();
+    method public byte[] getTriggerAudio();
+  }
+
+  public class VoiceInteractionService extends android.app.Service {
+    ctor public VoiceInteractionService();
+    method public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(java.lang.String, java.util.Locale, android.service.voice.AlwaysOnHotwordDetector.Callback);
+    method public static boolean isActiveService(android.content.Context, android.content.ComponentName);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public void onReady();
+    method public void onShutdown();
+    method public void startSession(android.os.Bundle);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService";
+    field public static final java.lang.String SERVICE_META_DATA = "android.voice_interaction";
+  }
+
+  public abstract class VoiceInteractionSession implements android.view.KeyEvent.Callback {
+    ctor public VoiceInteractionSession(android.content.Context);
+    ctor public VoiceInteractionSession(android.content.Context, android.os.Handler);
+    method public void finish();
+    method public void onCloseSystemDialogs();
+    method public void onCreate(android.os.Bundle);
+    method public void onDestroy();
+    method public boolean onKeyDown(int, android.view.KeyEvent);
+    method public boolean onKeyLongPress(int, android.view.KeyEvent);
+    method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
+    method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public void setContentView(android.view.View);
+  }
+
+  public abstract class VoiceInteractionSessionService extends android.app.Service {
+    ctor public VoiceInteractionSessionService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public abstract android.service.voice.VoiceInteractionSession onNewSession(android.os.Bundle);
+  }
+
+}
+
 package android.service.wallpaper {
 
   public abstract class WallpaperService extends android.app.Service {
@@ -22946,6 +27096,7 @@
     method public android.view.SurfaceHolder getSurfaceHolder();
     method public boolean isPreview();
     method public boolean isVisible();
+    method public void onApplyWindowInsets(android.view.WindowInsets);
     method public android.os.Bundle onCommand(java.lang.String, int, int, int, android.os.Bundle, boolean);
     method public void onCreate(android.view.SurfaceHolder);
     method public void onDesiredSizeChanged(int, int);
@@ -23073,52 +27224,78 @@
     method public abstract int audioAvailable(byte[], int, int);
     method public abstract int done();
     method public abstract void error();
+    method public abstract void error(int);
     method public abstract int getMaxBufferSize();
+    method public abstract boolean hasFinished();
+    method public abstract boolean hasStarted();
     method public abstract int start(int, int, int);
   }
 
   public final class SynthesisRequest {
     ctor public SynthesisRequest(java.lang.String, android.os.Bundle);
+    ctor public SynthesisRequest(java.lang.CharSequence, android.os.Bundle);
     method public int getCallerUid();
+    method public java.lang.CharSequence getCharSequenceText();
     method public java.lang.String getCountry();
     method public java.lang.String getLanguage();
     method public android.os.Bundle getParams();
     method public int getPitch();
     method public int getSpeechRate();
-    method public java.lang.String getText();
+    method public deprecated java.lang.String getText();
     method public java.lang.String getVariant();
+    method public java.lang.String getVoiceName();
   }
 
   public class TextToSpeech {
     ctor public TextToSpeech(android.content.Context, android.speech.tts.TextToSpeech.OnInitListener);
     ctor public TextToSpeech(android.content.Context, android.speech.tts.TextToSpeech.OnInitListener, java.lang.String);
     method public int addEarcon(java.lang.String, java.lang.String, int);
-    method public int addEarcon(java.lang.String, java.lang.String);
+    method public deprecated int addEarcon(java.lang.String, java.lang.String);
+    method public int addEarcon(java.lang.String, java.io.File);
     method public int addSpeech(java.lang.String, java.lang.String, int);
+    method public int addSpeech(java.lang.CharSequence, java.lang.String, int);
     method public int addSpeech(java.lang.String, java.lang.String);
-    method public boolean areDefaultsEnforced();
+    method public int addSpeech(java.lang.CharSequence, java.io.File);
+    method public deprecated boolean areDefaultsEnforced();
+    method public java.util.Set<java.util.Locale> getAvailableLanguages();
     method public java.lang.String getDefaultEngine();
-    method public java.util.Locale getDefaultLanguage();
+    method public deprecated java.util.Locale getDefaultLanguage();
+    method public android.speech.tts.Voice getDefaultVoice();
     method public java.util.List<android.speech.tts.TextToSpeech.EngineInfo> getEngines();
-    method public java.util.Set<java.lang.String> getFeatures(java.util.Locale);
-    method public java.util.Locale getLanguage();
+    method public deprecated java.util.Set<java.lang.String> getFeatures(java.util.Locale);
+    method public deprecated java.util.Locale getLanguage();
     method public static int getMaxSpeechInputLength();
+    method public android.speech.tts.Voice getVoice();
+    method public java.util.Set<android.speech.tts.Voice> getVoices();
     method public int isLanguageAvailable(java.util.Locale);
     method public boolean isSpeaking();
-    method public int playEarcon(java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>);
-    method public int playSilence(long, int, java.util.HashMap<java.lang.String, java.lang.String>);
+    method public int playEarcon(java.lang.String, int, android.os.Bundle, java.lang.String);
+    method public deprecated int playEarcon(java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>);
+    method public deprecated int playSilence(long, int, java.util.HashMap<java.lang.String, java.lang.String>);
+    method public int playSilentUtterance(long, int, java.lang.String);
+    method public int setAudioAttributes(android.media.AudioAttributes);
     method public deprecated int setEngineByPackageName(java.lang.String);
     method public int setLanguage(java.util.Locale);
     method public deprecated int setOnUtteranceCompletedListener(android.speech.tts.TextToSpeech.OnUtteranceCompletedListener);
     method public int setOnUtteranceProgressListener(android.speech.tts.UtteranceProgressListener);
     method public int setPitch(float);
     method public int setSpeechRate(float);
+    method public int setVoice(android.speech.tts.Voice);
     method public void shutdown();
-    method public int speak(java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>);
+    method public int speak(java.lang.CharSequence, int, android.os.Bundle, java.lang.String);
+    method public deprecated int speak(java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>);
     method public int stop();
-    method public int synthesizeToFile(java.lang.String, java.util.HashMap<java.lang.String, java.lang.String>, java.lang.String);
+    method public int synthesizeToFile(java.lang.CharSequence, android.os.Bundle, java.io.File, java.lang.String);
+    method public deprecated int synthesizeToFile(java.lang.String, java.util.HashMap<java.lang.String, java.lang.String>, java.lang.String);
     field public static final java.lang.String ACTION_TTS_QUEUE_PROCESSING_COMPLETED = "android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED";
     field public static final int ERROR = -1; // 0xffffffff
+    field public static final int ERROR_INVALID_REQUEST = -8; // 0xfffffff8
+    field public static final int ERROR_NETWORK = -6; // 0xfffffffa
+    field public static final int ERROR_NETWORK_TIMEOUT = -7; // 0xfffffff9
+    field public static final int ERROR_NOT_INSTALLED_YET = -9; // 0xfffffff7
+    field public static final int ERROR_OUTPUT = -5; // 0xfffffffb
+    field public static final int ERROR_SERVICE = -4; // 0xfffffffc
+    field public static final int ERROR_SYNTHESIS = -3; // 0xfffffffd
     field public static final int LANG_AVAILABLE = 0; // 0x0
     field public static final int LANG_COUNTRY_AVAILABLE = 1; // 0x1
     field public static final int LANG_COUNTRY_VAR_AVAILABLE = 2; // 0x2
@@ -23126,6 +27303,7 @@
     field public static final int LANG_NOT_SUPPORTED = -2; // 0xfffffffe
     field public static final int QUEUE_ADD = 1; // 0x1
     field public static final int QUEUE_FLUSH = 0; // 0x0
+    field public static final int STOPPED = -2; // 0xfffffffe
     field public static final int SUCCESS = 0; // 0x0
   }
 
@@ -23150,9 +27328,13 @@
     field public static final deprecated java.lang.String EXTRA_VOICE_DATA_FILES_INFO = "dataFilesInfo";
     field public static final deprecated java.lang.String EXTRA_VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
     field public static final java.lang.String INTENT_ACTION_TTS_SERVICE = "android.intent.action.TTS_SERVICE";
-    field public static final java.lang.String KEY_FEATURE_EMBEDDED_SYNTHESIS = "embeddedTts";
-    field public static final java.lang.String KEY_FEATURE_NETWORK_SYNTHESIS = "networkTts";
+    field public static final deprecated java.lang.String KEY_FEATURE_EMBEDDED_SYNTHESIS = "embeddedTts";
+    field public static final java.lang.String KEY_FEATURE_NETWORK_RETRIES_COUNT = "networkRetriesCount";
+    field public static final deprecated java.lang.String KEY_FEATURE_NETWORK_SYNTHESIS = "networkTts";
+    field public static final java.lang.String KEY_FEATURE_NETWORK_TIMEOUT_MS = "networkTimeoutMs";
+    field public static final java.lang.String KEY_FEATURE_NOT_INSTALLED = "notInstalled";
     field public static final java.lang.String KEY_PARAM_PAN = "pan";
+    field public static final java.lang.String KEY_PARAM_SESSION_ID = "sessionId";
     field public static final java.lang.String KEY_PARAM_STREAM = "streamType";
     field public static final java.lang.String KEY_PARAM_UTTERANCE_ID = "utteranceId";
     field public static final java.lang.String KEY_PARAM_VOLUME = "volume";
@@ -23177,10 +27359,14 @@
   public abstract class TextToSpeechService extends android.app.Service {
     ctor public TextToSpeechService();
     method public android.os.IBinder onBind(android.content.Intent);
+    method public java.lang.String onGetDefaultVoiceNameFor(java.lang.String, java.lang.String, java.lang.String);
     method protected java.util.Set<java.lang.String> onGetFeaturesForLanguage(java.lang.String, java.lang.String, java.lang.String);
     method protected abstract java.lang.String[] onGetLanguage();
+    method public java.util.List<android.speech.tts.Voice> onGetVoices();
     method protected abstract int onIsLanguageAvailable(java.lang.String, java.lang.String, java.lang.String);
+    method public int onIsValidVoiceName(java.lang.String);
     method protected abstract int onLoadLanguage(java.lang.String, java.lang.String, java.lang.String);
+    method public int onLoadVoice(java.lang.String);
     method protected abstract void onStop();
     method protected abstract void onSynthesizeText(android.speech.tts.SynthesisRequest, android.speech.tts.SynthesisCallback);
   }
@@ -23188,10 +27374,690 @@
   public abstract class UtteranceProgressListener {
     ctor public UtteranceProgressListener();
     method public abstract void onDone(java.lang.String);
-    method public abstract void onError(java.lang.String);
+    method public abstract deprecated void onError(java.lang.String);
+    method public void onError(java.lang.String, int);
     method public abstract void onStart(java.lang.String);
   }
 
+  public class Voice implements android.os.Parcelable {
+    ctor public Voice(java.lang.String, java.util.Locale, int, int, boolean, java.util.Set<java.lang.String>);
+    method public int describeContents();
+    method public java.util.Set<java.lang.String> getFeatures();
+    method public int getLatency();
+    method public java.util.Locale getLocale();
+    method public java.lang.String getName();
+    method public int getQuality();
+    method public boolean isNetworkConnectionRequired();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int LATENCY_HIGH = 400; // 0x190
+    field public static final int LATENCY_LOW = 200; // 0xc8
+    field public static final int LATENCY_NORMAL = 300; // 0x12c
+    field public static final int LATENCY_VERY_HIGH = 500; // 0x1f4
+    field public static final int LATENCY_VERY_LOW = 100; // 0x64
+    field public static final int QUALITY_HIGH = 400; // 0x190
+    field public static final int QUALITY_LOW = 200; // 0xc8
+    field public static final int QUALITY_NORMAL = 300; // 0x12c
+    field public static final int QUALITY_VERY_HIGH = 500; // 0x1f4
+    field public static final int QUALITY_VERY_LOW = 100; // 0x64
+  }
+
+}
+
+package android.system {
+
+  public final class ErrnoException extends java.lang.Exception {
+    ctor public ErrnoException(java.lang.String, int);
+    ctor public ErrnoException(java.lang.String, int, java.lang.Throwable);
+    field public final int errno;
+  }
+
+  public final class Os {
+    method public static java.io.FileDescriptor accept(java.io.FileDescriptor, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
+    method public static boolean access(java.lang.String, int) throws android.system.ErrnoException;
+    method public static void bind(java.io.FileDescriptor, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
+    method public static void chmod(java.lang.String, int) throws android.system.ErrnoException;
+    method public static void chown(java.lang.String, int, int) throws android.system.ErrnoException;
+    method public static void close(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static void connect(java.io.FileDescriptor, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
+    method public static java.io.FileDescriptor dup(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static java.io.FileDescriptor dup2(java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method public static java.lang.String[] environ();
+    method public static void execv(java.lang.String, java.lang.String[]) throws android.system.ErrnoException;
+    method public static void execve(java.lang.String, java.lang.String[], java.lang.String[]) throws android.system.ErrnoException;
+    method public static void fchmod(java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method public static void fchown(java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method public static void fdatasync(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static android.system.StructStat fstat(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static android.system.StructStatVfs fstatvfs(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static void fsync(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static void ftruncate(java.io.FileDescriptor, long) throws android.system.ErrnoException;
+    method public static java.lang.String gai_strerror(int);
+    method public static int getegid();
+    method public static java.lang.String getenv(java.lang.String);
+    method public static int geteuid();
+    method public static int getgid();
+    method public static java.net.SocketAddress getpeername(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static int getpid();
+    method public static int getppid();
+    method public static java.net.SocketAddress getsockname(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static int gettid();
+    method public static int getuid();
+    method public static java.lang.String if_indextoname(int);
+    method public static java.net.InetAddress inet_pton(int, java.lang.String);
+    method public static boolean isatty(java.io.FileDescriptor);
+    method public static void kill(int, int) throws android.system.ErrnoException;
+    method public static void lchown(java.lang.String, int, int) throws android.system.ErrnoException;
+    method public static void link(java.lang.String, java.lang.String) throws android.system.ErrnoException;
+    method public static void listen(java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method public static long lseek(java.io.FileDescriptor, long, int) throws android.system.ErrnoException;
+    method public static android.system.StructStat lstat(java.lang.String) throws android.system.ErrnoException;
+    method public static void mincore(long, long, byte[]) throws android.system.ErrnoException;
+    method public static void mkdir(java.lang.String, int) throws android.system.ErrnoException;
+    method public static void mkfifo(java.lang.String, int) throws android.system.ErrnoException;
+    method public static void mlock(long, long) throws android.system.ErrnoException;
+    method public static long mmap(long, long, int, int, java.io.FileDescriptor, long) throws android.system.ErrnoException;
+    method public static void msync(long, long, int) throws android.system.ErrnoException;
+    method public static void munlock(long, long) throws android.system.ErrnoException;
+    method public static void munmap(long, long) throws android.system.ErrnoException;
+    method public static java.io.FileDescriptor open(java.lang.String, int, int) throws android.system.ErrnoException;
+    method public static java.io.FileDescriptor[] pipe() throws android.system.ErrnoException;
+    method public static int poll(android.system.StructPollfd[], int) throws android.system.ErrnoException;
+    method public static void posix_fallocate(java.io.FileDescriptor, long, long) throws android.system.ErrnoException;
+    method public static int prctl(int, long, long, long, long) throws android.system.ErrnoException;
+    method public static int pread(java.io.FileDescriptor, java.nio.ByteBuffer, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int pread(java.io.FileDescriptor, byte[], int, int, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int pwrite(java.io.FileDescriptor, java.nio.ByteBuffer, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int pwrite(java.io.FileDescriptor, byte[], int, int, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int read(java.io.FileDescriptor, java.nio.ByteBuffer) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int read(java.io.FileDescriptor, byte[], int, int) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static java.lang.String readlink(java.lang.String) throws android.system.ErrnoException;
+    method public static int readv(java.io.FileDescriptor, java.lang.Object[], int[], int[]) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int recvfrom(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
+    method public static int recvfrom(java.io.FileDescriptor, byte[], int, int, int, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
+    method public static void remove(java.lang.String) throws android.system.ErrnoException;
+    method public static void rename(java.lang.String, java.lang.String) throws android.system.ErrnoException;
+    method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.util.MutableLong, long) throws android.system.ErrnoException;
+    method public static int sendto(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
+    method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
+    method public static void setegid(int) throws android.system.ErrnoException;
+    method public static void setenv(java.lang.String, java.lang.String, boolean) throws android.system.ErrnoException;
+    method public static void seteuid(int) throws android.system.ErrnoException;
+    method public static void setgid(int) throws android.system.ErrnoException;
+    method public static int setsid() throws android.system.ErrnoException;
+    method public static void setuid(int) throws android.system.ErrnoException;
+    method public static void shutdown(java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method public static java.io.FileDescriptor socket(int, int, int) throws android.system.ErrnoException;
+    method public static void socketpair(int, int, int, java.io.FileDescriptor, java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static android.system.StructStat stat(java.lang.String) throws android.system.ErrnoException;
+    method public static android.system.StructStatVfs statvfs(java.lang.String) throws android.system.ErrnoException;
+    method public static java.lang.String strerror(int);
+    method public static java.lang.String strsignal(int);
+    method public static void symlink(java.lang.String, java.lang.String) throws android.system.ErrnoException;
+    method public static long sysconf(int);
+    method public static void tcdrain(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static void tcsendbreak(java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method public static int umask(int);
+    method public static android.system.StructUtsname uname();
+    method public static void unsetenv(java.lang.String) throws android.system.ErrnoException;
+    method public static int waitpid(int, android.util.MutableInt, int) throws android.system.ErrnoException;
+    method public static int write(java.io.FileDescriptor, java.nio.ByteBuffer) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int write(java.io.FileDescriptor, byte[], int, int) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int writev(java.io.FileDescriptor, java.lang.Object[], int[], int[]) throws android.system.ErrnoException, java.io.InterruptedIOException;
+  }
+
+  public final class OsConstants {
+    method public static boolean S_ISBLK(int);
+    method public static boolean S_ISCHR(int);
+    method public static boolean S_ISDIR(int);
+    method public static boolean S_ISFIFO(int);
+    method public static boolean S_ISLNK(int);
+    method public static boolean S_ISREG(int);
+    method public static boolean S_ISSOCK(int);
+    method public static boolean WCOREDUMP(int);
+    method public static int WEXITSTATUS(int);
+    method public static boolean WIFEXITED(int);
+    method public static boolean WIFSIGNALED(int);
+    method public static boolean WIFSTOPPED(int);
+    method public static int WSTOPSIG(int);
+    method public static int WTERMSIG(int);
+    method public static java.lang.String errnoName(int);
+    method public static java.lang.String gaiName(int);
+    field public static final int AF_INET;
+    field public static final int AF_INET6;
+    field public static final int AF_UNIX;
+    field public static final int AF_UNSPEC;
+    field public static final int AI_ADDRCONFIG;
+    field public static final int AI_ALL;
+    field public static final int AI_CANONNAME;
+    field public static final int AI_NUMERICHOST;
+    field public static final int AI_NUMERICSERV;
+    field public static final int AI_PASSIVE;
+    field public static final int AI_V4MAPPED;
+    field public static final int CAP_AUDIT_CONTROL;
+    field public static final int CAP_AUDIT_WRITE;
+    field public static final int CAP_BLOCK_SUSPEND;
+    field public static final int CAP_CHOWN;
+    field public static final int CAP_DAC_OVERRIDE;
+    field public static final int CAP_DAC_READ_SEARCH;
+    field public static final int CAP_FOWNER;
+    field public static final int CAP_FSETID;
+    field public static final int CAP_IPC_LOCK;
+    field public static final int CAP_IPC_OWNER;
+    field public static final int CAP_KILL;
+    field public static final int CAP_LAST_CAP;
+    field public static final int CAP_LEASE;
+    field public static final int CAP_LINUX_IMMUTABLE;
+    field public static final int CAP_MAC_ADMIN;
+    field public static final int CAP_MAC_OVERRIDE;
+    field public static final int CAP_MKNOD;
+    field public static final int CAP_NET_ADMIN;
+    field public static final int CAP_NET_BIND_SERVICE;
+    field public static final int CAP_NET_BROADCAST;
+    field public static final int CAP_NET_RAW;
+    field public static final int CAP_SETFCAP;
+    field public static final int CAP_SETGID;
+    field public static final int CAP_SETPCAP;
+    field public static final int CAP_SETUID;
+    field public static final int CAP_SYSLOG;
+    field public static final int CAP_SYS_ADMIN;
+    field public static final int CAP_SYS_BOOT;
+    field public static final int CAP_SYS_CHROOT;
+    field public static final int CAP_SYS_MODULE;
+    field public static final int CAP_SYS_NICE;
+    field public static final int CAP_SYS_PACCT;
+    field public static final int CAP_SYS_PTRACE;
+    field public static final int CAP_SYS_RAWIO;
+    field public static final int CAP_SYS_RESOURCE;
+    field public static final int CAP_SYS_TIME;
+    field public static final int CAP_SYS_TTY_CONFIG;
+    field public static final int CAP_WAKE_ALARM;
+    field public static final int E2BIG;
+    field public static final int EACCES;
+    field public static final int EADDRINUSE;
+    field public static final int EADDRNOTAVAIL;
+    field public static final int EAFNOSUPPORT;
+    field public static final int EAGAIN;
+    field public static final int EAI_AGAIN;
+    field public static final int EAI_BADFLAGS;
+    field public static final int EAI_FAIL;
+    field public static final int EAI_FAMILY;
+    field public static final int EAI_MEMORY;
+    field public static final int EAI_NODATA;
+    field public static final int EAI_NONAME;
+    field public static final int EAI_OVERFLOW;
+    field public static final int EAI_SERVICE;
+    field public static final int EAI_SOCKTYPE;
+    field public static final int EAI_SYSTEM;
+    field public static final int EALREADY;
+    field public static final int EBADF;
+    field public static final int EBADMSG;
+    field public static final int EBUSY;
+    field public static final int ECANCELED;
+    field public static final int ECHILD;
+    field public static final int ECONNABORTED;
+    field public static final int ECONNREFUSED;
+    field public static final int ECONNRESET;
+    field public static final int EDEADLK;
+    field public static final int EDESTADDRREQ;
+    field public static final int EDOM;
+    field public static final int EDQUOT;
+    field public static final int EEXIST;
+    field public static final int EFAULT;
+    field public static final int EFBIG;
+    field public static final int EHOSTUNREACH;
+    field public static final int EIDRM;
+    field public static final int EILSEQ;
+    field public static final int EINPROGRESS;
+    field public static final int EINTR;
+    field public static final int EINVAL;
+    field public static final int EIO;
+    field public static final int EISCONN;
+    field public static final int EISDIR;
+    field public static final int ELOOP;
+    field public static final int EMFILE;
+    field public static final int EMLINK;
+    field public static final int EMSGSIZE;
+    field public static final int EMULTIHOP;
+    field public static final int ENAMETOOLONG;
+    field public static final int ENETDOWN;
+    field public static final int ENETRESET;
+    field public static final int ENETUNREACH;
+    field public static final int ENFILE;
+    field public static final int ENOBUFS;
+    field public static final int ENODATA;
+    field public static final int ENODEV;
+    field public static final int ENOENT;
+    field public static final int ENOEXEC;
+    field public static final int ENOLCK;
+    field public static final int ENOLINK;
+    field public static final int ENOMEM;
+    field public static final int ENOMSG;
+    field public static final int ENOPROTOOPT;
+    field public static final int ENOSPC;
+    field public static final int ENOSR;
+    field public static final int ENOSTR;
+    field public static final int ENOSYS;
+    field public static final int ENOTCONN;
+    field public static final int ENOTDIR;
+    field public static final int ENOTEMPTY;
+    field public static final int ENOTSOCK;
+    field public static final int ENOTSUP;
+    field public static final int ENOTTY;
+    field public static final int ENXIO;
+    field public static final int EOPNOTSUPP;
+    field public static final int EOVERFLOW;
+    field public static final int EPERM;
+    field public static final int EPIPE;
+    field public static final int EPROTO;
+    field public static final int EPROTONOSUPPORT;
+    field public static final int EPROTOTYPE;
+    field public static final int ERANGE;
+    field public static final int EROFS;
+    field public static final int ESPIPE;
+    field public static final int ESRCH;
+    field public static final int ESTALE;
+    field public static final int ETIME;
+    field public static final int ETIMEDOUT;
+    field public static final int ETXTBSY;
+    field public static final int EXDEV;
+    field public static final int EXIT_FAILURE;
+    field public static final int EXIT_SUCCESS;
+    field public static final int FD_CLOEXEC;
+    field public static final int FIONREAD;
+    field public static final int F_DUPFD;
+    field public static final int F_GETFD;
+    field public static final int F_GETFL;
+    field public static final int F_GETLK;
+    field public static final int F_GETLK64;
+    field public static final int F_GETOWN;
+    field public static final int F_OK;
+    field public static final int F_RDLCK;
+    field public static final int F_SETFD;
+    field public static final int F_SETFL;
+    field public static final int F_SETLK;
+    field public static final int F_SETLK64;
+    field public static final int F_SETLKW;
+    field public static final int F_SETLKW64;
+    field public static final int F_SETOWN;
+    field public static final int F_UNLCK;
+    field public static final int F_WRLCK;
+    field public static final int IFA_F_DADFAILED;
+    field public static final int IFA_F_DEPRECATED;
+    field public static final int IFA_F_HOMEADDRESS;
+    field public static final int IFA_F_NODAD;
+    field public static final int IFA_F_OPTIMISTIC;
+    field public static final int IFA_F_PERMANENT;
+    field public static final int IFA_F_SECONDARY;
+    field public static final int IFA_F_TEMPORARY;
+    field public static final int IFA_F_TENTATIVE;
+    field public static final int IFF_ALLMULTI;
+    field public static final int IFF_AUTOMEDIA;
+    field public static final int IFF_BROADCAST;
+    field public static final int IFF_DEBUG;
+    field public static final int IFF_DYNAMIC;
+    field public static final int IFF_LOOPBACK;
+    field public static final int IFF_MASTER;
+    field public static final int IFF_MULTICAST;
+    field public static final int IFF_NOARP;
+    field public static final int IFF_NOTRAILERS;
+    field public static final int IFF_POINTOPOINT;
+    field public static final int IFF_PORTSEL;
+    field public static final int IFF_PROMISC;
+    field public static final int IFF_RUNNING;
+    field public static final int IFF_SLAVE;
+    field public static final int IFF_UP;
+    field public static final int IPPROTO_ICMP;
+    field public static final int IPPROTO_ICMPV6;
+    field public static final int IPPROTO_IP;
+    field public static final int IPPROTO_IPV6;
+    field public static final int IPPROTO_RAW;
+    field public static final int IPPROTO_TCP;
+    field public static final int IPPROTO_UDP;
+    field public static final int IPV6_CHECKSUM;
+    field public static final int IPV6_MULTICAST_HOPS;
+    field public static final int IPV6_MULTICAST_IF;
+    field public static final int IPV6_MULTICAST_LOOP;
+    field public static final int IPV6_RECVDSTOPTS;
+    field public static final int IPV6_RECVHOPLIMIT;
+    field public static final int IPV6_RECVHOPOPTS;
+    field public static final int IPV6_RECVPKTINFO;
+    field public static final int IPV6_RECVRTHDR;
+    field public static final int IPV6_RECVTCLASS;
+    field public static final int IPV6_TCLASS;
+    field public static final int IPV6_UNICAST_HOPS;
+    field public static final int IPV6_V6ONLY;
+    field public static final int IP_MULTICAST_IF;
+    field public static final int IP_MULTICAST_LOOP;
+    field public static final int IP_MULTICAST_TTL;
+    field public static final int IP_TOS;
+    field public static final int IP_TTL;
+    field public static final int MAP_FIXED;
+    field public static final int MAP_PRIVATE;
+    field public static final int MAP_SHARED;
+    field public static final int MCAST_BLOCK_SOURCE;
+    field public static final int MCAST_JOIN_GROUP;
+    field public static final int MCAST_JOIN_SOURCE_GROUP;
+    field public static final int MCAST_LEAVE_GROUP;
+    field public static final int MCAST_LEAVE_SOURCE_GROUP;
+    field public static final int MCAST_UNBLOCK_SOURCE;
+    field public static final int MCL_CURRENT;
+    field public static final int MCL_FUTURE;
+    field public static final int MSG_CTRUNC;
+    field public static final int MSG_DONTROUTE;
+    field public static final int MSG_EOR;
+    field public static final int MSG_OOB;
+    field public static final int MSG_PEEK;
+    field public static final int MSG_TRUNC;
+    field public static final int MSG_WAITALL;
+    field public static final int MS_ASYNC;
+    field public static final int MS_INVALIDATE;
+    field public static final int MS_SYNC;
+    field public static final int NI_DGRAM;
+    field public static final int NI_NAMEREQD;
+    field public static final int NI_NOFQDN;
+    field public static final int NI_NUMERICHOST;
+    field public static final int NI_NUMERICSERV;
+    field public static final int O_ACCMODE;
+    field public static final int O_APPEND;
+    field public static final int O_CREAT;
+    field public static final int O_EXCL;
+    field public static final int O_NOCTTY;
+    field public static final int O_NOFOLLOW;
+    field public static final int O_NONBLOCK;
+    field public static final int O_RDONLY;
+    field public static final int O_RDWR;
+    field public static final int O_SYNC;
+    field public static final int O_TRUNC;
+    field public static final int O_WRONLY;
+    field public static final int POLLERR;
+    field public static final int POLLHUP;
+    field public static final int POLLIN;
+    field public static final int POLLNVAL;
+    field public static final int POLLOUT;
+    field public static final int POLLPRI;
+    field public static final int POLLRDBAND;
+    field public static final int POLLRDNORM;
+    field public static final int POLLWRBAND;
+    field public static final int POLLWRNORM;
+    field public static final int PROT_EXEC;
+    field public static final int PROT_NONE;
+    field public static final int PROT_READ;
+    field public static final int PROT_WRITE;
+    field public static final int PR_GET_DUMPABLE;
+    field public static final int PR_SET_DUMPABLE;
+    field public static final int PR_SET_NO_NEW_PRIVS;
+    field public static final int RT_SCOPE_HOST;
+    field public static final int RT_SCOPE_LINK;
+    field public static final int RT_SCOPE_NOWHERE;
+    field public static final int RT_SCOPE_SITE;
+    field public static final int RT_SCOPE_UNIVERSE;
+    field public static final int R_OK;
+    field public static final int SEEK_CUR;
+    field public static final int SEEK_END;
+    field public static final int SEEK_SET;
+    field public static final int SHUT_RD;
+    field public static final int SHUT_RDWR;
+    field public static final int SHUT_WR;
+    field public static final int SIGABRT;
+    field public static final int SIGALRM;
+    field public static final int SIGBUS;
+    field public static final int SIGCHLD;
+    field public static final int SIGCONT;
+    field public static final int SIGFPE;
+    field public static final int SIGHUP;
+    field public static final int SIGILL;
+    field public static final int SIGINT;
+    field public static final int SIGIO;
+    field public static final int SIGKILL;
+    field public static final int SIGPIPE;
+    field public static final int SIGPROF;
+    field public static final int SIGPWR;
+    field public static final int SIGQUIT;
+    field public static final int SIGRTMAX;
+    field public static final int SIGRTMIN;
+    field public static final int SIGSEGV;
+    field public static final int SIGSTKFLT;
+    field public static final int SIGSTOP;
+    field public static final int SIGSYS;
+    field public static final int SIGTERM;
+    field public static final int SIGTRAP;
+    field public static final int SIGTSTP;
+    field public static final int SIGTTIN;
+    field public static final int SIGTTOU;
+    field public static final int SIGURG;
+    field public static final int SIGUSR1;
+    field public static final int SIGUSR2;
+    field public static final int SIGVTALRM;
+    field public static final int SIGWINCH;
+    field public static final int SIGXCPU;
+    field public static final int SIGXFSZ;
+    field public static final int SIOCGIFADDR;
+    field public static final int SIOCGIFBRDADDR;
+    field public static final int SIOCGIFDSTADDR;
+    field public static final int SIOCGIFNETMASK;
+    field public static final int SOCK_DGRAM;
+    field public static final int SOCK_RAW;
+    field public static final int SOCK_SEQPACKET;
+    field public static final int SOCK_STREAM;
+    field public static final int SOL_SOCKET;
+    field public static final int SO_BINDTODEVICE;
+    field public static final int SO_BROADCAST;
+    field public static final int SO_DEBUG;
+    field public static final int SO_DONTROUTE;
+    field public static final int SO_ERROR;
+    field public static final int SO_KEEPALIVE;
+    field public static final int SO_LINGER;
+    field public static final int SO_OOBINLINE;
+    field public static final int SO_PASSCRED;
+    field public static final int SO_PEERCRED;
+    field public static final int SO_RCVBUF;
+    field public static final int SO_RCVLOWAT;
+    field public static final int SO_RCVTIMEO;
+    field public static final int SO_REUSEADDR;
+    field public static final int SO_SNDBUF;
+    field public static final int SO_SNDLOWAT;
+    field public static final int SO_SNDTIMEO;
+    field public static final int SO_TYPE;
+    field public static final int STDERR_FILENO;
+    field public static final int STDIN_FILENO;
+    field public static final int STDOUT_FILENO;
+    field public static final int S_IFBLK;
+    field public static final int S_IFCHR;
+    field public static final int S_IFDIR;
+    field public static final int S_IFIFO;
+    field public static final int S_IFLNK;
+    field public static final int S_IFMT;
+    field public static final int S_IFREG;
+    field public static final int S_IFSOCK;
+    field public static final int S_IRGRP;
+    field public static final int S_IROTH;
+    field public static final int S_IRUSR;
+    field public static final int S_IRWXG;
+    field public static final int S_IRWXO;
+    field public static final int S_IRWXU;
+    field public static final int S_ISGID;
+    field public static final int S_ISUID;
+    field public static final int S_ISVTX;
+    field public static final int S_IWGRP;
+    field public static final int S_IWOTH;
+    field public static final int S_IWUSR;
+    field public static final int S_IXGRP;
+    field public static final int S_IXOTH;
+    field public static final int S_IXUSR;
+    field public static final int TCP_NODELAY;
+    field public static final int WCONTINUED;
+    field public static final int WEXITED;
+    field public static final int WNOHANG;
+    field public static final int WNOWAIT;
+    field public static final int WSTOPPED;
+    field public static final int WUNTRACED;
+    field public static final int W_OK;
+    field public static final int X_OK;
+    field public static final int _SC_2_CHAR_TERM;
+    field public static final int _SC_2_C_BIND;
+    field public static final int _SC_2_C_DEV;
+    field public static final int _SC_2_C_VERSION;
+    field public static final int _SC_2_FORT_DEV;
+    field public static final int _SC_2_FORT_RUN;
+    field public static final int _SC_2_LOCALEDEF;
+    field public static final int _SC_2_SW_DEV;
+    field public static final int _SC_2_UPE;
+    field public static final int _SC_2_VERSION;
+    field public static final int _SC_AIO_LISTIO_MAX;
+    field public static final int _SC_AIO_MAX;
+    field public static final int _SC_AIO_PRIO_DELTA_MAX;
+    field public static final int _SC_ARG_MAX;
+    field public static final int _SC_ASYNCHRONOUS_IO;
+    field public static final int _SC_ATEXIT_MAX;
+    field public static final int _SC_AVPHYS_PAGES;
+    field public static final int _SC_BC_BASE_MAX;
+    field public static final int _SC_BC_DIM_MAX;
+    field public static final int _SC_BC_SCALE_MAX;
+    field public static final int _SC_BC_STRING_MAX;
+    field public static final int _SC_CHILD_MAX;
+    field public static final int _SC_CLK_TCK;
+    field public static final int _SC_COLL_WEIGHTS_MAX;
+    field public static final int _SC_DELAYTIMER_MAX;
+    field public static final int _SC_EXPR_NEST_MAX;
+    field public static final int _SC_FSYNC;
+    field public static final int _SC_GETGR_R_SIZE_MAX;
+    field public static final int _SC_GETPW_R_SIZE_MAX;
+    field public static final int _SC_IOV_MAX;
+    field public static final int _SC_JOB_CONTROL;
+    field public static final int _SC_LINE_MAX;
+    field public static final int _SC_LOGIN_NAME_MAX;
+    field public static final int _SC_MAPPED_FILES;
+    field public static final int _SC_MEMLOCK;
+    field public static final int _SC_MEMLOCK_RANGE;
+    field public static final int _SC_MEMORY_PROTECTION;
+    field public static final int _SC_MESSAGE_PASSING;
+    field public static final int _SC_MQ_OPEN_MAX;
+    field public static final int _SC_MQ_PRIO_MAX;
+    field public static final int _SC_NGROUPS_MAX;
+    field public static final int _SC_NPROCESSORS_CONF;
+    field public static final int _SC_NPROCESSORS_ONLN;
+    field public static final int _SC_OPEN_MAX;
+    field public static final int _SC_PAGESIZE;
+    field public static final int _SC_PAGE_SIZE;
+    field public static final int _SC_PASS_MAX;
+    field public static final int _SC_PHYS_PAGES;
+    field public static final int _SC_PRIORITIZED_IO;
+    field public static final int _SC_PRIORITY_SCHEDULING;
+    field public static final int _SC_REALTIME_SIGNALS;
+    field public static final int _SC_RE_DUP_MAX;
+    field public static final int _SC_RTSIG_MAX;
+    field public static final int _SC_SAVED_IDS;
+    field public static final int _SC_SEMAPHORES;
+    field public static final int _SC_SEM_NSEMS_MAX;
+    field public static final int _SC_SEM_VALUE_MAX;
+    field public static final int _SC_SHARED_MEMORY_OBJECTS;
+    field public static final int _SC_SIGQUEUE_MAX;
+    field public static final int _SC_STREAM_MAX;
+    field public static final int _SC_SYNCHRONIZED_IO;
+    field public static final int _SC_THREADS;
+    field public static final int _SC_THREAD_ATTR_STACKADDR;
+    field public static final int _SC_THREAD_ATTR_STACKSIZE;
+    field public static final int _SC_THREAD_DESTRUCTOR_ITERATIONS;
+    field public static final int _SC_THREAD_KEYS_MAX;
+    field public static final int _SC_THREAD_PRIORITY_SCHEDULING;
+    field public static final int _SC_THREAD_PRIO_INHERIT;
+    field public static final int _SC_THREAD_PRIO_PROTECT;
+    field public static final int _SC_THREAD_SAFE_FUNCTIONS;
+    field public static final int _SC_THREAD_STACK_MIN;
+    field public static final int _SC_THREAD_THREADS_MAX;
+    field public static final int _SC_TIMERS;
+    field public static final int _SC_TIMER_MAX;
+    field public static final int _SC_TTY_NAME_MAX;
+    field public static final int _SC_TZNAME_MAX;
+    field public static final int _SC_VERSION;
+    field public static final int _SC_XBS5_ILP32_OFF32;
+    field public static final int _SC_XBS5_ILP32_OFFBIG;
+    field public static final int _SC_XBS5_LP64_OFF64;
+    field public static final int _SC_XBS5_LPBIG_OFFBIG;
+    field public static final int _SC_XOPEN_CRYPT;
+    field public static final int _SC_XOPEN_ENH_I18N;
+    field public static final int _SC_XOPEN_LEGACY;
+    field public static final int _SC_XOPEN_REALTIME;
+    field public static final int _SC_XOPEN_REALTIME_THREADS;
+    field public static final int _SC_XOPEN_SHM;
+    field public static final int _SC_XOPEN_UNIX;
+    field public static final int _SC_XOPEN_VERSION;
+    field public static final int _SC_XOPEN_XCU_VERSION;
+  }
+
+  public final class StructPollfd {
+    ctor public StructPollfd();
+    field public short events;
+    field public java.io.FileDescriptor fd;
+    field public short revents;
+    field public java.lang.Object userData;
+  }
+
+  public final class StructStat {
+    ctor public StructStat(long, long, int, long, int, int, long, long, long, long, long, long, long);
+    field public final long st_atime;
+    field public final long st_blksize;
+    field public final long st_blocks;
+    field public final long st_ctime;
+    field public final long st_dev;
+    field public final int st_gid;
+    field public final long st_ino;
+    field public final int st_mode;
+    field public final long st_mtime;
+    field public final long st_nlink;
+    field public final long st_rdev;
+    field public final long st_size;
+    field public final int st_uid;
+  }
+
+  public final class StructStatVfs {
+    ctor public StructStatVfs(long, long, long, long, long, long, long, long, long, long, long);
+    field public final long f_bavail;
+    field public final long f_bfree;
+    field public final long f_blocks;
+    field public final long f_bsize;
+    field public final long f_favail;
+    field public final long f_ffree;
+    field public final long f_files;
+    field public final long f_flag;
+    field public final long f_frsize;
+    field public final long f_fsid;
+    field public final long f_namemax;
+  }
+
+  public final class StructUtsname {
+    ctor public StructUtsname(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+    field public final java.lang.String machine;
+    field public final java.lang.String nodename;
+    field public final java.lang.String release;
+    field public final java.lang.String sysname;
+    field public final java.lang.String version;
+  }
+
+}
+
+package android.telecom {
+
+  public class TelecomManager {
+    method public void cancelMissedCallsNotification();
+    method public boolean handleMmi(java.lang.String);
+    method public boolean isInCall();
+    method public void showInCallScreen(boolean);
+    field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
+    field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
+    field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
+    field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
+    field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
+    field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
+    field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
+    field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
+    field public static final int PRESENTATION_ALLOWED = 1; // 0x1
+    field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
+    field public static final int PRESENTATION_RESTRICTED = 2; // 0x2
+    field public static final int PRESENTATION_UNKNOWN = 3; // 0x3
+  }
+
 }
 
 package android.telephony {
@@ -23342,6 +28208,20 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
+  public class IccOpenLogicalChannelResponse implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getChannel();
+    method public byte[] getSelectResponse();
+    method public int getStatus();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int INVALID_CHANNEL = -1; // 0xffffffff
+    field public static final int STATUS_MISSING_RESOURCE = 2; // 0x2
+    field public static final int STATUS_NO_ERROR = 1; // 0x1
+    field public static final int STATUS_NO_SUCH_ELEMENT = 3; // 0x3
+    field public static final int STATUS_UNKNOWN_ERROR = 4; // 0x4
+  }
+
   public class NeighboringCellInfo implements android.os.Parcelable {
     ctor public deprecated NeighboringCellInfo();
     ctor public deprecated NeighboringCellInfo(int, int);
@@ -23363,6 +28243,7 @@
 
   public class PhoneNumberFormattingTextWatcher implements android.text.TextWatcher {
     ctor public PhoneNumberFormattingTextWatcher();
+    ctor public PhoneNumberFormattingTextWatcher(java.lang.String);
     method public synchronized void afterTextChanged(android.text.Editable);
     method public void beforeTextChanged(java.lang.CharSequence, int, int, int);
     method public void onTextChanged(java.lang.CharSequence, int, int, int);
@@ -23377,11 +28258,14 @@
     method public static java.lang.String convertKeypadLettersToDigits(java.lang.String);
     method public static java.lang.String extractNetworkPortion(java.lang.String);
     method public static java.lang.String extractPostDialPortion(java.lang.String);
-    method public static void formatJapaneseNumber(android.text.Editable);
-    method public static void formatNanpNumber(android.text.Editable);
-    method public static java.lang.String formatNumber(java.lang.String);
-    method public static void formatNumber(android.text.Editable, int);
-    method public static int getFormatTypeForLocale(java.util.Locale);
+    method public static deprecated void formatJapaneseNumber(android.text.Editable);
+    method public static deprecated void formatNanpNumber(android.text.Editable);
+    method public static deprecated java.lang.String formatNumber(java.lang.String);
+    method public static deprecated void formatNumber(android.text.Editable, int);
+    method public static java.lang.String formatNumber(java.lang.String, java.lang.String);
+    method public static java.lang.String formatNumber(java.lang.String, java.lang.String, java.lang.String);
+    method public static java.lang.String formatNumberToE164(java.lang.String, java.lang.String);
+    method public static deprecated int getFormatTypeForLocale(java.util.Locale);
     method public static java.lang.String getNumberFromIntent(android.content.Intent, android.content.Context);
     method public static java.lang.String getStrippedReversed(java.lang.String);
     method public static final boolean is12Key(char);
@@ -23389,13 +28273,17 @@
     method public static boolean isEmergencyNumber(java.lang.String);
     method public static boolean isGlobalPhoneNumber(java.lang.String);
     method public static boolean isISODigit(char);
+    method public static boolean isLocalEmergencyNumber(android.content.Context, java.lang.String);
     method public static final boolean isNonSeparator(char);
     method public static final boolean isReallyDialable(char);
     method public static final boolean isStartsPostDial(char);
+    method public static boolean isVoiceMailNumber(java.lang.String);
     method public static boolean isWellFormedSmsAddress(java.lang.String);
     method public static byte[] networkPortionToCalledPartyBCD(java.lang.String);
     method public static byte[] networkPortionToCalledPartyBCDWithLength(java.lang.String);
+    method public static java.lang.String normalizeNumber(java.lang.String);
     method public static byte[] numberToCalledPartyBCD(java.lang.String);
+    method public static java.lang.String replaceUnicodeDigits(java.lang.String);
     method public static java.lang.String stringFromStringAndTOA(java.lang.String, int);
     method public static java.lang.String stripSeparators(java.lang.String);
     method public static java.lang.String toCallerIDMinMatch(java.lang.String);
@@ -23477,10 +28365,50 @@
 
   public final class SmsManager {
     method public java.util.ArrayList<java.lang.String> divideMessage(java.lang.String);
+    method public void downloadMultimediaMessage(android.content.Context, java.lang.String, android.net.Uri, android.os.Bundle, android.app.PendingIntent);
+    method public android.os.Bundle getCarrierConfigValues();
     method public static android.telephony.SmsManager getDefault();
     method public void sendDataMessage(java.lang.String, java.lang.String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
+    method public void sendMultimediaMessage(android.content.Context, android.net.Uri, java.lang.String, android.os.Bundle, android.app.PendingIntent);
     method public void sendMultipartTextMessage(java.lang.String, java.lang.String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
     method public void sendTextMessage(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
+    field public static final java.lang.String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
+    field public static final java.lang.String MMS_CONFIG_ALIAS_ENABLED = "aliasEnabled";
+    field public static final java.lang.String MMS_CONFIG_ALIAS_MAX_CHARS = "aliasMaxChars";
+    field public static final java.lang.String MMS_CONFIG_ALIAS_MIN_CHARS = "aliasMinChars";
+    field public static final java.lang.String MMS_CONFIG_ALLOW_ATTACH_AUDIO = "allowAttachAudio";
+    field public static final java.lang.String MMS_CONFIG_APPEND_TRANSACTION_ID = "enabledTransID";
+    field public static final java.lang.String MMS_CONFIG_EMAIL_GATEWAY_NUMBER = "emailGatewayNumber";
+    field public static final java.lang.String MMS_CONFIG_GROUP_MMS_ENABLED = "enableGroupMms";
+    field public static final java.lang.String MMS_CONFIG_HTTP_PARAMS = "httpParams";
+    field public static final java.lang.String MMS_CONFIG_HTTP_SOCKET_TIMEOUT = "httpSocketTimeout";
+    field public static final java.lang.String MMS_CONFIG_MAX_IMAGE_HEIGHT = "maxImageHeight";
+    field public static final java.lang.String MMS_CONFIG_MAX_IMAGE_WIDTH = "maxImageWidth";
+    field public static final java.lang.String MMS_CONFIG_MAX_MESSAGE_SIZE = "maxMessageSize";
+    field public static final java.lang.String MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE = "maxMessageTextSize";
+    field public static final java.lang.String MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED = "enableMMSDeliveryReports";
+    field public static final java.lang.String MMS_CONFIG_MMS_ENABLED = "enabledMMS";
+    field public static final java.lang.String MMS_CONFIG_MMS_READ_REPORT_ENABLED = "enableMMSReadReports";
+    field public static final java.lang.String MMS_CONFIG_MULTIPART_SMS_ENABLED = "enableMultipartSMS";
+    field public static final java.lang.String MMS_CONFIG_NAI_SUFFIX = "naiSuffix";
+    field public static final java.lang.String MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED = "enabledNotifyWapMMSC";
+    field public static final java.lang.String MMS_CONFIG_RECIPIENT_LIMIT = "recipientLimit";
+    field public static final java.lang.String MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES = "sendMultipartSmsAsSeparateMessages";
+    field public static final java.lang.String MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED = "enableSMSDeliveryReports";
+    field public static final java.lang.String MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD = "smsToMmsTextLengthThreshold";
+    field public static final java.lang.String MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD = "smsToMmsTextThreshold";
+    field public static final java.lang.String MMS_CONFIG_SUBJECT_MAX_LENGTH = "maxSubjectLength";
+    field public static final java.lang.String MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION = "supportMmsContentDisposition";
+    field public static final java.lang.String MMS_CONFIG_UA_PROF_TAG_NAME = "uaProfTagName";
+    field public static final java.lang.String MMS_CONFIG_UA_PROF_URL = "uaProfUrl";
+    field public static final java.lang.String MMS_CONFIG_USER_AGENT = "userAgent";
+    field public static final int MMS_ERROR_CONFIGURATION_ERROR = 7; // 0x7
+    field public static final int MMS_ERROR_HTTP_FAILURE = 4; // 0x4
+    field public static final int MMS_ERROR_INVALID_APN = 2; // 0x2
+    field public static final int MMS_ERROR_IO_ERROR = 5; // 0x5
+    field public static final int MMS_ERROR_RETRY = 6; // 0x6
+    field public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3; // 0x3
+    field public static final int MMS_ERROR_UNSPECIFIED = 1; // 0x1
     field public static final int RESULT_ERROR_GENERIC_FAILURE = 1; // 0x1
     field public static final int RESULT_ERROR_NO_SERVICE = 4; // 0x4
     field public static final int RESULT_ERROR_NULL_PDU = 3; // 0x3
@@ -23577,8 +28505,15 @@
     method public java.lang.String getVoiceMailAlphaTag();
     method public java.lang.String getVoiceMailNumber();
     method public boolean hasIccCard();
+    method public boolean iccCloseLogicalChannel(int);
+    method public byte[] iccExchangeSimIO(int, int, int, int, int, java.lang.String);
+    method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
+    method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
+    method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
     method public boolean isNetworkRoaming();
+    method public boolean isSmsCapable();
     method public void listen(android.telephony.PhoneStateListener, int);
+    method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
     field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
     field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
     field public static final int CALL_STATE_IDLE = 0; // 0x0
@@ -24097,6 +29032,7 @@
     method public android.content.res.AssetManager getAssets();
     method public java.io.File getCacheDir();
     method public java.lang.ClassLoader getClassLoader();
+    method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
     method public java.io.File getDatabasePath(java.lang.String);
     method public java.io.File getDir(java.lang.String, int);
@@ -24104,9 +29040,11 @@
     method public java.io.File[] getExternalCacheDirs();
     method public java.io.File getExternalFilesDir(java.lang.String);
     method public java.io.File[] getExternalFilesDirs(java.lang.String);
+    method public java.io.File[] getExternalMediaDirs();
     method public java.io.File getFileStreamPath(java.lang.String);
     method public java.io.File getFilesDir();
     method public android.os.Looper getMainLooper();
+    method public java.io.File getNoBackupFilesDir();
     method public java.io.File getObbDir();
     method public java.io.File[] getObbDirs();
     method public java.lang.String getPackageCodePath();
@@ -24246,9 +29184,11 @@
     method public java.lang.String getInstallerPackageName(java.lang.String);
     method public android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.content.Intent getLaunchIntentForPackage(java.lang.String);
+    method public android.content.Intent getLeanbackLaunchIntentForPackage(java.lang.String);
     method public java.lang.String getNameForUid(int);
     method public int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public android.content.pm.PackageInstaller getPackageInstaller();
     method public java.lang.String[] getPackagesForUid(int);
     method public java.util.List<android.content.pm.PackageInfo> getPackagesHoldingPermissions(java.lang.String[], int);
     method public android.content.pm.PermissionGroupInfo getPermissionGroupInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -24264,6 +29204,9 @@
     method public android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
     method public java.lang.String[] getSystemSharedLibraryNames();
     method public java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
+    method public android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(android.graphics.drawable.Drawable, android.os.UserHandle, android.graphics.Rect, int);
+    method public android.graphics.drawable.Drawable getUserBadgedIcon(android.graphics.drawable.Drawable, android.os.UserHandle);
+    method public java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public boolean hasSystemFeature(java.lang.String);
     method public boolean isSafeMode();
@@ -24510,6 +29453,7 @@
   public static class InputFilter.LengthFilter implements android.text.InputFilter {
     ctor public InputFilter.LengthFilter(int);
     method public java.lang.CharSequence filter(java.lang.CharSequence, int, int, android.text.Spanned, int, int);
+    method public int getMax();
   }
 
   public abstract interface InputType {
@@ -24709,6 +29653,7 @@
     ctor public SpannableStringBuilder(java.lang.CharSequence);
     ctor public SpannableStringBuilder(java.lang.CharSequence, int, int);
     method public android.text.SpannableStringBuilder append(java.lang.CharSequence);
+    method public android.text.SpannableStringBuilder append(java.lang.CharSequence, java.lang.Object, int);
     method public android.text.SpannableStringBuilder append(java.lang.CharSequence, int, int);
     method public android.text.SpannableStringBuilder append(char);
     method public char charAt(int);
@@ -25633,6 +30578,227 @@
     method public void writeToParcel(android.os.Parcel, int);
   }
 
+  public class TtsSpan implements android.text.ParcelableSpan {
+    ctor public TtsSpan(java.lang.String, android.os.PersistableBundle);
+    ctor public TtsSpan(android.os.Parcel);
+    method public int describeContents();
+    method public android.os.PersistableBundle getArgs();
+    method public int getSpanTypeId();
+    method public java.lang.String getType();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String ANIMACY_ANIMATE = "android.animate";
+    field public static final java.lang.String ANIMACY_INANIMATE = "android.inanimate";
+    field public static final java.lang.String ARG_ANIMACY = "android.arg.animacy";
+    field public static final java.lang.String ARG_CASE = "android.arg.case";
+    field public static final java.lang.String ARG_COUNTRY_CODE = "android.arg.country_code";
+    field public static final java.lang.String ARG_CURRENCY = "android.arg.money";
+    field public static final java.lang.String ARG_DAY = "android.arg.day";
+    field public static final java.lang.String ARG_DENOMINATOR = "android.arg.denominator";
+    field public static final java.lang.String ARG_DIGITS = "android.arg.digits";
+    field public static final java.lang.String ARG_DOMAIN = "android.arg.domain";
+    field public static final java.lang.String ARG_EXTENSION = "android.arg.extension";
+    field public static final java.lang.String ARG_FRACTIONAL_PART = "android.arg.fractional_part";
+    field public static final java.lang.String ARG_FRAGMENT_ID = "android.arg.fragment_id";
+    field public static final java.lang.String ARG_GENDER = "android.arg.gender";
+    field public static final java.lang.String ARG_HOURS = "android.arg.hours";
+    field public static final java.lang.String ARG_INTEGER_PART = "android.arg.integer_part";
+    field public static final java.lang.String ARG_MINUTES = "android.arg.minutes";
+    field public static final java.lang.String ARG_MONTH = "android.arg.month";
+    field public static final java.lang.String ARG_MULTIPLICITY = "android.arg.multiplicity";
+    field public static final java.lang.String ARG_NUMBER = "android.arg.number";
+    field public static final java.lang.String ARG_NUMBER_PARTS = "android.arg.number_parts";
+    field public static final java.lang.String ARG_NUMERATOR = "android.arg.numerator";
+    field public static final java.lang.String ARG_PASSWORD = "android.arg.password";
+    field public static final java.lang.String ARG_PATH = "android.arg.path";
+    field public static final java.lang.String ARG_PORT = "android.arg.port";
+    field public static final java.lang.String ARG_PROTOCOL = "android.arg.protocol";
+    field public static final java.lang.String ARG_QUANTITY = "android.arg.quantity";
+    field public static final java.lang.String ARG_QUERY_STRING = "android.arg.query_string";
+    field public static final java.lang.String ARG_TEXT = "android.arg.text";
+    field public static final java.lang.String ARG_UNIT = "android.arg.unit";
+    field public static final java.lang.String ARG_USERNAME = "android.arg.username";
+    field public static final java.lang.String ARG_VERBATIM = "android.arg.verbatim";
+    field public static final java.lang.String ARG_WEEKDAY = "android.arg.weekday";
+    field public static final java.lang.String ARG_YEAR = "android.arg.year";
+    field public static final java.lang.String CASE_ABLATIVE = "android.ablative";
+    field public static final java.lang.String CASE_ACCUSATIVE = "android.accusative";
+    field public static final java.lang.String CASE_DATIVE = "android.dative";
+    field public static final java.lang.String CASE_GENITIVE = "android.genitive";
+    field public static final java.lang.String CASE_INSTRUMENTAL = "android.instrumental";
+    field public static final java.lang.String CASE_LOCATIVE = "android.locative";
+    field public static final java.lang.String CASE_NOMINATIVE = "android.nominative";
+    field public static final java.lang.String CASE_VOCATIVE = "android.vocative";
+    field public static final java.lang.String GENDER_FEMALE = "android.female";
+    field public static final java.lang.String GENDER_MALE = "android.male";
+    field public static final java.lang.String GENDER_NEUTRAL = "android.neutral";
+    field public static final int MONTH_APRIL = 3; // 0x3
+    field public static final int MONTH_AUGUST = 7; // 0x7
+    field public static final int MONTH_DECEMBER = 11; // 0xb
+    field public static final int MONTH_FEBRUARY = 1; // 0x1
+    field public static final int MONTH_JANUARY = 0; // 0x0
+    field public static final int MONTH_JULY = 6; // 0x6
+    field public static final int MONTH_JUNE = 5; // 0x5
+    field public static final int MONTH_MARCH = 2; // 0x2
+    field public static final int MONTH_MAY = 4; // 0x4
+    field public static final int MONTH_NOVEMBER = 10; // 0xa
+    field public static final int MONTH_OCTOBER = 9; // 0x9
+    field public static final int MONTH_SEPTEMBER = 8; // 0x8
+    field public static final java.lang.String MULTIPLICITY_DUAL = "android.dual";
+    field public static final java.lang.String MULTIPLICITY_PLURAL = "android.plural";
+    field public static final java.lang.String MULTIPLICITY_SINGLE = "android.single";
+    field public static final java.lang.String TYPE_CARDINAL = "android.type.cardinal";
+    field public static final java.lang.String TYPE_DATE = "android.type.date";
+    field public static final java.lang.String TYPE_DECIMAL = "android.type.decimal";
+    field public static final java.lang.String TYPE_DIGITS = "android.type.digits";
+    field public static final java.lang.String TYPE_ELECTRONIC = "android.type.electronic";
+    field public static final java.lang.String TYPE_FRACTION = "android.type.fraction";
+    field public static final java.lang.String TYPE_MEASURE = "android.type.measure";
+    field public static final java.lang.String TYPE_MONEY = "android.type.money";
+    field public static final java.lang.String TYPE_ORDINAL = "android.type.ordinal";
+    field public static final java.lang.String TYPE_TELEPHONE = "android.type.telephone";
+    field public static final java.lang.String TYPE_TEXT = "android.type.text";
+    field public static final java.lang.String TYPE_TIME = "android.type.time";
+    field public static final java.lang.String TYPE_VERBATIM = "android.type.verbatim";
+    field public static final int WEEKDAY_FRIDAY = 6; // 0x6
+    field public static final int WEEKDAY_MONDAY = 2; // 0x2
+    field public static final int WEEKDAY_SATURDAY = 7; // 0x7
+    field public static final int WEEKDAY_SUNDAY = 1; // 0x1
+    field public static final int WEEKDAY_THURSDAY = 5; // 0x5
+    field public static final int WEEKDAY_TUESDAY = 3; // 0x3
+    field public static final int WEEKDAY_WEDNESDAY = 4; // 0x4
+  }
+
+  public static class TtsSpan.Builder {
+    ctor public TtsSpan.Builder(java.lang.String);
+    method public android.text.style.TtsSpan build();
+    method public C setIntArgument(java.lang.String, int);
+    method public C setLongArgument(java.lang.String, long);
+    method public C setStringArgument(java.lang.String, java.lang.String);
+  }
+
+  public static class TtsSpan.CardinalBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.CardinalBuilder();
+    ctor public TtsSpan.CardinalBuilder(long);
+    ctor public TtsSpan.CardinalBuilder(java.lang.String);
+    method public android.text.style.TtsSpan.CardinalBuilder setNumber(long);
+    method public android.text.style.TtsSpan.CardinalBuilder setNumber(java.lang.String);
+  }
+
+  public static class TtsSpan.DateBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.DateBuilder();
+    ctor public TtsSpan.DateBuilder(java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer);
+    method public android.text.style.TtsSpan.DateBuilder setDay(int);
+    method public android.text.style.TtsSpan.DateBuilder setMonth(int);
+    method public android.text.style.TtsSpan.DateBuilder setWeekday(int);
+    method public android.text.style.TtsSpan.DateBuilder setYear(int);
+  }
+
+  public static class TtsSpan.DecimalBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.DecimalBuilder();
+    ctor public TtsSpan.DecimalBuilder(double, int, int);
+    ctor public TtsSpan.DecimalBuilder(java.lang.String, java.lang.String);
+    method public android.text.style.TtsSpan.DecimalBuilder setArgumentsFromDouble(double, int, int);
+    method public android.text.style.TtsSpan.DecimalBuilder setFractionalPart(java.lang.String);
+    method public android.text.style.TtsSpan.DecimalBuilder setIntegerPart(long);
+    method public android.text.style.TtsSpan.DecimalBuilder setIntegerPart(java.lang.String);
+  }
+
+  public static class TtsSpan.DigitsBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.DigitsBuilder();
+    ctor public TtsSpan.DigitsBuilder(java.lang.String);
+    method public android.text.style.TtsSpan.DigitsBuilder setDigits(java.lang.String);
+  }
+
+  public static class TtsSpan.ElectronicBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.ElectronicBuilder();
+    method public android.text.style.TtsSpan.ElectronicBuilder setDomain(java.lang.String);
+    method public android.text.style.TtsSpan.ElectronicBuilder setEmailArguments(java.lang.String, java.lang.String);
+    method public android.text.style.TtsSpan.ElectronicBuilder setFragmentId(java.lang.String);
+    method public android.text.style.TtsSpan.ElectronicBuilder setPassword(java.lang.String);
+    method public android.text.style.TtsSpan.ElectronicBuilder setPath(java.lang.String);
+    method public android.text.style.TtsSpan.ElectronicBuilder setPort(int);
+    method public android.text.style.TtsSpan.ElectronicBuilder setProtocol(java.lang.String);
+    method public android.text.style.TtsSpan.ElectronicBuilder setQueryString(java.lang.String);
+    method public android.text.style.TtsSpan.ElectronicBuilder setUsername(java.lang.String);
+  }
+
+  public static class TtsSpan.FractionBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.FractionBuilder();
+    ctor public TtsSpan.FractionBuilder(long, long, long);
+    method public android.text.style.TtsSpan.FractionBuilder setDenominator(long);
+    method public android.text.style.TtsSpan.FractionBuilder setDenominator(java.lang.String);
+    method public android.text.style.TtsSpan.FractionBuilder setIntegerPart(long);
+    method public android.text.style.TtsSpan.FractionBuilder setIntegerPart(java.lang.String);
+    method public android.text.style.TtsSpan.FractionBuilder setNumerator(long);
+    method public android.text.style.TtsSpan.FractionBuilder setNumerator(java.lang.String);
+  }
+
+  public static class TtsSpan.MeasureBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.MeasureBuilder();
+    method public android.text.style.TtsSpan.MeasureBuilder setDenominator(long);
+    method public android.text.style.TtsSpan.MeasureBuilder setDenominator(java.lang.String);
+    method public android.text.style.TtsSpan.MeasureBuilder setFractionalPart(java.lang.String);
+    method public android.text.style.TtsSpan.MeasureBuilder setIntegerPart(long);
+    method public android.text.style.TtsSpan.MeasureBuilder setIntegerPart(java.lang.String);
+    method public android.text.style.TtsSpan.MeasureBuilder setNumber(long);
+    method public android.text.style.TtsSpan.MeasureBuilder setNumber(java.lang.String);
+    method public android.text.style.TtsSpan.MeasureBuilder setNumerator(long);
+    method public android.text.style.TtsSpan.MeasureBuilder setNumerator(java.lang.String);
+    method public android.text.style.TtsSpan.MeasureBuilder setUnit(java.lang.String);
+  }
+
+  public static class TtsSpan.MoneyBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.MoneyBuilder();
+    method public android.text.style.TtsSpan.MoneyBuilder setCurrency(java.lang.String);
+    method public android.text.style.TtsSpan.MoneyBuilder setFractionalPart(java.lang.String);
+    method public android.text.style.TtsSpan.MoneyBuilder setIntegerPart(long);
+    method public android.text.style.TtsSpan.MoneyBuilder setIntegerPart(java.lang.String);
+    method public android.text.style.TtsSpan.MoneyBuilder setQuantity(java.lang.String);
+  }
+
+  public static class TtsSpan.OrdinalBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.OrdinalBuilder();
+    ctor public TtsSpan.OrdinalBuilder(long);
+    ctor public TtsSpan.OrdinalBuilder(java.lang.String);
+    method public android.text.style.TtsSpan.OrdinalBuilder setNumber(long);
+    method public android.text.style.TtsSpan.OrdinalBuilder setNumber(java.lang.String);
+  }
+
+  public static class TtsSpan.SemioticClassBuilder extends android.text.style.TtsSpan.Builder {
+    ctor public TtsSpan.SemioticClassBuilder(java.lang.String);
+    method public C setAnimacy(java.lang.String);
+    method public C setCase(java.lang.String);
+    method public C setGender(java.lang.String);
+    method public C setMultiplicity(java.lang.String);
+  }
+
+  public static class TtsSpan.TelephoneBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.TelephoneBuilder();
+    ctor public TtsSpan.TelephoneBuilder(java.lang.String);
+    method public android.text.style.TtsSpan.TelephoneBuilder setCountryCode(java.lang.String);
+    method public android.text.style.TtsSpan.TelephoneBuilder setExtension(java.lang.String);
+    method public android.text.style.TtsSpan.TelephoneBuilder setNumberParts(java.lang.String);
+  }
+
+  public static class TtsSpan.TextBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.TextBuilder();
+    ctor public TtsSpan.TextBuilder(java.lang.String);
+    method public android.text.style.TtsSpan.TextBuilder setText(java.lang.String);
+  }
+
+  public static class TtsSpan.TimeBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.TimeBuilder();
+    ctor public TtsSpan.TimeBuilder(int, int);
+    method public android.text.style.TtsSpan.TimeBuilder setHours(int);
+    method public android.text.style.TtsSpan.TimeBuilder setMinutes(int);
+  }
+
+  public static class TtsSpan.VerbatimBuilder extends android.text.style.TtsSpan.SemioticClassBuilder {
+    ctor public TtsSpan.VerbatimBuilder();
+    ctor public TtsSpan.VerbatimBuilder(java.lang.String);
+    method public android.text.style.TtsSpan.VerbatimBuilder setVerbatim(java.lang.String);
+  }
+
   public class TypefaceSpan extends android.text.style.MetricAffectingSpan implements android.text.ParcelableSpan {
     ctor public TypefaceSpan(java.lang.String);
     ctor public TypefaceSpan(android.os.Parcel);
@@ -25728,28 +30894,95 @@
 
 package android.transition {
 
+  public class ArcMotion extends android.transition.PathMotion {
+    ctor public ArcMotion();
+    ctor public ArcMotion(android.content.Context, android.util.AttributeSet);
+    method public float getMaximumAngle();
+    method public float getMinimumHorizontalAngle();
+    method public float getMinimumVerticalAngle();
+    method public android.graphics.Path getPath(float, float, float, float);
+    method public void setMaximumAngle(float);
+    method public void setMinimumHorizontalAngle(float);
+    method public void setMinimumVerticalAngle(float);
+  }
+
   public class AutoTransition extends android.transition.TransitionSet {
     ctor public AutoTransition();
+    ctor public AutoTransition(android.content.Context, android.util.AttributeSet);
   }
 
   public class ChangeBounds extends android.transition.Transition {
     ctor public ChangeBounds();
+    ctor public ChangeBounds(android.content.Context, android.util.AttributeSet);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
-    method public void setReparent(boolean);
+    method public deprecated void setReparent(boolean);
     method public void setResizeClip(boolean);
   }
 
+  public class ChangeClipBounds extends android.transition.Transition {
+    ctor public ChangeClipBounds();
+    ctor public ChangeClipBounds(android.content.Context, android.util.AttributeSet);
+    method public void captureEndValues(android.transition.TransitionValues);
+    method public void captureStartValues(android.transition.TransitionValues);
+  }
+
+  public class ChangeImageTransform extends android.transition.Transition {
+    ctor public ChangeImageTransform();
+    ctor public ChangeImageTransform(android.content.Context, android.util.AttributeSet);
+    method public void captureEndValues(android.transition.TransitionValues);
+    method public void captureStartValues(android.transition.TransitionValues);
+  }
+
+  public class ChangeTransform extends android.transition.Transition {
+    ctor public ChangeTransform();
+    ctor public ChangeTransform(android.content.Context, android.util.AttributeSet);
+    method public void captureEndValues(android.transition.TransitionValues);
+    method public void captureStartValues(android.transition.TransitionValues);
+    method public boolean getReparent();
+    method public boolean getReparentWithOverlay();
+    method public void setReparent(boolean);
+    method public void setReparentWithOverlay(boolean);
+  }
+
+  public class CircularPropagation extends android.transition.VisibilityPropagation {
+    ctor public CircularPropagation();
+    method public long getStartDelay(android.view.ViewGroup, android.transition.Transition, android.transition.TransitionValues, android.transition.TransitionValues);
+    method public void setPropagationSpeed(float);
+  }
+
+  public class Explode extends android.transition.Visibility {
+    ctor public Explode();
+    ctor public Explode(android.content.Context, android.util.AttributeSet);
+  }
+
   public class Fade extends android.transition.Visibility {
     ctor public Fade();
     ctor public Fade(int);
+    ctor public Fade(android.content.Context, android.util.AttributeSet);
     field public static final int IN = 1; // 0x1
     field public static final int OUT = 2; // 0x2
   }
 
+  public abstract class PathMotion {
+    ctor public PathMotion();
+    ctor public PathMotion(android.content.Context, android.util.AttributeSet);
+    method public abstract android.graphics.Path getPath(float, float, float, float);
+  }
+
+  public class PatternPathMotion extends android.transition.PathMotion {
+    ctor public PatternPathMotion();
+    ctor public PatternPathMotion(android.content.Context, android.util.AttributeSet);
+    ctor public PatternPathMotion(android.graphics.Path);
+    method public android.graphics.Path getPath(float, float, float, float);
+    method public android.graphics.Path getPatternPath();
+    method public void setPatternPath(android.graphics.Path);
+  }
+
   public final class Scene {
     ctor public Scene(android.view.ViewGroup);
-    ctor public Scene(android.view.ViewGroup, android.view.ViewGroup);
+    ctor public Scene(android.view.ViewGroup, android.view.View);
+    ctor public deprecated Scene(android.view.ViewGroup, android.view.ViewGroup);
     method public void enter();
     method public void exit();
     method public static android.transition.Scene getSceneForLayout(android.view.ViewGroup, int, android.content.Context);
@@ -25758,11 +30991,30 @@
     method public void setExitAction(java.lang.Runnable);
   }
 
+  public class SidePropagation extends android.transition.VisibilityPropagation {
+    ctor public SidePropagation();
+    method public long getStartDelay(android.view.ViewGroup, android.transition.Transition, android.transition.TransitionValues, android.transition.TransitionValues);
+    method public void setPropagationSpeed(float);
+    method public void setSide(int);
+  }
+
+  public class Slide extends android.transition.Visibility {
+    ctor public Slide();
+    ctor public Slide(int);
+    ctor public Slide(android.content.Context, android.util.AttributeSet);
+    method public int getSlideEdge();
+    method public void setSlideEdge(int);
+  }
+
   public abstract class Transition implements java.lang.Cloneable {
     ctor public Transition();
+    ctor public Transition(android.content.Context, android.util.AttributeSet);
     method public android.transition.Transition addListener(android.transition.Transition.TransitionListener);
     method public android.transition.Transition addTarget(int);
+    method public android.transition.Transition addTarget(java.lang.String);
+    method public android.transition.Transition addTarget(java.lang.Class);
     method public android.transition.Transition addTarget(android.view.View);
+    method public boolean canRemoveViews();
     method public abstract void captureEndValues(android.transition.TransitionValues);
     method public abstract void captureStartValues(android.transition.TransitionValues);
     method public android.transition.Transition clone();
@@ -25771,22 +31023,44 @@
     method public android.transition.Transition excludeChildren(android.view.View, boolean);
     method public android.transition.Transition excludeChildren(java.lang.Class, boolean);
     method public android.transition.Transition excludeTarget(int, boolean);
+    method public android.transition.Transition excludeTarget(java.lang.String, boolean);
     method public android.transition.Transition excludeTarget(android.view.View, boolean);
     method public android.transition.Transition excludeTarget(java.lang.Class, boolean);
     method public long getDuration();
+    method public android.graphics.Rect getEpicenter();
+    method public android.transition.Transition.EpicenterCallback getEpicenterCallback();
     method public android.animation.TimeInterpolator getInterpolator();
     method public java.lang.String getName();
+    method public android.transition.PathMotion getPathMotion();
+    method public android.transition.TransitionPropagation getPropagation();
     method public long getStartDelay();
     method public java.util.List<java.lang.Integer> getTargetIds();
+    method public java.util.List<java.lang.String> getTargetNames();
+    method public java.util.List<java.lang.Class> getTargetTypes();
     method public java.util.List<android.view.View> getTargets();
     method public java.lang.String[] getTransitionProperties();
     method public android.transition.TransitionValues getTransitionValues(android.view.View, boolean);
     method public android.transition.Transition removeListener(android.transition.Transition.TransitionListener);
     method public android.transition.Transition removeTarget(int);
+    method public android.transition.Transition removeTarget(java.lang.String);
     method public android.transition.Transition removeTarget(android.view.View);
+    method public android.transition.Transition removeTarget(java.lang.Class);
     method public android.transition.Transition setDuration(long);
+    method public void setEpicenterCallback(android.transition.Transition.EpicenterCallback);
     method public android.transition.Transition setInterpolator(android.animation.TimeInterpolator);
+    method public void setMatchOrder(int...);
+    method public void setPathMotion(android.transition.PathMotion);
+    method public void setPropagation(android.transition.TransitionPropagation);
     method public android.transition.Transition setStartDelay(long);
+    field public static final int MATCH_ID = 3; // 0x3
+    field public static final int MATCH_INSTANCE = 1; // 0x1
+    field public static final int MATCH_ITEM_ID = 4; // 0x4
+    field public static final int MATCH_NAME = 2; // 0x2
+  }
+
+  public static abstract class Transition.EpicenterCallback {
+    ctor public Transition.EpicenterCallback();
+    method public abstract android.graphics.Rect onGetEpicenter(android.transition.Transition);
   }
 
   public static abstract interface Transition.TransitionListener {
@@ -25814,12 +31088,22 @@
     method public void transitionTo(android.transition.Scene);
   }
 
+  public abstract class TransitionPropagation {
+    ctor public TransitionPropagation();
+    method public abstract void captureValues(android.transition.TransitionValues);
+    method public abstract java.lang.String[] getPropagationProperties();
+    method public abstract long getStartDelay(android.view.ViewGroup, android.transition.Transition, android.transition.TransitionValues, android.transition.TransitionValues);
+  }
+
   public class TransitionSet extends android.transition.Transition {
     ctor public TransitionSet();
+    ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
     method public android.transition.TransitionSet addTransition(android.transition.Transition);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
     method public int getOrdering();
+    method public android.transition.Transition getTransitionAt(int);
+    method public int getTransitionCount();
     method public android.transition.TransitionSet removeTransition(android.transition.Transition);
     method public android.transition.TransitionSet setOrdering(int);
     field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
@@ -25834,11 +31118,27 @@
 
   public abstract class Visibility extends android.transition.Transition {
     ctor public Visibility();
+    ctor public Visibility(android.content.Context, android.util.AttributeSet);
     method public void captureEndValues(android.transition.TransitionValues);
     method public void captureStartValues(android.transition.TransitionValues);
+    method public int getMode();
     method public boolean isVisible(android.transition.TransitionValues);
     method public android.animation.Animator onAppear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
+    method public android.animation.Animator onAppear(android.view.ViewGroup, android.view.View, android.transition.TransitionValues, android.transition.TransitionValues);
     method public android.animation.Animator onDisappear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
+    method public android.animation.Animator onDisappear(android.view.ViewGroup, android.view.View, android.transition.TransitionValues, android.transition.TransitionValues);
+    method public void setMode(int);
+    field public static final int MODE_IN = 1; // 0x1
+    field public static final int MODE_OUT = 2; // 0x2
+  }
+
+  public abstract class VisibilityPropagation extends android.transition.TransitionPropagation {
+    ctor public VisibilityPropagation();
+    method public void captureValues(android.transition.TransitionValues);
+    method public java.lang.String[] getPropagationProperties();
+    method public int getViewVisibility(android.transition.TransitionValues);
+    method public int getViewX(android.transition.TransitionValues);
+    method public int getViewY(android.transition.TransitionValues);
   }
 
 }
@@ -25870,6 +31170,7 @@
     method public void ensureCapacity(int);
     method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
     method public V get(java.lang.Object);
+    method public int indexOfKey(java.lang.Object);
     method public boolean isEmpty();
     method public K keyAt(int);
     method public java.util.Set<K> keySet();
@@ -25968,6 +31269,7 @@
     method public void setTo(android.util.DisplayMetrics);
     method public void setToDefaults();
     field public static final int DENSITY_400 = 400; // 0x190
+    field public static final int DENSITY_560 = 560; // 0x230
     field public static final int DENSITY_DEFAULT = 160; // 0xa0
     field public static final int DENSITY_HIGH = 240; // 0xf0
     field public static final int DENSITY_LOW = 120; // 0x78
@@ -26154,6 +31456,7 @@
     method public final V put(K, V);
     method public final synchronized int putCount();
     method public final V remove(K);
+    method public void resize(int);
     method public final synchronized int size();
     method protected int sizeOf(K, V);
     method public final synchronized java.util.Map<K, V> snapshot();
@@ -26183,6 +31486,46 @@
     method public void previousMonth();
   }
 
+  public final class MutableBoolean {
+    ctor public MutableBoolean(boolean);
+    field public boolean value;
+  }
+
+  public final class MutableByte {
+    ctor public MutableByte(byte);
+    field public byte value;
+  }
+
+  public final class MutableChar {
+    ctor public MutableChar(char);
+    field public char value;
+  }
+
+  public final class MutableDouble {
+    ctor public MutableDouble(double);
+    field public double value;
+  }
+
+  public final class MutableFloat {
+    ctor public MutableFloat(float);
+    field public float value;
+  }
+
+  public final class MutableInt {
+    ctor public MutableInt(int);
+    field public int value;
+  }
+
+  public final class MutableLong {
+    ctor public MutableLong(long);
+    field public long value;
+  }
+
+  public final class MutableShort {
+    ctor public MutableShort(short);
+    field public short value;
+  }
+
   public class NoSuchPropertyException extends java.lang.RuntimeException {
     ctor public NoSuchPropertyException(java.lang.String);
   }
@@ -26202,9 +31545,9 @@
     field public static final java.lang.String GOOD_IRI_CHAR = "a-zA-Z0-9\u00a0-\ud7ff\uf900-\ufdcf\ufdf0-\uffef";
     field public static final java.util.regex.Pattern IP_ADDRESS;
     field public static final java.util.regex.Pattern PHONE;
-    field public static final java.util.regex.Pattern TOP_LEVEL_DOMAIN;
-    field public static final java.lang.String TOP_LEVEL_DOMAIN_STR = "((aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(biz|b[abdefghijmnorstvwyz])|(cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(edu|e[cegrstu])|f[ijkmor]|(gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(info|int|i[delmnoqrst])|(jobs|j[emop])|k[eghimnprwyz]|l[abcikrstuvy]|(mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])|(name|net|n[acefgilopruz])|(org|om)|(pro|p[aefghklmnrstwy])|qa|r[eosuw]|s[abcdeghijklmnortuvyz]|(tel|travel|t[cdfghjklmnoprtvwz])|u[agksyz]|v[aceginu]|w[fs]|(\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae|\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435|\u0440\u0444|\u0441\u0440\u0431|\u05d8\u05e2\u05e1\u05d8|\u0622\u0632\u0645\u0627\u06cc\u0634\u06cc|\u0625\u062e\u062a\u0628\u0627\u0631|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0633\u0648\u0631\u064a\u0629|\u0641\u0644\u0633\u0637\u064a\u0646|\u0642\u0637\u0631|\u0645\u0635\u0631|\u092a\u0930\u0940\u0915\u094d\u0937\u093e|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|\u0baa\u0bb0\u0bbf\u0b9f\u0bcd\u0b9a\u0bc8|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e44\u0e17\u0e22|\u30c6\u30b9\u30c8|\u4e2d\u56fd|\u4e2d\u570b|\u53f0\u6e7e|\u53f0\u7063|\u65b0\u52a0\u5761|\u6d4b\u8bd5|\u6e2c\u8a66|\u9999\u6e2f|\ud14c\uc2a4\ud2b8|\ud55c\uad6d|xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-3e0b707e|xn\\-\\-45brj9c|xn\\-\\-80akhbyknj4f|xn\\-\\-90a3ac|xn\\-\\-9t4b11yi5a|xn\\-\\-clchc0ea0b2g2a9gcd|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-gecrj9c|xn\\-\\-h2brj9c|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-s9brj9c|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-yfro4i67o|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah|xxx)|y[et]|z[amw])";
-    field public static final java.lang.String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL = "(?:(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(?:biz|b[abdefghijmnorstvwyz])|(?:cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(?:edu|e[cegrstu])|f[ijkmor]|(?:gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(?:info|int|i[delmnoqrst])|(?:jobs|j[emop])|k[eghimnprwyz]|l[abcikrstuvy]|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])|(?:name|net|n[acefgilopruz])|(?:org|om)|(?:pro|p[aefghklmnrstwy])|qa|r[eosuw]|s[abcdeghijklmnortuvyz]|(?:tel|travel|t[cdfghjklmnoprtvwz])|u[agksyz]|v[aceginu]|w[fs]|(?:\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae|\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435|\u0440\u0444|\u0441\u0440\u0431|\u05d8\u05e2\u05e1\u05d8|\u0622\u0632\u0645\u0627\u06cc\u0634\u06cc|\u0625\u062e\u062a\u0628\u0627\u0631|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0633\u0648\u0631\u064a\u0629|\u0641\u0644\u0633\u0637\u064a\u0646|\u0642\u0637\u0631|\u0645\u0635\u0631|\u092a\u0930\u0940\u0915\u094d\u0937\u093e|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|\u0baa\u0bb0\u0bbf\u0b9f\u0bcd\u0b9a\u0bc8|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e44\u0e17\u0e22|\u30c6\u30b9\u30c8|\u4e2d\u56fd|\u4e2d\u570b|\u53f0\u6e7e|\u53f0\u7063|\u65b0\u52a0\u5761|\u6d4b\u8bd5|\u6e2c\u8a66|\u9999\u6e2f|\ud14c\uc2a4\ud2b8|\ud55c\uad6d|xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-3e0b707e|xn\\-\\-45brj9c|xn\\-\\-80akhbyknj4f|xn\\-\\-90a3ac|xn\\-\\-9t4b11yi5a|xn\\-\\-clchc0ea0b2g2a9gcd|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-gecrj9c|xn\\-\\-h2brj9c|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-s9brj9c|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-yfro4i67o|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah|xxx)|y[et]|z[amw]))";
+    field public static final deprecated java.util.regex.Pattern TOP_LEVEL_DOMAIN;
+    field public static final deprecated java.lang.String TOP_LEVEL_DOMAIN_STR = "((aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(biz|b[abdefghijmnorstvwyz])|(cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(edu|e[cegrstu])|f[ijkmor]|(gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(info|int|i[delmnoqrst])|(jobs|j[emop])|k[eghimnprwyz]|l[abcikrstuvy]|(mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])|(name|net|n[acefgilopruz])|(org|om)|(pro|p[aefghklmnrstwy])|qa|r[eosuw]|s[abcdeghijklmnortuvyz]|(tel|travel|t[cdfghjklmnoprtvwz])|u[agksyz]|v[aceginu]|w[fs]|(\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae|\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435|\u0440\u0444|\u0441\u0440\u0431|\u05d8\u05e2\u05e1\u05d8|\u0622\u0632\u0645\u0627\u06cc\u0634\u06cc|\u0625\u062e\u062a\u0628\u0627\u0631|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0633\u0648\u0631\u064a\u0629|\u0641\u0644\u0633\u0637\u064a\u0646|\u0642\u0637\u0631|\u0645\u0635\u0631|\u092a\u0930\u0940\u0915\u094d\u0937\u093e|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|\u0baa\u0bb0\u0bbf\u0b9f\u0bcd\u0b9a\u0bc8|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e44\u0e17\u0e22|\u30c6\u30b9\u30c8|\u4e2d\u56fd|\u4e2d\u570b|\u53f0\u6e7e|\u53f0\u7063|\u65b0\u52a0\u5761|\u6d4b\u8bd5|\u6e2c\u8a66|\u9999\u6e2f|\ud14c\uc2a4\ud2b8|\ud55c\uad6d|xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-3e0b707e|xn\\-\\-45brj9c|xn\\-\\-80akhbyknj4f|xn\\-\\-90a3ac|xn\\-\\-9t4b11yi5a|xn\\-\\-clchc0ea0b2g2a9gcd|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-gecrj9c|xn\\-\\-h2brj9c|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-s9brj9c|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-yfro4i67o|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah|xxx)|y[et]|z[amw])";
+    field public static final deprecated java.lang.String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL = "(?:(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(?:biz|b[abdefghijmnorstvwyz])|(?:cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(?:edu|e[cegrstu])|f[ijkmor]|(?:gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(?:info|int|i[delmnoqrst])|(?:jobs|j[emop])|k[eghimnprwyz]|l[abcikrstuvy]|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])|(?:name|net|n[acefgilopruz])|(?:org|om)|(?:pro|p[aefghklmnrstwy])|qa|r[eosuw]|s[abcdeghijklmnortuvyz]|(?:tel|travel|t[cdfghjklmnoprtvwz])|u[agksyz]|v[aceginu]|w[fs]|(?:\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae|\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435|\u0440\u0444|\u0441\u0440\u0431|\u05d8\u05e2\u05e1\u05d8|\u0622\u0632\u0645\u0627\u06cc\u0634\u06cc|\u0625\u062e\u062a\u0628\u0627\u0631|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0633\u0648\u0631\u064a\u0629|\u0641\u0644\u0633\u0637\u064a\u0646|\u0642\u0637\u0631|\u0645\u0635\u0631|\u092a\u0930\u0940\u0915\u094d\u0937\u093e|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|\u0baa\u0bb0\u0bbf\u0b9f\u0bcd\u0b9a\u0bc8|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e44\u0e17\u0e22|\u30c6\u30b9\u30c8|\u4e2d\u56fd|\u4e2d\u570b|\u53f0\u6e7e|\u53f0\u7063|\u65b0\u52a0\u5761|\u6d4b\u8bd5|\u6e2c\u8a66|\u9999\u6e2f|\ud14c\uc2a4\ud2b8|\ud55c\uad6d|xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-3e0b707e|xn\\-\\-45brj9c|xn\\-\\-80akhbyknj4f|xn\\-\\-90a3ac|xn\\-\\-9t4b11yi5a|xn\\-\\-clchc0ea0b2g2a9gcd|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-gecrj9c|xn\\-\\-h2brj9c|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-s9brj9c|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-yfro4i67o|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah|xxx)|y[et]|z[amw]))";
     field public static final java.util.regex.Pattern WEB_URL;
   }
 
@@ -26232,6 +31575,55 @@
     method public void set(T, V);
   }
 
+  public final class Range {
+    ctor public Range(T, T);
+    method public T clamp(T);
+    method public boolean contains(T);
+    method public boolean contains(android.util.Range<T>);
+    method public static android.util.Range<T> create(T, T);
+    method public android.util.Range<T> extend(android.util.Range<T>);
+    method public android.util.Range<T> extend(T, T);
+    method public android.util.Range<T> extend(T);
+    method public T getLower();
+    method public T getUpper();
+    method public android.util.Range<T> intersect(android.util.Range<T>);
+    method public android.util.Range<T> intersect(T, T);
+  }
+
+  public final class Rational extends java.lang.Number implements java.lang.Comparable {
+    ctor public Rational(int, int);
+    method public int compareTo(android.util.Rational);
+    method public double doubleValue();
+    method public float floatValue();
+    method public int getDenominator();
+    method public int getNumerator();
+    method public int intValue();
+    method public boolean isFinite();
+    method public boolean isInfinite();
+    method public boolean isNaN();
+    method public boolean isZero();
+    method public long longValue();
+    method public static android.util.Rational parseRational(java.lang.String) throws java.lang.NumberFormatException;
+    field public static final android.util.Rational NEGATIVE_INFINITY;
+    field public static final android.util.Rational NaN;
+    field public static final android.util.Rational POSITIVE_INFINITY;
+    field public static final android.util.Rational ZERO;
+  }
+
+  public final class Size {
+    ctor public Size(int, int);
+    method public int getHeight();
+    method public int getWidth();
+    method public static android.util.Size parseSize(java.lang.String) throws java.lang.NumberFormatException;
+  }
+
+  public final class SizeF {
+    ctor public SizeF(float, float);
+    method public float getHeight();
+    method public float getWidth();
+    method public static android.util.SizeF parseSizeF(java.lang.String) throws java.lang.NumberFormatException;
+  }
+
   public class SparseArray implements java.lang.Cloneable {
     ctor public SparseArray();
     ctor public SparseArray(int);
@@ -26513,6 +31905,7 @@
   }
 
   public final class Display {
+    method public long getAppVsyncOffsetNanos();
     method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
     method public int getDisplayId();
     method public int getFlags();
@@ -26521,6 +31914,7 @@
     method public java.lang.String getName();
     method public deprecated int getOrientation();
     method public deprecated int getPixelFormat();
+    method public long getPresentationDeadlineNanos();
     method public void getRealMetrics(android.util.DisplayMetrics);
     method public void getRealSize(android.graphics.Point);
     method public void getRectSize(android.graphics.Rect);
@@ -26528,6 +31922,7 @@
     method public int getRotation();
     method public void getSize(android.graphics.Point);
     method public int getState();
+    method public float[] getSupportedRefreshRates();
     method public deprecated int getWidth();
     method public boolean isValid();
     field public static final int DEFAULT_DISPLAY = 0; // 0x0
@@ -26535,7 +31930,8 @@
     field public static final int FLAG_PRIVATE = 4; // 0x4
     field public static final int FLAG_SECURE = 2; // 0x2
     field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1
-    field public static final int STATE_DOZING = 3; // 0x3
+    field public static final int STATE_DOZE = 3; // 0x3
+    field public static final int STATE_DOZE_SUSPEND = 4; // 0x4
     field public static final int STATE_OFF = 1; // 0x1
     field public static final int STATE_ON = 2; // 0x2
     field public static final int STATE_UNKNOWN = 0; // 0x0
@@ -26567,6 +31963,16 @@
     method public static android.view.FocusFinder getInstance();
   }
 
+  public abstract class FrameStats {
+    ctor public FrameStats();
+    method public final long getEndTimeNano();
+    method public final int getFrameCount();
+    method public final long getFramePresentedTimeNano(int);
+    method public final long getRefreshPeriodNano();
+    method public final long getStartTimeNano();
+    field public static final long UNDEFINED_TIME_NANO = -1L; // 0xffffffffffffffffL
+  }
+
   public class GestureDetector {
     ctor public deprecated GestureDetector(android.view.GestureDetector.OnGestureListener, android.os.Handler);
     ctor public deprecated GestureDetector(android.view.GestureDetector.OnGestureListener);
@@ -26648,6 +32054,7 @@
   }
 
   public class HapticFeedbackConstants {
+    field public static final int CLOCK_TICK = 4; // 0x4
     field public static final int FLAG_IGNORE_GLOBAL_SETTING = 2; // 0x2
     field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1
     field public static final int KEYBOARD_TAP = 3; // 0x3
@@ -26681,6 +32088,7 @@
     method public android.os.Vibrator getVibrator();
     method public boolean[] hasKeys(int...);
     method public boolean isVirtual();
+    method public boolean supportsSource(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int KEYBOARD_TYPE_ALPHABETIC = 2; // 0x2
@@ -26705,6 +32113,7 @@
     field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
     field public static final int SOURCE_DPAD = 513; // 0x201
     field public static final int SOURCE_GAMEPAD = 1025; // 0x401
+    field public static final int SOURCE_HDMI = 33554433; // 0x2000001
     field public static final int SOURCE_JOYSTICK = 16777232; // 0x1000010
     field public static final int SOURCE_KEYBOARD = 257; // 0x101
     field public static final int SOURCE_MOUSE = 8194; // 0x2002
@@ -26873,6 +32282,8 @@
     field public static final deprecated int FLAG_WOKE_HERE = 1; // 0x1
     field public static final int KEYCODE_0 = 7; // 0x7
     field public static final int KEYCODE_1 = 8; // 0x8
+    field public static final int KEYCODE_11 = 227; // 0xe3
+    field public static final int KEYCODE_12 = 228; // 0xe4
     field public static final int KEYCODE_2 = 9; // 0x9
     field public static final int KEYCODE_3 = 10; // 0xa
     field public static final int KEYCODE_3D_MODE = 206; // 0xce
@@ -26981,6 +32392,7 @@
     field public static final int KEYCODE_GUIDE = 172; // 0xac
     field public static final int KEYCODE_H = 36; // 0x24
     field public static final int KEYCODE_HEADSETHOOK = 79; // 0x4f
+    field public static final int KEYCODE_HELP = 259; // 0x103
     field public static final int KEYCODE_HENKAN = 214; // 0xd6
     field public static final int KEYCODE_HOME = 3; // 0x3
     field public static final int KEYCODE_I = 37; // 0x25
@@ -26992,6 +32404,7 @@
     field public static final int KEYCODE_KATAKANA_HIRAGANA = 215; // 0xd7
     field public static final int KEYCODE_L = 40; // 0x28
     field public static final int KEYCODE_LANGUAGE_SWITCH = 204; // 0xcc
+    field public static final int KEYCODE_LAST_CHANNEL = 229; // 0xe5
     field public static final int KEYCODE_LEFT_BRACKET = 71; // 0x47
     field public static final int KEYCODE_M = 41; // 0x29
     field public static final int KEYCODE_MANNER_MODE = 205; // 0xcd
@@ -27007,6 +32420,7 @@
     field public static final int KEYCODE_MEDIA_RECORD = 130; // 0x82
     field public static final int KEYCODE_MEDIA_REWIND = 89; // 0x59
     field public static final int KEYCODE_MEDIA_STOP = 86; // 0x56
+    field public static final int KEYCODE_MEDIA_TOP_MENU = 226; // 0xe2
     field public static final int KEYCODE_MENU = 82; // 0x52
     field public static final int KEYCODE_META_LEFT = 117; // 0x75
     field public static final int KEYCODE_META_RIGHT = 118; // 0x76
@@ -27044,6 +32458,7 @@
     field public static final int KEYCODE_P = 44; // 0x2c
     field public static final int KEYCODE_PAGE_DOWN = 93; // 0x5d
     field public static final int KEYCODE_PAGE_UP = 92; // 0x5c
+    field public static final int KEYCODE_PAIRING = 225; // 0xe1
     field public static final int KEYCODE_PERIOD = 56; // 0x38
     field public static final int KEYCODE_PICTSYMBOLS = 94; // 0x5e
     field public static final int KEYCODE_PLUS = 81; // 0x51
@@ -27078,11 +32493,40 @@
     field public static final int KEYCODE_T = 48; // 0x30
     field public static final int KEYCODE_TAB = 61; // 0x3d
     field public static final int KEYCODE_TV = 170; // 0xaa
+    field public static final int KEYCODE_TV_ANTENNA_CABLE = 242; // 0xf2
+    field public static final int KEYCODE_TV_AUDIO_DESCRIPTION = 252; // 0xfc
+    field public static final int KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN = 254; // 0xfe
+    field public static final int KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP = 253; // 0xfd
+    field public static final int KEYCODE_TV_CONTENTS_MENU = 256; // 0x100
+    field public static final int KEYCODE_TV_DATA_SERVICE = 230; // 0xe6
     field public static final int KEYCODE_TV_INPUT = 178; // 0xb2
+    field public static final int KEYCODE_TV_INPUT_COMPONENT_1 = 249; // 0xf9
+    field public static final int KEYCODE_TV_INPUT_COMPONENT_2 = 250; // 0xfa
+    field public static final int KEYCODE_TV_INPUT_COMPOSITE_1 = 247; // 0xf7
+    field public static final int KEYCODE_TV_INPUT_COMPOSITE_2 = 248; // 0xf8
+    field public static final int KEYCODE_TV_INPUT_HDMI_1 = 243; // 0xf3
+    field public static final int KEYCODE_TV_INPUT_HDMI_2 = 244; // 0xf4
+    field public static final int KEYCODE_TV_INPUT_HDMI_3 = 245; // 0xf5
+    field public static final int KEYCODE_TV_INPUT_HDMI_4 = 246; // 0xf6
+    field public static final int KEYCODE_TV_INPUT_VGA_1 = 251; // 0xfb
+    field public static final int KEYCODE_TV_MEDIA_CONTEXT_MENU = 257; // 0x101
+    field public static final int KEYCODE_TV_NETWORK = 241; // 0xf1
+    field public static final int KEYCODE_TV_NUMBER_ENTRY = 234; // 0xea
     field public static final int KEYCODE_TV_POWER = 177; // 0xb1
+    field public static final int KEYCODE_TV_RADIO_SERVICE = 232; // 0xe8
+    field public static final int KEYCODE_TV_SATELLITE = 237; // 0xed
+    field public static final int KEYCODE_TV_SATELLITE_BS = 238; // 0xee
+    field public static final int KEYCODE_TV_SATELLITE_CS = 239; // 0xef
+    field public static final int KEYCODE_TV_SATELLITE_SERVICE = 240; // 0xf0
+    field public static final int KEYCODE_TV_TELETEXT = 233; // 0xe9
+    field public static final int KEYCODE_TV_TERRESTRIAL_ANALOG = 235; // 0xeb
+    field public static final int KEYCODE_TV_TERRESTRIAL_DIGITAL = 236; // 0xec
+    field public static final int KEYCODE_TV_TIMER_PROGRAMMING = 258; // 0x102
+    field public static final int KEYCODE_TV_ZOOM_MODE = 255; // 0xff
     field public static final int KEYCODE_U = 49; // 0x31
     field public static final int KEYCODE_UNKNOWN = 0; // 0x0
     field public static final int KEYCODE_V = 50; // 0x32
+    field public static final int KEYCODE_VOICE_ASSIST = 231; // 0xe7
     field public static final int KEYCODE_VOLUME_DOWN = 25; // 0x19
     field public static final int KEYCODE_VOLUME_MUTE = 164; // 0xa4
     field public static final int KEYCODE_VOLUME_UP = 24; // 0x18
@@ -27339,6 +32783,7 @@
     method public final float getY();
     method public final float getY(int);
     method public final float getYPrecision();
+    method public final boolean isButtonPressed(int);
     method public static android.view.MotionEvent obtain(long, long, int, int, android.view.MotionEvent.PointerProperties[], android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int);
     method public static deprecated android.view.MotionEvent obtain(long, long, int, int, int[], android.view.MotionEvent.PointerCoords[], int, float, float, int, int, int, int);
     method public static android.view.MotionEvent obtain(long, long, int, float, float, float, float, int, float, float, int, int);
@@ -27600,6 +33045,7 @@
     ctor public SurfaceView(android.content.Context);
     ctor public SurfaceView(android.content.Context, android.util.AttributeSet);
     ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int);
+    ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean gatherTransparentRegion(android.graphics.Region);
     method public android.view.SurfaceHolder getHolder();
     method public void setSecure(boolean);
@@ -27611,6 +33057,7 @@
     ctor public TextureView(android.content.Context);
     ctor public TextureView(android.content.Context, android.util.AttributeSet);
     ctor public TextureView(android.content.Context, android.util.AttributeSet, int);
+    ctor public TextureView(android.content.Context, android.util.AttributeSet, int, int);
     method public final void draw(android.graphics.Canvas);
     method public android.graphics.Bitmap getBitmap();
     method public android.graphics.Bitmap getBitmap(int, int);
@@ -27662,6 +33109,7 @@
     ctor public View(android.content.Context);
     ctor public View(android.content.Context, android.util.AttributeSet);
     ctor public View(android.content.Context, android.util.AttributeSet, int);
+    ctor public View(android.content.Context, android.util.AttributeSet, int, int);
     method public void addChildrenForAccessibility(java.util.ArrayList<android.view.View>);
     method public void addFocusables(java.util.ArrayList<android.view.View>, int);
     method public void addFocusables(java.util.ArrayList<android.view.View>, int, int);
@@ -27693,6 +33141,7 @@
     method protected int computeHorizontalScrollOffset();
     method protected int computeHorizontalScrollRange();
     method public void computeScroll();
+    method public android.view.WindowInsets computeSystemWindowInsets(android.view.WindowInsets, android.graphics.Rect);
     method protected int computeVerticalScrollExtent();
     method protected int computeVerticalScrollOffset();
     method protected int computeVerticalScrollRange();
@@ -27711,6 +33160,10 @@
     method public boolean dispatchKeyEvent(android.view.KeyEvent);
     method public boolean dispatchKeyEventPreIme(android.view.KeyEvent);
     method public boolean dispatchKeyShortcutEvent(android.view.KeyEvent);
+    method public boolean dispatchNestedFling(float, float, boolean);
+    method public boolean dispatchNestedPreFling(float, float);
+    method public boolean dispatchNestedPreScroll(int, int, int[], int[]);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]);
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
     method protected void dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>);
     method protected void dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>);
@@ -27726,6 +33179,7 @@
     method public void dispatchWindowSystemUiVisiblityChanged(int);
     method public void dispatchWindowVisibilityChanged(int);
     method public void draw(android.graphics.Canvas);
+    method public void drawableHotspotChanged(float, float);
     method protected void drawableStateChanged();
     method public android.view.View findFocus();
     method public final android.view.View findViewById(int);
@@ -27741,12 +33195,15 @@
     method public android.view.animation.Animation getAnimation();
     method public android.os.IBinder getApplicationWindowToken();
     method public android.graphics.drawable.Drawable getBackground();
+    method public android.content.res.ColorStateList getBackgroundTintList();
+    method public android.graphics.PorterDuff.Mode getBackgroundTintMode();
     method public int getBaseline();
     method public final int getBottom();
     method protected float getBottomFadingEdgeStrength();
     method protected int getBottomPaddingOffset();
     method public float getCameraDistance();
     method public android.graphics.Rect getClipBounds();
+    method public final boolean getClipToOutline();
     method public java.lang.CharSequence getContentDescription();
     method public final android.content.Context getContext();
     method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
@@ -27759,6 +33216,7 @@
     method public int getDrawingCacheQuality();
     method public void getDrawingRect(android.graphics.Rect);
     method public long getDrawingTime();
+    method public float getElevation();
     method public boolean getFilterTouchesWhenObscured();
     method public boolean getFitsSystemWindows();
     method public java.util.ArrayList<android.view.View> getFocusables(int);
@@ -27798,6 +33256,7 @@
     method public int getNextFocusRightId();
     method public int getNextFocusUpId();
     method public android.view.View.OnFocusChangeListener getOnFocusChangeListener();
+    method public android.view.ViewOutlineProvider getOutlineProvider();
     method public int getOverScrollMode();
     method public android.view.ViewOverlay getOverlay();
     method public int getPaddingBottom();
@@ -27827,6 +33286,7 @@
     method public final int getScrollX();
     method public final int getScrollY();
     method public int getSolidColor();
+    method public android.animation.StateListAnimator getStateListAnimator();
     method protected int getSuggestedMinimumHeight();
     method protected int getSuggestedMinimumWidth();
     method public int getSystemUiVisibility();
@@ -27839,8 +33299,10 @@
     method protected int getTopPaddingOffset();
     method public android.view.TouchDelegate getTouchDelegate();
     method public java.util.ArrayList<android.view.View> getTouchables();
+    method public java.lang.String getTransitionName();
     method public float getTranslationX();
     method public float getTranslationY();
+    method public float getTranslationZ();
     method public int getVerticalFadingEdgeLength();
     method public int getVerticalScrollbarPosition();
     method public int getVerticalScrollbarWidth();
@@ -27855,19 +33317,21 @@
     method public void getWindowVisibleDisplayFrame(android.graphics.Rect);
     method public float getX();
     method public float getY();
+    method public float getZ();
     method public boolean hasFocus();
     method public boolean hasFocusable();
+    method public boolean hasNestedScrollingParent();
     method public boolean hasOnClickListeners();
     method public boolean hasOverlappingRendering();
     method public boolean hasTransientState();
     method public boolean hasWindowFocus();
     method public static android.view.View inflate(android.content.Context, int, android.view.ViewGroup);
-    method protected void initializeFadingEdge(android.content.res.TypedArray);
-    method protected void initializeScrollbars(android.content.res.TypedArray);
     method public void invalidate(android.graphics.Rect);
     method public void invalidate(int, int, int, int);
     method public void invalidate();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
+    method public void invalidateOutline();
+    method public boolean isAccessibilityFocused();
     method public boolean isActivated();
     method public boolean isAttachedToWindow();
     method public boolean isClickable();
@@ -27883,6 +33347,7 @@
     method public boolean isHorizontalFadingEdgeEnabled();
     method public boolean isHorizontalScrollBarEnabled();
     method public boolean isHovered();
+    method public boolean isImportantForAccessibility();
     method public boolean isInEditMode();
     method public boolean isInLayout();
     method public boolean isInTouchMode();
@@ -27890,6 +33355,7 @@
     method public boolean isLayoutDirectionResolved();
     method public boolean isLayoutRequested();
     method public boolean isLongClickable();
+    method public boolean isNestedScrollingEnabled();
     method public boolean isOpaque();
     method protected boolean isPaddingOffsetRequired();
     method public boolean isPaddingRelative();
@@ -27989,6 +33455,7 @@
     method public void requestLayout();
     method public boolean requestRectangleOnScreen(android.graphics.Rect);
     method public boolean requestRectangleOnScreen(android.graphics.Rect, boolean);
+    method public final void requestUnbufferedDispatch(android.view.MotionEvent);
     method public static int resolveSize(int, int);
     method public static int resolveSizeAndState(int, int, int);
     method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>);
@@ -28007,15 +33474,19 @@
     method public void setBackgroundColor(int);
     method public deprecated void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setBackgroundResource(int);
+    method public void setBackgroundTintList(android.content.res.ColorStateList);
+    method public void setBackgroundTintMode(android.graphics.PorterDuff.Mode);
     method public final void setBottom(int);
     method public void setCameraDistance(float);
     method public void setClickable(boolean);
     method public void setClipBounds(android.graphics.Rect);
+    method public void setClipToOutline(boolean);
     method public void setContentDescription(java.lang.CharSequence);
     method public void setDrawingCacheBackgroundColor(int);
     method public void setDrawingCacheEnabled(boolean);
     method public void setDrawingCacheQuality(int);
     method public void setDuplicateParentStateEnabled(boolean);
+    method public void setElevation(float);
     method public void setEnabled(boolean);
     method public void setFadingEdgeLength(int);
     method public void setFilterTouchesWhenObscured(boolean);
@@ -28040,6 +33511,7 @@
     method protected final void setMeasuredDimension(int, int);
     method public void setMinimumHeight(int);
     method public void setMinimumWidth(int);
+    method public void setNestedScrollingEnabled(boolean);
     method public void setNextFocusDownId(int);
     method public void setNextFocusForwardId(int);
     method public void setNextFocusLeftId(int);
@@ -28056,6 +33528,7 @@
     method public void setOnLongClickListener(android.view.View.OnLongClickListener);
     method public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener);
     method public void setOnTouchListener(android.view.View.OnTouchListener);
+    method public void setOutlineProvider(android.view.ViewOutlineProvider);
     method public void setOverScrollMode(int);
     method public void setPadding(int, int, int, int);
     method public void setPaddingRelative(int, int, int, int);
@@ -28080,6 +33553,7 @@
     method public void setScrollbarFadingEnabled(boolean);
     method public void setSelected(boolean);
     method public void setSoundEffectsEnabled(boolean);
+    method public void setStateListAnimator(android.animation.StateListAnimator);
     method public void setSystemUiVisibility(int);
     method public void setTag(java.lang.Object);
     method public void setTag(int, java.lang.Object);
@@ -28087,8 +33561,10 @@
     method public void setTextDirection(int);
     method public final void setTop(int);
     method public void setTouchDelegate(android.view.TouchDelegate);
+    method public final void setTransitionName(java.lang.String);
     method public void setTranslationX(float);
     method public void setTranslationY(float);
+    method public void setTranslationZ(float);
     method public void setVerticalFadingEdgeEnabled(boolean);
     method public void setVerticalScrollBarEnabled(boolean);
     method public void setVerticalScrollbarPosition(int);
@@ -28097,10 +33573,13 @@
     method public void setWillNotDraw(boolean);
     method public void setX(float);
     method public void setY(float);
+    method public void setZ(float);
     method public boolean showContextMenu();
     method public android.view.ActionMode startActionMode(android.view.ActionMode.Callback);
     method public void startAnimation(android.view.animation.Animation);
     method public final boolean startDrag(android.content.ClipData, android.view.View.DragShadowBuilder, java.lang.Object, int);
+    method public boolean startNestedScroll(int);
+    method public void stopNestedScroll();
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable);
     method protected boolean verifyDrawable(android.graphics.drawable.Drawable);
@@ -28189,6 +33668,9 @@
     field public static final int SCROLLBAR_POSITION_DEFAULT = 0; // 0x0
     field public static final int SCROLLBAR_POSITION_LEFT = 1; // 0x1
     field public static final int SCROLLBAR_POSITION_RIGHT = 2; // 0x2
+    field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
+    field public static final int SCROLL_AXIS_NONE = 0; // 0x0
+    field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
     field protected static final int[] SELECTED_STATE_SET;
     field protected static final int[] SELECTED_WINDOW_FOCUSED_STATE_SET;
     field public static final int SOUND_EFFECTS_ENABLED = 134217728; // 0x8000000
@@ -28219,11 +33701,13 @@
     field public static final int TEXT_DIRECTION_RTL = 4; // 0x4
     field public static final android.util.Property TRANSLATION_X;
     field public static final android.util.Property TRANSLATION_Y;
+    field public static final android.util.Property TRANSLATION_Z;
     field protected static final java.lang.String VIEW_LOG_TAG = "View";
     field public static final int VISIBLE = 0; // 0x0
     field protected static final int[] WINDOW_FOCUSED_STATE_SET;
     field public static final android.util.Property X;
     field public static final android.util.Property Y;
+    field public static final android.util.Property Z;
   }
 
   public static class View.AccessibilityDelegate {
@@ -28317,6 +33801,10 @@
     method public abstract boolean onTouch(android.view.View, android.view.MotionEvent);
   }
 
+  public final class ViewAnimationUtils {
+    method public static android.animation.Animator createCircularReveal(android.view.View, int, int, float, float);
+  }
+
   public class ViewConfiguration {
     ctor public deprecated ViewConfiguration();
     method public static android.view.ViewConfiguration get(android.content.Context);
@@ -28408,6 +33896,7 @@
     ctor public ViewGroup(android.content.Context);
     ctor public ViewGroup(android.content.Context, android.util.AttributeSet);
     ctor public ViewGroup(android.content.Context, android.util.AttributeSet, int);
+    ctor public ViewGroup(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean addStatesFromChildren();
     method public void addView(android.view.View);
     method public void addView(android.view.View, int);
@@ -28450,13 +33939,16 @@
     method protected boolean getChildStaticTransformation(android.view.View, android.view.animation.Transformation);
     method public boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point);
     method public boolean getClipChildren();
+    method public boolean getClipToPadding();
     method public int getDescendantFocusability();
     method public android.view.View getFocusedChild();
     method public android.view.animation.LayoutAnimationController getLayoutAnimation();
     method public android.view.animation.Animation.AnimationListener getLayoutAnimationListener();
     method public int getLayoutMode();
     method public android.animation.LayoutTransition getLayoutTransition();
+    method public int getNestedScrollAxes();
     method public int getPersistentDrawingCache();
+    method public boolean getTouchscreenBlocksFocus();
     method public int indexOfChild(android.view.View);
     method public final void invalidateChild(android.view.View, android.graphics.Rect);
     method public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
@@ -28465,6 +33957,7 @@
     method protected boolean isChildrenDrawingOrderEnabled();
     method protected boolean isChildrenDrawnWithCacheEnabled();
     method public boolean isMotionEventSplittingEnabled();
+    method public boolean isTransitionGroup();
     method public final void layout(int, int, int, int);
     method protected void measureChild(android.view.View, int, int);
     method protected void measureChildWithMargins(android.view.View, int, int, int, int);
@@ -28475,8 +33968,15 @@
     method public boolean onInterceptHoverEvent(android.view.MotionEvent);
     method public boolean onInterceptTouchEvent(android.view.MotionEvent);
     method protected abstract void onLayout(boolean, int, int, int, int);
+    method public boolean onNestedFling(android.view.View, float, float, boolean);
+    method public boolean onNestedPreFling(android.view.View, float, float);
+    method public void onNestedPreScroll(android.view.View, int, int, int[]);
+    method public void onNestedScroll(android.view.View, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
     method protected boolean onRequestFocusInDescendants(int, android.graphics.Rect);
     method public boolean onRequestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int);
+    method public void onStopNestedScroll(android.view.View);
     method public void recomputeViewAttributes(android.view.View);
     method public void removeAllViews();
     method public void removeAllViewsInLayout();
@@ -28509,6 +34009,8 @@
     method public void setOnHierarchyChangeListener(android.view.ViewGroup.OnHierarchyChangeListener);
     method public void setPersistentDrawingCache(int);
     method protected void setStaticTransformationsEnabled(boolean);
+    method public void setTouchscreenBlocksFocus(boolean);
+    method public void setTransitionGroup(boolean);
     method public boolean shouldDelayChildPressedState();
     method public boolean showContextMenuForChild(android.view.View);
     method public android.view.ActionMode startActionModeForChild(android.view.View, android.view.ActionMode.Callback);
@@ -28576,6 +34078,14 @@
     method public abstract void updateViewLayout(android.view.View, android.view.ViewGroup.LayoutParams);
   }
 
+  public abstract class ViewOutlineProvider {
+    ctor public ViewOutlineProvider();
+    method public abstract void getOutline(android.view.View, android.graphics.Outline);
+    field public static final android.view.ViewOutlineProvider BACKGROUND;
+    field public static final android.view.ViewOutlineProvider BOUNDS;
+    field public static final android.view.ViewOutlineProvider PADDED_BOUNDS;
+  }
+
   public class ViewOverlay {
     method public void add(android.graphics.drawable.Drawable);
     method public void clear();
@@ -28606,6 +34116,13 @@
     method public abstract boolean isTextAlignmentResolved();
     method public abstract boolean isTextDirectionResolved();
     method public abstract void notifySubtreeAccessibilityStateChanged(android.view.View, android.view.View, int);
+    method public abstract boolean onNestedFling(android.view.View, float, float, boolean);
+    method public abstract boolean onNestedPreFling(android.view.View, float, float);
+    method public abstract void onNestedPreScroll(android.view.View, int, int, int[]);
+    method public abstract void onNestedScroll(android.view.View, int, int, int, int);
+    method public abstract void onNestedScrollAccepted(android.view.View, android.view.View, int);
+    method public abstract boolean onStartNestedScroll(android.view.View, android.view.View, int);
+    method public abstract void onStopNestedScroll(android.view.View);
     method public abstract void recomputeViewAttributes(android.view.View);
     method public abstract void requestChildFocus(android.view.View, android.view.View);
     method public abstract boolean requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean);
@@ -28645,6 +34162,8 @@
     method public android.view.ViewPropertyAnimator translationXBy(float);
     method public android.view.ViewPropertyAnimator translationY(float);
     method public android.view.ViewPropertyAnimator translationYBy(float);
+    method public android.view.ViewPropertyAnimator translationZ(float);
+    method public android.view.ViewPropertyAnimator translationZBy(float);
     method public android.view.ViewPropertyAnimator withEndAction(java.lang.Runnable);
     method public android.view.ViewPropertyAnimator withLayer();
     method public android.view.ViewPropertyAnimator withStartAction(java.lang.Runnable);
@@ -28652,6 +34171,8 @@
     method public android.view.ViewPropertyAnimator xBy(float);
     method public android.view.ViewPropertyAnimator y(float);
     method public android.view.ViewPropertyAnimator yBy(float);
+    method public android.view.ViewPropertyAnimator z(float);
+    method public android.view.ViewPropertyAnimator zBy(float);
   }
 
   public final class ViewStub extends android.view.View {
@@ -28659,6 +34180,7 @@
     ctor public ViewStub(android.content.Context, int);
     ctor public ViewStub(android.content.Context, android.util.AttributeSet);
     ctor public ViewStub(android.content.Context, android.util.AttributeSet, int);
+    ctor public ViewStub(android.content.Context, android.util.AttributeSet, int, int);
     method public int getInflatedId();
     method public android.view.LayoutInflater getLayoutInflater();
     method public int getLayoutResource();
@@ -28738,16 +34260,33 @@
     method public abstract void closeAllPanels();
     method public abstract void closePanel(int);
     method public android.view.View findViewById(int);
+    method public boolean getAllowEnterTransitionOverlap();
+    method public boolean getAllowReturnTransitionOverlap();
     method public final android.view.WindowManager.LayoutParams getAttributes();
     method public final android.view.Window.Callback getCallback();
     method public final android.view.Window getContainer();
+    method public android.transition.Scene getContentScene();
     method public final android.content.Context getContext();
     method public abstract android.view.View getCurrentFocus();
     method public abstract android.view.View getDecorView();
+    method public android.transition.Transition getEnterTransition();
+    method public android.transition.Transition getExitTransition();
     method protected final int getFeatures();
     method protected final int getForcedWindowFlags();
     method public abstract android.view.LayoutInflater getLayoutInflater();
     method protected final int getLocalFeatures();
+    method public android.media.session.MediaController getMediaController();
+    method public abstract int getNavigationBarColor();
+    method public android.transition.Transition getReenterTransition();
+    method public android.transition.Transition getReturnTransition();
+    method public android.transition.Transition getSharedElementEnterTransition();
+    method public android.transition.Transition getSharedElementExitTransition();
+    method public android.transition.Transition getSharedElementReenterTransition();
+    method public android.transition.Transition getSharedElementReturnTransition();
+    method public boolean getSharedElementsUseOverlay();
+    method public abstract int getStatusBarColor();
+    method public long getTransitionBackgroundFadeDuration();
+    method public android.transition.TransitionManager getTransitionManager();
     method public abstract int getVolumeControlStream();
     method public android.view.WindowManager getWindowManager();
     method public final android.content.res.TypedArray getWindowStyle();
@@ -28770,6 +34309,8 @@
     method public boolean requestFeature(int);
     method public abstract void restoreHierarchyState(android.os.Bundle);
     method public abstract android.os.Bundle saveHierarchyState();
+    method public void setAllowEnterTransitionOverlap(boolean);
+    method public void setAllowReturnTransitionOverlap(boolean);
     method public void setAttributes(android.view.WindowManager.LayoutParams);
     method public abstract void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setBackgroundDrawableResource(int);
@@ -28782,6 +34323,8 @@
     method public abstract void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method protected void setDefaultWindowFormat(int);
     method public void setDimAmount(float);
+    method public void setEnterTransition(android.transition.Transition);
+    method public void setExitTransition(android.transition.Transition);
     method public abstract void setFeatureDrawable(int, android.graphics.drawable.Drawable);
     method public abstract void setFeatureDrawableAlpha(int, int);
     method public abstract void setFeatureDrawableResource(int, int);
@@ -28794,9 +34337,21 @@
     method public void setLayout(int, int);
     method public void setLocalFocus(boolean, boolean);
     method public void setLogo(int);
+    method public void setMediaController(android.media.session.MediaController);
+    method public abstract void setNavigationBarColor(int);
+    method public void setReenterTransition(android.transition.Transition);
+    method public void setReturnTransition(android.transition.Transition);
+    method public void setSharedElementEnterTransition(android.transition.Transition);
+    method public void setSharedElementExitTransition(android.transition.Transition);
+    method public void setSharedElementReenterTransition(android.transition.Transition);
+    method public void setSharedElementReturnTransition(android.transition.Transition);
+    method public void setSharedElementsUseOverlay(boolean);
     method public void setSoftInputMode(int);
+    method public abstract void setStatusBarColor(int);
     method public abstract void setTitle(java.lang.CharSequence);
-    method public abstract void setTitleColor(int);
+    method public abstract deprecated void setTitleColor(int);
+    method public void setTransitionBackgroundFadeDuration(long);
+    method public void setTransitionManager(android.transition.TransitionManager);
     method public void setType(int);
     method public void setUiOptions(int);
     method public void setUiOptions(int, int);
@@ -28817,6 +34372,8 @@
     field public static final int FEATURE_ACTION_BAR = 8; // 0x8
     field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
     field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+    field public static final int FEATURE_ACTIVITY_TRANSITIONS = 13; // 0xd
+    field public static final int FEATURE_CONTENT_TRANSITIONS = 12; // 0xc
     field public static final int FEATURE_CONTEXT_MENU = 6; // 0x6
     field public static final int FEATURE_CUSTOM_TITLE = 7; // 0x7
     field public static final int FEATURE_INDETERMINATE_PROGRESS = 5; // 0x5
@@ -28827,6 +34384,7 @@
     field public static final int FEATURE_RIGHT_ICON = 4; // 0x4
     field public static final int FEATURE_SWIPE_TO_DISMISS = 11; // 0xb
     field public static final int ID_ANDROID_CONTENT = 16908290; // 0x1020002
+    field public static final java.lang.String NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME = "android:navigation:background";
     field public static final int PROGRESS_END = 10000; // 0x2710
     field public static final int PROGRESS_INDETERMINATE_OFF = -4; // 0xfffffffc
     field public static final int PROGRESS_INDETERMINATE_ON = -3; // 0xfffffffd
@@ -28835,6 +34393,7 @@
     field public static final int PROGRESS_START = 0; // 0x0
     field public static final int PROGRESS_VISIBILITY_OFF = -2; // 0xfffffffe
     field public static final int PROGRESS_VISIBILITY_ON = -1; // 0xffffffff
+    field public static final java.lang.String STATUS_BAR_BACKGROUND_TRANSITION_NAME = "android:status:background";
   }
 
   public static abstract interface Window.Callback {
@@ -28861,6 +34420,20 @@
     method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback);
   }
 
+  public final class WindowAnimationFrameStats extends android.view.FrameStats implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public final class WindowContentFrameStats extends android.view.FrameStats implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getFramePostedTimeNano(int);
+    method public long getFrameReadyTimeNano(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public class WindowId implements android.os.Parcelable {
     method public int describeContents();
     method public boolean isFocused();
@@ -28878,15 +34451,23 @@
 
   public final class WindowInsets {
     ctor public WindowInsets(android.view.WindowInsets);
+    method public android.view.WindowInsets consumeStableInsets();
     method public android.view.WindowInsets consumeSystemWindowInsets();
+    method public int getStableInsetBottom();
+    method public int getStableInsetLeft();
+    method public int getStableInsetRight();
+    method public int getStableInsetTop();
     method public int getSystemWindowInsetBottom();
     method public int getSystemWindowInsetLeft();
     method public int getSystemWindowInsetRight();
     method public int getSystemWindowInsetTop();
     method public boolean hasInsets();
+    method public boolean hasStableInsets();
     method public boolean hasSystemWindowInsets();
+    method public boolean isConsumed();
     method public boolean isRound();
     method public android.view.WindowInsets replaceSystemWindowInsets(int, int, int, int);
+    method public android.view.WindowInsets replaceSystemWindowInsets(android.graphics.Rect);
   }
 
   public abstract interface WindowManager implements android.view.ViewManager {
@@ -28936,6 +34517,7 @@
     field public static final int FLAG_DIM_BEHIND = 2; // 0x2
     field public static final int FLAG_DISMISS_KEYGUARD = 4194304; // 0x400000
     field public static final deprecated int FLAG_DITHER = 4096; // 0x1000
+    field public static final int FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = -2147483648; // 0x80000000
     field public static final int FLAG_FORCE_NOT_FULLSCREEN = 2048; // 0x800
     field public static final int FLAG_FULLSCREEN = 1024; // 0x400
     field public static final int FLAG_HARDWARE_ACCELERATED = 16777216; // 0x1000000
@@ -29000,7 +34582,6 @@
     field public static final int TYPE_CHANGED = 2; // 0x2
     field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db
     field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc
-    field public static final int TYPE_KEYGUARD = 2004; // 0x7d4
     field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
     field public static final int TYPE_PHONE = 2002; // 0x7d2
     field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
@@ -29024,6 +34605,7 @@
     field public float horizontalWeight;
     field public deprecated int memoryType;
     field public java.lang.String packageName;
+    field public float preferredRefreshRate;
     field public int rotationAnimation;
     field public float screenBrightness;
     field public int screenOrientation;
@@ -29093,6 +34675,7 @@
     field public static final int TYPE_VIEW_TEXT_CHANGED = 16; // 0x10
     field public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
     field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
+    field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
     field public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
     field public static final int TYPE_WINDOW_STATE_CHANGED = 32; // 0x20
   }
@@ -29125,7 +34708,8 @@
   }
 
   public class AccessibilityNodeInfo implements android.os.Parcelable {
-    method public void addAction(int);
+    method public void addAction(android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction);
+    method public deprecated void addAction(int);
     method public void addChild(android.view.View);
     method public void addChild(android.view.View, int);
     method public boolean canOpenPopup();
@@ -29134,7 +34718,8 @@
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByViewId(java.lang.String);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public android.view.accessibility.AccessibilityNodeInfo focusSearch(int);
-    method public int getActions();
+    method public java.util.List<android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction> getActionList();
+    method public deprecated int getActions();
     method public void getBoundsInParent(android.graphics.Rect);
     method public void getBoundsInScreen(android.graphics.Rect);
     method public android.view.accessibility.AccessibilityNodeInfo getChild(int);
@@ -29143,11 +34728,13 @@
     method public android.view.accessibility.AccessibilityNodeInfo.CollectionInfo getCollectionInfo();
     method public android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo getCollectionItemInfo();
     method public java.lang.CharSequence getContentDescription();
+    method public java.lang.CharSequence getError();
     method public android.os.Bundle getExtras();
     method public int getInputType();
     method public android.view.accessibility.AccessibilityNodeInfo getLabelFor();
     method public android.view.accessibility.AccessibilityNodeInfo getLabeledBy();
     method public int getLiveRegion();
+    method public int getMaxTextLength();
     method public int getMovementGranularities();
     method public java.lang.CharSequence getPackageName();
     method public android.view.accessibility.AccessibilityNodeInfo getParent();
@@ -29156,6 +34743,7 @@
     method public int getTextSelectionEnd();
     method public int getTextSelectionStart();
     method public java.lang.String getViewIdResourceName();
+    method public android.view.accessibility.AccessibilityWindowInfo getWindow();
     method public int getWindowId();
     method public boolean isAccessibilityFocused();
     method public boolean isCheckable();
@@ -29181,6 +34769,10 @@
     method public boolean performAction(int, android.os.Bundle);
     method public void recycle();
     method public boolean refresh();
+    method public deprecated void removeAction(int);
+    method public boolean removeAction(android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction);
+    method public boolean removeChild(android.view.View);
+    method public boolean removeChild(android.view.View, int);
     method public void setAccessibilityFocused(boolean);
     method public void setBoundsInParent(android.graphics.Rect);
     method public void setBoundsInScreen(android.graphics.Rect);
@@ -29196,6 +34788,7 @@
     method public void setDismissable(boolean);
     method public void setEditable(boolean);
     method public void setEnabled(boolean);
+    method public void setError(java.lang.CharSequence);
     method public void setFocusable(boolean);
     method public void setFocused(boolean);
     method public void setInputType(int);
@@ -29205,6 +34798,7 @@
     method public void setLabeledBy(android.view.View, int);
     method public void setLiveRegion(int);
     method public void setLongClickable(boolean);
+    method public void setMaxTextLength(int);
     method public void setMovementGranularities(int);
     method public void setMultiLine(boolean);
     method public void setPackageName(java.lang.CharSequence);
@@ -29227,6 +34821,7 @@
     field public static final java.lang.String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
     field public static final java.lang.String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
     field public static final java.lang.String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
     field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
     field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
     field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
@@ -29247,6 +34842,7 @@
     field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
     field public static final int ACTION_SELECT = 4; // 0x4
     field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
+    field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
     field public static final int FOCUS_INPUT = 1; // 0x1
@@ -29257,11 +34853,44 @@
     field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
   }
 
+  public static final class AccessibilityNodeInfo.AccessibilityAction {
+    ctor public AccessibilityNodeInfo.AccessibilityAction(int, java.lang.CharSequence);
+    method public int getId();
+    method public java.lang.CharSequence getLabel();
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_ACCESSIBILITY_FOCUS;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_CLEAR_FOCUS;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_CLEAR_SELECTION;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_CLICK;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_COLLAPSE;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_COPY;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_CUT;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_DISMISS;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_EXPAND;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_FOCUS;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_LONG_CLICK;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_NEXT_HTML_ELEMENT;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PASTE;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PREVIOUS_HTML_ELEMENT;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_BACKWARD;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_FORWARD;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SELECT;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_SELECTION;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_TEXT;
+  }
+
   public static final class AccessibilityNodeInfo.CollectionInfo {
     method public int getColumnCount();
     method public int getRowCount();
+    method public int getSelectionMode();
     method public boolean isHierarchical();
     method public static android.view.accessibility.AccessibilityNodeInfo.CollectionInfo obtain(int, int, boolean);
+    method public static android.view.accessibility.AccessibilityNodeInfo.CollectionInfo obtain(int, int, boolean, int);
+    field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
+    field public static final int SELECTION_MODE_NONE = 0; // 0x0
+    field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
   }
 
   public static final class AccessibilityNodeInfo.CollectionItemInfo {
@@ -29270,7 +34899,9 @@
     method public int getRowIndex();
     method public int getRowSpan();
     method public boolean isHeading();
+    method public boolean isSelected();
     method public static android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo obtain(int, int, int, int, boolean);
+    method public static android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo obtain(int, int, int, int, boolean, boolean);
   }
 
   public static final class AccessibilityNodeInfo.RangeInfo {
@@ -29290,6 +34921,7 @@
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public boolean performAction(int, int, android.os.Bundle);
+    field public static final int HOST_VIEW_ID = -1; // 0xffffffff
   }
 
   public class AccessibilityRecord {
@@ -29341,6 +34973,29 @@
     method public void setToIndex(int);
   }
 
+  public final class AccessibilityWindowInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public void getBoundsInScreen(android.graphics.Rect);
+    method public android.view.accessibility.AccessibilityWindowInfo getChild(int);
+    method public int getChildCount();
+    method public int getId();
+    method public int getLayer();
+    method public android.view.accessibility.AccessibilityWindowInfo getParent();
+    method public android.view.accessibility.AccessibilityNodeInfo getRoot();
+    method public int getType();
+    method public boolean isAccessibilityFocused();
+    method public boolean isActive();
+    method public boolean isFocused();
+    method public static android.view.accessibility.AccessibilityWindowInfo obtain();
+    method public static android.view.accessibility.AccessibilityWindowInfo obtain(android.view.accessibility.AccessibilityWindowInfo);
+    method public void recycle();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int TYPE_APPLICATION = 1; // 0x1
+    field public static final int TYPE_INPUT_METHOD = 2; // 0x2
+    field public static final int TYPE_SYSTEM = 3; // 0x3
+  }
+
   public class CaptioningManager {
     method public void addCaptioningChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener);
     method public final float getFontScale();
@@ -29352,13 +35007,22 @@
 
   public static final class CaptioningManager.CaptionStyle {
     method public android.graphics.Typeface getTypeface();
+    method public boolean hasBackgroundColor();
+    method public boolean hasEdgeColor();
+    method public boolean hasEdgeType();
+    method public boolean hasForegroundColor();
+    method public boolean hasWindowColor();
+    field public static final int EDGE_TYPE_DEPRESSED = 4; // 0x4
     field public static final int EDGE_TYPE_DROP_SHADOW = 2; // 0x2
     field public static final int EDGE_TYPE_NONE = 0; // 0x0
     field public static final int EDGE_TYPE_OUTLINE = 1; // 0x1
+    field public static final int EDGE_TYPE_RAISED = 3; // 0x3
+    field public static final int EDGE_TYPE_UNSPECIFIED = -1; // 0xffffffff
     field public final int backgroundColor;
     field public final int edgeColor;
     field public final int edgeType;
     field public final int foregroundColor;
+    field public final int windowColor;
   }
 
   public static abstract class CaptioningManager.CaptioningChangeListener {
@@ -29596,6 +35260,14 @@
     method public float getInterpolation(float);
   }
 
+  public class PathInterpolator implements android.view.animation.Interpolator {
+    ctor public PathInterpolator(android.graphics.Path);
+    ctor public PathInterpolator(float, float);
+    ctor public PathInterpolator(float, float, float, float);
+    ctor public PathInterpolator(android.content.Context, android.util.AttributeSet);
+    method public float getInterpolation(float);
+  }
+
   public class RotateAnimation extends android.view.animation.Animation {
     ctor public RotateAnimation(android.content.Context, android.util.AttributeSet);
     ctor public RotateAnimation(float, float);
@@ -29663,6 +35335,7 @@
     method public boolean performPrivateCommand(java.lang.String, android.os.Bundle);
     method public static final void removeComposingSpans(android.text.Spannable);
     method public boolean reportFullscreenMode(boolean);
+    method public boolean requestCursorUpdates(int);
     method public boolean sendKeyEvent(android.view.KeyEvent);
     method public boolean setComposingRegion(int, int);
     method public static void setComposingSpans(android.text.Spannable);
@@ -29692,6 +35365,39 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
+  public final class CursorAnchorInfo implements android.os.Parcelable {
+    ctor public CursorAnchorInfo(android.os.Parcel);
+    method public int describeContents();
+    method public android.graphics.RectF getCharacterBounds(int);
+    method public int getCharacterBoundsFlags(int);
+    method public java.lang.CharSequence getComposingText();
+    method public int getComposingTextStart();
+    method public float getInsertionMarkerBaseline();
+    method public float getInsertionMarkerBottom();
+    method public int getInsertionMarkerFlags();
+    method public float getInsertionMarkerHorizontal();
+    method public float getInsertionMarkerTop();
+    method public android.graphics.Matrix getMatrix();
+    method public int getSelectionEnd();
+    method public int getSelectionStart();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int FLAG_HAS_INVISIBLE_REGION = 2; // 0x2
+    field public static final int FLAG_HAS_VISIBLE_REGION = 1; // 0x1
+    field public static final int FLAG_IS_RTL = 4; // 0x4
+  }
+
+  public static final class CursorAnchorInfo.Builder {
+    ctor public CursorAnchorInfo.Builder();
+    method public android.view.inputmethod.CursorAnchorInfo.Builder addCharacterBounds(int, float, float, float, float, int);
+    method public android.view.inputmethod.CursorAnchorInfo build();
+    method public void reset();
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setComposingText(int, java.lang.CharSequence);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, int);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setMatrix(android.graphics.Matrix);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setSelectionRange(int, int);
+  }
+
   public class EditorInfo implements android.text.InputType android.os.Parcelable {
     ctor public EditorInfo();
     method public int describeContents();
@@ -29789,10 +35495,13 @@
     method public abstract boolean performEditorAction(int);
     method public abstract boolean performPrivateCommand(java.lang.String, android.os.Bundle);
     method public abstract boolean reportFullscreenMode(boolean);
+    method public abstract boolean requestCursorUpdates(int);
     method public abstract boolean sendKeyEvent(android.view.KeyEvent);
     method public abstract boolean setComposingRegion(int, int);
     method public abstract boolean setComposingText(java.lang.CharSequence, int);
     method public abstract boolean setSelection(int, int);
+    field public static final int CURSOR_UPDATE_IMMEDIATE = 1; // 0x1
+    field public static final int CURSOR_UPDATE_MONITOR = 2; // 0x2
     field public static final int GET_EXTRACTED_TEXT_MONITOR = 1; // 0x1
     field public static final int GET_TEXT_WITH_STYLES = 1; // 0x1
   }
@@ -29816,6 +35525,7 @@
     method public boolean performEditorAction(int);
     method public boolean performPrivateCommand(java.lang.String, android.os.Bundle);
     method public boolean reportFullscreenMode(boolean);
+    method public boolean requestCursorUpdates(int);
     method public boolean sendKeyEvent(android.view.KeyEvent);
     method public boolean setComposingRegion(int, int);
     method public boolean setComposingText(java.lang.CharSequence, int);
@@ -29881,7 +35591,7 @@
     method public boolean isActive(android.view.View);
     method public boolean isActive();
     method public boolean isFullscreenMode();
-    method public boolean isWatchingCursor(android.view.View);
+    method public deprecated boolean isWatchingCursor(android.view.View);
     method public void restartInput(android.view.View);
     method public void sendAppPrivateCommand(android.view.View, java.lang.String, android.os.Bundle);
     method public void setAdditionalInputMethodSubtypes(java.lang.String, android.view.inputmethod.InputMethodSubtype[]);
@@ -29899,7 +35609,8 @@
     method public boolean switchToNextInputMethod(android.os.IBinder, boolean);
     method public void toggleSoftInput(int, int);
     method public void toggleSoftInputFromWindow(android.os.IBinder, int, int);
-    method public void updateCursor(android.view.View, int, int, int, int);
+    method public deprecated void updateCursor(android.view.View, int, int, int, int);
+    method public void updateCursorAnchorInfo(android.view.View, android.view.inputmethod.CursorAnchorInfo);
     method public void updateExtractedText(android.view.View, int, android.view.inputmethod.ExtractedText);
     method public void updateSelection(android.view.View, int, int, int, int);
     method public void viewClicked(android.view.View);
@@ -29922,6 +35633,7 @@
     method public abstract void finishInput();
     method public abstract void toggleSoftInput(int, int);
     method public abstract void updateCursor(android.graphics.Rect);
+    method public abstract void updateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo);
     method public abstract void updateExtractedText(int, android.view.inputmethod.ExtractedText);
     method public abstract void updateSelection(int, int, int, int, int, int);
     method public abstract void viewClicked(boolean);
@@ -30045,8 +35757,10 @@
   public final class TextInfo implements android.os.Parcelable {
     ctor public TextInfo(java.lang.String);
     ctor public TextInfo(java.lang.String, int, int);
+    ctor public TextInfo(java.lang.CharSequence, int, int, int, int);
     ctor public TextInfo(android.os.Parcel);
     method public int describeContents();
+    method public java.lang.CharSequence getCharSequence();
     method public int getCookie();
     method public int getSequence();
     method public java.lang.String getText();
@@ -30062,6 +35776,17 @@
 
 package android.webkit {
 
+  public abstract class ClientCertRequest {
+    ctor public ClientCertRequest();
+    method public abstract void cancel();
+    method public abstract java.lang.String getHost();
+    method public abstract java.lang.String[] getKeyTypes();
+    method public abstract int getPort();
+    method public abstract java.security.Principal[] getPrincipals();
+    method public abstract void ignore();
+    method public abstract void proceed(java.security.PrivateKey, java.security.cert.X509Certificate[]);
+  }
+
   public class ConsoleMessage {
     ctor public ConsoleMessage(java.lang.String, java.lang.String, int, android.webkit.ConsoleMessage.MessageLevel);
     method public int lineNumber();
@@ -30082,22 +35807,31 @@
 
   public class CookieManager {
     method public synchronized boolean acceptCookie();
+    method public boolean acceptThirdPartyCookies(android.webkit.WebView);
     method public static boolean allowFileSchemeCookies();
+    method public void flush();
     method public java.lang.String getCookie(java.lang.String);
     method public static synchronized android.webkit.CookieManager getInstance();
     method public synchronized boolean hasCookies();
-    method public void removeAllCookie();
-    method public void removeExpiredCookie();
-    method public void removeSessionCookie();
+    method public deprecated void removeAllCookie();
+    method public void removeAllCookies(android.webkit.ValueCallback<java.lang.Boolean>);
+    method public deprecated void removeExpiredCookie();
+    method public deprecated void removeSessionCookie();
+    method public void removeSessionCookies(android.webkit.ValueCallback<java.lang.Boolean>);
     method public synchronized void setAcceptCookie(boolean);
     method public static void setAcceptFileSchemeCookies(boolean);
+    method public void setAcceptThirdPartyCookies(android.webkit.WebView, boolean);
     method public void setCookie(java.lang.String, java.lang.String);
+    method public void setCookie(java.lang.String, java.lang.String, android.webkit.ValueCallback<java.lang.Boolean>);
   }
 
-  public final class CookieSyncManager extends android.webkit.WebSyncManager {
+  public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
     method public static synchronized android.webkit.CookieSyncManager createInstance(android.content.Context);
     method public static synchronized android.webkit.CookieSyncManager getInstance();
-    method protected void syncFromRamToFlash();
+    method protected deprecated void syncFromRamToFlash();
+    field protected static final java.lang.String LOGTAG = "websync";
+    field protected android.webkit.WebViewDatabase mDataBase;
+    field protected android.os.Handler mHandler;
   }
 
   public class DateSorter {
@@ -30152,6 +35886,17 @@
     method public boolean hasMimeType(java.lang.String);
   }
 
+  public abstract class PermissionRequest {
+    ctor public PermissionRequest();
+    method public abstract void deny();
+    method public abstract android.net.Uri getOrigin();
+    method public abstract java.lang.String[] getResources();
+    method public abstract void grant(java.lang.String[]);
+    field public static final java.lang.String RESOURCE_AUDIO_CAPTURE = "android.webkit.resource.AUDIO_CAPTURE";
+    field public static final java.lang.String RESOURCE_PROTECTED_MEDIA_ID = "android.webkit.resource.PROTECTED_MEDIA_ID";
+    field public static final java.lang.String RESOURCE_VIDEO_CAPTURE = "android.webkit.resource.VIDEO_CAPTURE";
+  }
+
   public abstract interface PluginStub {
     method public abstract android.view.View getEmbeddedView(int, android.content.Context);
     method public abstract android.view.View getFullScreenView(int, android.content.Context);
@@ -30211,6 +35956,8 @@
     method public boolean onJsConfirm(android.webkit.WebView, java.lang.String, java.lang.String, android.webkit.JsResult);
     method public boolean onJsPrompt(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String, android.webkit.JsPromptResult);
     method public deprecated boolean onJsTimeout();
+    method public void onPermissionRequest(android.webkit.PermissionRequest);
+    method public void onPermissionRequestCanceled(android.webkit.PermissionRequest);
     method public void onProgressChanged(android.webkit.WebView, int);
     method public deprecated void onReachedMaxAppCacheSize(long, long, android.webkit.WebStorage.QuotaUpdater);
     method public void onReceivedIcon(android.webkit.WebView, android.graphics.Bitmap);
@@ -30219,12 +35966,27 @@
     method public void onRequestFocus(android.webkit.WebView);
     method public void onShowCustomView(android.view.View, android.webkit.WebChromeClient.CustomViewCallback);
     method public deprecated void onShowCustomView(android.view.View, int, android.webkit.WebChromeClient.CustomViewCallback);
+    method public boolean onShowFileChooser(android.webkit.WebView, android.webkit.ValueCallback<android.net.Uri[]>, android.webkit.WebChromeClient.FileChooserParams);
   }
 
   public static abstract interface WebChromeClient.CustomViewCallback {
     method public abstract void onCustomViewHidden();
   }
 
+  public static abstract class WebChromeClient.FileChooserParams {
+    ctor public WebChromeClient.FileChooserParams();
+    method public abstract android.content.Intent createIntent();
+    method public abstract java.lang.String[] getAcceptTypes();
+    method public abstract java.lang.String getFilenameHint();
+    method public abstract int getMode();
+    method public abstract java.lang.CharSequence getTitle();
+    method public abstract boolean isCaptureEnabled();
+    method public static android.net.Uri[] parseResult(int, android.content.Intent);
+    field public static final int MODE_OPEN = 0; // 0x0
+    field public static final int MODE_OPEN_MULTIPLE = 1; // 0x1
+    field public static final int MODE_SAVE = 3; // 0x3
+  }
+
   public class WebHistoryItem implements java.lang.Cloneable {
     method public android.graphics.Bitmap getFavicon();
     method public java.lang.String getOriginalUrl();
@@ -30246,14 +36008,28 @@
     method public abstract void onReceivedIcon(java.lang.String, android.graphics.Bitmap);
   }
 
+  public abstract interface WebResourceRequest {
+    method public abstract java.lang.String getMethod();
+    method public abstract java.util.Map<java.lang.String, java.lang.String> getRequestHeaders();
+    method public abstract android.net.Uri getUrl();
+    method public abstract boolean hasGesture();
+    method public abstract boolean isForMainFrame();
+  }
+
   public class WebResourceResponse {
     ctor public WebResourceResponse(java.lang.String, java.lang.String, java.io.InputStream);
+    ctor public WebResourceResponse(java.lang.String, java.lang.String, int, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, java.io.InputStream);
     method public java.io.InputStream getData();
     method public java.lang.String getEncoding();
     method public java.lang.String getMimeType();
+    method public java.lang.String getReasonPhrase();
+    method public java.util.Map<java.lang.String, java.lang.String> getResponseHeaders();
+    method public int getStatusCode();
     method public void setData(java.io.InputStream);
     method public void setEncoding(java.lang.String);
     method public void setMimeType(java.lang.String);
+    method public void setResponseHeaders(java.util.Map<java.lang.String, java.lang.String>);
+    method public void setStatusCodeAndReasonPhrase(int, java.lang.String);
   }
 
   public abstract class WebSettings {
@@ -30287,6 +36063,7 @@
     method public boolean getMediaPlaybackRequiresUserGesture();
     method public synchronized int getMinimumFontSize();
     method public synchronized int getMinimumLogicalFontSize();
+    method public abstract int getMixedContentMode();
     method public deprecated synchronized android.webkit.WebSettings.PluginState getPluginState();
     method public synchronized java.lang.String getSansSerifFontFamily();
     method public boolean getSaveFormData();
@@ -30331,6 +36108,7 @@
     method public void setMediaPlaybackRequiresUserGesture(boolean);
     method public synchronized void setMinimumFontSize(int);
     method public synchronized void setMinimumLogicalFontSize(int);
+    method public abstract void setMixedContentMode(int);
     method public void setNeedInitialFocus(boolean);
     method public deprecated synchronized void setPluginState(android.webkit.WebSettings.PluginState);
     method public deprecated synchronized void setRenderPriority(android.webkit.WebSettings.RenderPriority);
@@ -30352,6 +36130,9 @@
     field public static final int LOAD_DEFAULT = -1; // 0xffffffff
     field public static final deprecated int LOAD_NORMAL = 0; // 0x0
     field public static final int LOAD_NO_CACHE = 2; // 0x2
+    field public static final int MIXED_CONTENT_ALWAYS_ALLOW = 0; // 0x0
+    field public static final int MIXED_CONTENT_COMPATIBILITY_MODE = 2; // 0x2
+    field public static final int MIXED_CONTENT_NEVER_ALLOW = 1; // 0x1
   }
 
   public static final class WebSettings.LayoutAlgorithm extends java.lang.Enum {
@@ -30417,7 +36198,7 @@
     method public abstract void updateQuota(long);
   }
 
-   abstract class WebSyncManager implements java.lang.Runnable {
+   abstract deprecated class WebSyncManager implements java.lang.Runnable {
     ctor protected WebSyncManager(android.content.Context, java.lang.String);
     method protected void onSyncInit();
     method public void resetSync();
@@ -30434,6 +36215,7 @@
     ctor public WebView(android.content.Context);
     ctor public WebView(android.content.Context, android.util.AttributeSet);
     ctor public WebView(android.content.Context, android.util.AttributeSet, int);
+    ctor public WebView(android.content.Context, android.util.AttributeSet, int, int);
     ctor public deprecated WebView(android.content.Context, android.util.AttributeSet, int, boolean);
     method public void addJavascriptInterface(java.lang.Object, java.lang.String);
     method public boolean canGoBack();
@@ -30443,15 +36225,18 @@
     method public deprecated boolean canZoomOut();
     method public deprecated android.graphics.Picture capturePicture();
     method public void clearCache(boolean);
+    method public static void clearClientCertPreferences(java.lang.Runnable);
     method public void clearFormData();
     method public void clearHistory();
     method public void clearMatches();
     method public void clearSslPreferences();
     method public deprecated void clearView();
     method public android.webkit.WebBackForwardList copyBackForwardList();
-    method public android.print.PrintDocumentAdapter createPrintDocumentAdapter();
+    method public deprecated android.print.PrintDocumentAdapter createPrintDocumentAdapter();
+    method public android.print.PrintDocumentAdapter createPrintDocumentAdapter(java.lang.String);
     method public void destroy();
     method public void documentHasImages(android.os.Message);
+    method public static void enableSlowWholeDocumentDraw();
     method public void evaluateJavascript(java.lang.String, android.webkit.ValueCallback<java.lang.String>);
     method public static java.lang.String findAddress(java.lang.String);
     method public deprecated int findAll(java.lang.String);
@@ -30515,6 +36300,7 @@
     method public void setWebViewClient(android.webkit.WebViewClient);
     method public deprecated boolean showFindDialog(java.lang.String, boolean);
     method public void stopLoading();
+    method public void zoomBy(float);
     method public boolean zoomIn();
     method public boolean zoomOut();
     field public static final java.lang.String SCHEME_GEO = "geo:0,0?q=";
@@ -30558,14 +36344,17 @@
     method public void onLoadResource(android.webkit.WebView, java.lang.String);
     method public void onPageFinished(android.webkit.WebView, java.lang.String);
     method public void onPageStarted(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
+    method public void onReceivedClientCertRequest(android.webkit.WebView, android.webkit.ClientCertRequest);
     method public void onReceivedError(android.webkit.WebView, int, java.lang.String, java.lang.String);
     method public void onReceivedHttpAuthRequest(android.webkit.WebView, android.webkit.HttpAuthHandler, java.lang.String, java.lang.String);
     method public void onReceivedLoginRequest(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String);
     method public void onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError);
     method public void onScaleChanged(android.webkit.WebView, float, float);
     method public deprecated void onTooManyRedirects(android.webkit.WebView, android.os.Message, android.os.Message);
-    method public void onUnhandledKeyEvent(android.webkit.WebView, android.view.KeyEvent);
-    method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebView, java.lang.String);
+    method public void onUnhandledInputEvent(android.webkit.WebView, android.view.InputEvent);
+    method public deprecated void onUnhandledKeyEvent(android.webkit.WebView, android.view.KeyEvent);
+    method public deprecated android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebView, java.lang.String);
+    method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebView, android.webkit.WebResourceRequest);
     method public boolean shouldOverrideKeyEvent(android.webkit.WebView, android.view.KeyEvent);
     method public boolean shouldOverrideUrlLoading(android.webkit.WebView, java.lang.String);
     field public static final int ERROR_AUTHENTICATION = -4; // 0xfffffffc
@@ -30608,12 +36397,14 @@
     ctor public AbsListView(android.content.Context);
     ctor public AbsListView(android.content.Context, android.util.AttributeSet);
     ctor public AbsListView(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsListView(android.content.Context, android.util.AttributeSet, int, int);
     method public void afterTextChanged(android.text.Editable);
     method public void beforeTextChanged(java.lang.CharSequence, int, int, int);
     method public boolean canScrollList(int);
     method public void clearChoices();
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
+    method public void fling(int);
     method public int getCacheColorHint();
     method public int getCheckedItemCount();
     method public long[] getCheckedItemIds();
@@ -30659,6 +36450,7 @@
     method public void setDrawSelectorOnTop(boolean);
     method public void setFastScrollAlwaysVisible(boolean);
     method public void setFastScrollEnabled(boolean);
+    method public void setFastScrollStyle(int);
     method public void setFilterText(java.lang.String);
     method public void setFriction(float);
     method public void setItemChecked(int, boolean);
@@ -30668,6 +36460,7 @@
     method public void setRemoteViewsAdapter(android.content.Intent);
     method public void setScrollIndicators(android.view.View, android.view.View);
     method public void setScrollingCacheEnabled(boolean);
+    method public void setSelectionFromTop(int, int);
     method public void setSelector(int);
     method public void setSelector(android.graphics.drawable.Drawable);
     method public void setSmoothScrollbarEnabled(boolean);
@@ -30721,18 +36514,26 @@
     ctor public AbsSeekBar(android.content.Context);
     ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet);
     ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet, int, int);
     method public int getKeyProgressIncrement();
+    method public boolean getSplitTrack();
     method public android.graphics.drawable.Drawable getThumb();
     method public int getThumbOffset();
+    method public android.content.res.ColorStateList getThumbTintList();
+    method public android.graphics.PorterDuff.Mode getThumbTintMode();
     method public void setKeyProgressIncrement(int);
+    method public void setSplitTrack(boolean);
     method public void setThumb(android.graphics.drawable.Drawable);
     method public void setThumbOffset(int);
+    method public void setThumbTintList(android.content.res.ColorStateList);
+    method public void setThumbTintMode(android.graphics.PorterDuff.Mode);
   }
 
   public abstract class AbsSpinner extends android.widget.AdapterView {
     ctor public AbsSpinner(android.content.Context);
     ctor public AbsSpinner(android.content.Context, android.util.AttributeSet);
     ctor public AbsSpinner(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsSpinner(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.SpinnerAdapter getAdapter();
     method public android.view.View getSelectedView();
     method public void onRestoreInstanceState(android.os.Parcelable);
@@ -30747,6 +36548,7 @@
     ctor public AbsoluteLayout(android.content.Context);
     ctor public AbsoluteLayout(android.content.Context, android.util.AttributeSet);
     ctor public AbsoluteLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsoluteLayout(android.content.Context, android.util.AttributeSet, int, int);
     method protected void onLayout(boolean, int, int, int, int);
   }
 
@@ -30759,6 +36561,32 @@
     field public int y;
   }
 
+  public class ActionMenuView extends android.widget.LinearLayout {
+    ctor public ActionMenuView(android.content.Context);
+    ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
+    method public void dismissPopupMenus();
+    method public android.view.Menu getMenu();
+    method public int getPopupTheme();
+    method public boolean hideOverflowMenu();
+    method public boolean isOverflowMenuShowing();
+    method public void onConfigurationChanged(android.content.res.Configuration);
+    method public void onDetachedFromWindow();
+    method public void setOnMenuItemClickListener(android.widget.ActionMenuView.OnMenuItemClickListener);
+    method public void setPopupTheme(int);
+    method public boolean showOverflowMenu();
+  }
+
+  public static class ActionMenuView.LayoutParams extends android.widget.LinearLayout.LayoutParams {
+    ctor public ActionMenuView.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public ActionMenuView.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public ActionMenuView.LayoutParams(android.widget.ActionMenuView.LayoutParams);
+    ctor public ActionMenuView.LayoutParams(int, int);
+  }
+
+  public static abstract interface ActionMenuView.OnMenuItemClickListener {
+    method public abstract boolean onMenuItemClick(android.view.MenuItem);
+  }
+
   public abstract interface Adapter {
     method public abstract int getCount();
     method public abstract java.lang.Object getItem(int);
@@ -30778,6 +36606,7 @@
     ctor public AdapterView(android.content.Context);
     ctor public AdapterView(android.content.Context, android.util.AttributeSet);
     ctor public AdapterView(android.content.Context, android.util.AttributeSet, int);
+    ctor public AdapterView(android.content.Context, android.util.AttributeSet, int, int);
     method public abstract T getAdapter();
     method public int getCount();
     method public android.view.View getEmptyView();
@@ -30831,6 +36660,7 @@
     ctor public AdapterViewAnimator(android.content.Context);
     ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet);
     ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet, int);
+    ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet, int, int);
     method public void advance();
     method public void deferNotifyDataSetChanged();
     method public void fyiWillBeAdvancedByHostKThx();
@@ -30860,6 +36690,8 @@
   public class AdapterViewFlipper extends android.widget.AdapterViewAnimator {
     ctor public AdapterViewFlipper(android.content.Context);
     ctor public AdapterViewFlipper(android.content.Context, android.util.AttributeSet);
+    ctor public AdapterViewFlipper(android.content.Context, android.util.AttributeSet, int);
+    ctor public AdapterViewFlipper(android.content.Context, android.util.AttributeSet, int, int);
     method public int getFlipInterval();
     method public boolean isAutoStart();
     method public boolean isFlipping();
@@ -30890,6 +36722,7 @@
     ctor public AnalogClock(android.content.Context);
     ctor public AnalogClock(android.content.Context, android.util.AttributeSet);
     ctor public AnalogClock(android.content.Context, android.util.AttributeSet, int);
+    ctor public AnalogClock(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class ArrayAdapter extends android.widget.BaseAdapter implements android.widget.Filterable {
@@ -30922,6 +36755,7 @@
     ctor public AutoCompleteTextView(android.content.Context);
     ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet);
     ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int, int);
     method public void clearListSelection();
     method protected java.lang.CharSequence convertSelectionToString(java.lang.Object);
     method public void dismissDropDown();
@@ -31014,12 +36848,14 @@
     ctor public Button(android.content.Context);
     ctor public Button(android.content.Context, android.util.AttributeSet);
     ctor public Button(android.content.Context, android.util.AttributeSet, int);
+    ctor public Button(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class CalendarView extends android.widget.FrameLayout {
     ctor public CalendarView(android.content.Context);
     ctor public CalendarView(android.content.Context, android.util.AttributeSet);
     ctor public CalendarView(android.content.Context, android.util.AttributeSet, int);
+    ctor public CalendarView(android.content.Context, android.util.AttributeSet, int, int);
     method public long getDate();
     method public int getDateTextAppearance();
     method public int getFirstDayOfWeek();
@@ -31061,6 +36897,7 @@
     ctor public CheckBox(android.content.Context);
     ctor public CheckBox(android.content.Context, android.util.AttributeSet);
     ctor public CheckBox(android.content.Context, android.util.AttributeSet, int);
+    ctor public CheckBox(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public abstract interface Checkable {
@@ -31073,10 +36910,15 @@
     ctor public CheckedTextView(android.content.Context);
     ctor public CheckedTextView(android.content.Context, android.util.AttributeSet);
     ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int, int);
     method public android.graphics.drawable.Drawable getCheckMarkDrawable();
+    method public android.content.res.ColorStateList getCheckMarkTintList();
+    method public android.graphics.PorterDuff.Mode getCheckMarkTintMode();
     method public boolean isChecked();
     method public void setCheckMarkDrawable(int);
     method public void setCheckMarkDrawable(android.graphics.drawable.Drawable);
+    method public void setCheckMarkTintList(android.content.res.ColorStateList);
+    method public void setCheckMarkTintMode(android.graphics.PorterDuff.Mode);
     method public void setChecked(boolean);
     method public void toggle();
   }
@@ -31085,6 +36927,7 @@
     ctor public Chronometer(android.content.Context);
     ctor public Chronometer(android.content.Context, android.util.AttributeSet);
     ctor public Chronometer(android.content.Context, android.util.AttributeSet, int);
+    ctor public Chronometer(android.content.Context, android.util.AttributeSet, int, int);
     method public long getBase();
     method public java.lang.String getFormat();
     method public android.widget.Chronometer.OnChronometerTickListener getOnChronometerTickListener();
@@ -31103,9 +36946,14 @@
     ctor public CompoundButton(android.content.Context);
     ctor public CompoundButton(android.content.Context, android.util.AttributeSet);
     ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int, int);
+    method public android.content.res.ColorStateList getButtonTintList();
+    method public android.graphics.PorterDuff.Mode getButtonTintMode();
     method public boolean isChecked();
     method public void setButtonDrawable(int);
     method public void setButtonDrawable(android.graphics.drawable.Drawable);
+    method public void setButtonTintList(android.content.res.ColorStateList);
+    method public void setButtonTintMode(android.graphics.PorterDuff.Mode);
     method public void setChecked(boolean);
     method public void setOnCheckedChangeListener(android.widget.CompoundButton.OnCheckedChangeListener);
     method public void toggle();
@@ -31174,9 +37022,11 @@
     ctor public DatePicker(android.content.Context);
     ctor public DatePicker(android.content.Context, android.util.AttributeSet);
     ctor public DatePicker(android.content.Context, android.util.AttributeSet, int);
+    ctor public DatePicker(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.CalendarView getCalendarView();
     method public boolean getCalendarViewShown();
     method public int getDayOfMonth();
+    method public int getFirstDayOfWeek();
     method public long getMaxDate();
     method public long getMinDate();
     method public int getMonth();
@@ -31184,6 +37034,7 @@
     method public int getYear();
     method public void init(int, int, int, android.widget.DatePicker.OnDateChangedListener);
     method public void setCalendarViewShown(boolean);
+    method public void setFirstDayOfWeek(int);
     method public void setMaxDate(long);
     method public void setMinDate(long);
     method public void setSpinnersShown(boolean);
@@ -31226,10 +37077,14 @@
     ctor public EdgeEffect(android.content.Context);
     method public boolean draw(android.graphics.Canvas);
     method public void finish();
+    method public int getColor();
+    method public int getMaxHeight();
     method public boolean isFinished();
     method public void onAbsorb(int);
     method public void onPull(float);
+    method public void onPull(float, float);
     method public void onRelease();
+    method public void setColor(int);
     method public void setSize(int, int);
   }
 
@@ -31237,6 +37092,7 @@
     ctor public EditText(android.content.Context);
     ctor public EditText(android.content.Context, android.util.AttributeSet);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
+    ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
     method public void selectAll();
     method public void setSelection(int, int);
@@ -31268,6 +37124,7 @@
     ctor public ExpandableListView(android.content.Context);
     ctor public ExpandableListView(android.content.Context, android.util.AttributeSet);
     ctor public ExpandableListView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ExpandableListView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean collapseGroup(int);
     method public boolean expandGroup(int);
     method public boolean expandGroup(int, boolean);
@@ -31357,13 +37214,18 @@
     ctor public FrameLayout(android.content.Context);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public android.graphics.drawable.Drawable getForeground();
     method public int getForegroundGravity();
+    method public android.content.res.ColorStateList getForegroundTintList();
+    method public android.graphics.PorterDuff.Mode getForegroundTintMode();
     method public boolean getMeasureAllChildren();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setForeground(android.graphics.drawable.Drawable);
     method public void setForegroundGravity(int);
+    method public void setForegroundTintList(android.content.res.ColorStateList);
+    method public void setForegroundTintMode(android.graphics.PorterDuff.Mode);
     method public void setMeasureAllChildren(boolean);
   }
 
@@ -31381,6 +37243,7 @@
     ctor public Gallery(android.content.Context);
     ctor public Gallery(android.content.Context, android.util.AttributeSet);
     ctor public Gallery(android.content.Context, android.util.AttributeSet, int);
+    ctor public Gallery(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean onDown(android.view.MotionEvent);
     method public boolean onFling(android.view.MotionEvent, android.view.MotionEvent, float, float);
     method public void onLongPress(android.view.MotionEvent);
@@ -31401,9 +37264,10 @@
   }
 
   public class GridLayout extends android.view.ViewGroup {
-    ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
-    ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context);
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet);
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -31419,6 +37283,10 @@
     method public void setRowCount(int);
     method public void setRowOrderPreserved(boolean);
     method public void setUseDefaultMargins(boolean);
+    method public static android.widget.GridLayout.Spec spec(int, int, android.widget.GridLayout.Alignment, float);
+    method public static android.widget.GridLayout.Spec spec(int, android.widget.GridLayout.Alignment, float);
+    method public static android.widget.GridLayout.Spec spec(int, int, float);
+    method public static android.widget.GridLayout.Spec spec(int, float);
     method public static android.widget.GridLayout.Spec spec(int, int, android.widget.GridLayout.Alignment);
     method public static android.widget.GridLayout.Spec spec(int, android.widget.GridLayout.Alignment);
     method public static android.widget.GridLayout.Spec spec(int, int);
@@ -31461,6 +37329,7 @@
     ctor public GridView(android.content.Context);
     ctor public GridView(android.content.Context, android.util.AttributeSet);
     ctor public GridView(android.content.Context, android.util.AttributeSet, int);
+    ctor public GridView(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.ListAdapter getAdapter();
     method public int getColumnWidth();
     method public int getGravity();
@@ -31518,6 +37387,7 @@
     ctor public HorizontalScrollView(android.content.Context);
     ctor public HorizontalScrollView(android.content.Context, android.util.AttributeSet);
     ctor public HorizontalScrollView(android.content.Context, android.util.AttributeSet, int);
+    ctor public HorizontalScrollView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean arrowScroll(int);
     method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect);
     method public boolean executeKeyEvent(android.view.KeyEvent);
@@ -31537,6 +37407,7 @@
     ctor public ImageButton(android.content.Context);
     ctor public ImageButton(android.content.Context, android.util.AttributeSet);
     ctor public ImageButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public ImageButton(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class ImageSwitcher extends android.widget.ViewSwitcher {
@@ -31551,6 +37422,7 @@
     ctor public ImageView(android.content.Context);
     ctor public ImageView(android.content.Context, android.util.AttributeSet);
     ctor public ImageView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ImageView(android.content.Context, android.util.AttributeSet, int, int);
     method public final void clearColorFilter();
     method public boolean getAdjustViewBounds();
     method public boolean getBaselineAlignBottom();
@@ -31559,6 +37431,8 @@
     method public android.graphics.drawable.Drawable getDrawable();
     method public int getImageAlpha();
     method public android.graphics.Matrix getImageMatrix();
+    method public android.content.res.ColorStateList getImageTintList();
+    method public android.graphics.PorterDuff.Mode getImageTintMode();
     method public int getMaxHeight();
     method public int getMaxWidth();
     method public android.widget.ImageView.ScaleType getScaleType();
@@ -31579,6 +37453,8 @@
     method public void setImageMatrix(android.graphics.Matrix);
     method public void setImageResource(int);
     method public void setImageState(int[], boolean);
+    method public void setImageTintList(android.content.res.ColorStateList);
+    method public void setImageTintMode(android.graphics.PorterDuff.Mode);
     method public void setImageURI(android.net.Uri);
     method public void setMaxHeight(int);
     method public void setMaxWidth(int);
@@ -31602,6 +37478,7 @@
     ctor public LinearLayout(android.content.Context);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -31712,6 +37589,7 @@
     ctor public ListView(android.content.Context);
     ctor public ListView(android.content.Context, android.util.AttributeSet);
     ctor public ListView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ListView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addFooterView(android.view.View, java.lang.Object, boolean);
     method public void addFooterView(android.view.View);
     method public void addHeaderView(android.view.View, java.lang.Object, boolean);
@@ -31741,7 +37619,6 @@
     method public void setOverscrollHeader(android.graphics.drawable.Drawable);
     method public void setSelection(int);
     method public void setSelectionAfterHeaderView();
-    method public void setSelectionFromTop(int, int);
     method public void smoothScrollByOffset(int);
   }
 
@@ -31784,6 +37661,7 @@
     ctor public MultiAutoCompleteTextView(android.content.Context);
     ctor public MultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet);
     ctor public MultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public MultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet, int, int);
     method protected void performFiltering(java.lang.CharSequence, int, int, int);
     method public void setTokenizer(android.widget.MultiAutoCompleteTextView.Tokenizer);
   }
@@ -31805,6 +37683,7 @@
     ctor public NumberPicker(android.content.Context);
     ctor public NumberPicker(android.content.Context, android.util.AttributeSet);
     ctor public NumberPicker(android.content.Context, android.util.AttributeSet, int);
+    ctor public NumberPicker(android.content.Context, android.util.AttributeSet, int, int);
     method public java.lang.String[] getDisplayedValues();
     method public int getMaxValue();
     method public int getMinValue();
@@ -31898,6 +37777,7 @@
     method public int getAnimationStyle();
     method public android.graphics.drawable.Drawable getBackground();
     method public android.view.View getContentView();
+    method public float getElevation();
     method public int getHeight();
     method public int getInputMethodMode();
     method public int getMaxAvailableHeight(android.view.View);
@@ -31915,6 +37795,7 @@
     method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setClippingEnabled(boolean);
     method public void setContentView(android.view.View);
+    method public void setElevation(float);
     method public void setFocusable(boolean);
     method public void setHeight(int);
     method public void setIgnoreCheekPress();
@@ -31950,12 +37831,21 @@
     ctor public ProgressBar(android.content.Context);
     ctor public ProgressBar(android.content.Context, android.util.AttributeSet);
     ctor public ProgressBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public ProgressBar(android.content.Context, android.util.AttributeSet, int, int);
     method public android.graphics.drawable.Drawable getIndeterminateDrawable();
+    method public android.content.res.ColorStateList getIndeterminateTintList();
+    method public android.graphics.PorterDuff.Mode getIndeterminateTintMode();
     method public android.view.animation.Interpolator getInterpolator();
     method public synchronized int getMax();
     method public synchronized int getProgress();
+    method public android.content.res.ColorStateList getProgressBackgroundTintList();
+    method public android.graphics.PorterDuff.Mode getProgressBackgroundTintMode();
     method public android.graphics.drawable.Drawable getProgressDrawable();
+    method public android.content.res.ColorStateList getProgressTintList();
+    method public android.graphics.PorterDuff.Mode getProgressTintMode();
     method public synchronized int getSecondaryProgress();
+    method public android.content.res.ColorStateList getSecondaryProgressTintList();
+    method public android.graphics.PorterDuff.Mode getSecondaryProgressTintMode();
     method public final synchronized void incrementProgressBy(int);
     method public final synchronized void incrementSecondaryProgressBy(int);
     method public synchronized boolean isIndeterminate();
@@ -31963,18 +37853,29 @@
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
     method public void setIndeterminateDrawable(android.graphics.drawable.Drawable);
+    method public void setIndeterminateDrawableTiled(android.graphics.drawable.Drawable);
+    method public void setIndeterminateTintList(android.content.res.ColorStateList);
+    method public void setIndeterminateTintMode(android.graphics.PorterDuff.Mode);
     method public void setInterpolator(android.content.Context, int);
     method public void setInterpolator(android.view.animation.Interpolator);
     method public synchronized void setMax(int);
     method public synchronized void setProgress(int);
+    method public void setProgressBackgroundTintList(android.content.res.ColorStateList);
+    method public void setProgressBackgroundTintMode(android.graphics.PorterDuff.Mode);
     method public void setProgressDrawable(android.graphics.drawable.Drawable);
+    method public void setProgressDrawableTiled(android.graphics.drawable.Drawable);
+    method public void setProgressTintList(android.content.res.ColorStateList);
+    method public void setProgressTintMode(android.graphics.PorterDuff.Mode);
     method public synchronized void setSecondaryProgress(int);
+    method public void setSecondaryProgressTintList(android.content.res.ColorStateList);
+    method public void setSecondaryProgressTintMode(android.graphics.PorterDuff.Mode);
   }
 
   public class QuickContactBadge extends android.widget.ImageView implements android.view.View.OnClickListener {
     ctor public QuickContactBadge(android.content.Context);
     ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet);
     ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet, int);
+    ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet, int, int);
     method public void assignContactFromEmail(java.lang.String, boolean);
     method public void assignContactFromEmail(java.lang.String, boolean, android.os.Bundle);
     method public void assignContactFromPhone(java.lang.String, boolean);
@@ -31984,6 +37885,7 @@
     method public void setExcludeMimes(java.lang.String[]);
     method public void setImageToDefault();
     method public void setMode(int);
+    method public void setOverlay(android.graphics.drawable.Drawable);
     field protected java.lang.String[] mExcludeMimes;
   }
 
@@ -31991,6 +37893,7 @@
     ctor public RadioButton(android.content.Context);
     ctor public RadioButton(android.content.Context, android.util.AttributeSet);
     ctor public RadioButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public RadioButton(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class RadioGroup extends android.widget.LinearLayout {
@@ -32016,6 +37919,7 @@
 
   public class RatingBar extends android.widget.AbsSeekBar {
     ctor public RatingBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public RatingBar(android.content.Context, android.util.AttributeSet, int, int);
     ctor public RatingBar(android.content.Context, android.util.AttributeSet);
     ctor public RatingBar(android.content.Context);
     method public int getNumStars();
@@ -32038,6 +37942,7 @@
     ctor public RelativeLayout(android.content.Context);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -32186,6 +38091,7 @@
     ctor public ScrollView(android.content.Context);
     ctor public ScrollView(android.content.Context, android.util.AttributeSet);
     ctor public ScrollView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ScrollView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean arrowScroll(int);
     method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect);
     method public boolean executeKeyEvent(android.view.KeyEvent);
@@ -32230,6 +38136,8 @@
   public class SearchView extends android.widget.LinearLayout implements android.view.CollapsibleActionView {
     ctor public SearchView(android.content.Context);
     ctor public SearchView(android.content.Context, android.util.AttributeSet);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet, int);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet, int, int);
     method public int getImeOptions();
     method public int getInputType();
     method public int getMaxWidth();
@@ -32284,6 +38192,7 @@
     ctor public SeekBar(android.content.Context);
     ctor public SeekBar(android.content.Context, android.util.AttributeSet);
     ctor public SeekBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public SeekBar(android.content.Context, android.util.AttributeSet, int, int);
     method public void setOnSeekBarChangeListener(android.widget.SeekBar.OnSeekBarChangeListener);
   }
 
@@ -32385,6 +38294,7 @@
   public deprecated class SlidingDrawer extends android.view.ViewGroup {
     ctor public SlidingDrawer(android.content.Context, android.util.AttributeSet);
     ctor public SlidingDrawer(android.content.Context, android.util.AttributeSet, int);
+    ctor public SlidingDrawer(android.content.Context, android.util.AttributeSet, int, int);
     method public void animateClose();
     method public void animateOpen();
     method public void animateToggle();
@@ -32419,6 +38329,7 @@
   }
 
   public final class Space extends android.view.View {
+    ctor public Space(android.content.Context, android.util.AttributeSet, int, int);
     ctor public Space(android.content.Context, android.util.AttributeSet, int);
     ctor public Space(android.content.Context, android.util.AttributeSet);
     ctor public Space(android.content.Context);
@@ -32430,6 +38341,7 @@
     ctor public Spinner(android.content.Context, android.util.AttributeSet);
     ctor public Spinner(android.content.Context, android.util.AttributeSet, int);
     ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int, int);
     method public int getDropDownHorizontalOffset();
     method public int getDropDownVerticalOffset();
     method public int getDropDownWidth();
@@ -32457,12 +38369,16 @@
     ctor public StackView(android.content.Context);
     ctor public StackView(android.content.Context, android.util.AttributeSet);
     ctor public StackView(android.content.Context, android.util.AttributeSet, int);
+    ctor public StackView(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class Switch extends android.widget.CompoundButton {
     ctor public Switch(android.content.Context);
     ctor public Switch(android.content.Context, android.util.AttributeSet);
     ctor public Switch(android.content.Context, android.util.AttributeSet, int);
+    ctor public Switch(android.content.Context, android.util.AttributeSet, int, int);
+    method public boolean getShowText();
+    method public boolean getSplitTrack();
     method public int getSwitchMinWidth();
     method public int getSwitchPadding();
     method public java.lang.CharSequence getTextOff();
@@ -32471,6 +38387,8 @@
     method public int getThumbTextPadding();
     method public android.graphics.drawable.Drawable getTrackDrawable();
     method public void onMeasure(int, int);
+    method public void setShowText(boolean);
+    method public void setSplitTrack(boolean);
     method public void setSwitchMinWidth(int);
     method public void setSwitchPadding(int);
     method public void setSwitchTextAppearance(android.content.Context, int);
@@ -32488,6 +38406,8 @@
   public class TabHost extends android.widget.FrameLayout implements android.view.ViewTreeObserver.OnTouchModeChangeListener {
     ctor public TabHost(android.content.Context);
     ctor public TabHost(android.content.Context, android.util.AttributeSet);
+    ctor public TabHost(android.content.Context, android.util.AttributeSet, int);
+    ctor public TabHost(android.content.Context, android.util.AttributeSet, int, int);
     method public void addTab(android.widget.TabHost.TabSpec);
     method public void clearAllTabs();
     method public int getCurrentTab();
@@ -32527,6 +38447,7 @@
     ctor public TabWidget(android.content.Context);
     ctor public TabWidget(android.content.Context, android.util.AttributeSet);
     ctor public TabWidget(android.content.Context, android.util.AttributeSet, int);
+    ctor public TabWidget(android.content.Context, android.util.AttributeSet, int, int);
     method public void dispatchDraw(android.graphics.Canvas);
     method public void focusCurrentTab(int);
     method public android.view.View getChildTabViewAt(int);
@@ -32589,6 +38510,7 @@
     ctor public TextClock(android.content.Context);
     ctor public TextClock(android.content.Context, android.util.AttributeSet);
     ctor public TextClock(android.content.Context, android.util.AttributeSet, int);
+    ctor public TextClock(android.content.Context, android.util.AttributeSet, int, int);
     method public java.lang.CharSequence getFormat12Hour();
     method public java.lang.CharSequence getFormat24Hour();
     method public java.lang.String getTimeZone();
@@ -32611,6 +38533,7 @@
     ctor public TextView(android.content.Context);
     ctor public TextView(android.content.Context, android.util.AttributeSet);
     ctor public TextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public TextView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addTextChangedListener(android.text.TextWatcher);
     method public final void append(java.lang.CharSequence);
     method public void append(java.lang.CharSequence, int, int);
@@ -32642,6 +38565,7 @@
     method public int getExtendedPaddingBottom();
     method public int getExtendedPaddingTop();
     method public android.text.InputFilter[] getFilters();
+    method public java.lang.String getFontFeatureSettings();
     method public boolean getFreezesText();
     method public int getGravity();
     method public int getHighlightColor();
@@ -32655,6 +38579,7 @@
     method public int getInputType();
     method public final android.text.method.KeyListener getKeyListener();
     method public final android.text.Layout getLayout();
+    method public float getLetterSpacing();
     method public int getLineBounds(int, android.graphics.Rect);
     method public int getLineCount();
     method public int getLineHeight();
@@ -32682,10 +38607,9 @@
     method public float getShadowDx();
     method public float getShadowDy();
     method public float getShadowRadius();
+    method public final boolean getShowSoftInputOnFocus();
     method public java.lang.CharSequence getText();
-    method public static int getTextColor(android.content.Context, android.content.res.TypedArray, int);
     method public final android.content.res.ColorStateList getTextColors();
-    method public static android.content.res.ColorStateList getTextColors(android.content.Context, android.content.res.TypedArray);
     method public java.util.Locale getTextLocale();
     method public float getTextScaleX();
     method public float getTextSize();
@@ -32730,12 +38654,14 @@
     method public void setCursorVisible(boolean);
     method public void setCustomSelectionActionModeCallback(android.view.ActionMode.Callback);
     method public final void setEditableFactory(android.text.Editable.Factory);
+    method public void setElegantTextHeight(boolean);
     method public void setEllipsize(android.text.TextUtils.TruncateAt);
     method public void setEms(int);
     method public void setError(java.lang.CharSequence);
     method public void setError(java.lang.CharSequence, android.graphics.drawable.Drawable);
     method public void setExtractedText(android.view.inputmethod.ExtractedText);
     method public void setFilters(android.text.InputFilter[]);
+    method public void setFontFeatureSettings(java.lang.String);
     method protected boolean setFrame(int, int, int, int);
     method public void setFreezesText(boolean);
     method public void setGravity(int);
@@ -32752,6 +38678,7 @@
     method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public void setInputType(int);
     method public void setKeyListener(android.text.method.KeyListener);
+    method public void setLetterSpacing(float);
     method public void setLineSpacing(float, float);
     method public void setLines(int);
     method public final void setLinkTextColor(int);
@@ -32774,6 +38701,7 @@
     method public void setScroller(android.widget.Scroller);
     method public void setSelectAllOnFocus(boolean);
     method public void setShadowLayer(float, float, float, int);
+    method public final void setShowSoftInputOnFocus(boolean);
     method public void setSingleLine();
     method public void setSingleLine(boolean);
     method public final void setSpannableFactory(android.text.Spannable.Factory);
@@ -32818,6 +38746,7 @@
     ctor public TimePicker(android.content.Context);
     ctor public TimePicker(android.content.Context, android.util.AttributeSet);
     ctor public TimePicker(android.content.Context, android.util.AttributeSet, int);
+    ctor public TimePicker(android.content.Context, android.util.AttributeSet, int, int);
     method public java.lang.Integer getCurrentHour();
     method public java.lang.Integer getCurrentMinute();
     method public boolean is24HourView();
@@ -32855,6 +38784,7 @@
   }
 
   public class ToggleButton extends android.widget.CompoundButton {
+    ctor public ToggleButton(android.content.Context, android.util.AttributeSet, int, int);
     ctor public ToggleButton(android.content.Context, android.util.AttributeSet, int);
     ctor public ToggleButton(android.content.Context, android.util.AttributeSet);
     ctor public ToggleButton(android.content.Context);
@@ -32864,10 +38794,74 @@
     method public void setTextOn(java.lang.CharSequence);
   }
 
+  public class Toolbar extends android.view.ViewGroup {
+    ctor public Toolbar(android.content.Context);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet, int);
+    ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
+    method public void collapseActionView();
+    method public void dismissPopupMenus();
+    method public int getContentInsetEnd();
+    method public int getContentInsetLeft();
+    method public int getContentInsetRight();
+    method public int getContentInsetStart();
+    method public android.graphics.drawable.Drawable getLogo();
+    method public java.lang.CharSequence getLogoDescription();
+    method public android.view.Menu getMenu();
+    method public java.lang.CharSequence getNavigationContentDescription();
+    method public android.graphics.drawable.Drawable getNavigationIcon();
+    method public int getPopupTheme();
+    method public java.lang.CharSequence getSubtitle();
+    method public java.lang.CharSequence getTitle();
+    method public boolean hasExpandedActionView();
+    method public boolean hideOverflowMenu();
+    method public void inflateMenu(int);
+    method public boolean isOverflowMenuShowing();
+    method protected void onLayout(boolean, int, int, int, int);
+    method public void setContentInsetsAbsolute(int, int);
+    method public void setContentInsetsRelative(int, int);
+    method public void setLogo(int);
+    method public void setLogo(android.graphics.drawable.Drawable);
+    method public void setLogoDescription(int);
+    method public void setLogoDescription(java.lang.CharSequence);
+    method public void setNavigationContentDescription(int);
+    method public void setNavigationContentDescription(java.lang.CharSequence);
+    method public void setNavigationIcon(int);
+    method public void setNavigationIcon(android.graphics.drawable.Drawable);
+    method public void setNavigationOnClickListener(android.view.View.OnClickListener);
+    method public void setOnMenuItemClickListener(android.widget.Toolbar.OnMenuItemClickListener);
+    method public void setPopupTheme(int);
+    method public void setSubtitle(int);
+    method public void setSubtitle(java.lang.CharSequence);
+    method public void setSubtitleTextAppearance(android.content.Context, int);
+    method public void setSubtitleTextColor(int);
+    method public void setTitle(int);
+    method public void setTitle(java.lang.CharSequence);
+    method public void setTitleTextAppearance(android.content.Context, int);
+    method public void setTitleTextColor(int);
+    method public boolean showOverflowMenu();
+  }
+
+  public static class Toolbar.LayoutParams extends android.app.ActionBar.LayoutParams {
+    ctor public Toolbar.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public Toolbar.LayoutParams(int, int);
+    ctor public Toolbar.LayoutParams(int, int, int);
+    ctor public Toolbar.LayoutParams(int);
+    ctor public Toolbar.LayoutParams(android.widget.Toolbar.LayoutParams);
+    ctor public Toolbar.LayoutParams(android.app.ActionBar.LayoutParams);
+    ctor public Toolbar.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public Toolbar.LayoutParams(android.view.ViewGroup.LayoutParams);
+  }
+
+  public static abstract interface Toolbar.OnMenuItemClickListener {
+    method public abstract boolean onMenuItemClick(android.view.MenuItem);
+  }
+
   public deprecated class TwoLineListItem extends android.widget.RelativeLayout {
     ctor public TwoLineListItem(android.content.Context);
     ctor public TwoLineListItem(android.content.Context, android.util.AttributeSet);
     ctor public TwoLineListItem(android.content.Context, android.util.AttributeSet, int);
+    ctor public TwoLineListItem(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.TextView getText1();
     method public android.widget.TextView getText2();
   }
@@ -32876,6 +38870,7 @@
     ctor public VideoView(android.content.Context);
     ctor public VideoView(android.content.Context, android.util.AttributeSet);
     ctor public VideoView(android.content.Context, android.util.AttributeSet, int);
+    ctor public VideoView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addSubtitleSource(java.io.InputStream, android.media.MediaFormat);
     method public boolean canPause();
     method public boolean canSeekBackward();
@@ -32896,6 +38891,7 @@
     method public void setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener);
     method public void setVideoPath(java.lang.String);
     method public void setVideoURI(android.net.Uri);
+    method public void setVideoURI(android.net.Uri, java.util.Map<java.lang.String, java.lang.String>);
     method public void start();
     method public void stopPlayback();
     method public void suspend();
@@ -32950,6 +38946,7 @@
     ctor public ZoomButton(android.content.Context);
     ctor public ZoomButton(android.content.Context, android.util.AttributeSet);
     ctor public ZoomButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public ZoomButton(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean onLongClick(android.view.View);
     method public void setZoomSpeed(long);
   }
@@ -36130,8 +42127,8 @@
     method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
     method public boolean isAccessible();
     method public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>);
-    method public static void setAccessible(java.lang.reflect.AccessibleObject[], boolean);
     method public void setAccessible(boolean);
+    method public static void setAccessible(java.lang.reflect.AccessibleObject[], boolean);
   }
 
   public abstract interface AnnotatedElement {
@@ -42088,6 +48085,13 @@
     method public int getWidth();
   }
 
+  public class IllformedLocaleException extends java.lang.RuntimeException {
+    ctor public IllformedLocaleException();
+    ctor public IllformedLocaleException(java.lang.String);
+    ctor public IllformedLocaleException(java.lang.String, int);
+    method public int getErrorIndex();
+  }
+
   public class InputMismatchException extends java.util.NoSuchElementException implements java.io.Serializable {
     ctor public InputMismatchException();
     ctor public InputMismatchException(java.lang.String);
@@ -42202,6 +48206,7 @@
     ctor public Locale(java.lang.String, java.lang.String);
     ctor public Locale(java.lang.String, java.lang.String, java.lang.String);
     method public java.lang.Object clone();
+    method public static java.util.Locale forLanguageTag(java.lang.String);
     method public static java.util.Locale[] getAvailableLocales();
     method public java.lang.String getCountry();
     method public static java.util.Locale getDefault();
@@ -42211,15 +48216,24 @@
     method public java.lang.String getDisplayLanguage(java.util.Locale);
     method public final java.lang.String getDisplayName();
     method public java.lang.String getDisplayName(java.util.Locale);
+    method public java.lang.String getDisplayScript();
+    method public java.lang.String getDisplayScript(java.util.Locale);
     method public final java.lang.String getDisplayVariant();
     method public java.lang.String getDisplayVariant(java.util.Locale);
+    method public java.lang.String getExtension(char);
+    method public java.util.Set<java.lang.Character> getExtensionKeys();
     method public java.lang.String getISO3Country();
     method public java.lang.String getISO3Language();
     method public static java.lang.String[] getISOCountries();
     method public static java.lang.String[] getISOLanguages();
     method public java.lang.String getLanguage();
+    method public java.lang.String getScript();
+    method public java.util.Set<java.lang.String> getUnicodeLocaleAttributes();
+    method public java.util.Set<java.lang.String> getUnicodeLocaleKeys();
+    method public java.lang.String getUnicodeLocaleType(java.lang.String);
     method public java.lang.String getVariant();
     method public static synchronized void setDefault(java.util.Locale);
+    method public java.lang.String toLanguageTag();
     method public final java.lang.String toString();
     field public static final java.util.Locale CANADA;
     field public static final java.util.Locale CANADA_FRENCH;
@@ -42237,14 +48251,33 @@
     field public static final java.util.Locale KOREA;
     field public static final java.util.Locale KOREAN;
     field public static final java.util.Locale PRC;
+    field public static final char PRIVATE_USE_EXTENSION = 120; // 0x0078 'x'
     field public static final java.util.Locale ROOT;
     field public static final java.util.Locale SIMPLIFIED_CHINESE;
     field public static final java.util.Locale TAIWAN;
     field public static final java.util.Locale TRADITIONAL_CHINESE;
     field public static final java.util.Locale UK;
+    field public static final char UNICODE_LOCALE_EXTENSION = 117; // 0x0075 'u'
     field public static final java.util.Locale US;
   }
 
+  public static final class Locale.Builder {
+    ctor public Locale.Builder();
+    method public java.util.Locale.Builder addUnicodeLocaleAttribute(java.lang.String);
+    method public java.util.Locale build();
+    method public java.util.Locale.Builder clear();
+    method public java.util.Locale.Builder clearExtensions();
+    method public java.util.Locale.Builder removeUnicodeLocaleAttribute(java.lang.String);
+    method public java.util.Locale.Builder setExtension(char, java.lang.String);
+    method public java.util.Locale.Builder setLanguage(java.lang.String);
+    method public java.util.Locale.Builder setLanguageTag(java.lang.String);
+    method public java.util.Locale.Builder setLocale(java.util.Locale);
+    method public java.util.Locale.Builder setRegion(java.lang.String);
+    method public java.util.Locale.Builder setScript(java.lang.String);
+    method public java.util.Locale.Builder setUnicodeLocaleKeyword(java.lang.String, java.lang.String);
+    method public java.util.Locale.Builder setVariant(java.lang.String);
+  }
+
   public abstract interface Map {
     method public abstract void clear();
     method public abstract boolean containsKey(java.lang.Object);
@@ -42931,6 +48964,35 @@
     method public V replace(K, V);
   }
 
+  public class ConcurrentLinkedDeque extends java.util.AbstractCollection implements java.util.Deque java.io.Serializable {
+    ctor public ConcurrentLinkedDeque();
+    ctor public ConcurrentLinkedDeque(java.util.Collection<? extends E>);
+    method public void addFirst(E);
+    method public void addLast(E);
+    method public java.util.Iterator<E> descendingIterator();
+    method public E element();
+    method public E getFirst();
+    method public E getLast();
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E);
+    method public boolean offerFirst(E);
+    method public boolean offerLast(E);
+    method public E peek();
+    method public E peekFirst();
+    method public E peekLast();
+    method public E poll();
+    method public E pollFirst();
+    method public E pollLast();
+    method public E pop();
+    method public void push(E);
+    method public E remove();
+    method public E removeFirst();
+    method public boolean removeFirstOccurrence(java.lang.Object);
+    method public E removeLast();
+    method public boolean removeLastOccurrence(java.lang.Object);
+    method public int size();
+  }
+
   public class ConcurrentLinkedQueue extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
     ctor public ConcurrentLinkedQueue();
     ctor public ConcurrentLinkedQueue(java.util.Collection<? extends E>);
@@ -43171,6 +49233,94 @@
     method public static java.util.concurrent.ScheduledExecutorService unconfigurableScheduledExecutorService(java.util.concurrent.ScheduledExecutorService);
   }
 
+  public class ForkJoinPool extends java.util.concurrent.AbstractExecutorService {
+    ctor public ForkJoinPool();
+    ctor public ForkJoinPool(int);
+    ctor public ForkJoinPool(int, java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory, java.lang.Thread.UncaughtExceptionHandler, boolean);
+    method public boolean awaitQuiescence(long, java.util.concurrent.TimeUnit);
+    method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method protected int drainTasksTo(java.util.Collection<? super java.util.concurrent.ForkJoinTask<?>>);
+    method public void execute(java.util.concurrent.ForkJoinTask<?>);
+    method public void execute(java.lang.Runnable);
+    method public int getActiveThreadCount();
+    method public boolean getAsyncMode();
+    method public java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory getFactory();
+    method public int getParallelism();
+    method public int getPoolSize();
+    method public int getQueuedSubmissionCount();
+    method public long getQueuedTaskCount();
+    method public int getRunningThreadCount();
+    method public long getStealCount();
+    method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
+    method public boolean hasQueuedSubmissions();
+    method public T invoke(java.util.concurrent.ForkJoinTask<T>);
+    method public boolean isQuiescent();
+    method public boolean isShutdown();
+    method public boolean isTerminated();
+    method public boolean isTerminating();
+    method public static void managedBlock(java.util.concurrent.ForkJoinPool.ManagedBlocker) throws java.lang.InterruptedException;
+    method protected java.util.concurrent.ForkJoinTask<?> pollSubmission();
+    method public void shutdown();
+    method public java.util.List<java.lang.Runnable> shutdownNow();
+    method public java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
+    field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
+  }
+
+  public static abstract interface ForkJoinPool.ForkJoinWorkerThreadFactory {
+    method public abstract java.util.concurrent.ForkJoinWorkerThread newThread(java.util.concurrent.ForkJoinPool);
+  }
+
+  public static abstract interface ForkJoinPool.ManagedBlocker {
+    method public abstract boolean block() throws java.lang.InterruptedException;
+    method public abstract boolean isReleasable();
+  }
+
+  public abstract class ForkJoinTask implements java.util.concurrent.Future java.io.Serializable {
+    ctor public ForkJoinTask();
+    method public static java.util.concurrent.ForkJoinTask<?> adapt(java.lang.Runnable);
+    method public static java.util.concurrent.ForkJoinTask<T> adapt(java.lang.Runnable, T);
+    method public static java.util.concurrent.ForkJoinTask<T> adapt(java.util.concurrent.Callable<? extends T>);
+    method public boolean cancel(boolean);
+    method public void complete(V);
+    method public void completeExceptionally(java.lang.Throwable);
+    method protected abstract boolean exec();
+    method public final java.util.concurrent.ForkJoinTask<V> fork();
+    method public final V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public final V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public final java.lang.Throwable getException();
+    method public static java.util.concurrent.ForkJoinPool getPool();
+    method public static int getQueuedTaskCount();
+    method public abstract V getRawResult();
+    method public static int getSurplusQueuedTaskCount();
+    method public static void helpQuiesce();
+    method public static boolean inForkJoinPool();
+    method public final V invoke();
+    method public static void invokeAll(java.util.concurrent.ForkJoinTask<?>, java.util.concurrent.ForkJoinTask<?>);
+    method public static void invokeAll(java.util.concurrent.ForkJoinTask<?>...);
+    method public static java.util.Collection<T> invokeAll(java.util.Collection<T>);
+    method public final boolean isCancelled();
+    method public final boolean isCompletedAbnormally();
+    method public final boolean isCompletedNormally();
+    method public final boolean isDone();
+    method public final V join();
+    method protected static java.util.concurrent.ForkJoinTask<?> peekNextLocalTask();
+    method protected static java.util.concurrent.ForkJoinTask<?> pollNextLocalTask();
+    method protected static java.util.concurrent.ForkJoinTask<?> pollTask();
+    method public final void quietlyInvoke();
+    method public final void quietlyJoin();
+    method public void reinitialize();
+    method protected abstract void setRawResult(V);
+    method public boolean tryUnfork();
+  }
+
+  public class ForkJoinWorkerThread extends java.lang.Thread {
+    ctor protected ForkJoinWorkerThread(java.util.concurrent.ForkJoinPool);
+    method public java.util.concurrent.ForkJoinPool getPool();
+    method public int getPoolIndex();
+    method protected void onStart();
+    method protected void onTermination(java.lang.Throwable);
+  }
+
   public abstract interface Future {
     method public abstract boolean cancel(boolean);
     method public abstract V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
@@ -43255,6 +49405,52 @@
     method public E take() throws java.lang.InterruptedException;
   }
 
+  public class LinkedTransferQueue extends java.util.AbstractQueue implements java.io.Serializable java.util.concurrent.TransferQueue {
+    ctor public LinkedTransferQueue();
+    ctor public LinkedTransferQueue(java.util.Collection<? extends E>);
+    method public int drainTo(java.util.Collection<? super E>);
+    method public int drainTo(java.util.Collection<? super E>, int);
+    method public int getWaitingConsumerCount();
+    method public boolean hasWaitingConsumer();
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E, long, java.util.concurrent.TimeUnit);
+    method public boolean offer(E);
+    method public E peek();
+    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E poll();
+    method public void put(E);
+    method public int remainingCapacity();
+    method public int size();
+    method public E take() throws java.lang.InterruptedException;
+    method public void transfer(E) throws java.lang.InterruptedException;
+    method public boolean tryTransfer(E);
+    method public boolean tryTransfer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+  }
+
+  public class Phaser {
+    ctor public Phaser();
+    ctor public Phaser(int);
+    ctor public Phaser(java.util.concurrent.Phaser);
+    ctor public Phaser(java.util.concurrent.Phaser, int);
+    method public int arrive();
+    method public int arriveAndAwaitAdvance();
+    method public int arriveAndDeregister();
+    method public int awaitAdvance(int);
+    method public int awaitAdvanceInterruptibly(int) throws java.lang.InterruptedException;
+    method public int awaitAdvanceInterruptibly(int, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public int bulkRegister(int);
+    method public void forceTermination();
+    method public int getArrivedParties();
+    method public java.util.concurrent.Phaser getParent();
+    method public final int getPhase();
+    method public int getRegisteredParties();
+    method public java.util.concurrent.Phaser getRoot();
+    method public int getUnarrivedParties();
+    method public boolean isTerminated();
+    method protected boolean onAdvance(int, int);
+    method public int register();
+  }
+
   public class PriorityBlockingQueue extends java.util.AbstractQueue implements java.util.concurrent.BlockingQueue java.io.Serializable {
     ctor public PriorityBlockingQueue();
     ctor public PriorityBlockingQueue(int);
@@ -43275,6 +49471,22 @@
     method public E take() throws java.lang.InterruptedException;
   }
 
+  public abstract class RecursiveAction extends java.util.concurrent.ForkJoinTask {
+    ctor public RecursiveAction();
+    method protected abstract void compute();
+    method protected final boolean exec();
+    method public final java.lang.Void getRawResult();
+    method protected final void setRawResult(java.lang.Void);
+  }
+
+  public abstract class RecursiveTask extends java.util.concurrent.ForkJoinTask {
+    ctor public RecursiveTask();
+    method protected abstract V compute();
+    method protected final boolean exec();
+    method public final V getRawResult();
+    method protected final void setRawResult(V);
+  }
+
   public class RejectedExecutionException extends java.lang.RuntimeException {
     ctor public RejectedExecutionException();
     ctor public RejectedExecutionException(java.lang.String);
@@ -43313,12 +49525,14 @@
     method protected java.util.concurrent.RunnableScheduledFuture<V> decorateTask(java.util.concurrent.Callable<V>, java.util.concurrent.RunnableScheduledFuture<V>);
     method public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy();
     method public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy();
+    method public boolean getRemoveOnCancelPolicy();
     method public java.util.concurrent.ScheduledFuture<?> schedule(java.lang.Runnable, long, java.util.concurrent.TimeUnit);
     method public java.util.concurrent.ScheduledFuture<V> schedule(java.util.concurrent.Callable<V>, long, java.util.concurrent.TimeUnit);
     method public java.util.concurrent.ScheduledFuture<?> scheduleAtFixedRate(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit);
     method public java.util.concurrent.ScheduledFuture<?> scheduleWithFixedDelay(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit);
     method public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean);
     method public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean);
+    method public void setRemoveOnCancelPolicy(boolean);
   }
 
   public class Semaphore implements java.io.Serializable {
@@ -43364,6 +49578,15 @@
     method public abstract java.lang.Thread newThread(java.lang.Runnable);
   }
 
+  public class ThreadLocalRandom extends java.util.Random {
+    method public static java.util.concurrent.ThreadLocalRandom current();
+    method public double nextDouble(double);
+    method public double nextDouble(double, double);
+    method public int nextInt(int, int);
+    method public long nextLong(long);
+    method public long nextLong(long, long);
+  }
+
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
     ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>);
     ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.ThreadFactory);
@@ -43451,6 +49674,14 @@
     ctor public TimeoutException(java.lang.String);
   }
 
+  public abstract interface TransferQueue implements java.util.concurrent.BlockingQueue {
+    method public abstract int getWaitingConsumerCount();
+    method public abstract boolean hasWaitingConsumer();
+    method public abstract void transfer(E) throws java.lang.InterruptedException;
+    method public abstract boolean tryTransfer(E);
+    method public abstract boolean tryTransfer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+  }
+
 }
 
 package java.util.concurrent.atomic {
@@ -43660,6 +49891,7 @@
     method public final int getWaitQueueLength(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
     method public final java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
     method public final boolean hasContended();
+    method public final boolean hasQueuedPredecessors();
     method public final boolean hasQueuedThreads();
     method public final boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
     method protected boolean isHeldExclusively();
@@ -43706,6 +49938,7 @@
     method public final int getWaitQueueLength(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
     method public final java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
     method public final boolean hasContended();
+    method public final boolean hasQueuedPredecessors();
     method public final boolean hasQueuedThreads();
     method public final boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
     method protected boolean isHeldExclusively();
@@ -44595,7 +50828,47 @@
     method public void setMethod(int);
     method public void setSize(long);
     method public void setTime(long);
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
     field public static final int DEFLATED = 8; // 0x8
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
     field public static final int STORED = 0; // 0x0
   }
 
@@ -44619,6 +50892,46 @@
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.lang.String getName();
     method public int size();
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
     field public static final int OPEN_DELETE = 4; // 0x4
     field public static final int OPEN_READ = 1; // 0x1
   }
@@ -44628,6 +50941,46 @@
     method public void closeEntry() throws java.io.IOException;
     method protected java.util.zip.ZipEntry createZipEntry(java.lang.String);
     method public java.util.zip.ZipEntry getNextEntry() throws java.io.IOException;
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
   }
 
   public class ZipOutputStream extends java.util.zip.DeflaterOutputStream {
@@ -44637,7 +50990,47 @@
     method public void setComment(java.lang.String);
     method public void setLevel(int);
     method public void setMethod(int);
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
     field public static final int DEFLATED = 8; // 0x8
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
     field public static final int STORED = 0; // 0x0
   }
 
diff --git a/api/removed.txt b/api/removed.txt
new file mode 100644
index 0000000..8972679
--- /dev/null
+++ b/api/removed.txt
@@ -0,0 +1,46 @@
+package android.media {
+
+  public class AudioFormat {
+    ctor public AudioFormat();
+  }
+
+}
+
+package android.os {
+
+  public final class PowerManager {
+    method public void goToSleep(long);
+    method public deprecated void userActivity(long, boolean);
+    method public void wakeUp(long);
+  }
+
+  public class UserManager {
+    method public android.graphics.drawable.Drawable getBadgedDrawableForUser(android.graphics.drawable.Drawable, android.os.UserHandle, android.graphics.Rect, int);
+    method public android.graphics.drawable.Drawable getBadgedIconForUser(android.graphics.drawable.Drawable, android.os.UserHandle);
+    method public java.lang.CharSequence getBadgedLabelForUser(java.lang.CharSequence, android.os.UserHandle);
+  }
+
+}
+
+package android.view {
+
+  public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
+    method protected void initializeFadingEdge(android.content.res.TypedArray);
+    method protected void initializeScrollbars(android.content.res.TypedArray);
+  }
+
+  public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
+    field public static final int TYPE_KEYGUARD = 2004; // 0x7d4
+  }
+
+}
+
+package android.widget {
+
+  public class TextView extends android.view.View implements android.view.ViewTreeObserver.OnPreDrawListener {
+    method public static int getTextColor(android.content.Context, android.content.res.TypedArray, int);
+    method public static android.content.res.ColorStateList getTextColors(android.content.Context, android.content.res.TypedArray);
+  }
+
+}
+
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index abab094..cc0d51c 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -26,12 +26,19 @@
 import android.app.IActivityManager;
 import android.app.IInstrumentationWatcher;
 import android.app.Instrumentation;
+import android.app.ProfilerInfo;
 import android.app.UiAutomationConnection;
+import android.app.usage.ConfigurationStats;
+import android.app.usage.IUsageStatsManager;
+import android.app.usage.UsageStatsManager;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.IIntentReceiver;
 import android.content.Intent;
 import android.content.pm.IPackageManager;
+import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Binder;
@@ -41,10 +48,15 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.AndroidException;
+import android.util.ArrayMap;
 import android.view.IWindowManager;
+import android.view.View;
+
 import com.android.internal.os.BaseCommand;
 
 import dalvik.system.VMRuntime;
@@ -56,6 +68,9 @@
 import java.io.InputStreamReader;
 import java.io.PrintStream;
 import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
 
@@ -72,6 +87,8 @@
     private String mReceiverPermission;
 
     private String mProfileFile;
+    private int mSamplingInterval;
+    private boolean mAutoStop;
 
     /**
      * Command-line entry point.
@@ -87,7 +104,7 @@
         out.println(
                 "usage: am [subcommand] [options]\n" +
                 "usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
-                "               [--R COUNT] [-S] [--opengl-trace]\n" +
+                "               [--sampling INTERVAL] [-R COUNT] [-S] [--opengl-trace]\n" +
                 "               [--user <USER_ID> | current] <INTENT>\n" +
                 "       am startservice [--user <USER_ID> | current] <INTENT>\n" +
                 "       am stopservice [--user <USER_ID> | current] <INTENT>\n" +
@@ -115,17 +132,23 @@
                 "       am to-uri [INTENT]\n" +
                 "       am to-intent-uri [INTENT]\n" +
                 "       am switch-user <USER_ID>\n" +
+                "       am start-user <USER_ID>\n" +
                 "       am stop-user <USER_ID>\n" +
                 "       am stack start <DISPLAY_ID> <INTENT>\n" +
                 "       am stack movetask <TASK_ID> <STACK_ID> [true|false]\n" +
                 "       am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
                 "       am stack list\n" +
                 "       am stack info <STACK_ID>\n" +
+                "       am lock-task <TASK_ID>\n" +
+                "       am lock-task stop\n" +
+                "       am get-config\n" +
                 "\n" +
                 "am start: start an Activity.  Options are:\n" +
                 "    -D: enable debugging\n" +
                 "    -W: wait for launch to complete\n" +
                 "    --start-profiler <FILE>: start profiler and send results to <FILE>\n" +
+                "    --sampling INTERVAL: use sample profiling with INTERVAL microseconds\n" +
+                "        between samples (use with --start-profiler)\n" +
                 "    -P <FILE>: like above, but profiling stops when app goes idle\n" +
                 "    -R: repeat the activity launch <COUNT> times.  Prior to each repeat,\n" +
                 "        the top activity will be finished.\n" +
@@ -211,8 +234,11 @@
                 "am switch-user: switch to put USER_ID in the foreground, starting\n" +
                 "  execution of that user if it is currently stopped.\n" +
                 "\n" +
+                "am start-user: start USER_ID in background if it is currently stopped,\n" +
+                "  use switch-user if you want to start the user in foreground.\n" +
+                "\n" +
                 "am stop-user: stop execution of USER_ID, not allowing it to run any\n" +
-                "  code until a later explicit switch to it.\n" +
+                "  code until a later explicit start or switch to it.\n" +
                 "\n" +
                 "am stack start: start a new activity on <DISPLAY_ID> using <INTENT>.\n" +
                 "\n" +
@@ -225,6 +251,11 @@
                 "\n" +
                 "am stack info: display the information about activity stack <STACK_ID>.\n" +
                 "\n" +
+                "am lock-task: bring <TASK_ID> to the front and don't allow other tasks to run\n" +
+                "\n" +
+                "am get-config: retrieve the configuration and any recent configurations\n" +
+                "  of the device\n" +
+                "\n" +
                 "<INTENT> specifications include these flags and arguments:\n" +
                 "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
                 "    [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
@@ -239,8 +270,11 @@
                 "    [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" +
                 "    [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
                 "    [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
+                "    [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]\n" +
+                "        (to embed a comma into a string escape it using \"\\,\")\n" +
                 "    [-n <COMPONENT>] [-f <FLAGS>]\n" +
                 "    [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
+                "    [--grant-persistable-uri-permission] [--grant-prefix-uri-permission]\n" +
                 "    [--debug-log-resolution] [--exclude-stopped-packages]\n" +
                 "    [--include-stopped-packages]\n" +
                 "    [--activity-brought-to-front] [--activity-clear-top]\n" +
@@ -310,10 +344,16 @@
             runToUri(true);
         } else if (op.equals("switch-user")) {
             runSwitchUser();
+        } else if (op.equals("start-user")) {
+            runStartUserInBackground();
         } else if (op.equals("stop-user")) {
             runStopUser();
         } else if (op.equals("stack")) {
             runStack();
+        } else if (op.equals("lock-task")) {
+            runLockTask();
+        } else if (op.equals("get-config")) {
+            runGetConfig();
         } else {
             showError("Error: unknown command '" + op + "'");
         }
@@ -341,6 +381,8 @@
         mStopOption = false;
         mRepeat = 0;
         mProfileFile = null;
+        mSamplingInterval = 0;
+        mAutoStop = false;
         mUserId = defUser;
         Uri data = null;
         String type = null;
@@ -426,6 +468,15 @@
                 }
                 intent.putExtra(key, list);
                 hasIntentInfo = true;
+            } else if (opt.equals("--esa")) {
+                String key = nextArgRequired();
+                String value = nextArgRequired();
+                // Split on commas unless they are preceeded by an escape.
+                // The escape character must be escaped for the string and
+                // again for the regex, thus four escape characters become one.
+                String[] strings = value.split("(?<!\\\\),");
+                intent.putExtra(key, strings);
+                hasIntentInfo = true;
             } else if (opt.equals("--ez")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
@@ -445,6 +496,10 @@
                 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
             } else if (opt.equals("--grant-write-uri-permission")) {
                 intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+            } else if (opt.equals("--grant-persistable-uri-permission")) {
+                intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
+            } else if (opt.equals("--grant-prefix-uri-permission")) {
+                intent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
             } else if (opt.equals("--exclude-stopped-packages")) {
                 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
             } else if (opt.equals("--include-stopped-packages")) {
@@ -494,10 +549,12 @@
                 mWaitOption = true;
             } else if (opt.equals("-P")) {
                 mProfileFile = nextArgRequired();
-                mStartFlags |= ActivityManager.START_FLAG_AUTO_STOP_PROFILER;
+                mAutoStop = true;
             } else if (opt.equals("--start-profiler")) {
                 mProfileFile = nextArgRequired();
-                mStartFlags &= ~ActivityManager.START_FLAG_AUTO_STOP_PROFILER;
+                mAutoStop = false;
+            } else if (opt.equals("--sampling")) {
+                mSamplingInterval = Integer.parseInt(nextArgRequired());
             } else if (opt.equals("-R")) {
                 mRepeat = Integer.parseInt(nextArgRequired());
             } else if (opt.equals("-S")) {
@@ -653,12 +710,13 @@
                 mAm.forceStopPackage(packageName, mUserId);
                 Thread.sleep(250);
             }
-    
+
             System.out.println("Starting: " + intent);
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-    
+
             ParcelFileDescriptor fd = null;
-    
+            ProfilerInfo profilerInfo = null;
+
             if (mProfileFile != null) {
                 try {
                     fd = ParcelFileDescriptor.open(
@@ -670,18 +728,21 @@
                     System.err.println("Error: Unable to open file: " + mProfileFile);
                     return;
                 }
+                profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop);
             }
 
             IActivityManager.WaitResult result = null;
             int res;
+            final long startTime = SystemClock.uptimeMillis();
             if (mWaitOption) {
                 result = mAm.startActivityAndWait(null, null, intent, mimeType,
-                            null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId);
+                            null, null, 0, mStartFlags, profilerInfo, null, mUserId);
                 res = result.result;
             } else {
                 res = mAm.startActivityAsUser(null, null, intent, mimeType,
-                        null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId);
+                        null, null, 0, mStartFlags, profilerInfo, null, mUserId);
             }
+            final long endTime = SystemClock.uptimeMillis();
             PrintStream out = mWaitOption ? System.out : System.err;
             boolean launched = false;
             switch (res) {
@@ -734,6 +795,11 @@
                             "Error: Activity not started, you do not "
                             + "have permission to access it.");
                     break;
+                case ActivityManager.START_NOT_VOICE_COMPATIBLE:
+                    out.println(
+                            "Error: Activity not started, voice control not allowed for: "
+                                    + intent);
+                    break;
                 default:
                     out.println(
                             "Error: Activity not started, unknown error code " + res);
@@ -754,6 +820,7 @@
                 if (result.totalTime >= 0) {
                     System.out.println("TotalTime: " + result.totalTime);
                 }
+                System.out.println("WaitTime: " + (endTime-startTime));
                 System.out.println("Complete");
             }
             mRepeat--;
@@ -798,7 +865,7 @@
     }
 
     private void sendBroadcast() throws Exception {
-        Intent intent = makeIntent(UserHandle.USER_ALL);
+        Intent intent = makeIntent(UserHandle.USER_CURRENT);
         IntentReceiver receiver = new IntentReceiver();
         System.out.println("Broadcasting: " + intent);
         mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, mReceiverPermission,
@@ -882,8 +949,7 @@
             }
         }
 
-        if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId,
-                abi)) {
+        if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId, abi)) {
             throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
         }
 
@@ -906,7 +972,7 @@
             SystemProperties.set("dalvik.vm.extra-opts", props);
         }
     }
-    
+
     private void runProfile() throws Exception {
         String profileFile = null;
         boolean start = false;
@@ -960,6 +1026,7 @@
         }
 
         ParcelFileDescriptor fd = null;
+        ProfilerInfo profilerInfo = null;
 
         if (start) {
             profileFile = nextArgRequired();
@@ -973,6 +1040,7 @@
                 System.err.println("Error: Unable to open file: " + profileFile);
                 return;
             }
+            profilerInfo = new ProfilerInfo(profileFile, fd, 0, false);
         }
 
         try {
@@ -986,7 +1054,7 @@
             } else if (start) {
                 //removeWallOption();
             }
-            if (!mAm.profileControl(process, userId, start, profileFile, fd, profileType)) {
+            if (!mAm.profileControl(process, userId, start, profilerInfo, profileType)) {
                 wall = false;
                 throw new AndroidException("PROFILE FAILED on process " + process);
             }
@@ -1071,6 +1139,16 @@
         mAm.switchUser(Integer.parseInt(user));
     }
 
+    private void runStartUserInBackground() throws Exception {
+        String user = nextArgRequired();
+        boolean success = mAm.startUserInBackground(Integer.parseInt(user));
+        if (success) {
+            System.out.println("Success: user started");
+        } else {
+            System.err.println("Error: could not start user");
+        }
+    }
+
     private void runStopUser() throws Exception {
         String user = nextArgRequired();
         int res = mAm.stopUser(Integer.parseInt(user), null);
@@ -1429,7 +1507,7 @@
 
         System.out.println("Performing idle maintenance...");
         Intent intent = new Intent(
-                "com.android.server.IdleMaintenanceService.action.FORCE_IDLE_MAINTENANCE");
+                "com.android.server.task.controllers.IdleController.ACTION_TRIGGER_IDLE");
         mAm.broadcastIntent(null, intent, null, null, 0, null, null, null,
                 android.app.AppOpsManager.OP_NONE, true, false, UserHandle.USER_ALL);
     }
@@ -1657,4 +1735,102 @@
         } catch (RemoteException e) {
         }
     }
+
+    private void runLockTask() throws Exception {
+        String taskIdStr = nextArgRequired();
+        try {
+            if (taskIdStr.equals("stop")) {
+                mAm.stopLockTaskMode();
+            } else {
+                int taskId = Integer.valueOf(taskIdStr);
+                mAm.startLockTaskMode(taskId);
+            }
+            System.err.println("Activity manager is " + (mAm.isInLockTaskMode() ? "" : "not ") +
+                    "in lockTaskMode");
+        } catch (RemoteException e) {
+        }
+    }
+
+    private List<Configuration> getRecentConfigurations(int days) {
+        IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
+                    Context.USAGE_STATS_SERVICE));
+        final long now = System.currentTimeMillis();
+        final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000);
+        try {
+            @SuppressWarnings("unchecked")
+            ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats(
+                    UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell");
+            if (configStatsSlice == null) {
+                return Collections.emptyList();
+            }
+
+            final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>();
+            final List<ConfigurationStats> configStatsList = configStatsSlice.getList();
+            final int configStatsListSize = configStatsList.size();
+            for (int i = 0; i < configStatsListSize; i++) {
+                final ConfigurationStats stats = configStatsList.get(i);
+                final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration());
+                if (indexOfKey < 0) {
+                    recentConfigs.put(stats.getConfiguration(), stats.getActivationCount());
+                } else {
+                    recentConfigs.setValueAt(indexOfKey,
+                            recentConfigs.valueAt(indexOfKey) + stats.getActivationCount());
+                }
+            }
+
+            final Comparator<Configuration> comparator = new Comparator<Configuration>() {
+                @Override
+                public int compare(Configuration a, Configuration b) {
+                    return recentConfigs.get(b).compareTo(recentConfigs.get(a));
+                }
+            };
+
+            ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size());
+            configs.addAll(recentConfigs.keySet());
+            Collections.sort(configs, comparator);
+            return configs;
+
+        } catch (RemoteException e) {
+            return Collections.emptyList();
+        }
+    }
+
+    private void runGetConfig() throws Exception {
+        int days = 14;
+        String option = nextOption();
+        if (option != null) {
+            if (!option.equals("--days")) {
+                throw new IllegalArgumentException("unrecognized option " + option);
+            }
+
+            days = Integer.parseInt(nextArgRequired());
+            if (days <= 0) {
+                throw new IllegalArgumentException("--days must be a positive integer");
+            }
+        }
+
+        try {
+            Configuration config = mAm.getConfiguration();
+            if (config == null) {
+                System.err.println("Activity manager has no configuration");
+                return;
+            }
+
+            System.out.println("config: " + Configuration.resourceQualifierString(config));
+            System.out.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
+
+            final List<Configuration> recentConfigs = getRecentConfigurations(days);
+            final int recentConfigSize = recentConfigs.size();
+            if (recentConfigSize > 0) {
+                System.out.println("recentConfigs:");
+            }
+
+            for (int i = 0; i < recentConfigSize; i++) {
+                System.out.println("  config: " + Configuration.resourceQualifierString(
+                        recentConfigs.get(i)));
+            }
+
+        } catch (RemoteException e) {
+        }
+    }
 }
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 74ccbc2..1bb28c3 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -133,8 +133,7 @@
     // names if the zygote command line decreases in size.
     uintptr_t start = reinterpret_cast<uintptr_t>(argv[0]);
     uintptr_t end = reinterpret_cast<uintptr_t>(argv[argc - 1]);
-    end += strlen(argv[argc - 1]);
-
+    end += strlen(argv[argc - 1]) + 1;
     return (end - start);
 }
 
@@ -161,17 +160,17 @@
     LOG_ALWAYS_FATAL_IF((numChars >= PATH_MAX || numChars < 0),
             "Error constructing dalvik cache : %s", strerror(errno));
 
-    int result = mkdir(dalvikCacheDir, 0771);
+    int result = mkdir(dalvikCacheDir, 0711);
     LOG_ALWAYS_FATAL_IF((result < 0 && errno != EEXIST),
             "Error creating cache dir %s : %s", dalvikCacheDir, strerror(errno));
 
     // We always perform these steps because the directory might
     // already exist, with wider permissions and a different owner
     // than we'd like.
-    result = chown(dalvikCacheDir, AID_SYSTEM, AID_SYSTEM);
+    result = chown(dalvikCacheDir, AID_ROOT, AID_ROOT);
     LOG_ALWAYS_FATAL_IF((result < 0), "Error changing dalvik-cache ownership : %s", strerror(errno));
 
-    result = chmod(dalvikCacheDir, 0771);
+    result = chmod(dalvikCacheDir, 0711);
     LOG_ALWAYS_FATAL_IF((result < 0),
             "Error changing dalvik-cache permissions : %s", strerror(errno));
 }
@@ -220,15 +219,27 @@
     //
     // For zygote starts, all remaining arguments are passed to the zygote.
     // main function.
+    //
+    // Note that we must copy argument string values since we will rewrite the
+    // entire argument block when we apply the nice name to argv0.
 
-
-    int i = runtime.addVmArguments(argc, argv);
+    int i;
+    for (i = 0; i < argc; i++) {
+        if (argv[i][0] != '-') {
+            break;
+        }
+        if (argv[i][1] == '-' && argv[i][2] == 0) {
+            ++i; // Skip --.
+            break;
+        }
+        runtime.addOption(strdup(argv[i]));
+    }
 
     // Parse runtime arguments.  Stop at first unrecognized option.
     bool zygote = false;
     bool startSystemServer = false;
     bool application = false;
-    const char* niceName = NULL;
+    String8 niceName;
     String8 className;
 
     ++i;  // Skip unused "parent dir" argument.
@@ -242,7 +253,7 @@
         } else if (strcmp(arg, "--application") == 0) {
             application = true;
         } else if (strncmp(arg, "--nice-name=", 12) == 0) {
-            niceName = arg + 12;
+            niceName.setTo(arg + 12);
         } else if (strncmp(arg, "--", 2) != 0) {
             className.setTo(arg);
             break;
@@ -287,9 +298,9 @@
         }
     }
 
-    if (niceName && *niceName) {
-        runtime.setArgv0(niceName);
-        set_process_name(niceName);
+    if (!niceName.isEmpty()) {
+        runtime.setArgv0(niceName.string());
+        set_process_name(niceName.string());
     }
 
     if (zygote) {
diff --git a/cmds/appops/Android.mk b/cmds/appops/Android.mk
new file mode 100644
index 0000000..1e15204
--- /dev/null
+++ b/cmds/appops/Android.mk
@@ -0,0 +1,16 @@
+# Copyright 2014 The Android Open Source Project
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE := appops
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := appops
+LOCAL_SRC_FILES := appops
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_PREBUILT)
+
diff --git a/media/jni/mediaeditor/MODULE_LICENSE_APACHE2 b/cmds/appops/MODULE_LICENSE_APACHE2
similarity index 100%
rename from media/jni/mediaeditor/MODULE_LICENSE_APACHE2
rename to cmds/appops/MODULE_LICENSE_APACHE2
diff --git a/cmds/appops/NOTICE b/cmds/appops/NOTICE
new file mode 100644
index 0000000..06a9081
--- /dev/null
+++ b/cmds/appops/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2014, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/cmds/appops/appops b/cmds/appops/appops
new file mode 100755
index 0000000..407e551
--- /dev/null
+++ b/cmds/appops/appops
@@ -0,0 +1,5 @@
+# Script to start "appwidget" on the device, which has a very rudimentary shell.
+base=/system
+export CLASSPATH=$base/framework/appops.jar
+exec app_process $base/bin com.android.commands.appops.AppOpsCommand "$@"
+
diff --git a/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
new file mode 100644
index 0000000..c414f58
--- /dev/null
+++ b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
@@ -0,0 +1,137 @@
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.commands.appops;
+
+import android.app.ActivityManager;
+import android.app.ActivityThread;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+
+import com.android.internal.app.IAppOpsService;
+import com.android.internal.os.BaseCommand;
+
+import java.io.PrintStream;
+
+/**
+ * This class is a command line utility for manipulating AppOps permissions.
+ */
+public class AppOpsCommand extends BaseCommand {
+
+    public static void main(String[] args) {
+        new AppOpsCommand().run(args);
+    }
+
+    @Override
+    public void onShowUsage(PrintStream out) {
+        out.println("usage: adb shell appops set <PACKAGE> <OP> "
+                + "<allow|ignore|deny|default> [--user <USER_ID>]\n"
+                + "  <PACKAGE> an Android package name.\n"
+                + "  <OP>      an AppOps operation.\n"
+                + "  <USER_ID> the user id under which the package is installed. If --user is not\n"
+                + "            specified, the current user is assumed.\n");
+    }
+
+    private static final String COMMAND_SET = "set";
+
+    @Override
+    public void onRun() throws Exception {
+        String command = nextArgRequired();
+        switch (command) {
+            case COMMAND_SET:
+                runSet();
+                break;
+
+            default:
+                throw new IllegalArgumentException("Unknown command '" + command + "'.");
+        }
+    }
+
+    private static final String ARGUMENT_USER = "--user";
+
+    // Modes
+    private static final String MODE_ALLOW = "allow";
+    private static final String MODE_DENY = "deny";
+    private static final String MODE_IGNORE = "ignore";
+    private static final String MODE_DEFAULT = "default";
+
+    private void runSet() throws Exception {
+        String packageName = null;
+        String op = null;
+        String mode = null;
+        int userId = UserHandle.USER_CURRENT;
+        for (String argument; (argument = nextArg()) != null;) {
+            if (ARGUMENT_USER.equals(argument)) {
+                userId = Integer.parseInt(nextArgRequired());
+            } else {
+                if (packageName == null) {
+                    packageName = argument;
+                } else if (op == null) {
+                    op = argument;
+                } else if (mode == null) {
+                    mode = argument;
+                } else {
+                    throw new IllegalArgumentException("Unsupported argument: " + argument);
+                }
+            }
+        }
+
+        if (packageName == null) {
+            throw new IllegalArgumentException("Package name not specified.");
+        } else if (op == null) {
+            throw new IllegalArgumentException("Operation not specified.");
+        } else if (mode == null) {
+            throw new IllegalArgumentException("Mode not specified.");
+        }
+
+        final int opInt = AppOpsManager.strOpToOp(op);
+        final int modeInt;
+        switch (mode) {
+            case MODE_ALLOW:
+                modeInt = AppOpsManager.MODE_ALLOWED;
+                break;
+            case MODE_DENY:
+                modeInt = AppOpsManager.MODE_ERRORED;
+                break;
+            case MODE_IGNORE:
+                modeInt = AppOpsManager.MODE_IGNORED;
+                break;
+            case MODE_DEFAULT:
+                modeInt = AppOpsManager.MODE_DEFAULT;
+                break;
+            default:
+                throw new IllegalArgumentException("Mode is invalid.");
+        }
+
+        // Parsing complete, let's execute the command.
+
+        if (userId == UserHandle.USER_CURRENT) {
+            userId = ActivityManager.getCurrentUser();
+        }
+
+        final IPackageManager pm = ActivityThread.getPackageManager();
+        final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
+                ServiceManager.getService(Context.APP_OPS_SERVICE));
+        final int uid = pm.getPackageUid(packageName, userId);
+        if (uid < 0) {
+            throw new Exception("No UID for " + packageName + " for user " + userId);
+        }
+        appOpsService.setMode(opInt, uid, packageName, modeInt);
+    }
+}
diff --git a/cmds/appwidget/Android.mk b/cmds/appwidget/Android.mk
new file mode 100644
index 0000000..1fb258d
--- /dev/null
+++ b/cmds/appwidget/Android.mk
@@ -0,0 +1,16 @@
+# Copyright 2014 The Android Open Source Project
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE := appwidget
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := appwidget
+LOCAL_SRC_FILES := appwidget
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_PREBUILT)
+
diff --git a/media/jni/mediaeditor/MODULE_LICENSE_APACHE2 b/cmds/appwidget/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/jni/mediaeditor/MODULE_LICENSE_APACHE2
copy to cmds/appwidget/MODULE_LICENSE_APACHE2
diff --git a/cmds/appwidget/NOTICE b/cmds/appwidget/NOTICE
new file mode 100644
index 0000000..06a9081
--- /dev/null
+++ b/cmds/appwidget/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2014, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/cmds/appwidget/appwidget b/cmds/appwidget/appwidget
new file mode 100755
index 0000000..6105009
--- /dev/null
+++ b/cmds/appwidget/appwidget
@@ -0,0 +1,5 @@
+# Script to start "appwidget" on the device, which has a very rudimentary shell.
+base=/system
+export CLASSPATH=$base/framework/appwidget.jar
+exec app_process $base/bin com.android.commands.appwidget.AppWidget "$@"
+
diff --git a/cmds/appwidget/src/com/android/commands/appwidget/AppWidget.java b/cmds/appwidget/src/com/android/commands/appwidget/AppWidget.java
new file mode 100644
index 0000000..5ea7352
--- /dev/null
+++ b/cmds/appwidget/src/com/android/commands/appwidget/AppWidget.java
@@ -0,0 +1,167 @@
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.commands.appwidget;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.text.TextUtils;
+
+import com.android.internal.appwidget.IAppWidgetService;
+
+/**
+ * This class is a command line utility for manipulating app widgets. A client
+ * can grant or revoke the permission for a given package to bind app widgets.
+ */
+public class AppWidget {
+
+    private static final String USAGE =
+        "usage: adb shell appwidget [subcommand] [options]\n"
+        + "\n"
+        + "usage: adb shell appwidget grantbind --package <PACKAGE> "
+                + " [--user <USER_ID> | current]\n"
+        + "  <PACKAGE> an Android package name.\n"
+        + "  <USER_ID> The user id under which the package is installed.\n"
+        + "  Example:\n"
+        + "  # Grant the \"foo.bar.baz\" package to bind app widgets for the current user.\n"
+        + "  adb shell grantbind --package foo.bar.baz --user current\n"
+        + "\n"
+        + "usage: adb shell appwidget revokebind --package <PACKAGE> "
+                + "[--user <USER_ID> | current]\n"
+        + "  <PACKAGE> an Android package name.\n"
+        + "  <USER_ID> The user id under which the package is installed.\n"
+        + "  Example:\n"
+        + "  # Revoke the permisison to bind app widgets from the \"foo.bar.baz\" package.\n"
+        + "  adb shell revokebind --package foo.bar.baz --user current\n"
+        + "\n";
+
+    private static class Parser {
+        private static final String ARGUMENT_GRANT_BIND = "grantbind";
+        private static final String ARGUMENT_REVOKE_BIND = "revokebind";
+        private static final String ARGUMENT_PACKAGE = "--package";
+        private static final String ARGUMENT_USER = "--user";
+        private static final String ARGUMENT_PREFIX = "--";
+        private static final String VALUE_USER_CURRENT = "current";
+
+        private final Tokenizer mTokenizer;
+
+        public Parser(String[] args) {
+            mTokenizer = new Tokenizer(args);
+        }
+
+        public Runnable parseCommand() {
+            try {
+                String operation = mTokenizer.nextArg();
+                if (ARGUMENT_GRANT_BIND.equals(operation)) {
+                    return parseSetGrantBindAppWidgetPermissionCommand(true);
+                } else if (ARGUMENT_REVOKE_BIND.equals(operation)) {
+                    return parseSetGrantBindAppWidgetPermissionCommand(false);
+                } else {
+                    throw new IllegalArgumentException("Unsupported operation: " + operation);
+                }
+            } catch (IllegalArgumentException iae) {
+                System.out.println(USAGE);
+                System.out.println("[ERROR] " + iae.getMessage());
+                return null;
+            }
+        }
+
+        private SetBindAppWidgetPermissionCommand parseSetGrantBindAppWidgetPermissionCommand(
+                boolean granted) {
+            String packageName = null;
+            int userId = UserHandle.USER_OWNER;
+            for (String argument; (argument = mTokenizer.nextArg()) != null;) {
+                if (ARGUMENT_PACKAGE.equals(argument)) {
+                    packageName = argumentValueRequired(argument);
+                } else if (ARGUMENT_USER.equals(argument)) {
+                    String user = argumentValueRequired(argument);
+                    if (VALUE_USER_CURRENT.equals(user)) {
+                        userId = UserHandle.USER_CURRENT;
+                    } else {
+                        userId = Integer.parseInt(user);
+                    }
+                } else {
+                    throw new IllegalArgumentException("Unsupported argument: " + argument);
+                }
+            }
+            if (packageName == null) {
+                throw new IllegalArgumentException("Package name not specified."
+                        + " Did you specify --package argument?");
+            }
+            return new SetBindAppWidgetPermissionCommand(packageName, granted, userId);
+        }
+
+        private String argumentValueRequired(String argument) {
+            String value = mTokenizer.nextArg();
+            if (TextUtils.isEmpty(value) || value.startsWith(ARGUMENT_PREFIX)) {
+                throw new IllegalArgumentException("No value for argument: " + argument);
+            }
+            return value;
+        }
+    }
+
+    private static class Tokenizer {
+        private final String[] mArgs;
+        private int mNextArg;
+
+        public Tokenizer(String[] args) {
+            mArgs = args;
+        }
+
+        private String nextArg() {
+            if (mNextArg < mArgs.length) {
+                return mArgs[mNextArg++];
+            } else {
+                return null;
+            }
+        }
+    }
+
+    private static class SetBindAppWidgetPermissionCommand implements Runnable {
+        final String mPackageName;
+        final boolean mGranted;
+        final int mUserId;
+
+        public SetBindAppWidgetPermissionCommand(String packageName, boolean granted,
+                int userId) {
+            mPackageName = packageName;
+            mGranted = granted;
+            mUserId = userId;
+        }
+
+        @Override
+        public void run() {
+            IBinder binder = ServiceManager.getService(Context.APPWIDGET_SERVICE);
+            IAppWidgetService appWidgetService = IAppWidgetService.Stub.asInterface(binder);
+            try {
+                appWidgetService.setBindAppWidgetPermission(mPackageName, mUserId, mGranted);
+            } catch (RemoteException re) {
+                re.printStackTrace();
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        Parser parser = new Parser(args);
+        Runnable command = parser.parseCommand();
+        if (command != null) {
+            command.run();
+        }
+    }
+}
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index db3d8bb..d683851 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -23,6 +23,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 
+import java.util.ArrayList;
 import java.util.HashSet;
 
 public final class Bmgr {
@@ -102,6 +103,11 @@
             return;
         }
 
+        if ("fullbackup".equals(op)) {
+            doFullTransportBackup();
+            return;
+        }
+
         System.err.println("Unknown command");
         showUsage();
     }
@@ -165,6 +171,24 @@
         }
     }
 
+    private void doFullTransportBackup() {
+        System.out.println("Performing full transport backup");
+
+        String pkg;
+        ArrayList<String> allPkgs = new ArrayList<String>();
+        while ((pkg = nextArg()) != null) {
+            allPkgs.add(pkg);
+        }
+        if (allPkgs.size() > 0) {
+            try {
+                mBmgr.fullTransportBackup(allPkgs.toArray(new String[allPkgs.size()]));
+            } catch (RemoteException e) {
+                System.err.println(e.toString());
+                System.err.println(BMGR_NOT_RUNNING_ERR);
+            }
+        }
+    }
+
     private void doTransport() {
         try {
             String which = nextArg();
@@ -453,6 +477,7 @@
         System.err.println("       bmgr restore PACKAGE");
         System.err.println("       bmgr run");
         System.err.println("       bmgr wipe TRANSPORT PACKAGE");
+        System.err.println("       bmgr fullbackup PACKAGE...");
         System.err.println("");
         System.err.println("The 'backup' command schedules a backup pass for the named package.");
         System.err.println("Note that the backup pass will effectively be a no-op if the package");
@@ -468,11 +493,11 @@
         System.err.println("");
         System.err.println("The 'list transports' command reports the names of the backup transports");
         System.err.println("currently available on the device.  These names can be passed as arguments");
-        System.err.println("to the 'transport' and 'wipe' commands.  The currently selected transport");
+        System.err.println("to the 'transport' and 'wipe' commands.  The currently active transport");
         System.err.println("is indicated with a '*' character.");
         System.err.println("");
         System.err.println("The 'list sets' command reports the token and name of each restore set");
-        System.err.println("available to the device via the current transport.");
+        System.err.println("available to the device via the currently active transport.");
         System.err.println("");
         System.err.println("The 'transport' command designates the named transport as the currently");
         System.err.println("active one.  This setting is persistent across reboots.");
@@ -500,5 +525,8 @@
         System.err.println("erased from the given transport's storage.  The next backup operation");
         System.err.println("that the given application performs will rewrite its entire data set.");
         System.err.println("Transport names to use here are those reported by 'list transports'.");
+        System.err.println("");
+        System.err.println("The 'fullbackup' command induces a full-data stream backup for one or more");
+        System.err.println("packages.  The data is sent via the currently active transport.");
     }
 }
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index dd987e0..c4fe6cf 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -19,9 +19,6 @@
     libGLESv1_CM \
     libgui
 
-LOCAL_C_INCLUDES := \
-	$(call include-path-for, corecg graphics)
-
 LOCAL_MODULE:= bootanimation
 
 ifdef TARGET_32_BIT_SURFACEFLINGER
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 7f7ae2c..08923119 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -36,15 +36,14 @@
 #include <ui/Rect.h>
 #include <ui/Region.h>
 #include <ui/DisplayInfo.h>
-#include <ui/FramebufferNativeWindow.h>
 
 #include <gui/ISurfaceComposer.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
 
-#include <core/SkBitmap.h>
-#include <core/SkStream.h>
-#include <core/SkImageDecoder.h>
+#include <SkBitmap.h>
+#include <SkStream.h>
+#include <SkImageDecoder.h>
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
@@ -52,6 +51,7 @@
 
 #include "BootAnimation.h"
 
+#define OEM_BOOTANIMATION_FILE "/oem/media/bootanimation.zip"
 #define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"
 #define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip"
 #define EXIT_PROP_NAME "service.bootanim.exit"
@@ -108,7 +108,7 @@
         return NO_INIT;
     SkBitmap bitmap;
     SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
-            &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
+            &bitmap, kUnknown_SkColorType, SkImageDecoder::kDecodePixels_Mode);
     asset->close();
     delete asset;
 
@@ -127,20 +127,20 @@
     glGenTextures(1, &texture->name);
     glBindTexture(GL_TEXTURE_2D, texture->name);
 
-    switch (bitmap.getConfig()) {
-        case SkBitmap::kA8_Config:
+    switch (bitmap.colorType()) {
+        case kAlpha_8_SkColorType:
             glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA,
                     GL_UNSIGNED_BYTE, p);
             break;
-        case SkBitmap::kARGB_4444_Config:
+        case kARGB_4444_SkColorType:
             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
                     GL_UNSIGNED_SHORT_4_4_4_4, p);
             break;
-        case SkBitmap::kARGB_8888_Config:
+        case kN32_SkColorType:
             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, p);
             break;
-        case SkBitmap::kRGB_565_Config:
+        case kRGB_565_SkColorType:
             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
                     GL_UNSIGNED_SHORT_5_6_5, p);
             break;
@@ -166,7 +166,7 @@
     if (codec) {
         codec->setDitherImage(false);
         codec->decode(&stream, &bitmap,
-                SkBitmap::kARGB_8888_Config,
+                kN32_SkColorType,
                 SkImageDecoder::kDecodePixels_Mode);
         delete codec;
     }
@@ -190,8 +190,8 @@
     if (tw < w) tw <<= 1;
     if (th < h) th <<= 1;
 
-    switch (bitmap.getConfig()) {
-        case SkBitmap::kARGB_8888_Config:
+    switch (bitmap.colorType()) {
+        case kN32_SkColorType:
             if (tw != w || th != h) {
                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
                         GL_UNSIGNED_BYTE, 0);
@@ -203,7 +203,7 @@
             }
             break;
 
-        case SkBitmap::kRGB_565_Config:
+        case kRGB_565_SkColorType:
             if (tw != w || th != h) {
                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
                         GL_UNSIGNED_SHORT_5_6_5, 0);
@@ -289,6 +289,9 @@
             (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) &&
             ((zipFile = ZipFileRO::open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)) != NULL)) ||
 
+            ((access(OEM_BOOTANIMATION_FILE, R_OK) == 0) &&
+            ((zipFile = ZipFileRO::open(OEM_BOOTANIMATION_FILE)) != NULL)) ||
+
             ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) &&
             ((zipFile = ZipFileRO::open(SYSTEM_BOOTANIMATION_FILE)) != NULL))) {
         mZip = zipFile;
@@ -394,6 +397,31 @@
     }
 }
 
+// Parse a color represented as an HTML-style 'RRGGBB' string: each pair of
+// characters in str is a hex number in [0, 255], which are converted to
+// floating point values in the range [0.0, 1.0] and placed in the
+// corresponding elements of color.
+//
+// If the input string isn't valid, parseColor returns false and color is
+// left unchanged.
+static bool parseColor(const char str[7], float color[3]) {
+    float tmpColor[3];
+    for (int i = 0; i < 3; i++) {
+        int val = 0;
+        for (int j = 0; j < 2; j++) {
+            val *= 16;
+            char c = str[2*i + j];
+            if      (c >= '0' && c <= '9') val += c - '0';
+            else if (c >= 'A' && c <= 'F') val += (c - 'A') + 10;
+            else if (c >= 'a' && c <= 'f') val += (c - 'a') + 10;
+            else                           return false;
+        }
+        tmpColor[i] = static_cast<float>(val) / 255.0f;
+    }
+    memcpy(color, tmpColor, sizeof(tmpColor));
+    return true;
+}
+
 bool BootAnimation::movie()
 {
     ZipEntryRO desc = mZip->findEntryByName("desc.txt");
@@ -424,20 +452,28 @@
         const char* l = line.string();
         int fps, width, height, count, pause;
         char path[ANIM_ENTRY_NAME_MAX];
+        char color[7] = "000000"; // default to black if unspecified
+
         char pathType;
         if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
-            //LOGD("> w=%d, h=%d, fps=%d", width, height, fps);
+            // ALOGD("> w=%d, h=%d, fps=%d", width, height, fps);
             animation.width = width;
             animation.height = height;
             animation.fps = fps;
         }
-        else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) {
-            //LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path);
+        else if (sscanf(l, " %c %d %d %s #%6s", &pathType, &count, &pause, path, color) >= 4) {
+            // ALOGD("> type=%c, count=%d, pause=%d, path=%s, color=%s", pathType, count, pause, path, color);
             Animation::Part part;
             part.playUntilComplete = pathType == 'c';
             part.count = count;
             part.pause = pause;
             part.path = path;
+            if (!parseColor(color, part.backgroundColor)) {
+                ALOGE("> invalid color '#%s'", color);
+                part.backgroundColor[0] = 0.0f;
+                part.backgroundColor[1] = 0.0f;
+                part.backgroundColor[2] = 0.0f;
+            }
             animation.parts.add(part);
         }
 
@@ -523,6 +559,12 @@
             if(exitPending() && !part.playUntilComplete)
                 break;
 
+            glClearColor(
+                    part.backgroundColor[0],
+                    part.backgroundColor[1],
+                    part.backgroundColor[2],
+                    1.0f);
+
             for (size_t j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) {
                 const Animation::Frame& frame(part.frames[j]);
                 nsecs_t lastFrame = systemTime();
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index ba1c507..72cd62b 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -71,6 +71,7 @@
             String8 path;
             SortedVector<Frame> frames;
             bool playUntilComplete;
+            float backgroundColor[3];
         };
         int fps;
         int width;
diff --git a/cmds/bu/src/com/android/commands/bu/Backup.java b/cmds/bu/src/com/android/commands/bu/Backup.java
index 73fd660..ffc0f87 100644
--- a/cmds/bu/src/com/android/commands/bu/Backup.java
+++ b/cmds/bu/src/com/android/commands/bu/Backup.java
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.system.OsConstants;
 import android.util.Log;
 
 import java.io.IOException;
@@ -50,13 +51,11 @@
             return;
         }
 
-        int socketFd = Integer.parseInt(nextArg());
-
         String arg = nextArg();
         if (arg.equals("backup")) {
-            doFullBackup(socketFd);
+            doFullBackup(OsConstants.STDOUT_FILENO);
         } else if (arg.equals("restore")) {
-            doFullRestore(socketFd);
+            doFullRestore(OsConstants.STDIN_FILENO);
         } else {
             Log.e(TAG, "Invalid operation '" + arg + "'");
         }
@@ -68,7 +67,9 @@
         boolean saveObbs = false;
         boolean saveShared = false;
         boolean doEverything = false;
+        boolean doWidgets = false;
         boolean allIncludesSystem = true;
+        boolean doCompress = true;
 
         String arg;
         while ((arg = nextArg()) != null) {
@@ -89,8 +90,16 @@
                     allIncludesSystem = true;
                 } else if ("-nosystem".equals(arg)) {
                     allIncludesSystem = false;
+                } else if ("-widgets".equals(arg)) {
+                    doWidgets = true;
+                } else if ("-nowidgets".equals(arg)) {
+                    doWidgets = false;
                 } else if ("-all".equals(arg)) {
                     doEverything = true;
+                } else if ("-compress".equals(arg)) {
+                    doCompress = true;
+                } else if ("-nocompress".equals(arg)) {
+                    doCompress = false;
                 } else {
                     Log.w(TAG, "Unknown backup flag " + arg);
                     continue;
@@ -114,8 +123,8 @@
         try {
             fd = ParcelFileDescriptor.adoptFd(socketFd);
             String[] packArray = new String[packages.size()];
-            mBackupManager.fullBackup(fd, saveApks, saveObbs, saveShared, doEverything,
-                    allIncludesSystem, packages.toArray(packArray));
+            mBackupManager.fullBackup(fd, saveApks, saveObbs, saveShared, doWidgets,
+                    doEverything, allIncludesSystem, doCompress, packages.toArray(packArray));
         } catch (RemoteException e) {
             Log.e(TAG, "Unable to invoke backup manager for backup");
         } finally {
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index e66bdf4..948c9a2 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -26,9 +26,17 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
 import android.os.UserHandle;
 import android.text.TextUtils;
 
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import libcore.io.IoUtils;
+
 /**
  * This class is a command line utility for manipulating content. A client
  * can insert, update, and remove records in a content provider. For example,
@@ -109,6 +117,12 @@
         + "  <METHOD> is the name of a provider-defined method\n"
         + "  <ARG> is an optional string argument\n"
         + "  <BINDING> is like --bind above, typed data of the form <KEY>:{b,s,i,l,f,d}:<VAL>\n"
+        + "\n"
+        + "usage: adb shell content read --uri <URI> [--user <USER_ID>]\n"
+        + "  Example:\n"
+        + "  # cat default ringtone to a file, then pull to host\n"
+        + "  adb shell 'content read --uri content://settings/system/ringtone >"
+                + " /mnt/sdcard/tmp.ogg' && adb pull /mnt/sdcard/tmp.ogg\n"
         + "\n";
 
     private static class Parser {
@@ -117,6 +131,7 @@
         private static final String ARGUMENT_UPDATE = "update";
         private static final String ARGUMENT_QUERY = "query";
         private static final String ARGUMENT_CALL = "call";
+        private static final String ARGUMENT_READ = "read";
         private static final String ARGUMENT_WHERE = "--where";
         private static final String ARGUMENT_BIND = "--bind";
         private static final String ARGUMENT_URI = "--uri";
@@ -154,6 +169,8 @@
                     return parseQueryCommand();
                 } else if (ARGUMENT_CALL.equals(operation)) {
                     return parseCallCommand();
+                } else if (ARGUMENT_READ.equals(operation)) {
+                    return parseReadCommand();
                 } else {
                     throw new IllegalArgumentException("Unsupported operation: " + operation);
                 }
@@ -273,6 +290,25 @@
             return new CallCommand(uri, userId, method, arg, values);
         }
 
+        private ReadCommand parseReadCommand() {
+            Uri uri = null;
+            int userId = UserHandle.USER_OWNER;
+            for (String argument; (argument = mTokenizer.nextArg())!= null;) {
+                if (ARGUMENT_URI.equals(argument)) {
+                    uri = Uri.parse(argumentValueRequired(argument));
+                } else if (ARGUMENT_USER.equals(argument)) {
+                    userId = Integer.parseInt(argumentValueRequired(argument));
+                } else {
+                    throw new IllegalArgumentException("Unsupported argument: " + argument);
+                }
+            }
+            if (uri == null) {
+                throw new IllegalArgumentException("Content provider URI not specified."
+                        + " Did you specify --uri argument?");
+            }
+            return new ReadCommand(uri, userId);
+        }
+
         public QueryCommand parseQueryCommand() {
             Uri uri = null;
             int userId = UserHandle.USER_OWNER;
@@ -458,6 +494,31 @@
         }
     }
 
+    private static class ReadCommand extends Command {
+        public ReadCommand(Uri uri, int userId) {
+            super(uri, userId);
+        }
+
+        @Override
+        public void onExecute(IContentProvider provider) throws Exception {
+            final ParcelFileDescriptor fd = provider.openFile(null, mUri, "r", null);
+            copy(new FileInputStream(fd.getFileDescriptor()), System.out);
+        }
+
+        private static void copy(InputStream is, OutputStream os) throws IOException {
+            final byte[] buffer = new byte[8 * 1024];
+            int read;
+            try {
+                while ((read = is.read(buffer)) > -1) {
+                    os.write(buffer, 0, read);
+                }
+            } finally {
+                IoUtils.closeQuietly(is);
+                IoUtils.closeQuietly(os);
+            }
+        }
+    }
+
     private static class QueryCommand extends DeleteCommand {
         final String[] mProjection;
         final String mSortOrder;
@@ -498,7 +559,7 @@
                                     columnValue = String.valueOf(cursor.getFloat(columnIndex));
                                     break;
                                 case Cursor.FIELD_TYPE_INTEGER:
-                                    columnValue = String.valueOf(cursor.getInt(columnIndex));
+                                    columnValue = String.valueOf(cursor.getLong(columnIndex));
                                     break;
                                 case Cursor.FIELD_TYPE_STRING:
                                     columnValue = cursor.getString(columnIndex);
diff --git a/cmds/dpm/Android.mk b/cmds/dpm/Android.mk
new file mode 100644
index 0000000..9f5aee4
--- /dev/null
+++ b/cmds/dpm/Android.mk
@@ -0,0 +1,15 @@
+# Copyright 2014 The Android Open Source Project
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE := dpm
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := dpm
+LOCAL_SRC_FILES := dpm
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_PREBUILT)
diff --git a/media/jni/mediaeditor/MODULE_LICENSE_APACHE2 b/cmds/dpm/MODULE_LICENSE_APACHE2
similarity index 100%
copy from media/jni/mediaeditor/MODULE_LICENSE_APACHE2
copy to cmds/dpm/MODULE_LICENSE_APACHE2
diff --git a/cmds/dpm/NOTICE b/cmds/dpm/NOTICE
new file mode 100644
index 0000000..316b4eb
--- /dev/null
+++ b/cmds/dpm/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2014, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/cmds/dpm/dpm b/cmds/dpm/dpm
new file mode 100755
index 0000000..c2e5cbb
--- /dev/null
+++ b/cmds/dpm/dpm
@@ -0,0 +1,6 @@
+# Script to start "dpm" on the device
+#
+base=/system
+export CLASSPATH=$base/framework/dpm.jar
+exec app_process $base/bin com.android.commands.dpm.Dpm "$@"
+
diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
new file mode 100644
index 0000000..3b9a785
--- /dev/null
+++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.commands.dpm;
+
+import android.app.admin.IDevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+
+import com.android.internal.os.BaseCommand;
+
+import java.io.PrintStream;
+
+public final class Dpm extends BaseCommand {
+
+    /**
+     * Command-line entry point.
+     *
+     * @param args The command-line arguments
+     */
+    public static void main(String[] args) {
+      (new Dpm()).run(args);
+    }
+
+    private static final String COMMAND_SET_DEVICE_OWNER = "set-device-owner";
+    private static final String COMMAND_SET_PROFILE_OWNER = "set-profile-owner";
+
+    private IDevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    public void onShowUsage(PrintStream out) {
+        out.println(
+                "usage: dpm [subcommand] [options]\n" +
+                "usage: dpm set-device-owner <COMPONENT>\n" +
+                "usage: dpm set-profile-owner <COMPONENT> <USER_ID>\n" +
+                "\n" +
+                "dpm set-device-owner: Sets the given component as active admin, and its\n" +
+                "  package as device owner.\n" +
+                "\n" +
+                "dpm set-profile-owner: Sets the given component as active admin and profile" +
+                "  owner for an existing user.\n");
+    }
+
+    @Override
+    public void onRun() throws Exception {
+        mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
+                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
+        if (mDevicePolicyManager == null) {
+            showError("Error: Could not access the Device Policy Manager. Is the system running?");
+            return;
+        }
+
+        String command = nextArgRequired();
+        switch (command) {
+            case COMMAND_SET_DEVICE_OWNER:
+                runSetDeviceOwner();
+                break;
+            case COMMAND_SET_PROFILE_OWNER:
+                runSetProfileOwner();
+                break;
+            default:
+                throw new IllegalArgumentException ("unknown command '" + command + "'");
+        }
+    }
+
+    private void runSetDeviceOwner() throws RemoteException {
+        ComponentName component = parseComponentName(nextArgRequired());
+        mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, UserHandle.USER_OWNER);
+
+        String packageName = component.getPackageName();
+        try {
+            if (!mDevicePolicyManager.setDeviceOwner(packageName, null /*ownerName*/)) {
+                throw new RuntimeException(
+                        "Can't set package " + packageName + " as device owner.");
+            }
+        } catch (Exception e) {
+            // Need to remove the admin that we just added.
+            mDevicePolicyManager.removeActiveAdmin(component, UserHandle.USER_OWNER);
+            throw e;
+        }
+        System.out.println("Success: Device owner set to package " + packageName);
+        System.out.println("Active admin set to component " + component.toShortString());
+    }
+
+    private void runSetProfileOwner() throws RemoteException {
+        ComponentName component = parseComponentName(nextArgRequired());
+        int userId = parseInt(nextArgRequired());
+        mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, userId);
+
+        try {
+            if (!mDevicePolicyManager.setProfileOwner(component, "" /*ownerName*/, userId)) {
+                throw new RuntimeException("Can't set component " + component.toShortString() +
+                        " as profile owner for user " + userId);
+            }
+        } catch (Exception e) {
+            // Need to remove the admin that we just added.
+            mDevicePolicyManager.removeActiveAdmin(component, userId);
+            throw e;
+        }
+        System.out.println("Success: Active admin and profile owner set to "
+                + component.toShortString() + " for user " + userId);
+    }
+
+    private ComponentName parseComponentName(String component) {
+        ComponentName cn = ComponentName.unflattenFromString(component);
+        if (cn == null) {
+            throw new IllegalArgumentException ("Invalid component " + component);
+        }
+        return cn;
+    }
+
+    private int parseInt(String argument) {
+        try {
+            return Integer.parseInt(argument);
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException ("Invalid integer argument '" + argument + "'", e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/cmds/idmap/create.cpp b/cmds/idmap/create.cpp
index ae35f7b..593a197 100644
--- a/cmds/idmap/create.cpp
+++ b/cmds/idmap/create.cpp
@@ -105,7 +105,7 @@
 
         uint32_t cached_target_crc, cached_overlay_crc;
         String8 cached_target_path, cached_overlay_path;
-        if (!ResTable::getIdmapInfo(buf, N, &cached_target_crc, &cached_overlay_crc,
+        if (!ResTable::getIdmapInfo(buf, N, NULL, &cached_target_crc, &cached_overlay_crc,
                     &cached_target_path, &cached_overlay_path)) {
             return true;
         }
diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp
index 46c0edc..90cfa2c 100644
--- a/cmds/idmap/idmap.cpp
+++ b/cmds/idmap/idmap.cpp
@@ -66,26 +66,32 @@
       Display an idmap file: \n\
 \n\
       $ adb shell idmap --inspect /data/resource-cache/vendor@overlay@overlay.apk@idmap \n\
-      SECTION      ENTRY        VALUE      OFFSET    COMMENT \n\
-      IDMAP HEADER magic        0x706d6469 0x0 \n\
-                   base crc     0x484aa77f 0x1 \n\
-                   overlay crc  0x03c66fa5 0x2 \n\
-                   base path    .......... 0x03-0x42 /system/app/target.apk \n\
-                   overlay path .......... 0x43-0x82 /vendor/overlay/overlay.apk \n\
-      DATA HEADER  types count  0x00000003 0x83 \n\
-                   padding      0x00000000 0x84 \n\
-                   type offset  0x00000004 0x85      absolute offset 0x87, xml \n\
-                   type offset  0x00000007 0x86      absolute offset 0x8a, string \n\
-      DATA BLOCK   entry count  0x00000001 0x87 \n\
-                   entry offset 0x00000000 0x88 \n\
-                   entry        0x7f020000 0x89      xml/integer \n\
-      DATA BLOCK   entry count  0x00000002 0x8a \n\
-                   entry offset 0x00000000 0x8b \n\
-                   entry        0x7f030000 0x8c      string/str \n\
-                   entry        0x7f030001 0x8d      string/str2 \n\
+      SECTION      ENTRY        VALUE      COMMENT \n\
+      IDMAP HEADER magic        0x706d6469 \n\
+                   base crc     0xb65a383f \n\
+                   overlay crc  0x7b9675e8 \n\
+                   base path    .......... /path/to/target.apk \n\
+                   overlay path .......... /path/to/overlay.apk \n\
+      DATA HEADER  target pkg   0x0000007f \n\
+                   types count  0x00000003 \n\
+      DATA BLOCK   target type  0x00000002 \n\
+                   overlay type 0x00000002 \n\
+                   entry count  0x00000001 \n\
+                   entry offset 0x00000000 \n\
+                   entry        0x00000000 drawable/drawable \n\
+      DATA BLOCK   target type  0x00000003 \n\
+                   overlay type 0x00000003 \n\
+                   entry count  0x00000001 \n\
+                   entry offset 0x00000000 \n\
+                   entry        0x00000000 xml/integer \n\
+      DATA BLOCK   target type  0x00000004 \n\
+                   overlay type 0x00000004 \n\
+                   entry count  0x00000001 \n\
+                   entry offset 0x00000000 \n\
+                   entry        0x00000000 raw/lorem_ipsum \n\
 \n\
       In this example, the overlay package provides three alternative resource values:\n\
-      xml/integer, string/str and string/str2.\n\
+      drawable/drawable, xml/integer, and raw/lorem_ipsum \n\
 \n\
 NOTES \n\
       This tool and its expected invocation from installd is modelled on dexopt.";
diff --git a/cmds/idmap/inspect.cpp b/cmds/idmap/inspect.cpp
index a59f5d31..b9ac8a5 100644
--- a/cmds/idmap/inspect.cpp
+++ b/cmds/idmap/inspect.cpp
@@ -10,92 +10,108 @@
 
 using namespace android;
 
-#define NEXT(b, i, o) do { if (buf.next(&i, &o) < 0) { return -1; } } while (0)
-
 namespace {
-    static const uint32_t IDMAP_MAGIC = 0x706d6469;
+    static const uint32_t IDMAP_MAGIC = 0x504D4449;
     static const size_t PATH_LENGTH = 256;
-    static const uint32_t IDMAP_HEADER_SIZE = (3 + 2 * (PATH_LENGTH / sizeof(uint32_t)));
 
     void printe(const char *fmt, ...);
 
     class IdmapBuffer {
         private:
-            char *buf_;
+            const char* buf_;
             size_t len_;
-            mutable size_t pos_;
+            size_t pos_;
         public:
-            IdmapBuffer() : buf_((char *)MAP_FAILED), len_(0), pos_(0) {}
+            IdmapBuffer() : buf_((const char *)MAP_FAILED), len_(0), pos_(0) {}
 
             ~IdmapBuffer() {
                 if (buf_ != MAP_FAILED) {
-                    munmap(buf_, len_);
+                    munmap(const_cast<char*>(buf_), len_);
                 }
             }
 
-            int init(const char *idmap_path)
-            {
+            status_t init(const char *idmap_path) {
                 struct stat st;
                 int fd;
 
                 if (stat(idmap_path, &st) < 0) {
                     printe("failed to stat idmap '%s': %s\n", idmap_path, strerror(errno));
-                    return -1;
+                    return UNKNOWN_ERROR;
                 }
                 len_ = st.st_size;
                 if ((fd = TEMP_FAILURE_RETRY(open(idmap_path, O_RDONLY))) < 0) {
                     printe("failed to open idmap '%s': %s\n", idmap_path, strerror(errno));
-                    return -1;
+                    return UNKNOWN_ERROR;
                 }
-                if ((buf_ = (char*)mmap(NULL, len_, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
+                if ((buf_ = (const char*)mmap(NULL, len_, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
                     close(fd);
                     printe("failed to mmap idmap: %s\n", strerror(errno));
-                    return -1;
+                    return UNKNOWN_ERROR;
                 }
                 close(fd);
-                return 0;
+                return NO_ERROR;
             }
 
-            int next(uint32_t *i, uint32_t *offset) const
-            {
+            status_t nextUint32(uint32_t* i) {
                 if (!buf_) {
                     printe("failed to read next uint32_t: buffer not initialized\n");
-                    return -1;
+                    return UNKNOWN_ERROR;
                 }
-                if (pos_ + 4 > len_) {
+
+                if (pos_ + sizeof(uint32_t) > len_) {
                     printe("failed to read next uint32_t: end of buffer reached at pos=0x%08x\n",
                             pos_);
-                    return -1;
+                    return UNKNOWN_ERROR;
                 }
-                *offset = pos_ / sizeof(uint32_t);
-                char a = buf_[pos_++];
-                char b = buf_[pos_++];
-                char c = buf_[pos_++];
-                char d = buf_[pos_++];
-                *i = (d << 24) | (c << 16) | (b << 8) | a;
-                return 0;
+
+                if ((reinterpret_cast<uintptr_t>(buf_ + pos_) & 0x3) != 0) {
+                    printe("failed to read next uint32_t: not aligned on 4-byte boundary\n");
+                    return UNKNOWN_ERROR;
+                }
+
+                *i = dtohl(*reinterpret_cast<const uint32_t*>(buf_ + pos_));
+                pos_ += sizeof(uint32_t);
+                return NO_ERROR;
             }
 
-            int nextPath(char *b, uint32_t *offset_start, uint32_t *offset_end) const
-            {
+            status_t nextUint16(uint16_t* i) {
+                if (!buf_) {
+                    printe("failed to read next uint16_t: buffer not initialized\n");
+                    return UNKNOWN_ERROR;
+                }
+
+                if (pos_ + sizeof(uint16_t) > len_) {
+                    printe("failed to read next uint16_t: end of buffer reached at pos=0x%08x\n",
+                            pos_);
+                    return UNKNOWN_ERROR;
+                }
+
+                if ((reinterpret_cast<uintptr_t>(buf_ + pos_) & 0x1) != 0) {
+                    printe("failed to read next uint32_t: not aligned on 2-byte boundary\n");
+                    return UNKNOWN_ERROR;
+                }
+
+                *i = dtohs(*reinterpret_cast<const uint16_t*>(buf_ + pos_));
+                pos_ += sizeof(uint16_t);
+                return NO_ERROR;
+            }
+
+            status_t nextPath(char *b) {
                 if (!buf_) {
                     printe("failed to read next path: buffer not initialized\n");
-                    return -1;
+                    return UNKNOWN_ERROR;
                 }
                 if (pos_ + PATH_LENGTH > len_) {
                     printe("failed to read next path: end of buffer reached at pos=0x%08x\n", pos_);
-                    return -1;
+                    return UNKNOWN_ERROR;
                 }
                 memcpy(b, buf_ + pos_, PATH_LENGTH);
-                *offset_start = pos_ / sizeof(uint32_t);
                 pos_ += PATH_LENGTH;
-                *offset_end = pos_ / sizeof(uint32_t) - 1;
-                return 0;
+                return NO_ERROR;
             }
     };
 
-    void printe(const char *fmt, ...)
-    {
+    void printe(const char *fmt, ...) {
         va_list ap;
 
         va_start(ap, fmt);
@@ -104,44 +120,37 @@
         va_end(ap);
     }
 
-    void print_header()
-    {
-        printf("SECTION      ENTRY        VALUE      OFFSET    COMMENT\n");
+    void print_header() {
+        printf("SECTION      ENTRY        VALUE      COMMENT\n");
     }
 
-    void print(const char *section, const char *subsection, uint32_t value, uint32_t offset,
-            const char *fmt, ...)
-    {
+    void print(const char *section, const char *subsection, uint32_t value, const char *fmt, ...) {
         va_list ap;
 
         va_start(ap, fmt);
-        printf("%-12s %-12s 0x%08x 0x%-4x    ", section, subsection, value, offset);
+        printf("%-12s %-12s 0x%08x ", section, subsection, value);
         vprintf(fmt, ap);
         printf("\n");
         va_end(ap);
     }
 
-    void print_path(const char *section, const char *subsection, uint32_t offset_start,
-            uint32_t offset_end, const char *fmt, ...)
-    {
+    void print_path(const char *section, const char *subsection, const char *fmt, ...) {
         va_list ap;
 
         va_start(ap, fmt);
-        printf("%-12s %-12s .......... 0x%02x-0x%02x ", section, subsection, offset_start,
-                offset_end);
+        printf("%-12s %-12s .......... ", section, subsection);
         vprintf(fmt, ap);
         printf("\n");
         va_end(ap);
     }
 
-    int resource_metadata(const AssetManager& am, uint32_t res_id,
-            String8 *package, String8 *type, String8 *name)
-    {
+    status_t resource_metadata(const AssetManager& am, uint32_t res_id,
+            String8 *package, String8 *type, String8 *name) {
         const ResTable& rt = am.getResources();
         struct ResTable::resource_name data;
         if (!rt.getResourceName(res_id, false, &data)) {
             printe("failed to get resource name id=0x%08x\n", res_id);
-            return -1;
+            return UNKNOWN_ERROR;
         }
         if (package) {
             *package = String8(String16(data.package, data.packageLen));
@@ -152,140 +161,150 @@
         if (name) {
             *name = String8(String16(data.name, data.nameLen));
         }
-        return 0;
+        return NO_ERROR;
     }
 
-    int package_id(const AssetManager& am)
-    {
-        return (am.getResources().getBasePackageId(0)) << 24;
-    }
-
-    int parse_idmap_header(const IdmapBuffer& buf, AssetManager& am)
-    {
-        uint32_t i, o, e;
+    status_t parse_idmap_header(IdmapBuffer& buf, AssetManager& am) {
+        uint32_t i;
         char path[PATH_LENGTH];
 
-        NEXT(buf, i, o);
+        status_t err = buf.nextUint32(&i);
+        if (err != NO_ERROR) {
+            return err;
+        }
+
         if (i != IDMAP_MAGIC) {
             printe("not an idmap file: actual magic constant 0x%08x does not match expected magic "
                     "constant 0x%08x\n", i, IDMAP_MAGIC);
-            return -1;
+            return UNKNOWN_ERROR;
         }
+
         print_header();
-        print("IDMAP HEADER", "magic", i, o, "");
+        print("IDMAP HEADER", "magic", i, "");
 
-        NEXT(buf, i, o);
-        print("", "base crc", i, o, "");
-
-        NEXT(buf, i, o);
-        print("", "overlay crc", i, o, "");
-
-        if (buf.nextPath(path, &o, &e) < 0) {
-            // printe done from IdmapBuffer::nextPath
-            return -1;
+        err = buf.nextUint32(&i);
+        if (err != NO_ERROR) {
+            return err;
         }
-        print_path("", "base path", o, e, "%s", path);
+        print("", "version", i, "");
+
+        err = buf.nextUint32(&i);
+        if (err != NO_ERROR) {
+            return err;
+        }
+        print("", "base crc", i, "");
+
+        err = buf.nextUint32(&i);
+        if (err != NO_ERROR) {
+            return err;
+        }
+        print("", "overlay crc", i, "");
+
+        err = buf.nextPath(path);
+        if (err != NO_ERROR) {
+            // printe done from IdmapBuffer::nextPath
+            return err;
+        }
+        print_path("", "base path", "%s", path);
+
         if (!am.addAssetPath(String8(path), NULL)) {
             printe("failed to add '%s' as asset path\n", path);
-            return -1;
+            return UNKNOWN_ERROR;
         }
 
-        if (buf.nextPath(path, &o, &e) < 0) {
+        err = buf.nextPath(path);
+        if (err != NO_ERROR) {
             // printe done from IdmapBuffer::nextPath
-            return -1;
+            return err;
         }
-        print_path("", "overlay path", o, e, "%s", path);
+        print_path("", "overlay path", "%s", path);
 
-        return 0;
+        return NO_ERROR;
     }
 
-    int parse_data_header(const IdmapBuffer& buf, const AssetManager& am, Vector<uint32_t>& types)
-    {
-        uint32_t i, o;
-        const uint32_t numeric_package = package_id(am);
+    status_t parse_data(IdmapBuffer& buf, const AssetManager& am) {
+        const uint32_t packageId = am.getResources().getBasePackageId(0);
 
-        NEXT(buf, i, o);
-        print("DATA HEADER", "types count", i, o, "");
-        const uint32_t N = i;
+        uint16_t data16;
+        status_t err = buf.nextUint16(&data16);
+        if (err != NO_ERROR) {
+            return err;
+        }
+        print("DATA HEADER", "target pkg", static_cast<uint32_t>(data16), "");
 
-        for (uint32_t j = 0; j < N; ++j) {
-            NEXT(buf, i, o);
-            if (i == 0) {
-                print("", "padding", i, o, "");
-            } else {
+        err = buf.nextUint16(&data16);
+        if (err != NO_ERROR) {
+            return err;
+        }
+        print("", "types count", static_cast<uint32_t>(data16), "");
+
+        uint32_t typeCount = static_cast<uint32_t>(data16);
+        while (typeCount > 0) {
+            typeCount--;
+
+            err = buf.nextUint16(&data16);
+            if (err != NO_ERROR) {
+                return err;
+            }
+            const uint32_t targetTypeId = static_cast<uint32_t>(data16);
+            print("DATA BLOCK", "target type", targetTypeId, "");
+
+            err = buf.nextUint16(&data16);
+            if (err != NO_ERROR) {
+                return err;
+            }
+            print("", "overlay type", static_cast<uint32_t>(data16), "");
+
+            err = buf.nextUint16(&data16);
+            if (err != NO_ERROR) {
+                return err;
+            }
+            const uint32_t entryCount = static_cast<uint32_t>(data16);
+            print("", "entry count", entryCount, "");
+
+            err = buf.nextUint16(&data16);
+            if (err != NO_ERROR) {
+                return err;
+            }
+            const uint32_t entryOffset = static_cast<uint32_t>(data16);
+            print("", "entry offset", entryOffset, "");
+
+            for (uint32_t i = 0; i < entryCount; i++) {
+                uint32_t data32;
+                err = buf.nextUint32(&data32);
+                if (err != NO_ERROR) {
+                    return err;
+                }
+
+                uint32_t resID = (packageId << 24) | (targetTypeId << 16) | (entryOffset + i);
                 String8 type;
-                const uint32_t numeric_type = (j + 1) << 16;
-                const uint32_t res_id = numeric_package | numeric_type;
-                if (resource_metadata(am, res_id, NULL, &type, NULL) < 0) {
-                    // printe done from resource_metadata
-                    return -1;
+                String8 name;
+                err = resource_metadata(am, resID, NULL, &type, &name);
+                if (err != NO_ERROR) {
+                    return err;
                 }
-                print("", "type offset", i, o, "absolute offset 0x%02x, %s",
-                        i + IDMAP_HEADER_SIZE, type.string());
-                types.add(numeric_type);
+                print("", "entry", data32, "%s/%s", type.string(), name.string());
             }
         }
 
-        return 0;
-    }
-
-    int parse_data_block(const IdmapBuffer& buf, const AssetManager& am, size_t numeric_type)
-    {
-        uint32_t i, o, n, id_offset;
-        const uint32_t numeric_package = package_id(am);
-
-        NEXT(buf, i, o);
-        print("DATA BLOCK", "entry count", i, o, "");
-        n = i;
-
-        NEXT(buf, i, o);
-        print("", "entry offset", i, o, "");
-        id_offset = i;
-
-        for ( ; n > 0; --n) {
-            String8 type, name;
-
-            NEXT(buf, i, o);
-            if (i == 0) {
-                print("", "padding", i, o, "");
-            } else {
-                uint32_t res_id = numeric_package | numeric_type | id_offset;
-                if (resource_metadata(am, res_id, NULL, &type, &name) < 0) {
-                    // printe done from resource_metadata
-                    return -1;
-                }
-                print("", "entry", i, o, "%s/%s", type.string(), name.string());
-            }
-            ++id_offset;
-        }
-
-        return 0;
+        return NO_ERROR;
     }
 }
 
-int idmap_inspect(const char *idmap_path)
-{
+int idmap_inspect(const char *idmap_path) {
     IdmapBuffer buf;
     if (buf.init(idmap_path) < 0) {
         // printe done from IdmapBuffer::init
         return EXIT_FAILURE;
     }
     AssetManager am;
-    if (parse_idmap_header(buf, am) < 0) {
+    if (parse_idmap_header(buf, am) != NO_ERROR) {
         // printe done from parse_idmap_header
         return EXIT_FAILURE;
     }
-    Vector<uint32_t> types;
-    if (parse_data_header(buf, am, types) < 0) {
+    if (parse_data(buf, am) != NO_ERROR) {
         // printe done from parse_data_header
         return EXIT_FAILURE;
     }
-    const size_t N = types.size();
-    for (size_t i = 0; i < N; ++i) {
-        if (parse_data_block(buf, am, types.itemAt(i)) < 0) {
-            // printe done from parse_data_block
-            return EXIT_FAILURE;
-        }
-    }
     return EXIT_SUCCESS;
 }
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
index c5fc941..1153f38 100644
--- a/cmds/idmap/scan.cpp
+++ b/cmds/idmap/scan.cpp
@@ -119,7 +119,8 @@
 
     int parse_manifest(const void *data, size_t size, const char *target_package_name)
     {
-        ResXMLTree parser(data, size);
+        ResXMLTree parser;
+        parser.setTo(data, size);
         if (parser.getError() != NO_ERROR) {
             ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError());
             return -1;
diff --git a/cmds/media/src/com/android/commands/media/Media.java b/cmds/media/src/com/android/commands/media/Media.java
index 92c6a51..6a8fb05 100644
--- a/cmds/media/src/com/android/commands/media/Media.java
+++ b/cmds/media/src/com/android/commands/media/Media.java
@@ -17,12 +17,19 @@
 
 package com.android.commands.media;
 
-import android.app.PendingIntent;
+import android.app.ActivityManager;
 import android.content.Context;
-import android.graphics.Bitmap;
-import android.media.IAudioService;
-import android.media.IRemoteControlDisplay;
+import android.content.pm.ParceledListSlice;
+import android.media.MediaMetadata;
+import android.media.session.ISessionController;
+import android.media.session.ISessionControllerCallback;
+import android.media.session.ISessionManager;
+import android.media.session.MediaController;
+import android.media.session.ParcelableVolumeInfo;
+import android.media.session.PlaybackState;
 import android.os.Bundle;
+import android.os.HandlerThread;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
@@ -30,16 +37,17 @@
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
+
 import com.android.internal.os.BaseCommand;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintStream;
+import java.util.List;
 
 public class Media extends BaseCommand {
-
-    private IAudioService mAudioService;
+    private ISessionManager mSessionService;
 
     /**
      * Command-line entry point.
@@ -54,29 +62,35 @@
         out.println(
                 "usage: media [subcommand] [options]\n" +
                 "       media dispatch KEY\n" +
-                "       media remote-display\n" +
+                "       media list-sessions\n" +
+                "       media monitor <tag>\n" +
                 "\n" +
-                "media dispatch: dispatch a media key to the current media client.\n" +
+                "media dispatch: dispatch a media key to the system.\n" +
                 "                KEY may be: play, pause, play-pause, mute, headsethook,\n" +
-                "                stop, next, previous, rewind, recordm fast-forword.\n" +
-                "media remote-display: monitor remote display updates.\n"
+                "                stop, next, previous, rewind, record, fast-forword.\n" +
+                "media list-sessions: print a list of the current sessions.\n" +
+                        "media monitor: monitor updates to the specified session.\n" +
+                "                       Use the tag from list-sessions.\n"
         );
     }
 
     public void onRun() throws Exception {
-        mAudioService = IAudioService.Stub.asInterface(ServiceManager.checkService(
-                Context.AUDIO_SERVICE));
-        if (mAudioService == null) {
+        mSessionService = ISessionManager.Stub.asInterface(ServiceManager.checkService(
+                Context.MEDIA_SESSION_SERVICE));
+        if (mSessionService == null) {
             System.err.println(NO_SYSTEM_ERROR_CODE);
-            throw new AndroidException("Can't connect to audio service; is the system running?");
+            throw new AndroidException(
+                    "Can't connect to media session service; is the system running?");
         }
 
         String op = nextArgRequired();
 
         if (op.equals("dispatch")) {
             runDispatch();
-        } else if (op.equals("remote-display")) {
-            runRemoteDisplay();
+        } else if (op.equals("list-sessions")) {
+            runListSessions();
+        } else if (op.equals("monitor")) {
+            runMonitor();
         } else {
             showError("Error: unknown command '" + op + "'");
             return;
@@ -85,11 +99,42 @@
 
     private void sendMediaKey(KeyEvent event) {
         try {
-            mAudioService.dispatchMediaKeyEvent(event);
+            mSessionService.dispatchMediaKeyEvent(event, false);
         } catch (RemoteException e) {
         }
     }
 
+    private void runMonitor() throws Exception {
+        String id = nextArgRequired();
+        if (id == null) {
+            showError("Error: must include a session id");
+            return;
+        }
+        boolean success = false;
+        try {
+            List<IBinder> sessions = mSessionService
+                    .getSessions(null, ActivityManager.getCurrentUser());
+            for (IBinder session : sessions) {
+                ISessionController controller = ISessionController.Stub.asInterface(session);
+                try {
+                    if (controller != null && id.equals(controller.getTag())) {
+                        ControllerMonitor monitor = new ControllerMonitor(controller);
+                        monitor.run();
+                        success = true;
+                        break;
+                    }
+                } catch (RemoteException e) {
+                    // ignore
+                }
+            }
+        } catch (Exception e) {
+            System.out.println("***Error monitoring session*** " + e.getMessage());
+        }
+        if (!success) {
+            System.out.println("No session found with id " + id);
+        }
+    }
+
     private void runDispatch() throws Exception {
         String cmd = nextArgRequired();
         int keycode;
@@ -127,65 +172,80 @@
                 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
     }
 
-    class RemoteDisplayMonitor extends IRemoteControlDisplay.Stub {
-        RemoteDisplayMonitor() {
-        }
+    class ControllerMonitor extends ISessionControllerCallback.Stub {
+        private final ISessionController mController;
 
-
-        @Override
-        public void setCurrentClientId(int clientGeneration, PendingIntent clientMediaIntent,
-                boolean clearing) {
-            System.out.println("New client: id=" + clientGeneration
-                    + " intent=" + clientMediaIntent + " clearing=" + clearing);
+        public ControllerMonitor(ISessionController controller) {
+            mController = controller;
         }
 
         @Override
-        public void setEnabled(boolean enabled) {
-            System.out.println("New enable state= " + (enabled ? "enabled" : "disabled"));
+        public void onSessionDestroyed() {
+            System.out.println("onSessionDestroyed. Enter q to quit.");
+
         }
 
         @Override
-        public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
-                long currentPosMs, float speed) {
-            System.out.println("New state: id=" + generationId + " state=" + state
-                    + " time=" + stateChangeTimeMs + " pos=" + currentPosMs + " speed=" + speed);
+        public void onEvent(String event, Bundle extras) {
+            System.out.println("onSessionEvent event=" + event + ", extras=" + extras);
         }
 
         @Override
-        public void setTransportControlInfo(int generationId, int transportControlFlags,
-                int posCapabilities) {
-            System.out.println("New control info: id=" + generationId
-                    + " flags=0x" + Integer.toHexString(transportControlFlags)
-                    + " cap=0x" + Integer.toHexString(posCapabilities));
+        public void onPlaybackStateChanged(PlaybackState state) {
+            System.out.println("onPlaybackStateChanged " + state);
         }
 
         @Override
-        public void setMetadata(int generationId, Bundle metadata) {
-            System.out.println("New metadata: id=" + generationId
-                    + " data=" + metadata);
+        public void onMetadataChanged(MediaMetadata metadata) {
+            String mmString = metadata == null ? null : "title=" + metadata
+                    .getDescription();
+            System.out.println("onMetadataChanged " + mmString);
         }
 
         @Override
-        public void setArtwork(int generationId, Bitmap artwork) {
-            System.out.println("New artwork: id=" + generationId
-                    + " art=" + artwork);
+        public void onQueueChanged(ParceledListSlice queue) throws RemoteException {
+            System.out.println("onQueueChanged, "
+                    + (queue == null ? "null queue" : " size=" + queue.getList().size()));
         }
 
         @Override
-        public void setAllMetadata(int generationId, Bundle metadata, Bitmap artwork) {
-            System.out.println("New metadata+artwork: id=" + generationId
-                    + " data=" + metadata + " art=" + artwork);
+        public void onQueueTitleChanged(CharSequence title) throws RemoteException {
+            System.out.println("onQueueTitleChange " + title);
+        }
+
+        @Override
+        public void onExtrasChanged(Bundle extras) throws RemoteException {
+            System.out.println("onExtrasChanged " + extras);
+        }
+
+        @Override
+        public void onVolumeInfoChanged(ParcelableVolumeInfo info) throws RemoteException {
+            System.out.println("onVolumeInfoChanged " + info);
         }
 
         void printUsageMessage() {
-            System.out.println("Monitoring remote control displays...  available commands:");
+            try {
+                System.out.println("V2Monitoring session " + mController.getTag()
+                        + "...  available commands: play, pause, next, previous");
+            } catch (RemoteException e) {
+                System.out.println("Error trying to monitor session!");
+            }
             System.out.println("(q)uit: finish monitoring");
         }
 
         void run() throws RemoteException {
             printUsageMessage();
-
-            mAudioService.registerRemoteControlDisplay(this, 0, 0);
+            HandlerThread cbThread = new HandlerThread("MediaCb") {
+                @Override
+                protected void onLooperPrepared() {
+                    try {
+                        mController.registerCallbackListener(ControllerMonitor.this);
+                    } catch (RemoteException e) {
+                        System.out.println("Error registering monitor callback");
+                    }
+                }
+            };
+            cbThread.start();
 
             try {
                 InputStreamReader converter = new InputStreamReader(System.in);
@@ -198,6 +258,14 @@
                         addNewline = false;
                     } else if ("q".equals(line) || "quit".equals(line)) {
                         break;
+                    } else if ("play".equals(line)) {
+                        mController.play();
+                    } else if ("pause".equals(line)) {
+                        mController.pause();
+                    } else if ("next".equals(line)) {
+                        mController.next();
+                    } else if ("previous".equals(line)) {
+                        mController.previous();
                     } else {
                         System.out.println("Invalid command: " + line);
                     }
@@ -209,17 +277,38 @@
                         printUsageMessage();
                     }
                 }
-
             } catch (IOException e) {
                 e.printStackTrace();
             } finally {
-                mAudioService.unregisterRemoteControlDisplay(this);
+                cbThread.getLooper().quit();
+                try {
+                    mController.unregisterCallbackListener(this);
+                } catch (Exception e) {
+                    // ignoring
+                }
             }
         }
     }
 
-    private void runRemoteDisplay() throws Exception {
-        RemoteDisplayMonitor monitor = new RemoteDisplayMonitor();
-        monitor.run();
+    private void runListSessions() {
+        System.out.println("Sessions:");
+        try {
+            List<IBinder> sessions = mSessionService
+                    .getSessions(null, ActivityManager.getCurrentUser());
+            for (IBinder session : sessions) {
+
+                ISessionController controller = ISessionController.Stub.asInterface(session);
+                if (controller != null) {
+                    try {
+                        System.out.println("  tag=" + controller.getTag()
+                                + ", package=" + controller.getPackageName());
+                    } catch (RemoteException e) {
+                        // ignore
+                    }
+                }
+            }
+        } catch (Exception e) {
+            System.out.println("***Error listing sessions***");
+        }
     }
 }
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 75b0a82..5e9d8f7 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -18,16 +18,23 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.app.PackageInstallObserver;
 import android.content.ComponentName;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentSender;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageDeleteObserver;
-import android.content.pm.IPackageInstallObserver;
+import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageManager;
 import android.content.pm.InstrumentationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageInstaller.SessionInfo;
+import android.content.pm.PackageInstaller.SessionParams;
 import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
@@ -39,30 +46,43 @@
 import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.IUserManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.content.PackageHelper;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.SizedInputStream;
+
+import libcore.io.IoUtils;
 
 import java.io.File;
 import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.security.InvalidAlgorithmParameterException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.WeakHashMap;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-import com.android.internal.content.PackageHelper;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
 
 public final class Pm {
+    private static final String TAG = "Pm";
+
     IPackageManager mPm;
+    IPackageInstaller mInstaller;
     IUserManager mUm;
 
     private WeakHashMap<String, Resources> mResourceCache
@@ -76,10 +96,18 @@
         "Error: Could not access the Package Manager.  Is the system running?";
 
     public static void main(String[] args) {
-        new Pm().run(args);
+        try {
+            new Pm().run(args);
+        } catch (Exception e) {
+            Log.e(TAG, "Error", e);
+            System.err.println("Error: " + e);
+            if (e instanceof RemoteException) {
+                System.err.println(PM_NOT_RUNNING_ERR);
+            }
+        }
     }
 
-    public void run(String[] args) {
+    public void run(String[] args) throws IOException, RemoteException {
         boolean validCommand = false;
         if (args.length < 1) {
             showUsage();
@@ -92,6 +120,7 @@
             System.err.println(PM_NOT_RUNNING_ERR);
             return;
         }
+        mInstaller = mPm.getPackageInstaller();
 
         mArgs = args;
         String op = args[0];
@@ -117,6 +146,31 @@
             return;
         }
 
+        if ("install-create".equals(op)) {
+            runInstallCreate();
+            return;
+        }
+
+        if ("install-write".equals(op)) {
+            runInstallWrite();
+            return;
+        }
+
+        if ("install-commit".equals(op)) {
+            runInstallCommit();
+            return;
+        }
+
+        if ("install-abandon".equals(op) || "install-destroy".equals(op)) {
+            runInstallAbandon();
+            return;
+        }
+
+        if ("set-installer".equals(op)) {
+            runSetInstaller();
+            return;
+        }
+
         if ("uninstall".equals(op)) {
             runUninstall();
             return;
@@ -147,13 +201,13 @@
             return;
         }
 
-        if ("block".equals(op)) {
-            runSetBlockedSetting(true);
+        if ("hide".equals(op)) {
+            runSetHiddenSetting(true);
             return;
         }
 
-        if ("unblock".equals(op)) {
-            runSetBlockedSetting(false);
+        if ("unhide".equals(op)) {
+            runSetHiddenSetting(false);
             return;
         }
 
@@ -202,6 +256,11 @@
             return;
         }
 
+        if ("force-dex-opt".equals(op)) {
+            runForceDexOpt();
+            return;
+        }
+
         try {
             if (args.length == 1) {
                 if (args[0].equalsIgnoreCase("-l")) {
@@ -698,14 +757,23 @@
         ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg);
     }
 
-    class PackageInstallObserver extends IPackageInstallObserver.Stub {
+    class LocalPackageInstallObserver extends PackageInstallObserver {
         boolean finished;
         int result;
+        String extraPermission;
+        String extraPackage;
 
-        public void packageInstalled(String name, int status) {
-            synchronized( this) {
+        @Override
+        public void onPackageInstalled(String name, int status, String msg, Bundle extras) {
+            synchronized (this) {
                 finished = true;
                 result = status;
+                if (status == PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION) {
+                    extraPermission = extras.getString(
+                            PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION);
+                    extraPackage = extras.getString(
+                            PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
+                }
                 notifyAll();
             }
         }
@@ -715,7 +783,8 @@
      * Converts a failure code into a string by using reflection to find a matching constant
      * in PackageManager.
      */
-    private String installFailureToString(int result) {
+    private String installFailureToString(LocalPackageInstallObserver obs) {
+        final int result = obs.result;
         Field[] fields = PackageManager.class.getFields();
         for (Field f: fields) {
             if (f.getType() == int.class) {
@@ -730,7 +799,16 @@
                         // get the int value and compare it to result.
                         try {
                             if (result == f.getInt(null)) {
-                                return fieldName;
+                                StringBuilder sb = new StringBuilder(64);
+                                sb.append(fieldName);
+                                if (obs.extraPermission != null) {
+                                    sb.append(" perm=");
+                                    sb.append(obs.extraPermission);
+                                }
+                                if (obs.extraPackage != null) {
+                                    sb.append(" pkg=" + obs.extraPackage);
+                                }
+                                return sb.toString();
                             }
                         } catch (IllegalAccessException e) {
                             // this shouldn't happen since we only look for public static fields.
@@ -787,18 +865,12 @@
     }
 
     private void runInstall() {
-        int installFlags = PackageManager.INSTALL_ALL_USERS;
+        int installFlags = 0;
+        int userId = UserHandle.USER_ALL;
         String installerPackageName = null;
 
         String opt;
 
-        String algo = null;
-        byte[] iv = null;
-        byte[] key = null;
-
-        String macAlgo = null;
-        byte[] macKey = null;
-        byte[] tag = null;
         String originatingUriString = null;
         String referrer = null;
         String abi = null;
@@ -824,42 +896,6 @@
                 installFlags |= PackageManager.INSTALL_INTERNAL;
             } else if (opt.equals("-d")) {
                 installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
-            } else if (opt.equals("--algo")) {
-                algo = nextOptionData();
-                if (algo == null) {
-                    System.err.println("Error: must supply argument for --algo");
-                    return;
-                }
-            } else if (opt.equals("--iv")) {
-                iv = hexToBytes(nextOptionData());
-                if (iv == null) {
-                    System.err.println("Error: must supply argument for --iv");
-                    return;
-                }
-            } else if (opt.equals("--key")) {
-                key = hexToBytes(nextOptionData());
-                if (key == null) {
-                    System.err.println("Error: must supply argument for --key");
-                    return;
-                }
-            } else if (opt.equals("--macalgo")) {
-                macAlgo = nextOptionData();
-                if (macAlgo == null) {
-                    System.err.println("Error: must supply argument for --macalgo");
-                    return;
-                }
-            } else if (opt.equals("--mackey")) {
-                macKey = hexToBytes(nextOptionData());
-                if (macKey == null) {
-                    System.err.println("Error: must supply argument for --mackey");
-                    return;
-                }
-            } else if (opt.equals("--tag")) {
-                tag = hexToBytes(nextOptionData());
-                if (tag == null) {
-                    System.err.println("Error: must supply argument for --tag");
-                    return;
-                }
             } else if (opt.equals("--originating-uri")) {
                 originatingUriString = nextOptionData();
                 if (originatingUriString == null) {
@@ -873,70 +909,20 @@
                     return;
                 }
             } else if (opt.equals("--abi")) {
-                abi = nextOptionData();
-                if (abi == null) {
-                    System.err.println("Error: must supply argument for --abi");
-                    return;
-                }
+                abi = checkAbiArgument(nextOptionData());
+            } else if (opt.equals("--user")) {
+                userId = Integer.parseInt(nextOptionData());
             } else {
                 System.err.println("Error: Unknown option: " + opt);
                 return;
             }
         }
 
-        if (abi != null) {
-            final String[] supportedAbis = Build.SUPPORTED_ABIS;
-            boolean matched = false;
-            for (String supportedAbi : supportedAbis) {
-                if (supportedAbi.equals(abi)) {
-                    matched = true;
-                    break;
-                }
-            }
-
-            if (!matched) {
-                System.err.println("Error: abi " + abi + " not supported on this device.");
-                return;
-            }
+        if (userId == UserHandle.USER_ALL) {
+            userId = UserHandle.USER_OWNER;
+            installFlags |= PackageManager.INSTALL_ALL_USERS;
         }
 
-        final ContainerEncryptionParams encryptionParams;
-        if (algo != null || iv != null || key != null || macAlgo != null || macKey != null
-                || tag != null) {
-            if (algo == null || iv == null || key == null) {
-                System.err.println("Error: all of --algo, --iv, and --key must be specified");
-                return;
-            }
-
-            if (macAlgo != null || macKey != null || tag != null) {
-                if (macAlgo == null || macKey == null || tag == null) {
-                    System.err.println("Error: all of --macalgo, --mackey, and --tag must "
-                            + "be specified");
-                    return;
-                }
-            }
-
-            try {
-                final SecretKey encKey = new SecretKeySpec(key, "RAW");
-
-                final SecretKey macSecretKey;
-                if (macKey == null || macKey.length == 0) {
-                    macSecretKey = null;
-                } else {
-                    macSecretKey = new SecretKeySpec(macKey, "RAW");
-                }
-
-                encryptionParams = new ContainerEncryptionParams(algo, new IvParameterSpec(iv),
-                        encKey, macAlgo, null, macSecretKey, tag, -1, -1, -1);
-            } catch (InvalidAlgorithmParameterException e) {
-                e.printStackTrace();
-                return;
-            }
-        } else {
-            encryptionParams = null;
-        }
-
-        final Uri apkURI;
         final Uri verificationURI;
         final Uri originatingURI;
         final Uri referrerURI;
@@ -956,9 +942,7 @@
         // Populate apkURI, must be present
         final String apkFilePath = nextArg();
         System.err.println("\tpkg: " + apkFilePath);
-        if (apkFilePath != null) {
-            apkURI = Uri.fromFile(new File(apkFilePath));
-        } else {
+        if (apkFilePath == null) {
             System.err.println("Error: no package specified");
             return;
         }
@@ -972,14 +956,13 @@
             verificationURI = null;
         }
 
-        PackageInstallObserver obs = new PackageInstallObserver();
+        LocalPackageInstallObserver obs = new LocalPackageInstallObserver();
         try {
             VerificationParams verificationParams = new VerificationParams(verificationURI,
                     originatingURI, referrerURI, VerificationParams.NO_UID, null);
 
-            mPm.installPackageWithVerificationEncryptionAndAbiOverride(apkURI, obs,
-                    installFlags, installerPackageName, verificationParams,
-                    encryptionParams, abi);
+            mPm.installPackageAsUser(apkFilePath, obs.getBinder(), installFlags,
+                    installerPackageName, verificationParams, abi, userId);
 
             synchronized (obs) {
                 while (!obs.finished) {
@@ -992,7 +975,7 @@
                     System.out.println("Success");
                 } else {
                     System.err.println("Failure ["
-                            + installFailureToString(obs.result)
+                            + installFailureToString(obs)
                             + "]");
                 }
             }
@@ -1002,39 +985,200 @@
         }
     }
 
-    /**
-     * Convert a string containing hex-encoded bytes to a byte array.
-     *
-     * @param input String containing hex-encoded bytes
-     * @return input as an array of bytes
-     */
-    private byte[] hexToBytes(String input) {
-        if (input == null) {
-            return null;
+    private void runInstallCreate() throws RemoteException {
+        int userId = UserHandle.USER_ALL;
+        String installerPackageName = null;
+
+        final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
+
+        String opt;
+        while ((opt = nextOption()) != null) {
+            if (opt.equals("-l")) {
+                params.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
+            } else if (opt.equals("-r")) {
+                params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
+            } else if (opt.equals("-i")) {
+                installerPackageName = nextArg();
+                if (installerPackageName == null) {
+                    throw new IllegalArgumentException("Missing installer package");
+                }
+            } else if (opt.equals("-t")) {
+                params.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
+            } else if (opt.equals("-s")) {
+                params.installFlags |= PackageManager.INSTALL_EXTERNAL;
+            } else if (opt.equals("-f")) {
+                params.installFlags |= PackageManager.INSTALL_INTERNAL;
+            } else if (opt.equals("-d")) {
+                params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
+            } else if (opt.equals("--originating-uri")) {
+                params.originatingUri = Uri.parse(nextOptionData());
+            } else if (opt.equals("--referrer")) {
+                params.referrerUri = Uri.parse(nextOptionData());
+            } else if (opt.equals("-p")) {
+                params.mode = SessionParams.MODE_INHERIT_EXISTING;
+                params.appPackageName = nextOptionData();
+                if (params.appPackageName == null) {
+                    throw new IllegalArgumentException("Missing inherit package name");
+                }
+            } else if (opt.equals("-S")) {
+                params.setSize(Long.parseLong(nextOptionData()));
+            } else if (opt.equals("--abi")) {
+                params.abiOverride = checkAbiArgument(nextOptionData());
+            } else if (opt.equals("--user")) {
+                userId = Integer.parseInt(nextOptionData());
+            } else {
+                throw new IllegalArgumentException("Unknown option " + opt);
+            }
         }
 
-        final int inputLength = input.length();
-        if ((inputLength % 2) != 0) {
-            System.err.print("Invalid length; must be multiple of 2");
-            return null;
+        if (userId == UserHandle.USER_ALL) {
+            userId = UserHandle.USER_OWNER;
+            params.installFlags |= PackageManager.INSTALL_ALL_USERS;
         }
 
-        final int byteLength = inputLength / 2;
-        final byte[] output = new byte[byteLength];
+        final int sessionId = mInstaller.createSession(params, installerPackageName, userId);
 
-        int inputIndex = 0;
-        int byteIndex = 0;
-        while (inputIndex < inputLength) {
-            output[byteIndex++] = (byte) Integer.parseInt(
-                    input.substring(inputIndex, inputIndex + 2), 16);
-            inputIndex += 2;
+        // NOTE: adb depends on parsing this string
+        System.out.println("Success: created install session [" + sessionId + "]");
+    }
+
+    private void runInstallWrite() throws IOException, RemoteException {
+        long sizeBytes = -1;
+
+        String opt;
+        while ((opt = nextOption()) != null) {
+            if (opt.equals("-S")) {
+                sizeBytes = Long.parseLong(nextOptionData());
+            } else {
+                throw new IllegalArgumentException("Unknown option: " + opt);
+            }
         }
 
-        return output;
+        final int sessionId = Integer.parseInt(nextArg());
+        final String splitName = nextArg();
+
+        String path = nextArg();
+        if ("-".equals(path)) {
+            path = null;
+        } else if (path != null) {
+            final File file = new File(path);
+            if (file.isFile()) {
+                sizeBytes = file.length();
+            }
+        }
+
+        final SessionInfo info = mInstaller.getSessionInfo(sessionId);
+
+        PackageInstaller.Session session = null;
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
+
+            if (path != null) {
+                in = new FileInputStream(path);
+            } else {
+                in = new SizedInputStream(System.in, sizeBytes);
+            }
+            out = session.openWrite(splitName, 0, sizeBytes);
+
+            int total = 0;
+            byte[] buffer = new byte[65536];
+            int c;
+            while ((c = in.read(buffer)) != -1) {
+                total += c;
+                out.write(buffer, 0, c);
+
+                if (info.sizeBytes > 0) {
+                    final float fraction = ((float) c / (float) info.sizeBytes);
+                    session.addProgress(fraction);
+                }
+            }
+            session.fsync(out);
+
+            System.out.println("Success: streamed " + total + " bytes");
+        } finally {
+            IoUtils.closeQuietly(out);
+            IoUtils.closeQuietly(in);
+            IoUtils.closeQuietly(session);
+        }
+    }
+
+    private void runInstallCommit() throws RemoteException {
+        final int sessionId = Integer.parseInt(nextArg());
+
+        PackageInstaller.Session session = null;
+        try {
+            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
+
+            final LocalIntentReceiver receiver = new LocalIntentReceiver();
+            session.commit(receiver.getIntentSender());
+
+            final Intent result = receiver.getResult();
+            final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+                    PackageInstaller.STATUS_FAILURE);
+            if (status == PackageInstaller.STATUS_SUCCESS) {
+                System.out.println("Success");
+            } else {
+                Log.e(TAG, "Failure details: " + result.getExtras());
+                System.out.println("Failure ["
+                        + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
+                return;
+            }
+        } finally {
+            IoUtils.closeQuietly(session);
+        }
+    }
+
+    private void runInstallAbandon() throws RemoteException {
+        final int sessionId = Integer.parseInt(nextArg());
+
+        PackageInstaller.Session session = null;
+        try {
+            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
+            session.abandon();
+            System.out.println("Success");
+        } finally {
+            IoUtils.closeQuietly(session);
+        }
+    }
+
+    private void runSetInstaller() throws RemoteException {
+        final String targetPackage = nextArg();
+        final String installerPackageName = nextArg();
+
+        if (targetPackage == null || installerPackageName == null) {
+            throw new IllegalArgumentException(
+                    "must provide both target and installer package names");
+        }
+
+        mPm.setInstallerPackageName(targetPackage, installerPackageName);
+        System.out.println("Success");
     }
 
     public void runCreateUser() {
         String name;
+        int userId = -1;
+        int flags = 0;
+        String opt;
+        while ((opt = nextOption()) != null) {
+            if ("--profileOf".equals(opt)) {
+                String optionData = nextOptionData();
+                if (optionData == null || !isNumber(optionData)) {
+                    System.err.println("Error: no USER_ID specified");
+                    showUsage();
+                    return;
+                } else {
+                    userId = Integer.parseInt(optionData);
+                }
+            } else if ("--managed".equals(opt)) {
+                flags |= UserInfo.FLAG_MANAGED_PROFILE;
+            } else {
+                System.err.println("Error: unknown option " + opt);
+                showUsage();
+                return;
+            }
+        }
         String arg = nextArg();
         if (arg == null) {
             System.err.println("Error: no user name specified.");
@@ -1042,7 +1186,12 @@
         }
         name = arg;
         try {
-            final UserInfo info = mUm.createUser(name, 0);
+            UserInfo info = null;
+            if (userId < 0) {
+                info = mUm.createUser(name, flags);
+            } else {
+                info = mUm.createProfileForUser(name, flags, userId);
+            }
             if (info != null) {
                 System.out.println("Success: created user id " + info.id);
             } else {
@@ -1082,13 +1231,16 @@
 
     public void runListUsers() {
         try {
+            IActivityManager am = ActivityManagerNative.getDefault();
+
             List<UserInfo> users = mUm.getUsers(false);
             if (users == null) {
                 System.err.println("Error: couldn't get users");
             } else {
                 System.out.println("Users:");
                 for (int i = 0; i < users.size(); i++) {
-                    System.out.println("\t" + users.get(i).toString());
+                    String running = am.isUserRunning(users.get(i).id, false) ? " running" : "";
+                    System.out.println("\t" + users.get(i).toString() + running);
                 }
             }
         } catch (RemoteException e) {
@@ -1101,26 +1253,32 @@
         System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers());
     }
 
-    class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
-        boolean finished;
-        boolean result;
-
-        public void packageDeleted(String packageName, int returnCode) {
-            synchronized (this) {
-                finished = true;
-                result = returnCode == PackageManager.DELETE_SUCCEEDED;
-                notifyAll();
-            }
+    public void runForceDexOpt() {
+        final String packageName = nextArg();
+        try {
+            mPm.forceDexOpt(packageName);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
         }
     }
 
-    private void runUninstall() {
-        int unInstallFlags = PackageManager.DELETE_ALL_USERS;
+    private void runUninstall() throws RemoteException {
+        int flags = 0;
+        int userId = UserHandle.USER_ALL;
 
         String opt;
         while ((opt=nextOption()) != null) {
             if (opt.equals("-k")) {
-                unInstallFlags |= PackageManager.DELETE_KEEP_DATA;
+                flags |= PackageManager.DELETE_KEEP_DATA;
+            } else if (opt.equals("--user")) {
+                String param = nextArg();
+                if (isNumber(param)) {
+                    userId = Integer.parseInt(param);
+                } else {
+                    showUsage();
+                    System.err.println("Error: Invalid user: " + param);
+                    return;
+                }
             } else {
                 System.err.println("Error: Unknown option: " + opt);
                 return;
@@ -1133,34 +1291,48 @@
             showUsage();
             return;
         }
-        boolean result = deletePackage(pkg, unInstallFlags);
-        if (result) {
+
+        if (userId == UserHandle.USER_ALL) {
+            userId = UserHandle.USER_OWNER;
+            flags |= PackageManager.DELETE_ALL_USERS;
+        } else {
+            PackageInfo info;
+            try {
+                info = mPm.getPackageInfo(pkg, 0, userId);
+            } catch (RemoteException e) {
+                System.err.println(e.toString());
+                System.err.println(PM_NOT_RUNNING_ERR);
+                return;
+            }
+            if (info == null) {
+                System.err.println("Failure - not installed for " + userId);
+                return;
+            }
+            final boolean isSystem =
+                    (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+            // If we are being asked to delete a system app for just one
+            // user set flag so it disables rather than reverting to system
+            // version of the app.
+            if (isSystem) {
+                flags |= PackageManager.DELETE_SYSTEM_APP;
+            }
+        }
+
+        final LocalIntentReceiver receiver = new LocalIntentReceiver();
+        mInstaller.uninstall(pkg, flags, receiver.getIntentSender(), userId);
+
+        final Intent result = receiver.getResult();
+        final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+                PackageInstaller.STATUS_FAILURE);
+        if (status == PackageInstaller.STATUS_SUCCESS) {
             System.out.println("Success");
         } else {
-            System.out.println("Failure");
+            Log.e(TAG, "Failure details: " + result.getExtras());
+            System.out.println("Failure ["
+                    + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
         }
     }
 
-    private boolean deletePackage(String pkg, int unInstallFlags) {
-        PackageDeleteObserver obs = new PackageDeleteObserver();
-        try {
-            mPm.deletePackageAsUser(pkg, obs, UserHandle.USER_OWNER, unInstallFlags);
-
-            synchronized (obs) {
-                while (!obs.finished) {
-                    try {
-                        obs.wait();
-                    } catch (InterruptedException e) {
-                    }
-                }
-            }
-        } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(PM_NOT_RUNNING_ERR);
-        }
-        return obs.result;
-    }
-
     static class ClearDataObserver extends IPackageDataObserver.Stub {
         boolean finished;
         boolean result;
@@ -1173,7 +1345,6 @@
                 notifyAll();
             }
         }
-
     }
 
     private void runClear() {
@@ -1290,7 +1461,7 @@
         }
     }
 
-    private void runSetBlockedSetting(boolean state) {
+    private void runSetHiddenSetting(boolean state) {
         int userId = 0;
         String option = nextOption();
         if (option != null && option.equals("--user")) {
@@ -1311,9 +1482,9 @@
             return;
         }
         try {
-            mPm.setApplicationBlockedSettingAsUser(pkg, state, userId);
-            System.err.println("Package " + pkg + " new blocked state: "
-                    + mPm.getApplicationBlockedSettingAsUser(pkg, userId));
+            mPm.setApplicationHiddenSettingAsUser(pkg, state, userId);
+            System.err.println("Package " + pkg + " new hidden state: "
+                    + mPm.getApplicationHiddenSettingAsUser(pkg, userId));
         } catch (RemoteException e) {
             System.err.println(e.toString());
             System.err.println(PM_NOT_RUNNING_ERR);
@@ -1456,6 +1627,12 @@
             if (info != null && info.applicationInfo != null) {
                 System.out.print("package:");
                 System.out.println(info.applicationInfo.sourceDir);
+                if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
+                    for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
+                        System.out.print("package:");
+                        System.out.println(splitSourceDir);
+                    }
+                }
             }
         } catch (RemoteException e) {
             System.err.println(e.toString());
@@ -1481,6 +1658,54 @@
         }
     }
 
+    private static String checkAbiArgument(String abi) {
+        if (TextUtils.isEmpty(abi)) {
+            throw new IllegalArgumentException("Missing ABI argument");
+        }
+
+        if ("-".equals(abi)) {
+            return abi;
+        }
+
+        final String[] supportedAbis = Build.SUPPORTED_ABIS;
+        for (String supportedAbi : supportedAbis) {
+            if (supportedAbi.equals(abi)) {
+                return abi;
+            }
+        }
+
+        throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
+    }
+
+    private static class LocalIntentReceiver {
+        private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
+
+        private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
+            @Override
+            public int send(int code, Intent intent, String resolvedType,
+                    IIntentReceiver finishedReceiver, String requiredPermission) {
+                try {
+                    mResult.offer(intent, 5, TimeUnit.SECONDS);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+                return 0;
+            }
+        };
+
+        public IntentSender getIntentSender() {
+            return new IntentSender((IIntentSender) mLocalSender);
+        }
+
+        public Intent getResult() {
+            try {
+                return mResult.take();
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
     private String nextOption() {
         if (mNextArg >= mArgs.length) {
             return null;
@@ -1537,24 +1762,27 @@
         System.err.println("       pm list users");
         System.err.println("       pm path PACKAGE");
         System.err.println("       pm dump PACKAGE");
-        System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]");
-        System.err.println("                  [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]");
-        System.err.println("                  [--originating-uri <URI>] [--referrer <URI>] PATH");
-        System.err.println("       pm uninstall [-k] PACKAGE");
+        System.err.println("       pm install [-lrtsfd] [-i PACKAGE] [PATH]");
+        System.err.println("       pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]");
+        System.err.println("       pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]");
+        System.err.println("       pm install-commit SESSION_ID");
+        System.err.println("       pm install-abandon SESSION_ID");
+        System.err.println("       pm uninstall [-k] [--user USER_ID] PACKAGE");
+        System.err.println("       pm set-installer PACKAGE INSTALLER");
         System.err.println("       pm clear [--user USER_ID] PACKAGE");
         System.err.println("       pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
-        System.err.println("       pm block [--user USER_ID] PACKAGE_OR_COMPONENT");
-        System.err.println("       pm unblock [--user USER_ID] PACKAGE_OR_COMPONENT");
+        System.err.println("       pm hide [--user USER_ID] PACKAGE_OR_COMPONENT");
+        System.err.println("       pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm grant PACKAGE PERMISSION");
         System.err.println("       pm revoke PACKAGE PERMISSION");
         System.err.println("       pm set-install-location [0/auto] [1/internal] [2/external]");
         System.err.println("       pm get-install-location");
         System.err.println("       pm set-permission-enforced PERMISSION [true|false]");
         System.err.println("       pm trim-caches DESIRED_FREE_SPACE");
-        System.err.println("       pm create-user USER_NAME");
+        System.err.println("       pm create-user [--profileOf USER_ID] [--managed] USER_NAME");
         System.err.println("       pm remove-user USER_ID");
         System.err.println("       pm get-max-users");
         System.err.println("");
@@ -1589,16 +1817,28 @@
         System.err.println("");
         System.err.println("pm path: print the path to the .apk of the given PACKAGE.");
         System.err.println("");
-        System.err.println("pm dump: print system state associated w ith the given PACKAGE.");
+        System.err.println("pm dump: print system state associated with the given PACKAGE.");
         System.err.println("");
-        System.err.println("pm install: installs a package to the system.  Options:");
-        System.err.println("    -l: install the package with FORWARD_LOCK.");
-        System.err.println("    -r: reinstall an exisiting app, keeping its data.");
-        System.err.println("    -t: allow test .apks to be installed.");
-        System.err.println("    -i: specify the installer package name.");
-        System.err.println("    -s: install package on sdcard.");
-        System.err.println("    -f: install package on internal flash.");
-        System.err.println("    -d: allow version code downgrade.");
+        System.err.println("pm install: install a single legacy package");
+        System.err.println("pm install-create: create an install session");
+        System.err.println("    -l: forward lock application");
+        System.err.println("    -r: replace existing application");
+        System.err.println("    -t: allow test packages");
+        System.err.println("    -i: specify the installer package name");
+        System.err.println("    -s: install application on sdcard");
+        System.err.println("    -f: install application on internal flash");
+        System.err.println("    -d: allow version code downgrade");
+        System.err.println("    -p: partial application install");
+        System.err.println("    -S: size in bytes of entire session");
+        System.err.println("");
+        System.err.println("pm install-write: write a package into existing session; path may");
+        System.err.println("  be '-' to read from stdin");
+        System.err.println("    -S: size in bytes of package, required for stdin");
+        System.err.println("");
+        System.err.println("pm install-commit: perform install of fully staged session");
+        System.err.println("pm install-abandon: abandon session");
+        System.err.println("");
+        System.err.println("pm set-installer: set installer package name");
         System.err.println("");
         System.err.println("pm uninstall: removes a package from the system. Options:");
         System.err.println("    -k: keep the data and cache directories around after package removal.");
@@ -1632,5 +1872,6 @@
         System.err.println("");
         System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,");
         System.err.println("  deleting all data associated with that user");
+        System.err.println("");
     }
 }
diff --git a/cmds/screencap/Android.mk b/cmds/screencap/Android.mk
index ca8008b..5c11b75 100644
--- a/cmds/screencap/Android.mk
+++ b/cmds/screencap/Android.mk
@@ -16,11 +16,4 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_C_INCLUDES += \
-	external/skia/include/core \
-	external/skia/include/effects \
-	external/skia/include/images \
-	external/skia/src/ports \
-	external/skia/include/utils
-
 include $(BUILD_EXECUTABLE)
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index a57de01..6b2a0e2 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -52,13 +52,13 @@
     );
 }
 
-static SkBitmap::Config flinger2skia(PixelFormat f)
+static SkColorType flinger2skia(PixelFormat f)
 {
     switch (f) {
         case PIXEL_FORMAT_RGB_565:
-            return SkBitmap::kRGB_565_Config;
+            return kRGB_565_SkColorType;
         default:
-            return SkBitmap::kARGB_8888_Config;
+            return kN32_SkColorType;
     }
 }
 
@@ -141,7 +141,7 @@
 
     ScreenshotClient screenshot;
     sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
-    if (display != NULL && screenshot.update(display) == NO_ERROR) {
+    if (display != NULL && screenshot.update(display, Rect(), false) == NO_ERROR) {
         base = screenshot.getPixels();
         w = screenshot.getWidth();
         h = screenshot.getHeight();
@@ -174,9 +174,10 @@
 
     if (base) {
         if (png) {
+            const SkImageInfo info = SkImageInfo::Make(w, h, flinger2skia(f),
+                                                       kPremul_SkAlphaType);
             SkBitmap b;
-            b.setConfig(flinger2skia(f), w, h, s*bytesPerPixel(f));
-            b.setPixels((void*)base);
+            b.installPixels(info, const_cast<void*>(base), s*bytesPerPixel(f));
             SkDynamicMemoryWStream stream;
             SkImageEncoder::EncodeStream(&stream, b,
                     SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality);
diff --git a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
index dce0a75..e6847a9 100644
--- a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
+++ b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
@@ -20,6 +20,7 @@
 import android.app.IActivityManager;
 import android.app.IActivityManager.ContentProviderHolder;
 import android.content.IContentProvider;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -33,7 +34,8 @@
     enum CommandVerb {
         UNSPECIFIED,
         GET,
-        PUT
+        PUT,
+        DELETE
     }
 
     static String[] mArgs;
@@ -74,6 +76,8 @@
                         mVerb = CommandVerb.GET;
                     } else if ("put".equalsIgnoreCase(arg)) {
                         mVerb = CommandVerb.PUT;
+                    } else if ("delete".equalsIgnoreCase(arg)) {
+                        mVerb = CommandVerb.DELETE;
                     } else {
                         // invalid
                         System.err.println("Invalid command: " + arg);
@@ -87,7 +91,7 @@
                         break;  // invalid
                     }
                     mTable = arg.toLowerCase();
-                } else if (mVerb == CommandVerb.GET) {
+                } else if (mVerb == CommandVerb.GET || mVerb == CommandVerb.DELETE) {
                     mKey = arg;
                     if (mNextArg >= mArgs.length) {
                         valid = true;
@@ -136,6 +140,10 @@
                         case PUT:
                             putForUser(provider, mUser, mTable, mKey, mValue);
                             break;
+                        case DELETE:
+                            System.out.println("Deleted "
+                                    + deleteForUser(provider, mUser, mTable, mKey) + " rows");
+                            break;
                         default:
                             System.err.println("Unspecified command");
                             break;
@@ -211,9 +219,31 @@
         }
     }
 
+    int deleteForUser(IContentProvider provider, int userHandle,
+            final String table, final String key) {
+        Uri targetUri;
+        if ("system".equals(table)) targetUri = Settings.System.getUriFor(key);
+        else if ("secure".equals(table)) targetUri = Settings.Secure.getUriFor(key);
+        else if ("global".equals(table)) targetUri = Settings.Global.getUriFor(key);
+        else {
+            System.err.println("Invalid table; no delete performed");
+            throw new IllegalArgumentException("Invalid table " + table);
+        }
+
+        int num = 0;
+        try {
+            num = provider.delete(null, targetUri, null, null);
+        } catch (RemoteException e) {
+            System.err.println("Can't clear key " + key + " in " + table + " for user "
+                    + userHandle);
+        }
+        return num;
+    }
+
     private static void printUsage() {
         System.err.println("usage:  settings [--user NUM] get namespace key");
         System.err.println("        settings [--user NUM] put namespace key value");
+        System.err.println("        settings [--user NUM] delete namespace key");
         System.err.println("\n'namespace' is one of {system, secure, global}, case-insensitive");
         System.err.println("If '--user NUM' is not given, the operations are performed on the owner user.");
     }
diff --git a/cmds/svc/src/com/android/commands/svc/DataCommand.java b/cmds/svc/src/com/android/commands/svc/DataCommand.java
index 72cb86d..406e33b 100644
--- a/cmds/svc/src/com/android/commands/svc/DataCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/DataCommand.java
@@ -36,9 +36,7 @@
         return shortHelp() + "\n"
                 + "\n"
                 + "usage: svc data [enable|disable]\n"
-                + "         Turn mobile data on or off.\n\n"
-                + "       svc data prefer\n"
-                + "          Set mobile as the preferred data network\n";
+                + "         Turn mobile data on or off.\n\n";
     }
 
     public void run(String[] args) {
@@ -51,15 +49,6 @@
             } else if ("disable".equals(args[1])) {
                 flag = false;
                 validCommand = true;
-            } else if ("prefer".equals(args[1])) {
-                IConnectivityManager connMgr =
-                        IConnectivityManager.Stub.asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
-                try {
-                    connMgr.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);
-                } catch (RemoteException e) {
-                    System.err.println("Failed to set preferred network: " + e);
-                }
-                return;
             }
             if (validCommand) {
                 ITelephony phoneMgr
@@ -78,4 +67,4 @@
         }
         System.err.println(longHelp());
     }
-}
\ No newline at end of file
+}
diff --git a/cmds/svc/src/com/android/commands/svc/WifiCommand.java b/cmds/svc/src/com/android/commands/svc/WifiCommand.java
index d29e8b2..39f0e35 100644
--- a/cmds/svc/src/com/android/commands/svc/WifiCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/WifiCommand.java
@@ -36,9 +36,7 @@
         return shortHelp() + "\n"
                 + "\n"
                 + "usage: svc wifi [enable|disable]\n"
-                + "         Turn Wi-Fi on or off.\n\n"
-                + "       svc wifi prefer\n"
-                + "          Set Wi-Fi as the preferred data network\n";
+                + "         Turn Wi-Fi on or off.\n\n";
     }
 
     public void run(String[] args) {
@@ -51,15 +49,6 @@
             } else if ("disable".equals(args[1])) {
                 flag = false;
                 validCommand = true;
-            } else if ("prefer".equals(args[1])) {
-                IConnectivityManager connMgr =
-                        IConnectivityManager.Stub.asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
-                try {
-                    connMgr.setNetworkPreference(ConnectivityManager.TYPE_WIFI);
-                } catch (RemoteException e) {
-                    System.err.println("Failed to set preferred network: " + e);
-                }
-                return;
             }
             if (validCommand) {
                 IWifiManager wifiMgr
@@ -75,4 +64,4 @@
         }
         System.err.println(longHelp());
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 1e3d5be..13ceb4a 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -28,9 +28,12 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
 
 import com.android.internal.os.HandlerCaller;
 
+import java.util.List;
+
 /**
  * An accessibility service runs in the background and receives callbacks by the system
  * when {@link AccessibilityEvent}s are fired. Such events denote some state transition
@@ -180,28 +183,37 @@
  * event generation has settled down.</p>
  * <h3>Event types</h3>
  * <ul>
- * <li>{@link AccessibilityEvent#TYPE_VIEW_CLICKED}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_SELECTED}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
- * <li>{@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
- * <li>{@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}
- * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}
- * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_SCROLLED}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED}
- * <li>{@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_CLICKED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_FOCUSED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_SELECTED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}</li>
+ * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_SCROLLED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_ANNOUNCEMENT}</li>
+ * <li>{@link AccessibilityEvent#TYPE_GESTURE_DETECTION_START}</li>
+ * <li>{@link AccessibilityEvent#TYPE_GESTURE_DETECTION_END}</li>
+ * <li>{@link AccessibilityEvent#TYPE_TOUCH_INTERACTION_START}</li>
+ * <li>{@link AccessibilityEvent#TYPE_TOUCH_INTERACTION_END}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUSED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_WINDOWS_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED}</li>
  * </ul>
  * <h3>Feedback types</h3>
  * <ul>
- * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
- * <li>{@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}
- * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
- * <li>{@link AccessibilityServiceInfo#FEEDBACK_VISUAL}
- * <li>{@link AccessibilityServiceInfo#FEEDBACK_GENERIC}
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}</li>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}</li>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}</li>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_VISUAL}</li>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_GENERIC}</li>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_BRAILLE}</li>
  * </ul>
  * @see AccessibilityEvent
  * @see AccessibilityServiceInfo
@@ -340,6 +352,11 @@
      */
     public static final int GLOBAL_ACTION_QUICK_SETTINGS = 5;
 
+    /**
+     * Action to open the power long-press dialog.
+     */
+    public static final int GLOBAL_ACTION_POWER_DIALOG = 6;
+
     private static final String LOG_TAG = "AccessibilityService";
 
     /**
@@ -443,8 +460,43 @@
     }
 
     /**
+     * Gets the windows on the screen. This method returns only the windows
+     * that a sighted user can interact with, as opposed to all windows.
+     * For example, if there is a modal dialog shown and the user cannot touch
+     * anything behind it, then only the modal window will be reported
+     * (assuming it is the top one). For convenience the returned windows
+     * are ordered in a descending layer order, which is the windows that
+     * are higher in the Z-order are reported first. Since the user can always
+     * interact with the window that has input focus by typing, the focused
+     * window is always returned (even if covered by a modal window).
+     * <p>
+     * <strong>Note:</strong> In order to access the windows your service has
+     * to declare the capability to retrieve window content by setting the
+     * {@link android.R.styleable#AccessibilityService_canRetrieveWindowContent}
+     * property in its meta-data. For details refer to {@link #SERVICE_META_DATA}.
+     * Also the service has to opt-in to retrieve the interactive windows by
+     * setting the {@link AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS}
+     * flag.
+     * </p>
+     *
+     * @return The windows if there are windows and the service is can retrieve
+     *         them, otherwise an empty list.
+     */
+    public List<AccessibilityWindowInfo> getWindows() {
+        return AccessibilityInteractionClient.getInstance().getWindows(mConnectionId);
+    }
+
+    /**
      * Gets the root node in the currently active window if this service
-     * can retrieve window content.
+     * can retrieve window content. The active window is the one that the user
+     * is currently touching or the window with input focus, if the user is not
+     * touching any window.
+     * <p>
+     * <strong>Note:</strong> In order to access the root node your service has
+     * to declare the capability to retrieve window content by setting the
+     * {@link android.R.styleable#AccessibilityService_canRetrieveWindowContent}
+     * property in its meta-data. For details refer to {@link #SERVICE_META_DATA}.
+     * </p>
      *
      * @return The root node if this service can retrieve window content.
      */
@@ -480,6 +532,31 @@
     }
 
     /**
+     * Find the view that has the specified focus type. The search is performed
+     * across all windows.
+     * <p>
+     * <strong>Note:</strong> In order to access the windows your service has
+     * to declare the capability to retrieve window content by setting the
+     * {@link android.R.styleable#AccessibilityService_canRetrieveWindowContent}
+     * property in its meta-data. For details refer to {@link #SERVICE_META_DATA}.
+     * Also the service has to opt-in to retrieve the interactive windows by
+     * setting the {@link AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS}
+     * flag.Otherwise, the search will be performed only in the active window.
+     * </p>
+     *
+     * @param focus The focus to find. One of {@link AccessibilityNodeInfo#FOCUS_INPUT} or
+     *         {@link AccessibilityNodeInfo#FOCUS_ACCESSIBILITY}.
+     * @return The node info of the focused view or null.
+     *
+     * @see AccessibilityNodeInfo#FOCUS_INPUT
+     * @see AccessibilityNodeInfo#FOCUS_ACCESSIBILITY
+     */
+    public AccessibilityNodeInfo findFocus(int focus) {
+        return AccessibilityInteractionClient.getInstance().findFocus(mConnectionId,
+                AccessibilityNodeInfo.ANY_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, focus);
+    }
+
+    /**
      * Gets the an {@link AccessibilityServiceInfo} describing this
      * {@link AccessibilityService}. This method is useful if one wants
      * to change some of the dynamically configurable properties at
@@ -581,15 +658,12 @@
      */
     public static class IAccessibilityServiceClientWrapper extends IAccessibilityServiceClient.Stub
             implements HandlerCaller.Callback {
-
-        static final int NO_ID = -1;
-
-        private static final int DO_SET_SET_CONNECTION = 10;
-        private static final int DO_ON_INTERRUPT = 20;
-        private static final int DO_ON_ACCESSIBILITY_EVENT = 30;
-        private static final int DO_ON_GESTURE = 40;
-        private static final int DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE = 50;
-        private static final int DO_ON_KEY_EVENT = 60;
+        private static final int DO_SET_SET_CONNECTION = 1;
+        private static final int DO_ON_INTERRUPT = 2;
+        private static final int DO_ON_ACCESSIBILITY_EVENT = 3;
+        private static final int DO_ON_GESTURE = 4;
+        private static final int DO_CLEAR_ACCESSIBILITY_CACHE = 5;
+        private static final int DO_ON_KEY_EVENT = 6;
 
         private final HandlerCaller mCaller;
 
@@ -624,8 +698,8 @@
             mCaller.sendMessage(message);
         }
 
-        public void clearAccessibilityNodeInfoCache() {
-            Message message = mCaller.obtainMessage(DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE);
+        public void clearAccessibilityCache() {
+            Message message = mCaller.obtainMessage(DO_CLEAR_ACCESSIBILITY_CACHE);
             mCaller.sendMessage(message);
         }
 
@@ -635,6 +709,7 @@
             mCaller.sendMessage(message);
         }
 
+        @Override
         public void executeMessage(Message message) {
             switch (message.what) {
                 case DO_ON_ACCESSIBILITY_EVENT: {
@@ -642,12 +717,19 @@
                     if (event != null) {
                         AccessibilityInteractionClient.getInstance().onAccessibilityEvent(event);
                         mCallback.onAccessibilityEvent(event);
-                        event.recycle();
+                        // Make sure the event is recycled.
+                        try {
+                            event.recycle();
+                        } catch (IllegalStateException ise) {
+                            /* ignore - best effort */
+                        }
                     }
                 } return;
+
                 case DO_ON_INTERRUPT: {
                     mCallback.onInterrupt();
                 } return;
+
                 case DO_SET_SET_CONNECTION: {
                     mConnectionId = message.arg1;
                     IAccessibilityServiceConnection connection =
@@ -658,18 +740,22 @@
                         mCallback.onSetConnectionId(mConnectionId);
                         mCallback.onServiceConnected();
                     } else {
-                        AccessibilityInteractionClient.getInstance().removeConnection(mConnectionId);
+                        AccessibilityInteractionClient.getInstance().removeConnection(
+                                mConnectionId);
                         AccessibilityInteractionClient.getInstance().clearCache();
                         mCallback.onSetConnectionId(AccessibilityInteractionClient.NO_ID);
                     }
                 } return;
+
                 case DO_ON_GESTURE: {
                     final int gestureId = message.arg1;
                     mCallback.onGesture(gestureId);
                 } return;
-                case DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE: {
+
+                case DO_CLEAR_ACCESSIBILITY_CACHE: {
                     AccessibilityInteractionClient.getInstance().clearCache();
                 } return;
+
                 case DO_ON_KEY_EVENT: {
                     KeyEvent event = (KeyEvent) message.obj;
                     try {
@@ -685,9 +771,15 @@
                             }
                         }
                     } finally {
-                        event.recycle();
+                        // Make sure the event is recycled.
+                        try {
+                            event.recycle();
+                        } catch (IllegalStateException ise) {
+                            /* ignore - best effort */
+                        }
                     }
                 } return;
+
                 default :
                     Log.w(LOG_TAG, "Unknown message type " + message.what);
             }
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index bdc4fdde..4edb0c6 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -284,6 +284,27 @@
     public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020;
 
     /**
+     * This flag indicates to the system that the accessibility service wants
+     * to access content of all interactive windows. An interactive window is a
+     * window that has input focus or can be touched by a sighted user when explore
+     * by touch is not enabled. If this flag is not set your service will not receive
+     * {@link android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED}
+     * events, calling AccessibilityService{@link AccessibilityService#getWindows()
+     * AccessibilityService.getWindows()} will return an empty list, and {@link
+     * AccessibilityNodeInfo#getWindow() AccessibilityNodeInfo.getWindow()} will
+     * return null.
+     * <p>
+     * Services that want to set this flag have to declare the capability
+     * to retrieve window content in their meta-data by setting the attribute
+     * {@link android.R.attr#canRetrieveWindowContent canRetrieveWindowContent} to
+     * true, otherwise this flag will be ignored. For how to declare the meta-data
+     * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
+     * </p>
+     * @see android.R.styleable#AccessibilityService_canRetrieveWindowContent
+     */
+    public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 0x00000040;
+
+    /**
      * The event types an {@link AccessibilityService} is interested in.
      * <p>
      *   <strong>Can be dynamically set at runtime.</strong>
@@ -302,6 +323,15 @@
      * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED
      * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED
      * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_INTERACTION_START
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_INTERACTION_END
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_ANNOUNCEMENT
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_GESTURE_DETECTION_START
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_GESTURE_DETECTION_END
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUSED
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED
      */
     public int eventTypes;
 
@@ -354,6 +384,7 @@
      * @see #FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
      * @see #FLAG_REQUEST_FILTER_KEY_EVENTS
      * @see #FLAG_REPORT_VIEW_IDS
+     * @see #FLAG_RETRIEVE_INTERACTIVE_WINDOWS
      */
     public int flags;
 
@@ -449,7 +480,7 @@
                     com.android.internal.R.styleable.AccessibilityService_accessibilityFeedbackType,
                     0);
             notificationTimeout = asAttributes.getInt(
-                    com.android.internal.R.styleable.AccessibilityService_notificationTimeout, 
+                    com.android.internal.R.styleable.AccessibilityService_notificationTimeout,
                     0);
             flags = asAttributes.getInt(
                     com.android.internal.R.styleable.AccessibilityService_accessibilityFlags, 0);
@@ -861,6 +892,8 @@
                 return "FLAG_REPORT_VIEW_IDS";
             case FLAG_REQUEST_FILTER_KEY_EVENTS:
                 return "FLAG_REQUEST_FILTER_KEY_EVENTS";
+            case FLAG_RETRIEVE_INTERACTIVE_WINDOWS:
+                return "FLAG_RETRIEVE_INTERACTIVE_WINDOWS";
             default:
                 return null;
         }
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
index c5e3d43a..6ce0219 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
@@ -18,6 +18,7 @@
 
 import android.accessibilityservice.IAccessibilityServiceConnection;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.KeyEvent;
 
 /**
@@ -35,7 +36,7 @@
 
     void onGesture(int gesture);
 
-    void clearAccessibilityNodeInfoCache();
+    void clearAccessibilityCache();
 
     void onKeyEvent(in KeyEvent event, int sequence);
 }
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 3df06b5..27a03b6 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -21,6 +21,7 @@
 import android.view.MagnificationSpec;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
+import android.view.accessibility.AccessibilityWindowInfo;
 
 /**
  * Interface given to an AccessibilitySerivce to talk to the AccessibilityManagerService.
@@ -53,6 +54,14 @@
         int action, in Bundle arguments, int interactionId,
         IAccessibilityInteractionConnectionCallback callback, long threadId);
 
+    boolean computeClickPointInScreen(int accessibilityWindowId, long accessibilityNodeId,
+        int interactionId, IAccessibilityInteractionConnectionCallback callback,
+        long threadId);
+
+    AccessibilityWindowInfo getWindow(int windowId);
+
+    List<AccessibilityWindowInfo> getWindows();
+
     AccessibilityServiceInfo getServiceInfo();
 
     boolean performGlobalAction(int action);
diff --git a/core/java/android/accounts/AccountAuthenticatorActivity.java b/core/java/android/accounts/AccountAuthenticatorActivity.java
index 6a55ddf..f9284e67 100644
--- a/core/java/android/accounts/AccountAuthenticatorActivity.java
+++ b/core/java/android/accounts/AccountAuthenticatorActivity.java
@@ -17,7 +17,6 @@
 package android.accounts;
 
 import android.app.Activity;
-import android.content.Intent;
 import android.os.Bundle;
 
 /**
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 12fcdcf..09b484b 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -155,6 +155,8 @@
 
     /** @hide */
     public static final int ERROR_CODE_USER_RESTRICTED = 100;
+    /** @hide */
+    public static final int ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE = 101;
 
     /**
      * Bundle key used for the {@link String} account name in results
@@ -359,7 +361,29 @@
      */
     public AuthenticatorDescription[] getAuthenticatorTypes() {
         try {
-            return mService.getAuthenticatorTypes();
+            return mService.getAuthenticatorTypes(UserHandle.getCallingUserId());
+        } catch (RemoteException e) {
+            // will never happen
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * @hide
+     * Lists the currently registered authenticators for a given user id.
+     *
+     * <p>It is safe to call this method from the main thread.
+     *
+     * <p>The caller has to be in the same user or have the permission
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}.
+     *
+     * @return An array of {@link AuthenticatorDescription} for every
+     *     authenticator known to the AccountManager service.  Empty (never
+     *     null) if no authenticators are known.
+     */
+    public AuthenticatorDescription[] getAuthenticatorTypesAsUser(int userId) {
+        try {
+            return mService.getAuthenticatorTypes(userId);
         } catch (RemoteException e) {
             // will never happen
             throw new RuntimeException(e);
@@ -389,6 +413,28 @@
 
     /**
      * @hide
+     * Lists all accounts of any type registered on the device for a given
+     * user id. Equivalent to getAccountsByType(null).
+     *
+     * <p>It is safe to call this method from the main thread.
+     *
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#GET_ACCOUNTS}.
+     *
+     * @return An array of {@link Account}, one for each account.  Empty
+     *     (never null) if no accounts have been added.
+     */
+    public Account[] getAccountsAsUser(int userId) {
+        try {
+            return mService.getAccountsAsUser(null, userId);
+        } catch (RemoteException e) {
+            // won't ever happen
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * @hide
      * For use by internal activities. Returns the list of accounts that the calling package
      * is authorized to use, particularly for shared accounts.
      * @param packageName package name of the calling app.
@@ -617,6 +663,72 @@
     }
 
     /**
+     * Rename the specified {@link Account}.  This is equivalent to removing
+     * the existing account and adding a new renamed account with the old
+     * account's user data.
+     *
+     * <p>It is safe to call this method from the main thread.
+     *
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
+     * and have the same UID as the account's authenticator.
+     *
+     * @param account The {@link Account} to rename
+     * @param newName String name to be associated with the account.
+     * @param callback Callback to invoke when the request completes, null for
+     *     no callback
+     * @param handler {@link Handler} identifying the callback thread, null for
+     *     the main thread
+     * @return An {@link AccountManagerFuture} which resolves to the Account
+     *     after the name change. If successful the account's name will be the
+     *     specified new name.
+     */
+    public AccountManagerFuture<Account> renameAccount(
+            final Account account,
+            final String newName,
+            AccountManagerCallback<Account> callback,
+            Handler handler) {
+        if (account == null) throw new IllegalArgumentException("account is null.");
+        if (TextUtils.isEmpty(newName)) {
+              throw new IllegalArgumentException("newName is empty or null.");
+        }
+        return new Future2Task<Account>(handler, callback) {
+            @Override
+            public void doWork() throws RemoteException {
+                mService.renameAccount(mResponse, account, newName);
+            }
+            @Override
+            public Account bundleToResult(Bundle bundle) throws AuthenticatorException {
+                String name = bundle.getString(KEY_ACCOUNT_NAME);
+                String type = bundle.getString(KEY_ACCOUNT_TYPE);
+                return new Account(name, type);
+            }
+        }.start();
+    }
+
+    /**
+     * Gets the previous name associated with the account or {@code null}, if
+     * none. This is intended so that clients of {@link
+     * #LOGIN_ACCOUNTS_CHANGED_ACTION} broadcasts can determine if an
+     * authenticator has renamed an account.
+     *
+     * <p>It is safe to call this method from the main thread.
+     *
+     * @param account The account to query for a previous name.
+     * @return The account's previous name, null if the account has never been
+     *         renamed.
+     */
+    public String getPreviousName(final Account account) {
+        if (account == null) throw new IllegalArgumentException("account is null");
+        try {
+            return mService.getPreviousName(account);
+        } catch (RemoteException e) {
+            // will never happen
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
      * Removes an account from the AccountManager.  Does nothing if the account
      * does not exist.  Does not delete the account from the server.
      * The authenticator may have its own policies preventing account
@@ -634,8 +746,7 @@
      * @param handler {@link Handler} identifying the callback thread,
      *     null for the main thread
      * @return An {@link AccountManagerFuture} which resolves to a Boolean,
-     *     true if the account has been successfully removed,
-     *     false if the authenticator forbids deleting this account.
+     *     true if the account has been successfully removed
      */
     public AccountManagerFuture<Boolean> removeAccount(final Account account,
             AccountManagerCallback<Boolean> callback, Handler handler) {
@@ -654,6 +765,28 @@
     }
 
     /**
+     * @see #removeAccount(Account, AccountManagerCallback, Handler)
+     * @hide
+     */
+    public AccountManagerFuture<Boolean> removeAccountAsUser(final Account account,
+            AccountManagerCallback<Boolean> callback, Handler handler,
+            final UserHandle userHandle) {
+        if (account == null) throw new IllegalArgumentException("account is null");
+        if (userHandle == null) throw new IllegalArgumentException("userHandle is null");
+        return new Future2Task<Boolean>(handler, callback) {
+            public void doWork() throws RemoteException {
+                mService.removeAccountAsUser(mResponse, account, userHandle.getIdentifier());
+            }
+            public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
+                if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
+                    throw new AuthenticatorException("no result in response");
+                }
+                return bundle.getBoolean(KEY_BOOLEAN_RESULT);
+            }
+        }.start();
+    }
+
+    /**
      * Removes an auth token from the AccountManager's cache.  Does nothing if
      * the auth token is not currently in the cache.  Applications must call this
      * method when the auth token is found to have expired or otherwise become
@@ -1139,7 +1272,8 @@
      * <li> {@link AuthenticatorException} if no authenticator was registered for
      *      this account type or the authenticator failed to respond
      * <li> {@link OperationCanceledException} if the operation was canceled for
-     *      any reason, including the user canceling the creation process
+     *      any reason, including the user canceling the creation process or adding accounts
+     *      (of this type) has been disabled by policy
      * <li> {@link IOException} if the authenticator experienced an I/O problem
      *      creating a new account, usually because of network trouble
      * </ul>
@@ -1164,6 +1298,30 @@
     }
 
     /**
+     * @see #addAccount(String, String, String[], Bundle, Activity, AccountManagerCallback, Handler)
+     * @hide
+     */
+    public AccountManagerFuture<Bundle> addAccountAsUser(final String accountType,
+            final String authTokenType, final String[] requiredFeatures,
+            final Bundle addAccountOptions, final Activity activity,
+            AccountManagerCallback<Bundle> callback, Handler handler, final UserHandle userHandle) {
+        if (accountType == null) throw new IllegalArgumentException("accountType is null");
+        if (userHandle == null) throw new IllegalArgumentException("userHandle is null");
+        final Bundle optionsIn = new Bundle();
+        if (addAccountOptions != null) {
+            optionsIn.putAll(addAccountOptions);
+        }
+        optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
+
+        return new AmsTask(activity, handler, callback) {
+            public void doWork() throws RemoteException {
+                mService.addAccountAsUser(mResponse, accountType, authTokenType,
+                        requiredFeatures, activity != null, optionsIn, userHandle.getIdentifier());
+            }
+        }.start();
+    }
+
+    /**
      * Adds a shared account from the primary user to a secondary user. Adding the shared account
      * doesn't take effect immediately. When the target user starts up, any pending shared accounts
      * are attempted to be copied to the target user from the primary via calls to the
@@ -1564,8 +1722,10 @@
             }
 
             public void onError(int code, String message) {
-                if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED) {
-                    // the authenticator indicated that this request was canceled, do so now
+                if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED
+                        || code == ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) {
+                    // the authenticator indicated that this request was canceled or we were
+                    // forbidden to fulfill; cancel now
                     cancel(true /* mayInterruptIfRunning */);
                     return;
                 }
@@ -1624,7 +1784,10 @@
             }
 
             public void onError(int code, String message) {
-                if (code == ERROR_CODE_CANCELED) {
+                if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED
+                        || code == ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) {
+                    // the authenticator indicated that this request was canceled or we were
+                    // forbidden to fulfill; cancel now
                     cancel(true /* mayInterruptIfRunning */);
                     return;
                 }
diff --git a/core/java/android/accounts/AccountManagerFuture.java b/core/java/android/accounts/AccountManagerFuture.java
index a1ab00c..77670d9 100644
--- a/core/java/android/accounts/AccountManagerFuture.java
+++ b/core/java/android/accounts/AccountManagerFuture.java
@@ -15,10 +15,7 @@
  */
 package android.accounts;
 
-import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
 import java.io.IOException;
 
 /**
@@ -87,7 +84,8 @@
      * will be thrown rather than the call returning normally.
      * @return the actual result
      * @throws android.accounts.OperationCanceledException if the request was canceled for any
-     * reason
+     * reason (including if it is forbidden
+     * by policy to modify an account (of that type))
      * @throws android.accounts.AuthenticatorException if there was an error communicating with
      * the authenticator or if the authenticator returned an invalid response
      * @throws java.io.IOException if the authenticator returned an error response that indicates
diff --git a/core/java/android/accounts/CantAddAccountActivity.java b/core/java/android/accounts/CantAddAccountActivity.java
index e1717a6..f7f232e 100644
--- a/core/java/android/accounts/CantAddAccountActivity.java
+++ b/core/java/android/accounts/CantAddAccountActivity.java
@@ -27,6 +27,7 @@
  * Just shows an error message about the account restrictions for the limited user.
  */
 public class CantAddAccountActivity extends Activity {
+    public static final String EXTRA_ERROR_CODE = "android.accounts.extra.ERROR_CODE";
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index bfbae24..242b3ea 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -100,7 +100,7 @@
             try {
                 AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
                 Context authContext = createPackageContext(desc.packageName, 0);
-                icon = authContext.getResources().getDrawable(desc.iconId);
+                icon = authContext.getDrawable(desc.iconId);
             } catch (PackageManager.NameNotFoundException e) {
                 // Nothing we can do much here, just log
                 if (Log.isLoggable(TAG, Log.WARN)) {
diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java
index acc8549..a3222d8 100644
--- a/core/java/android/accounts/ChooseAccountTypeActivity.java
+++ b/core/java/android/accounts/ChooseAccountTypeActivity.java
@@ -129,7 +129,7 @@
             Drawable icon = null;
             try {
                 Context authContext = createPackageContext(desc.packageName, 0);
-                icon = authContext.getResources().getDrawable(desc.iconId);
+                icon = authContext.getDrawable(desc.iconId);
                 final CharSequence sequence = authContext.getResources().getText(desc.labelId);
                 if (sequence != null) {
                     name = sequence.toString();
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index 8b01c6a..12b2b9c 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -16,7 +16,6 @@
 package android.accounts;
 
 import android.app.Activity;
-import android.content.pm.RegisteredServicesCache;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.widget.TextView;
@@ -30,7 +29,6 @@
 import com.android.internal.R;
 
 import java.io.IOException;
-import java.net.Authenticator;
 
 /**
  * @hide
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 86e279f..a133788 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -29,7 +29,7 @@
 interface IAccountManager {
     String getPassword(in Account account);
     String getUserData(in Account account, String key);
-    AuthenticatorDescription[] getAuthenticatorTypes();
+    AuthenticatorDescription[] getAuthenticatorTypes(int userId);
     Account[] getAccounts(String accountType);
     Account[] getAccountsForPackage(String packageName, int uid);
     Account[] getAccountsByTypeForPackage(String type, String packageName);
@@ -38,6 +38,7 @@
     void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features);
     boolean addAccountExplicitly(in Account account, String password, in Bundle extras);
     void removeAccount(in IAccountManagerResponse response, in Account account);
+    void removeAccountAsUser(in IAccountManagerResponse response, in Account account, int userId);
     void invalidateAuthToken(String accountType, String authToken);
     String peekAuthToken(in Account account, String authTokenType);
     void setAuthToken(in Account account, String authTokenType, String authToken);
@@ -52,6 +53,9 @@
     void addAccount(in IAccountManagerResponse response, String accountType,
         String authTokenType, in String[] requiredFeatures, boolean expectActivityLaunch,
         in Bundle options);
+    void addAccountAsUser(in IAccountManagerResponse response, String accountType,
+        String authTokenType, in String[] requiredFeatures, boolean expectActivityLaunch,
+        in Bundle options, int userId);
     void updateCredentials(in IAccountManagerResponse response, in Account account,
         String authTokenType, boolean expectActivityLaunch, in Bundle options);
     void editProperties(in IAccountManagerResponse response, String accountType,
@@ -65,4 +69,10 @@
     boolean addSharedAccountAsUser(in Account account, int userId);
     Account[] getSharedAccountsAsUser(int userId);
     boolean removeSharedAccountAsUser(in Account account, int userId);
+
+    /* Account renaming. */
+    void renameAccount(in IAccountManagerResponse response, in Account accountToRename, String newName);
+    String getPreviousName(in Account account);
+    boolean renameSharedAccountAsUser(in Account accountToRename, String newName, int userId);
+
 }
diff --git a/core/java/android/alsa/AlsaCardsParser.java b/core/java/android/alsa/AlsaCardsParser.java
new file mode 100644
index 0000000..8b44881
--- /dev/null
+++ b/core/java/android/alsa/AlsaCardsParser.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.alsa;
+
+import android.util.Slog;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * @hide Retrieves information from an ALSA "cards" file.
+ */
+public class AlsaCardsParser {
+    private static final String TAG = "AlsaCardsParser";
+
+    private static LineTokenizer tokenizer_ = new LineTokenizer(" :[]");
+
+    public class AlsaCardRecord {
+        public int mCardNum = -1;
+        public String mField1 = "";
+        public String mCardName = "";
+        public String mCardDescription = "";
+
+        public AlsaCardRecord() {}
+
+        public boolean parse(String line, int lineIndex) {
+            int tokenIndex = 0;
+            int delimIndex = 0;
+            if (lineIndex == 0) {
+                // line # (skip)
+                tokenIndex = tokenizer_.nextToken(line, tokenIndex);
+                delimIndex = tokenizer_.nextDelimiter(line, tokenIndex);
+
+                // mField1
+                tokenIndex = tokenizer_.nextToken(line, delimIndex);
+                delimIndex = tokenizer_.nextDelimiter(line, tokenIndex);
+                mField1 = line.substring(tokenIndex, delimIndex);
+
+                // mCardName
+                tokenIndex = tokenizer_.nextToken(line, delimIndex);
+                // delimIndex = tokenizer_.nextDelimiter(line, tokenIndex);
+                mCardName = line.substring(tokenIndex);
+                // done
+              } else if (lineIndex == 1) {
+                  tokenIndex = tokenizer_.nextToken(line, 0);
+                  if (tokenIndex != -1) {
+                      mCardDescription = line.substring(tokenIndex);
+                  }
+            }
+
+            return true;
+        }
+
+        public String textFormat() {
+          return mCardName + " : " + mCardDescription;
+        }
+    }
+
+    private Vector<AlsaCardRecord> cardRecords_ = new Vector<AlsaCardRecord>();
+
+    public void scan() {
+          cardRecords_.clear();
+          final String cardsFilePath = "/proc/asound/cards";
+          File cardsFile = new File(cardsFilePath);
+          try {
+              FileReader reader = new FileReader(cardsFile);
+              BufferedReader bufferedReader = new BufferedReader(reader);
+              String line = "";
+              while ((line = bufferedReader.readLine()) != null) {
+                  AlsaCardRecord cardRecord = new AlsaCardRecord();
+                  cardRecord.parse(line, 0);
+                  cardRecord.parse(line = bufferedReader.readLine(), 1);
+                  cardRecords_.add(cardRecord);
+              }
+              reader.close();
+          } catch (FileNotFoundException e) {
+              e.printStackTrace();
+          } catch (IOException e) {
+              e.printStackTrace();
+          }
+      }
+
+      public AlsaCardRecord getCardRecordAt(int index) {
+          return cardRecords_.get(index);
+      }
+
+      public int getNumCardRecords() {
+          return cardRecords_.size();
+      }
+
+    public void Log() {
+      int numCardRecs = getNumCardRecords();
+      for (int index = 0; index < numCardRecs; ++index) {
+          Slog.w(TAG, "usb:" + getCardRecordAt(index).textFormat());
+      }
+    }
+
+    public AlsaCardsParser() {}
+}
diff --git a/core/java/android/alsa/AlsaDevicesParser.java b/core/java/android/alsa/AlsaDevicesParser.java
new file mode 100644
index 0000000..82cc1ae
--- /dev/null
+++ b/core/java/android/alsa/AlsaDevicesParser.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.alsa;
+
+import android.util.Slog;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * @hide
+ * Retrieves information from an ALSA "devices" file.
+ */
+public class AlsaDevicesParser {
+    private static final String TAG = "AlsaDevicesParser";
+
+    private static final int kIndex_CardDeviceField = 5;
+    private static final int kStartIndex_CardNum = 6;
+    private static final int kEndIndex_CardNum = 8; // one past
+    private static final int kStartIndex_DeviceNum = 9;
+    private static final int kEndIndex_DeviceNum = 11; // one past
+    private static final int kStartIndex_Type = 14;
+
+    private static LineTokenizer mTokenizer = new LineTokenizer(" :[]-");
+
+    private boolean mHasCaptureDevices = false;
+    private boolean mHasPlaybackDevices = false;
+    private boolean mHasMIDIDevices = false;
+
+    public class AlsaDeviceRecord {
+        public static final int kDeviceType_Unknown = -1;
+        public static final int kDeviceType_Audio = 0;
+        public static final int kDeviceType_Control = 1;
+        public static final int kDeviceType_MIDI = 2;
+
+        public static final int kDeviceDir_Unknown = -1;
+        public static final int kDeviceDir_Capture = 0;
+        public static final int kDeviceDir_Playback = 1;
+
+        int mCardNum = -1;
+        int mDeviceNum = -1;
+        int mDeviceType = kDeviceType_Unknown;
+        int mDeviceDir = kDeviceDir_Unknown;
+
+        public AlsaDeviceRecord() {
+        }
+
+        public boolean parse(String line) {
+            // "0123456789012345678901234567890"
+            // "  2: [ 0-31]: digital audio playback"
+            // "  3: [ 0-30]: digital audio capture"
+            // " 35: [ 1]   : control"
+            // " 36: [ 2- 0]: raw midi"
+
+            final int kToken_LineNum = 0;
+            final int kToken_CardNum = 1;
+            final int kToken_DeviceNum = 2;
+            final int kToken_Type0 = 3; // "digital", "control", "raw"
+            final int kToken_Type1 = 4; // "audio", "midi"
+            final int kToken_Type2 = 5; // "capture", "playback"
+
+            int tokenOffset = 0;
+            int delimOffset = 0;
+            int tokenIndex = kToken_LineNum;
+            while (true) {
+                tokenOffset = mTokenizer.nextToken(line, delimOffset);
+                if (tokenOffset == LineTokenizer.kTokenNotFound) {
+                    break; // bail
+                }
+                delimOffset = mTokenizer.nextDelimiter(line, tokenOffset);
+                if (delimOffset == LineTokenizer.kTokenNotFound) {
+                    delimOffset = line.length();
+                }
+                String token = line.substring(tokenOffset, delimOffset);
+
+                switch (tokenIndex) {
+                case kToken_LineNum:
+                    // ignore
+                    break;
+
+                case kToken_CardNum:
+                    mCardNum = Integer.parseInt(token);
+                    if (line.charAt(delimOffset) != '-') {
+                        tokenIndex++; // no device # in the token stream
+                    }
+                    break;
+
+                case kToken_DeviceNum:
+                    mDeviceNum = Integer.parseInt(token);
+                    break;
+
+                case kToken_Type0:
+                    if (token.equals("digital")) {
+                        // NOP
+                    } else if (token.equals("control")) {
+                        mDeviceType = kDeviceType_Control;
+                    } else if (token.equals("raw")) {
+                        // NOP
+                    }
+                    break;
+
+                case kToken_Type1:
+                    if (token.equals("audio")) {
+                        mDeviceType = kDeviceType_Audio;
+                    } else if (token.equals("midi")) {
+                        mDeviceType = kDeviceType_MIDI;
+                        mHasMIDIDevices = true;
+                    }
+                    break;
+
+                case kToken_Type2:
+                    if (token.equals("capture")) {
+                        mDeviceDir = kDeviceDir_Capture;
+                        mHasCaptureDevices = true;
+                    } else if (token.equals("playback")) {
+                        mDeviceDir = kDeviceDir_Playback;
+                        mHasPlaybackDevices = true;
+                    }
+                    break;
+                } // switch (tokenIndex)
+
+                tokenIndex++;
+            } // while (true)
+
+            return true;
+        } // parse()
+
+        public String textFormat() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("[" + mCardNum + ":" + mDeviceNum + "]");
+
+            switch (mDeviceType) {
+            case kDeviceType_Unknown:
+                sb.append(" N/A");
+                break;
+            case kDeviceType_Audio:
+                sb.append(" Audio");
+                break;
+            case kDeviceType_Control:
+                sb.append(" Control");
+                break;
+            case kDeviceType_MIDI:
+                sb.append(" MIDI");
+                break;
+            }
+
+            switch (mDeviceDir) {
+            case kDeviceDir_Unknown:
+                sb.append(" N/A");
+                break;
+            case kDeviceDir_Capture:
+                sb.append(" Capture");
+                break;
+            case kDeviceDir_Playback:
+                sb.append(" Playback");
+                break;
+            }
+
+            return sb.toString();
+        }
+    }
+
+    private Vector<AlsaDeviceRecord>
+            deviceRecords_ = new Vector<AlsaDeviceRecord>();
+
+    private boolean isLineDeviceRecord(String line) {
+        return line.charAt(kIndex_CardDeviceField) == '[';
+    }
+
+    public AlsaDevicesParser() {
+    }
+
+    public int getNumDeviceRecords() {
+        return deviceRecords_.size();
+    }
+
+    public AlsaDeviceRecord getDeviceRecordAt(int index) {
+        return deviceRecords_.get(index);
+    }
+
+    public void Log() {
+        int numDevRecs = getNumDeviceRecords();
+        for (int index = 0; index < numDevRecs; ++index) {
+            Slog.w(TAG, "usb:" + getDeviceRecordAt(index).textFormat());
+        }
+    }
+
+    public boolean hasPlaybackDevices() {
+        return mHasPlaybackDevices;
+    }
+
+    public boolean hasPlaybackDevices(int card) {
+        for (int index = 0; index < deviceRecords_.size(); index++) {
+            AlsaDeviceRecord deviceRecord = deviceRecords_.get(index);
+            if (deviceRecord.mCardNum == card &&
+                deviceRecord.mDeviceType == AlsaDeviceRecord.kDeviceType_Audio &&
+                deviceRecord.mDeviceDir == AlsaDeviceRecord.kDeviceDir_Playback) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean hasCaptureDevices() {
+        return mHasCaptureDevices;
+    }
+
+    public boolean hasCaptureDevices(int card) {
+        for (int index = 0; index < deviceRecords_.size(); index++) {
+            AlsaDeviceRecord deviceRecord = deviceRecords_.get(index);
+            if (deviceRecord.mCardNum == card &&
+                deviceRecord.mDeviceType == AlsaDeviceRecord.kDeviceType_Audio &&
+                deviceRecord.mDeviceDir == AlsaDeviceRecord.kDeviceDir_Capture) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean hasMIDIDevices() {
+        return mHasMIDIDevices;
+    }
+
+    public boolean hasMIDIDevices(int card) {
+        for (int index = 0; index < deviceRecords_.size(); index++) {
+            AlsaDeviceRecord deviceRecord = deviceRecords_.get(index);
+            if (deviceRecord.mCardNum == card &&
+                deviceRecord.mDeviceType == AlsaDeviceRecord.kDeviceType_MIDI) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void scan() {
+        deviceRecords_.clear();
+
+        final String devicesFilePath = "/proc/asound/devices";
+        File devicesFile = new File(devicesFilePath);
+        try {
+            FileReader reader = new FileReader(devicesFile);
+            BufferedReader bufferedReader = new BufferedReader(reader);
+            String line = "";
+            while ((line = bufferedReader.readLine()) != null) {
+                if (isLineDeviceRecord(line)) {
+                    AlsaDeviceRecord deviceRecord = new AlsaDeviceRecord();
+                    deviceRecord.parse(line);
+                    deviceRecords_.add(deviceRecord);
+                }
+            }
+            reader.close();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+} // class AlsaDevicesParser
+
diff --git a/core/java/android/alsa/LineTokenizer.java b/core/java/android/alsa/LineTokenizer.java
new file mode 100644
index 0000000..78c91b5
--- /dev/null
+++ b/core/java/android/alsa/LineTokenizer.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.alsa;
+
+/**
+ * @hide
+ * Breaks lines in an ALSA "cards" or "devices" file into tokens.
+ * TODO(pmclean) Look into replacing this with String.split().
+ */
+public class LineTokenizer {
+    public static final int kTokenNotFound = -1;
+
+    private String mDelimiters = "";
+
+    public LineTokenizer(String delimiters) {
+        mDelimiters = delimiters;
+    }
+
+    int nextToken(String line, int startIndex) {
+        int len = line.length();
+        int offset = startIndex;
+        for (; offset < len; offset++) {
+            if (mDelimiters.indexOf(line.charAt(offset)) == -1) {
+                // past a delimiter
+                break;
+            }
+      }
+
+      return offset < len ? offset : kTokenNotFound;
+    }
+
+    int nextDelimiter(String line, int startIndex) {
+        int len = line.length();
+        int offset = startIndex;
+        for (; offset < len; offset++) {
+            if (mDelimiters.indexOf(line.charAt(offset)) != -1) {
+                // past a delimiter
+                break;
+            }
+        }
+
+      return offset < len ? offset : kTokenNotFound;
+    }
+}
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 129e52c..3720c81 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -356,6 +356,23 @@
     public void setTarget(Object target) {
     }
 
+    // Hide reverse() and canReverse() for now since reverse() only work for simple
+    // cases, like we don't support sequential, neither startDelay.
+    // TODO: make reverse() works for all the Animators.
+    /**
+     * @hide
+     */
+    public boolean canReverse() {
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    public void reverse() {
+        throw new IllegalStateException("Reverse is not supported");
+    }
+
     /**
      * <p>An animation listener receives notifications from an animation.
      * Notifications indicate animation related events, such as the end or the
@@ -417,4 +434,39 @@
          */
         void onAnimationResume(Animator animation);
     }
+
+    /**
+     * <p>Whether or not the Animator is allowed to run asynchronously off of
+     * the UI thread. This is a hint that informs the Animator that it is
+     * OK to run the animation off-thread, however the Animator may decide
+     * that it must run the animation on the UI thread anyway.
+     *
+     * <p>Regardless of whether or not the animation runs asynchronously, all
+     * listener callbacks will be called on the UI thread.</p>
+     *
+     * <p>To be able to use this hint the following must be true:</p>
+     * <ol>
+     * <li>The animator is immutable while {@link #isStarted()} is true. Requests
+     *    to change duration, delay, etc... may be ignored.</li>
+     * <li>Lifecycle callback events may be asynchronous. Events such as
+     *    {@link Animator.AnimatorListener#onAnimationEnd(Animator)} or
+     *    {@link Animator.AnimatorListener#onAnimationRepeat(Animator)} may end up delayed
+     *    as they must be posted back to the UI thread, and any actions performed
+     *    by those callbacks (such as starting new animations) will not happen
+     *    in the same frame.</li>
+     * <li>State change requests ({@link #cancel()}, {@link #end()}, {@link #reverse()}, etc...)
+     *    may be asynchronous. It is guaranteed that all state changes that are
+     *    performed on the UI thread in the same frame will be applied as a single
+     *    atomic update, however that frame may be the current frame,
+     *    the next frame, or some future frame. This will also impact the observed
+     *    state of the Animator. For example, {@link #isStarted()} may still return true
+     *    after a call to {@link #end()}. Using the lifecycle callbacks is preferred over
+     *    queries to {@link #isStarted()}, {@link #isRunning()}, and {@link #isPaused()}
+     *    for this reason.</li>
+     * </ol>
+     * @hide
+     */
+    public void setAllowRunningAsynchronously(boolean mayRunAsync) {
+        // It is up to subclasses to support this, if they can.
+    }
 }
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index d753e32..25417ed 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -17,13 +17,22 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
-import android.content.res.Resources.NotFoundException;
+import android.graphics.Path;
 import android.util.AttributeSet;
+import android.util.Log;
+import android.util.PathParser;
+import android.util.StateSet;
 import android.util.TypedValue;
 import android.util.Xml;
+import android.view.InflateException;
 import android.view.animation.AnimationUtils;
+
+import com.android.internal.R;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -40,7 +49,7 @@
  * <em>something</em> file.)
  */
 public class AnimatorInflater {
-
+    private static final String TAG = "AnimatorInflater";
     /**
      * These flags are used when parsing AnimatorSet objects
      */
@@ -52,9 +61,12 @@
      */
     private static final int VALUE_TYPE_FLOAT       = 0;
     private static final int VALUE_TYPE_INT         = 1;
+    private static final int VALUE_TYPE_PATH        = 2;
     private static final int VALUE_TYPE_COLOR       = 4;
     private static final int VALUE_TYPE_CUSTOM      = 5;
 
+    private static final boolean DBG_ANIMATOR_INFLATER = false;
+
     /**
      * Loads an {@link Animator} object from a resource
      *
@@ -65,21 +77,42 @@
      */
     public static Animator loadAnimator(Context context, int id)
             throws NotFoundException {
+        return loadAnimator(context.getResources(), context.getTheme(), id);
+    }
+
+    /**
+     * Loads an {@link Animator} object from a resource
+     *
+     * @param resources The resources
+     * @param theme The theme
+     * @param id The resource id of the animation to load
+     * @return The animator object reference by the specified id
+     * @throws android.content.res.Resources.NotFoundException when the animation cannot be loaded
+     * @hide
+     */
+    public static Animator loadAnimator(Resources resources, Theme theme, int id)
+            throws NotFoundException {
+        return loadAnimator(resources, theme, id, 1);
+    }
+
+    /** @hide */
+    public static Animator loadAnimator(Resources resources, Theme theme, int id,
+            float pathErrorScale) throws NotFoundException {
 
         XmlResourceParser parser = null;
         try {
-            parser = context.getResources().getAnimation(id);
-            return createAnimatorFromXml(context, parser);
+            parser = resources.getAnimation(id);
+            return createAnimatorFromXml(resources, theme, parser, pathErrorScale);
         } catch (XmlPullParserException ex) {
             Resources.NotFoundException rnf =
                     new Resources.NotFoundException("Can't load animation resource ID #0x" +
-                    Integer.toHexString(id));
+                            Integer.toHexString(id));
             rnf.initCause(ex);
             throw rnf;
         } catch (IOException ex) {
             Resources.NotFoundException rnf =
                     new Resources.NotFoundException("Can't load animation resource ID #0x" +
-                    Integer.toHexString(id));
+                            Integer.toHexString(id));
             rnf.initCause(ex);
             throw rnf;
         } finally {
@@ -87,14 +120,393 @@
         }
     }
 
-    private static Animator createAnimatorFromXml(Context c, XmlPullParser parser)
-            throws XmlPullParserException, IOException {
-
-        return createAnimatorFromXml(c, parser, Xml.asAttributeSet(parser), null, 0);
+    public static StateListAnimator loadStateListAnimator(Context context, int id)
+            throws NotFoundException {
+        XmlResourceParser parser = null;
+        try {
+            parser = context.getResources().getAnimation(id);
+            return createStateListAnimatorFromXml(context, parser, Xml.asAttributeSet(parser));
+        } catch (XmlPullParserException ex) {
+            Resources.NotFoundException rnf =
+                    new Resources.NotFoundException(
+                            "Can't load state list animator resource ID #0x" +
+                                    Integer.toHexString(id)
+                    );
+            rnf.initCause(ex);
+            throw rnf;
+        } catch (IOException ex) {
+            Resources.NotFoundException rnf =
+                    new Resources.NotFoundException(
+                            "Can't load state list animator resource ID #0x" +
+                                    Integer.toHexString(id)
+                    );
+            rnf.initCause(ex);
+            throw rnf;
+        } finally {
+            if (parser != null) {
+                parser.close();
+            }
+        }
     }
 
-    private static Animator createAnimatorFromXml(Context c, XmlPullParser parser,
-            AttributeSet attrs, AnimatorSet parent, int sequenceOrdering)
+    private static StateListAnimator createStateListAnimatorFromXml(Context context,
+            XmlPullParser parser, AttributeSet attributeSet)
+            throws IOException, XmlPullParserException {
+        int type;
+        StateListAnimator stateListAnimator = new StateListAnimator();
+
+        while (true) {
+            type = parser.next();
+            switch (type) {
+                case XmlPullParser.END_DOCUMENT:
+                case XmlPullParser.END_TAG:
+                    return stateListAnimator;
+
+                case XmlPullParser.START_TAG:
+                    // parse item
+                    Animator animator = null;
+                    if ("item".equals(parser.getName())) {
+                        int attributeCount = parser.getAttributeCount();
+                        int[] states = new int[attributeCount];
+                        int stateIndex = 0;
+                        for (int i = 0; i < attributeCount; i++) {
+                            int attrName = attributeSet.getAttributeNameResource(i);
+                            if (attrName == R.attr.animation) {
+                                animator = loadAnimator(context,
+                                        attributeSet.getAttributeResourceValue(i, 0));
+                            } else {
+                                states[stateIndex++] =
+                                        attributeSet.getAttributeBooleanValue(i, false) ?
+                                                attrName : -attrName;
+                            }
+
+                        }
+                        if (animator == null) {
+                            animator = createAnimatorFromXml(context.getResources(),
+                                    context.getTheme(), parser, 1f);
+                        }
+
+                        if (animator == null) {
+                            throw new Resources.NotFoundException(
+                                    "animation state item must have a valid animation");
+                        }
+                        stateListAnimator
+                                .addState(StateSet.trimStateSet(states, stateIndex), animator);
+
+                    }
+                    break;
+            }
+        }
+    }
+
+    /**
+     * PathDataEvaluator is used to interpolate between two paths which are
+     * represented in the same format but different control points' values.
+     * The path is represented as an array of PathDataNode here, which is
+     * fundamentally an array of floating point numbers.
+     */
+    private static class PathDataEvaluator implements TypeEvaluator<PathParser.PathDataNode[]> {
+        private PathParser.PathDataNode[] mNodeArray;
+
+        /**
+         * Create a PathParser.PathDataNode[] that does not reuse the animated value.
+         * Care must be taken when using this option because on every evaluation
+         * a new <code>PathParser.PathDataNode[]</code> will be allocated.
+         */
+        private PathDataEvaluator() {}
+
+        /**
+         * Create a PathDataEvaluator that reuses <code>nodeArray</code> for every evaluate() call.
+         * Caution must be taken to ensure that the value returned from
+         * {@link android.animation.ValueAnimator#getAnimatedValue()} is not cached, modified, or
+         * used across threads. The value will be modified on each <code>evaluate()</code> call.
+         *
+         * @param nodeArray The array to modify and return from <code>evaluate</code>.
+         */
+        public PathDataEvaluator(PathParser.PathDataNode[] nodeArray) {
+            mNodeArray = nodeArray;
+        }
+
+        @Override
+        public PathParser.PathDataNode[] evaluate(float fraction,
+                PathParser.PathDataNode[] startPathData,
+                PathParser.PathDataNode[] endPathData) {
+            if (!PathParser.canMorph(startPathData, endPathData)) {
+                throw new IllegalArgumentException("Can't interpolate between"
+                        + " two incompatible pathData");
+            }
+
+            if (mNodeArray == null || !PathParser.canMorph(mNodeArray, startPathData)) {
+                mNodeArray = PathParser.deepCopyNodes(startPathData);
+            }
+
+            for (int i = 0; i < startPathData.length; i++) {
+                mNodeArray[i].interpolatePathDataNode(startPathData[i],
+                        endPathData[i], fraction);
+            }
+
+            return mNodeArray;
+        }
+    }
+
+    /**
+     * @param anim The animator, must not be null
+     * @param arrayAnimator Incoming typed array for Animator's attributes.
+     * @param arrayObjectAnimator Incoming typed array for Object Animator's
+     *            attributes.
+     * @param pixelSize The relative pixel size, used to calculate the
+     *                  maximum error for path animations.
+     */
+    private static void parseAnimatorFromTypeArray(ValueAnimator anim,
+            TypedArray arrayAnimator, TypedArray arrayObjectAnimator, float pixelSize) {
+        long duration = arrayAnimator.getInt(R.styleable.Animator_duration, 300);
+
+        long startDelay = arrayAnimator.getInt(R.styleable.Animator_startOffset, 0);
+
+        int valueType = arrayAnimator.getInt(R.styleable.Animator_valueType,
+                VALUE_TYPE_FLOAT);
+
+        TypeEvaluator evaluator = null;
+
+        boolean getFloats = (valueType == VALUE_TYPE_FLOAT);
+
+        TypedValue tvFrom = arrayAnimator.peekValue(R.styleable.Animator_valueFrom);
+        boolean hasFrom = (tvFrom != null);
+        int fromType = hasFrom ? tvFrom.type : 0;
+        TypedValue tvTo = arrayAnimator.peekValue(R.styleable.Animator_valueTo);
+        boolean hasTo = (tvTo != null);
+        int toType = hasTo ? tvTo.type : 0;
+
+        // TODO: Further clean up this part of code into 4 types : path, color,
+        // integer and float.
+        if (valueType == VALUE_TYPE_PATH) {
+            evaluator = setupAnimatorForPath(anim, arrayAnimator);
+        } else {
+            // Integer and float value types are handled here.
+            if ((hasFrom && (fromType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
+                    (fromType <= TypedValue.TYPE_LAST_COLOR_INT)) ||
+                    (hasTo && (toType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
+                            (toType <= TypedValue.TYPE_LAST_COLOR_INT))) {
+                // special case for colors: ignore valueType and get ints
+                getFloats = false;
+                evaluator = ArgbEvaluator.getInstance();
+            }
+            setupValues(anim, arrayAnimator, getFloats, hasFrom, fromType, hasTo, toType);
+        }
+
+        anim.setDuration(duration);
+        anim.setStartDelay(startDelay);
+
+        if (arrayAnimator.hasValue(R.styleable.Animator_repeatCount)) {
+            anim.setRepeatCount(
+                    arrayAnimator.getInt(R.styleable.Animator_repeatCount, 0));
+        }
+        if (arrayAnimator.hasValue(R.styleable.Animator_repeatMode)) {
+            anim.setRepeatMode(
+                    arrayAnimator.getInt(R.styleable.Animator_repeatMode,
+                            ValueAnimator.RESTART));
+        }
+        if (evaluator != null) {
+            anim.setEvaluator(evaluator);
+        }
+
+        if (arrayObjectAnimator != null) {
+            setupObjectAnimator(anim, arrayObjectAnimator, getFloats, pixelSize);
+        }
+    }
+
+    /**
+     * Setup the Animator to achieve path morphing.
+     *
+     * @param anim The target Animator which will be updated.
+     * @param arrayAnimator TypedArray for the ValueAnimator.
+     * @return the PathDataEvaluator.
+     */
+    private static TypeEvaluator setupAnimatorForPath(ValueAnimator anim,
+             TypedArray arrayAnimator) {
+        TypeEvaluator evaluator = null;
+        String fromString = arrayAnimator.getString(R.styleable.Animator_valueFrom);
+        String toString = arrayAnimator.getString(R.styleable.Animator_valueTo);
+        PathParser.PathDataNode[] nodesFrom = PathParser.createNodesFromPathData(fromString);
+        PathParser.PathDataNode[] nodesTo = PathParser.createNodesFromPathData(toString);
+
+        if (nodesFrom != null) {
+            if (nodesTo != null) {
+                anim.setObjectValues(nodesFrom, nodesTo);
+                if (!PathParser.canMorph(nodesFrom, nodesTo)) {
+                    throw new InflateException(arrayAnimator.getPositionDescription()
+                            + " Can't morph from " + fromString + " to " + toString);
+                }
+            } else {
+                anim.setObjectValues((Object)nodesFrom);
+            }
+            evaluator = new PathDataEvaluator(PathParser.deepCopyNodes(nodesFrom));
+        } else if (nodesTo != null) {
+            anim.setObjectValues((Object)nodesTo);
+            evaluator = new PathDataEvaluator(PathParser.deepCopyNodes(nodesTo));
+        }
+
+        if (DBG_ANIMATOR_INFLATER && evaluator != null) {
+            Log.v(TAG, "create a new PathDataEvaluator here");
+        }
+
+        return evaluator;
+    }
+
+    /**
+     * Setup ObjectAnimator's property or values from pathData.
+     *
+     * @param anim The target Animator which will be updated.
+     * @param arrayObjectAnimator TypedArray for the ObjectAnimator.
+     * @param getFloats True if the value type is float.
+     * @param pixelSize The relative pixel size, used to calculate the
+     *                  maximum error for path animations.
+     */
+    private static void setupObjectAnimator(ValueAnimator anim, TypedArray arrayObjectAnimator,
+            boolean getFloats, float pixelSize) {
+        ObjectAnimator oa = (ObjectAnimator) anim;
+        String pathData = arrayObjectAnimator.getString(R.styleable.PropertyAnimator_pathData);
+
+        // Note that if there is a pathData defined in the Object Animator,
+        // valueFrom / valueTo will be ignored.
+        if (pathData != null) {
+            String propertyXName =
+                    arrayObjectAnimator.getString(R.styleable.PropertyAnimator_propertyXName);
+            String propertyYName =
+                    arrayObjectAnimator.getString(R.styleable.PropertyAnimator_propertyYName);
+
+            if (propertyXName == null && propertyYName == null) {
+                throw new InflateException(arrayObjectAnimator.getPositionDescription()
+                        + " propertyXName or propertyYName is needed for PathData");
+            } else {
+                Path path = PathParser.createPathFromPathData(pathData);
+                float error = 0.5f * pixelSize; // max half a pixel error
+                PathKeyframes keyframeSet = KeyframeSet.ofPath(path, error);
+                Keyframes xKeyframes;
+                Keyframes yKeyframes;
+                if (getFloats) {
+                    xKeyframes = keyframeSet.createXFloatKeyframes();
+                    yKeyframes = keyframeSet.createYFloatKeyframes();
+                } else {
+                    xKeyframes = keyframeSet.createXIntKeyframes();
+                    yKeyframes = keyframeSet.createYIntKeyframes();
+                }
+                PropertyValuesHolder x = null;
+                PropertyValuesHolder y = null;
+                if (propertyXName != null) {
+                    x = PropertyValuesHolder.ofKeyframes(propertyXName, xKeyframes);
+                }
+                if (propertyYName != null) {
+                    y = PropertyValuesHolder.ofKeyframes(propertyYName, yKeyframes);
+                }
+                if (x == null) {
+                    oa.setValues(y);
+                } else if (y == null) {
+                    oa.setValues(x);
+                } else {
+                    oa.setValues(x, y);
+                }
+            }
+        } else {
+            String propertyName =
+                    arrayObjectAnimator.getString(R.styleable.PropertyAnimator_propertyName);
+            oa.setPropertyName(propertyName);
+        }
+    }
+
+    /**
+     * Setup ValueAnimator's values.
+     * This will handle all of the integer, float and color types.
+     *
+     * @param anim The target Animator which will be updated.
+     * @param arrayAnimator TypedArray for the ValueAnimator.
+     * @param getFloats True if the value type is float.
+     * @param hasFrom True if "valueFrom" exists.
+     * @param fromType The type of "valueFrom".
+     * @param hasTo True if "valueTo" exists.
+     * @param toType The type of "valueTo".
+     */
+    private static void setupValues(ValueAnimator anim, TypedArray arrayAnimator,
+            boolean getFloats, boolean hasFrom, int fromType, boolean hasTo, int toType) {
+        int valueFromIndex = R.styleable.Animator_valueFrom;
+        int valueToIndex = R.styleable.Animator_valueTo;
+        if (getFloats) {
+            float valueFrom;
+            float valueTo;
+            if (hasFrom) {
+                if (fromType == TypedValue.TYPE_DIMENSION) {
+                    valueFrom = arrayAnimator.getDimension(valueFromIndex, 0f);
+                } else {
+                    valueFrom = arrayAnimator.getFloat(valueFromIndex, 0f);
+                }
+                if (hasTo) {
+                    if (toType == TypedValue.TYPE_DIMENSION) {
+                        valueTo = arrayAnimator.getDimension(valueToIndex, 0f);
+                    } else {
+                        valueTo = arrayAnimator.getFloat(valueToIndex, 0f);
+                    }
+                    anim.setFloatValues(valueFrom, valueTo);
+                } else {
+                    anim.setFloatValues(valueFrom);
+                }
+            } else {
+                if (toType == TypedValue.TYPE_DIMENSION) {
+                    valueTo = arrayAnimator.getDimension(valueToIndex, 0f);
+                } else {
+                    valueTo = arrayAnimator.getFloat(valueToIndex, 0f);
+                }
+                anim.setFloatValues(valueTo);
+            }
+        } else {
+            int valueFrom;
+            int valueTo;
+            if (hasFrom) {
+                if (fromType == TypedValue.TYPE_DIMENSION) {
+                    valueFrom = (int) arrayAnimator.getDimension(valueFromIndex, 0f);
+                } else if ((fromType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
+                        (fromType <= TypedValue.TYPE_LAST_COLOR_INT)) {
+                    valueFrom = arrayAnimator.getColor(valueFromIndex, 0);
+                } else {
+                    valueFrom = arrayAnimator.getInt(valueFromIndex, 0);
+                }
+                if (hasTo) {
+                    if (toType == TypedValue.TYPE_DIMENSION) {
+                        valueTo = (int) arrayAnimator.getDimension(valueToIndex, 0f);
+                    } else if ((toType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
+                            (toType <= TypedValue.TYPE_LAST_COLOR_INT)) {
+                        valueTo = arrayAnimator.getColor(valueToIndex, 0);
+                    } else {
+                        valueTo = arrayAnimator.getInt(valueToIndex, 0);
+                    }
+                    anim.setIntValues(valueFrom, valueTo);
+                } else {
+                    anim.setIntValues(valueFrom);
+                }
+            } else {
+                if (hasTo) {
+                    if (toType == TypedValue.TYPE_DIMENSION) {
+                        valueTo = (int) arrayAnimator.getDimension(valueToIndex, 0f);
+                    } else if ((toType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
+                            (toType <= TypedValue.TYPE_LAST_COLOR_INT)) {
+                        valueTo = arrayAnimator.getColor(valueToIndex, 0);
+                    } else {
+                        valueTo = arrayAnimator.getInt(valueToIndex, 0);
+                    }
+                    anim.setIntValues(valueTo);
+                }
+            }
+        }
+    }
+
+    private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser,
+            float pixelSize)
+            throws XmlPullParserException, IOException {
+        return createAnimatorFromXml(res, theme, parser, Xml.asAttributeSet(parser), null, 0,
+                pixelSize);
+    }
+
+    private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser,
+            AttributeSet attrs, AnimatorSet parent, int sequenceOrdering, float pixelSize)
             throws XmlPullParserException, IOException {
 
         Animator anim = null;
@@ -104,26 +516,31 @@
         int type;
         int depth = parser.getDepth();
 
-        while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
-               && type != XmlPullParser.END_DOCUMENT) {
+        while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+                && type != XmlPullParser.END_DOCUMENT) {
 
             if (type != XmlPullParser.START_TAG) {
                 continue;
             }
 
-            String  name = parser.getName();
+            String name = parser.getName();
 
             if (name.equals("objectAnimator")) {
-                anim = loadObjectAnimator(c, attrs);
+                anim = loadObjectAnimator(res, theme, attrs, pixelSize);
             } else if (name.equals("animator")) {
-                anim = loadAnimator(c, attrs, null);
+                anim = loadAnimator(res, theme, attrs, null, pixelSize);
             } else if (name.equals("set")) {
                 anim = new AnimatorSet();
-                TypedArray a = c.obtainStyledAttributes(attrs,
-                        com.android.internal.R.styleable.AnimatorSet);
-                int ordering = a.getInt(com.android.internal.R.styleable.AnimatorSet_ordering,
+                TypedArray a;
+                if (theme != null) {
+                    a = theme.obtainStyledAttributes(attrs, R.styleable.AnimatorSet, 0, 0);
+                } else {
+                    a = res.obtainAttributes(attrs, R.styleable.AnimatorSet);
+                }
+                int ordering = a.getInt(R.styleable.AnimatorSet_ordering,
                         TOGETHER);
-                createAnimatorFromXml(c, parser, attrs, (AnimatorSet) anim,  ordering);
+                createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering,
+                        pixelSize);
                 a.recycle();
             } else {
                 throw new RuntimeException("Unknown animator name: " + parser.getName());
@@ -153,160 +570,63 @@
 
     }
 
-    private static ObjectAnimator loadObjectAnimator(Context context, AttributeSet attrs)
-            throws NotFoundException {
-
+    private static ObjectAnimator loadObjectAnimator(Resources res, Theme theme, AttributeSet attrs,
+            float pathErrorScale) throws NotFoundException {
         ObjectAnimator anim = new ObjectAnimator();
 
-        loadAnimator(context, attrs, anim);
-
-        TypedArray a =
-                context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.PropertyAnimator);
-
-        String propertyName = a.getString(com.android.internal.R.styleable.PropertyAnimator_propertyName);
-
-        anim.setPropertyName(propertyName);
-
-        a.recycle();
+        loadAnimator(res, theme, attrs, anim, pathErrorScale);
 
         return anim;
     }
 
     /**
-     * Creates a new animation whose parameters come from the specified context and
-     * attributes set.
+     * Creates a new animation whose parameters come from the specified context
+     * and attributes set.
      *
-     * @param context the application environment
-     * @param attrs the set of attributes holding the animation parameters
+     * @param res The resources
+     * @param attrs The set of attributes holding the animation parameters
+     * @param anim Null if this is a ValueAnimator, otherwise this is an
+     *            ObjectAnimator
      */
-    private static ValueAnimator loadAnimator(Context context, AttributeSet attrs, ValueAnimator anim)
+    private static ValueAnimator loadAnimator(Resources res, Theme theme,
+            AttributeSet attrs, ValueAnimator anim, float pathErrorScale)
             throws NotFoundException {
 
-        TypedArray a =
-                context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Animator);
+        TypedArray arrayAnimator = null;
+        TypedArray arrayObjectAnimator = null;
 
-        long duration = a.getInt(com.android.internal.R.styleable.Animator_duration, 300);
+        if (theme != null) {
+            arrayAnimator = theme.obtainStyledAttributes(attrs, R.styleable.Animator, 0, 0);
+        } else {
+            arrayAnimator = res.obtainAttributes(attrs, R.styleable.Animator);
+        }
 
-        long startDelay = a.getInt(com.android.internal.R.styleable.Animator_startOffset, 0);
-
-        int valueType = a.getInt(com.android.internal.R.styleable.Animator_valueType,
-                VALUE_TYPE_FLOAT);
+        // If anim is not null, then it is an object animator.
+        if (anim != null) {
+            if (theme != null) {
+                arrayObjectAnimator = theme.obtainStyledAttributes(attrs,
+                        R.styleable.PropertyAnimator, 0, 0);
+            } else {
+                arrayObjectAnimator = res.obtainAttributes(attrs, R.styleable.PropertyAnimator);
+            }
+        }
 
         if (anim == null) {
             anim = new ValueAnimator();
         }
-        TypeEvaluator evaluator = null;
 
-        int valueFromIndex = com.android.internal.R.styleable.Animator_valueFrom;
-        int valueToIndex = com.android.internal.R.styleable.Animator_valueTo;
-
-        boolean getFloats = (valueType == VALUE_TYPE_FLOAT);
-
-        TypedValue tvFrom = a.peekValue(valueFromIndex);
-        boolean hasFrom = (tvFrom != null);
-        int fromType = hasFrom ? tvFrom.type : 0;
-        TypedValue tvTo = a.peekValue(valueToIndex);
-        boolean hasTo = (tvTo != null);
-        int toType = hasTo ? tvTo.type : 0;
-
-        if ((hasFrom && (fromType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
-                (fromType <= TypedValue.TYPE_LAST_COLOR_INT)) ||
-            (hasTo && (toType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
-                (toType <= TypedValue.TYPE_LAST_COLOR_INT))) {
-            // special case for colors: ignore valueType and get ints
-            getFloats = false;
-            anim.setEvaluator(new ArgbEvaluator());
-        }
-
-        if (getFloats) {
-            float valueFrom;
-            float valueTo;
-            if (hasFrom) {
-                if (fromType == TypedValue.TYPE_DIMENSION) {
-                    valueFrom = a.getDimension(valueFromIndex, 0f);
-                } else {
-                    valueFrom = a.getFloat(valueFromIndex, 0f);
-                }
-                if (hasTo) {
-                    if (toType == TypedValue.TYPE_DIMENSION) {
-                        valueTo = a.getDimension(valueToIndex, 0f);
-                    } else {
-                        valueTo = a.getFloat(valueToIndex, 0f);
-                    }
-                    anim.setFloatValues(valueFrom, valueTo);
-                } else {
-                    anim.setFloatValues(valueFrom);
-                }
-            } else {
-                if (toType == TypedValue.TYPE_DIMENSION) {
-                    valueTo = a.getDimension(valueToIndex, 0f);
-                } else {
-                    valueTo = a.getFloat(valueToIndex, 0f);
-                }
-                anim.setFloatValues(valueTo);
-            }
-        } else {
-            int valueFrom;
-            int valueTo;
-            if (hasFrom) {
-                if (fromType == TypedValue.TYPE_DIMENSION) {
-                    valueFrom = (int) a.getDimension(valueFromIndex, 0f);
-                } else if ((fromType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
-                        (fromType <= TypedValue.TYPE_LAST_COLOR_INT)) {
-                    valueFrom = a.getColor(valueFromIndex, 0);
-                } else {
-                    valueFrom = a.getInt(valueFromIndex, 0);
-                }
-                if (hasTo) {
-                    if (toType == TypedValue.TYPE_DIMENSION) {
-                        valueTo = (int) a.getDimension(valueToIndex, 0f);
-                    } else if ((toType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
-                            (toType <= TypedValue.TYPE_LAST_COLOR_INT)) {
-                        valueTo = a.getColor(valueToIndex, 0);
-                    } else {
-                        valueTo = a.getInt(valueToIndex, 0);
-                    }
-                    anim.setIntValues(valueFrom, valueTo);
-                } else {
-                    anim.setIntValues(valueFrom);
-                }
-            } else {
-                if (hasTo) {
-                    if (toType == TypedValue.TYPE_DIMENSION) {
-                        valueTo = (int) a.getDimension(valueToIndex, 0f);
-                    } else if ((toType >= TypedValue.TYPE_FIRST_COLOR_INT) &&
-                        (toType <= TypedValue.TYPE_LAST_COLOR_INT)) {
-                        valueTo = a.getColor(valueToIndex, 0);
-                    } else {
-                        valueTo = a.getInt(valueToIndex, 0);
-                    }
-                    anim.setIntValues(valueTo);
-                }
-            }
-        }
-
-        anim.setDuration(duration);
-        anim.setStartDelay(startDelay);
-
-        if (a.hasValue(com.android.internal.R.styleable.Animator_repeatCount)) {
-            anim.setRepeatCount(
-                    a.getInt(com.android.internal.R.styleable.Animator_repeatCount, 0));
-        }
-        if (a.hasValue(com.android.internal.R.styleable.Animator_repeatMode)) {
-            anim.setRepeatMode(
-                    a.getInt(com.android.internal.R.styleable.Animator_repeatMode,
-                            ValueAnimator.RESTART));
-        }
-        if (evaluator != null) {
-            anim.setEvaluator(evaluator);
-        }
+        parseAnimatorFromTypeArray(anim, arrayAnimator, arrayObjectAnimator, pathErrorScale);
 
         final int resID =
-                a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0);
+                arrayAnimator.getResourceId(R.styleable.Animator_interpolator, 0);
         if (resID > 0) {
-            anim.setInterpolator(AnimationUtils.loadInterpolator(context, resID));
+            anim.setInterpolator(AnimationUtils.loadInterpolator(res, theme, resID));
         }
-        a.recycle();
+
+        arrayAnimator.recycle();
+        if (arrayObjectAnimator != null) {
+            arrayObjectAnimator.recycle();
+        }
 
         return anim;
     }
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 018a2d6..0aa8fdd 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -124,7 +124,7 @@
     // was set on this AnimatorSet, so it should not be passed down to the children.
     private TimeInterpolator mInterpolator = null;
 
-
+    private boolean mReversible = true;
     /**
      * Sets up this AnimatorSet to play all of the supplied animations at the same time.
      * This is equivalent to calling {@link #play(Animator)} with the first animator in the
@@ -177,6 +177,7 @@
             if (items.length == 1) {
                 play(items[0]);
             } else {
+                mReversible = false;
                 for (int i = 0; i < items.length - 1; ++i) {
                     play(items[i]).before(items[i+1]);
                 }
@@ -196,6 +197,7 @@
             if (items.size() == 1) {
                 play(items.get(0));
             } else {
+                mReversible = false;
                 for (int i = 0; i < items.size() - 1; ++i) {
                     play(items.get(i)).before(items.get(i+1));
                 }
@@ -407,6 +409,9 @@
      */
     @Override
     public void setStartDelay(long startDelay) {
+        if (mStartDelay > 0) {
+            mReversible = false;
+        }
         mStartDelay = startDelay;
     }
 
@@ -499,6 +504,10 @@
         mStarted = true;
         mPaused = false;
 
+        for (Node node : mNodes) {
+            node.animation.setAllowRunningAsynchronously(false);
+        }
+
         if (mDuration >= 0) {
             // If the duration was set on this AnimatorSet, pass it along to all child animations
             for (Node node : mNodes) {
@@ -512,7 +521,7 @@
                 node.animation.setInterpolator(mInterpolator);
             }
         }
-            // First, sort the nodes (if necessary). This will ensure that sortedNodes
+        // First, sort the nodes (if necessary). This will ensure that sortedNodes
         // contains the animation nodes in the correct order.
         sortNodes();
 
@@ -626,6 +635,8 @@
         anim.mNodeMap = new HashMap<Animator, Node>();
         anim.mNodes = new ArrayList<Node>();
         anim.mSortedNodes = new ArrayList<Node>();
+        anim.mReversible = mReversible;
+        anim.mSetListener = null;
 
         // Walk through the old nodes list, cloning each node and adding it to the new nodemap.
         // One problem is that the old node dependencies point to nodes in the old AnimatorSet.
@@ -908,6 +919,35 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean canReverse() {
+        if (!mReversible)  {
+            return false;
+        }
+        // Loop to make sure all the Nodes can reverse.
+        for (Node node : mNodes) {
+            if (!node.animation.canReverse() || node.animation.getStartDelay() > 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void reverse() {
+        if (canReverse()) {
+            for (Node node : mNodes) {
+                node.animation.reverse();
+            }
+        }
+    }
+
+    /**
      * Dependency holds information about the node that some other node is
      * dependent upon and the nature of that dependency.
      *
@@ -1124,6 +1164,7 @@
          * {@link AnimatorSet#play(Animator)} method ends.
          */
         public Builder before(Animator anim) {
+            mReversible = false;
             Node node = mNodeMap.get(anim);
             if (node == null) {
                 node = new Node(anim);
@@ -1144,6 +1185,7 @@
          * {@link AnimatorSet#play(Animator)} method to play.
          */
         public Builder after(Animator anim) {
+            mReversible = false;
             Node node = mNodeMap.get(anim);
             if (node == null) {
                 node = new Node(anim);
diff --git a/core/java/android/animation/ArgbEvaluator.java b/core/java/android/animation/ArgbEvaluator.java
index 717a3d9..ed07195 100644
--- a/core/java/android/animation/ArgbEvaluator.java
+++ b/core/java/android/animation/ArgbEvaluator.java
@@ -21,6 +21,19 @@
  * values that represent ARGB colors.
  */
 public class ArgbEvaluator implements TypeEvaluator {
+    private static final ArgbEvaluator sInstance = new ArgbEvaluator();
+
+    /**
+     * Returns an instance of <code>ArgbEvaluator</code> that may be used in
+     * {@link ValueAnimator#setEvaluator(TypeEvaluator)}. The same instance may
+     * be used in multiple <code>Animator</code>s because it holds no state.
+     * @return An instance of <code>ArgbEvalutor</code>.
+     *
+     * @hide
+     */
+    public static ArgbEvaluator getInstance() {
+        return sInstance;
+    }
 
     /**
      * This function returns the calculated in-between value for a color
diff --git a/core/java/android/animation/BidirectionalTypeConverter.java b/core/java/android/animation/BidirectionalTypeConverter.java
new file mode 100644
index 0000000..960650e
--- /dev/null
+++ b/core/java/android/animation/BidirectionalTypeConverter.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.animation;
+
+/**
+ * Abstract base class used convert type T to another type V and back again. This
+ * is necessary when the value types of in animation are different from the property
+ * type. BidirectionalTypeConverter is needed when only the final value for the
+ * animation is supplied to animators.
+ * @see PropertyValuesHolder#setConverter(TypeConverter)
+ */
+public abstract class BidirectionalTypeConverter<T, V> extends TypeConverter<T, V> {
+    private BidirectionalTypeConverter mInvertedConverter;
+
+    public BidirectionalTypeConverter(Class<T> fromClass, Class<V> toClass) {
+        super(fromClass, toClass);
+    }
+
+    /**
+     * Does a conversion from the target type back to the source type. The subclass
+     * must implement this when a TypeConverter is used in animations and current
+     * values will need to be read for an animation.
+     * @param value The Object to convert.
+     * @return A value of type T, converted from <code>value</code>.
+     */
+    public abstract T convertBack(V value);
+
+    /**
+     * Returns the inverse of this converter, where the from and to classes are reversed.
+     * The inverted converter uses this convert to call {@link #convertBack(Object)} for
+     * {@link #convert(Object)} calls and {@link #convert(Object)} for
+     * {@link #convertBack(Object)} calls.
+     * @return The inverse of this converter, where the from and to classes are reversed.
+     */
+    public BidirectionalTypeConverter<V, T> invert() {
+        if (mInvertedConverter == null) {
+            mInvertedConverter = new InvertedConverter(this);
+        }
+        return mInvertedConverter;
+    }
+
+    private static class InvertedConverter<From, To> extends BidirectionalTypeConverter<From, To> {
+        private BidirectionalTypeConverter<To, From> mConverter;
+
+        public InvertedConverter(BidirectionalTypeConverter<To, From> converter) {
+            super(converter.getTargetType(), converter.getSourceType());
+            mConverter = converter;
+        }
+
+        @Override
+        public From convertBack(To value) {
+            return mConverter.convert(value);
+        }
+
+        @Override
+        public To convert(From value) {
+            return mConverter.convertBack(value);
+        }
+    }
+}
diff --git a/core/java/android/animation/FloatArrayEvaluator.java b/core/java/android/animation/FloatArrayEvaluator.java
new file mode 100644
index 0000000..9ae1197
--- /dev/null
+++ b/core/java/android/animation/FloatArrayEvaluator.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.animation;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>float[]</code> values.
+ * Each index into the array is treated as a separate value to interpolate. For example,
+ * evaluating <code>{100, 200}</code> and <code>{300, 400}</code> will interpolate the value at
+ * the first index between 100 and 300 and the value at the second index value between 200 and 400.
+ */
+public class FloatArrayEvaluator implements TypeEvaluator<float[]> {
+
+    private float[] mArray;
+
+    /**
+     * Create a FloatArrayEvaluator that does not reuse the animated value. Care must be taken
+     * when using this option because on every evaluation a new <code>float[]</code> will be
+     * allocated.
+     *
+     * @see #FloatArrayEvaluator(float[])
+     */
+    public FloatArrayEvaluator() {
+    }
+
+    /**
+     * Create a FloatArrayEvaluator that reuses <code>reuseArray</code> for every evaluate() call.
+     * Caution must be taken to ensure that the value returned from
+     * {@link android.animation.ValueAnimator#getAnimatedValue()} is not cached, modified, or
+     * used across threads. The value will be modified on each <code>evaluate()</code> call.
+     *
+     * @param reuseArray The array to modify and return from <code>evaluate</code>.
+     */
+    public FloatArrayEvaluator(float[] reuseArray) {
+        mArray = reuseArray;
+    }
+
+    /**
+     * Interpolates the value at each index by the fraction. If
+     * {@link #FloatArrayEvaluator(float[])} was used to construct this object,
+     * <code>reuseArray</code> will be returned, otherwise a new <code>float[]</code>
+     * will be returned.
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue The start value.
+     * @param endValue   The end value.
+     * @return A <code>float[]</code> where each element is an interpolation between
+     *         the same index in startValue and endValue.
+     */
+    @Override
+    public float[] evaluate(float fraction, float[] startValue, float[] endValue) {
+        float[] array = mArray;
+        if (array == null) {
+            array = new float[startValue.length];
+        }
+
+        for (int i = 0; i < array.length; i++) {
+            float start = startValue[i];
+            float end = endValue[i];
+            array[i] = start + (fraction * (end - start));
+        }
+        return array;
+    }
+}
diff --git a/core/java/android/animation/FloatKeyframeSet.java b/core/java/android/animation/FloatKeyframeSet.java
index 377b5a05..12e5862 100644
--- a/core/java/android/animation/FloatKeyframeSet.java
+++ b/core/java/android/animation/FloatKeyframeSet.java
@@ -30,7 +30,7 @@
  * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
  * Object equivalents of these primitive types.</p>
  */
-class FloatKeyframeSet extends KeyframeSet {
+class FloatKeyframeSet extends KeyframeSet implements Keyframes.FloatKeyframes {
     private float firstValue;
     private float lastValue;
     private float deltaValue;
@@ -57,6 +57,12 @@
         return newSet;
     }
 
+    @Override
+    public void invalidateCache() {
+        firstTime = true;
+    }
+
+    @Override
     public float getFloatValue(float fraction) {
         if (mNumKeyframes == 2) {
             if (firstTime) {
@@ -130,5 +136,9 @@
         return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue();
     }
 
+    @Override
+    public Class getType() {
+        return Float.class;
+    }
 }
 
diff --git a/core/java/android/animation/IntArrayEvaluator.java b/core/java/android/animation/IntArrayEvaluator.java
new file mode 100644
index 0000000..d7f10f3
--- /dev/null
+++ b/core/java/android/animation/IntArrayEvaluator.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.animation;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>int[]</code> values.
+ * Each index into the array is treated as a separate value to interpolate. For example,
+ * evaluating <code>{100, 200}</code> and <code>{300, 400}</code> will interpolate the value at
+ * the first index between 100 and 300 and the value at the second index value between 200 and 400.
+ */
+public class IntArrayEvaluator implements TypeEvaluator<int[]> {
+
+    private int[] mArray;
+
+    /**
+     * Create an IntArrayEvaluator that does not reuse the animated value. Care must be taken
+     * when using this option because on every evaluation a new <code>int[]</code> will be
+     * allocated.
+     *
+     * @see #IntArrayEvaluator(int[])
+     */
+    public IntArrayEvaluator() {
+    }
+
+    /**
+     * Create an IntArrayEvaluator that reuses <code>reuseArray</code> for every evaluate() call.
+     * Caution must be taken to ensure that the value returned from
+     * {@link android.animation.ValueAnimator#getAnimatedValue()} is not cached, modified, or
+     * used across threads. The value will be modified on each <code>evaluate()</code> call.
+     *
+     * @param reuseArray The array to modify and return from <code>evaluate</code>.
+     */
+    public IntArrayEvaluator(int[] reuseArray) {
+        mArray = reuseArray;
+    }
+
+    /**
+     * Interpolates the value at each index by the fraction. If {@link #IntArrayEvaluator(int[])}
+     * was used to construct this object, <code>reuseArray</code> will be returned, otherwise
+     * a new <code>int[]</code> will be returned.
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue The start value.
+     * @param endValue   The end value.
+     * @return An <code>int[]</code> where each element is an interpolation between
+     *         the same index in startValue and endValue.
+     */
+    @Override
+    public int[] evaluate(float fraction, int[] startValue, int[] endValue) {
+        int[] array = mArray;
+        if (array == null) {
+            array = new int[startValue.length];
+        }
+        for (int i = 0; i < array.length; i++) {
+            int start = startValue[i];
+            int end = endValue[i];
+            array[i] = (int) (start + (fraction * (end - start)));
+        }
+        return array;
+    }
+}
diff --git a/core/java/android/animation/IntKeyframeSet.java b/core/java/android/animation/IntKeyframeSet.java
index 7b7c876..7a5b0ec 100644
--- a/core/java/android/animation/IntKeyframeSet.java
+++ b/core/java/android/animation/IntKeyframeSet.java
@@ -30,7 +30,7 @@
  * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
  * Object equivalents of these primitive types.</p>
  */
-class IntKeyframeSet extends KeyframeSet {
+class IntKeyframeSet extends KeyframeSet implements Keyframes.IntKeyframes {
     private int firstValue;
     private int lastValue;
     private int deltaValue;
@@ -57,6 +57,12 @@
         return newSet;
     }
 
+    @Override
+    public void invalidateCache() {
+        firstTime = true;
+    }
+
+    @Override
     public int getIntValue(float fraction) {
         if (mNumKeyframes == 2) {
             if (firstTime) {
@@ -129,5 +135,9 @@
         return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue();
     }
 
+    @Override
+    public Class getType() {
+        return Integer.class;
+    }
 }
 
diff --git a/core/java/android/animation/Keyframe.java b/core/java/android/animation/Keyframe.java
index dc8538f..5483c49 100644
--- a/core/java/android/animation/Keyframe.java
+++ b/core/java/android/animation/Keyframe.java
@@ -35,6 +35,20 @@
  */
 public abstract class Keyframe implements Cloneable {
     /**
+     * Flag to indicate whether this keyframe has a valid value. This flag is used when an
+     * animation first starts, to populate placeholder keyframes with real values derived
+     * from the target object.
+     */
+    boolean mHasValue;
+
+    /**
+     * Flag to indicate whether the value in the keyframe was read from the target object or not.
+     * If so, its value will be recalculated if target changes.
+     */
+    boolean mValueWasSetOnStart;
+
+
+    /**
      * The time at which mValue will hold true.
      */
     float mFraction;
@@ -51,12 +65,7 @@
      */
     private TimeInterpolator mInterpolator = null;
 
-    /**
-     * Flag to indicate whether this keyframe has a valid value. This flag is used when an
-     * animation first starts, to populate placeholder keyframes with real values derived
-     * from the target object.
-     */
-    boolean mHasValue = false;
+
 
     /**
      * Constructs a Keyframe object with the given time and value. The time defines the
@@ -166,6 +175,20 @@
     }
 
     /**
+     * If the Keyframe's value was acquired from the target object, this flag should be set so that,
+     * if target changes, value will be reset.
+     *
+     * @return boolean Whether this Keyframe's value was retieved from the target object or not.
+     */
+    boolean valueWasSetOnStart() {
+        return mValueWasSetOnStart;
+    }
+
+    void setValueWasSetOnStart(boolean valueWasSetOnStart) {
+        mValueWasSetOnStart = valueWasSetOnStart;
+    }
+
+    /**
      * Gets the value for this Keyframe.
      *
      * @return The value for this Keyframe.
@@ -261,7 +284,8 @@
 
         @Override
         public ObjectKeyframe clone() {
-            ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), mHasValue ? mValue : null);
+            ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), hasValue() ? mValue : null);
+            kfClone.mValueWasSetOnStart = mValueWasSetOnStart;
             kfClone.setInterpolator(getInterpolator());
             return kfClone;
         }
@@ -310,6 +334,7 @@
                     new IntKeyframe(getFraction(), mValue) :
                     new IntKeyframe(getFraction());
             kfClone.setInterpolator(getInterpolator());
+            kfClone.mValueWasSetOnStart = mValueWasSetOnStart;
             return kfClone;
         }
     }
@@ -356,6 +381,7 @@
                     new FloatKeyframe(getFraction(), mValue) :
                     new FloatKeyframe(getFraction());
             kfClone.setInterpolator(getInterpolator());
+            kfClone.mValueWasSetOnStart = mValueWasSetOnStart;
             return kfClone;
         }
     }
diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java
index 4026f7f..8d15db2 100644
--- a/core/java/android/animation/KeyframeSet.java
+++ b/core/java/android/animation/KeyframeSet.java
@@ -21,6 +21,7 @@
 import android.animation.Keyframe.IntKeyframe;
 import android.animation.Keyframe.FloatKeyframe;
 import android.animation.Keyframe.ObjectKeyframe;
+import android.graphics.Path;
 import android.util.Log;
 
 /**
@@ -28,7 +29,7 @@
  * values between those keyframes for a given animation. The class internal to the animation
  * package because it is an implementation detail of how Keyframes are stored and used.
  */
-class KeyframeSet {
+class KeyframeSet implements Keyframes {
 
     int mNumKeyframes;
 
@@ -48,6 +49,18 @@
         mInterpolator = mLastKeyframe.getInterpolator();
     }
 
+    /**
+     * If subclass has variables that it calculates based on the Keyframes, it should reset them
+     * when this method is called because Keyframe contents might have changed.
+     */
+    @Override
+    public void invalidateCache() {
+    }
+
+    public ArrayList<Keyframe> getKeyframes() {
+        return mKeyframes;
+    }
+
     public static KeyframeSet ofInt(int... values) {
         int numKeyframes = values.length;
         IntKeyframe keyframes[] = new IntKeyframe[Math.max(numKeyframes,2)];
@@ -137,6 +150,14 @@
         return new KeyframeSet(keyframes);
     }
 
+    public static PathKeyframes ofPath(Path path) {
+        return new PathKeyframes(path);
+    }
+
+    public static PathKeyframes ofPath(Path path, float error) {
+        return new PathKeyframes(path, error);
+    }
+
     /**
      * Sets the TypeEvaluator to be used when calculating animated values. This object
      * is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet,
@@ -150,6 +171,11 @@
     }
 
     @Override
+    public Class getType() {
+        return mFirstKeyframe.getType();
+    }
+
+    @Override
     public KeyframeSet clone() {
         ArrayList<Keyframe> keyframes = mKeyframes;
         int numKeyframes = mKeyframes.size();
diff --git a/core/java/android/animation/Keyframes.java b/core/java/android/animation/Keyframes.java
new file mode 100644
index 0000000..6611c6c
--- /dev/null
+++ b/core/java/android/animation/Keyframes.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.animation;
+
+import java.util.ArrayList;
+
+/**
+ * This interface abstracts a collection of Keyframe objects and is called by
+ * ValueAnimator to calculate values between those keyframes for a given animation.
+ */
+interface Keyframes extends Cloneable {
+
+    /**
+     * Sets the TypeEvaluator to be used when calculating animated values. This object
+     * is required only for Keyframes that are not either IntKeyframes or FloatKeyframes,
+     * both of which assume their own evaluator to speed up calculations with those primitive
+     * types.
+     *
+     * @param evaluator The TypeEvaluator to be used to calculate animated values.
+     */
+    void setEvaluator(TypeEvaluator evaluator);
+
+    /**
+     * @return The value type contained by the contained Keyframes.
+     */
+    Class getType();
+
+    /**
+     * Gets the animated value, given the elapsed fraction of the animation (interpolated by the
+     * animation's interpolator) and the evaluator used to calculate in-between values. This
+     * function maps the input fraction to the appropriate keyframe interval and a fraction
+     * between them and returns the interpolated value. Note that the input fraction may fall
+     * outside the [0-1] bounds, if the animation's interpolator made that happen (e.g., a
+     * spring interpolation that might send the fraction past 1.0). We handle this situation by
+     * just using the two keyframes at the appropriate end when the value is outside those bounds.
+     *
+     * @param fraction The elapsed fraction of the animation
+     * @return The animated value.
+     */
+    Object getValue(float fraction);
+
+    /**
+     * If subclass has variables that it calculates based on the Keyframes, it should reset them
+     * when this method is called because Keyframe contents might have changed.
+     */
+    void invalidateCache();
+
+    /**
+     * @return A list of all Keyframes contained by this. This may return null if this is
+     * not made up of Keyframes.
+     */
+    ArrayList<Keyframe> getKeyframes();
+
+    Keyframes clone();
+
+    /**
+     * A specialization of Keyframes that has integer primitive value calculation.
+     */
+    public interface IntKeyframes extends Keyframes {
+
+        /**
+         * Works like {@link #getValue(float)}, but returning a primitive.
+         * @param fraction The elapsed fraction of the animation
+         * @return The animated value.
+         */
+        int getIntValue(float fraction);
+    }
+
+    /**
+     * A specialization of Keyframes that has float primitive value calculation.
+     */
+    public interface FloatKeyframes extends Keyframes {
+
+        /**
+         * Works like {@link #getValue(float)}, but returning a primitive.
+         * @param fraction The elapsed fraction of the animation
+         * @return The animated value.
+         */
+        float getFloatValue(float fraction);
+    }
+}
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index 188408d..57906824 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -899,11 +899,15 @@
                     PropertyValuesHolder[] oldValues = valueAnim.getValues();
                     for (int i = 0; i < oldValues.length; ++i) {
                         PropertyValuesHolder pvh = oldValues[i];
-                        KeyframeSet keyframeSet = pvh.mKeyframeSet;
-                        if (keyframeSet.mFirstKeyframe == null ||
-                                keyframeSet.mLastKeyframe == null ||
-                                !keyframeSet.mFirstKeyframe.getValue().equals(
-                                keyframeSet.mLastKeyframe.getValue())) {
+                        if (pvh.mKeyframes instanceof KeyframeSet) {
+                            KeyframeSet keyframeSet = (KeyframeSet) pvh.mKeyframes;
+                            if (keyframeSet.mFirstKeyframe == null ||
+                                    keyframeSet.mLastKeyframe == null ||
+                                    !keyframeSet.mFirstKeyframe.getValue().equals(
+                                            keyframeSet.mLastKeyframe.getValue())) {
+                                valuesDiffer = true;
+                            }
+                        } else if (!pvh.mKeyframes.getValue(0).equals(pvh.mKeyframes.getValue(1))) {
                             valuesDiffer = true;
                         }
                     }
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 9c88ccf..500634c 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -16,9 +16,14 @@
 
 package android.animation;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Path;
+import android.graphics.PointF;
 import android.util.Log;
 import android.util.Property;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
 /**
@@ -39,10 +44,15 @@
  *
  */
 public final class ObjectAnimator extends ValueAnimator {
+    private static final String LOG_TAG = "ObjectAnimator";
+
     private static final boolean DBG = false;
 
-    // The target object on which the property exists, set in the constructor
-    private Object mTarget;
+    /**
+     * A weak reference to the target object on which the property exists, set
+     * in the constructor. We'll cancel the animation if this goes away.
+     */
+    private WeakReference<Object> mTarget;
 
     private String mPropertyName;
 
@@ -76,7 +86,7 @@
      *
      * @param propertyName The name of the property being animated. Should not be null.
      */
-    public void setPropertyName(String propertyName) {
+    public void setPropertyName(@NonNull String propertyName) {
         // mValues could be null if this is being constructed piecemeal. Just record the
         // propertyName to be used later when setValues() is called if so.
         if (mValues != null) {
@@ -98,7 +108,7 @@
      *
      * @param property The property being animated. Should not be null.
      */
-    public void setProperty(Property property) {
+    public void setProperty(@NonNull Property property) {
         // mValues could be null if this is being constructed piecemeal. Just record the
         // propertyName to be used later when setValues() is called if so.
         if (mValues != null) {
@@ -132,6 +142,7 @@
      * object (if there was just one) or a comma-separated list of all of the
      * names (if there are more than one).</p>
      */
+    @Nullable
     public String getPropertyName() {
         String propertyName = null;
         if (mPropertyName != null) {
@@ -174,7 +185,7 @@
      * @param propertyName The name of the property being animated.
      */
     private ObjectAnimator(Object target, String propertyName) {
-        mTarget = target;
+        setTarget(target);
         setPropertyName(propertyName);
     }
 
@@ -185,13 +196,13 @@
      * @param property The property being animated.
      */
     private <T> ObjectAnimator(T target, Property<T, ?> property) {
-        mTarget = target;
+        setTarget(target);
         setProperty(property);
     }
 
     /**
      * Constructs and returns an ObjectAnimator that animates between int values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -210,8 +221,35 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are integers that are set to separate properties designated by
+     * <code>xPropertyName</code> and <code>yPropertyName</code>.
+     *
+     * @param target The object whose properties are to be animated. This object should
+     *               have public methods on it called <code>setNameX()</code> and
+     *               <code>setNameY</code>, where <code>nameX</code> and <code>nameY</code>
+     *               are the value of <code>xPropertyName</code> and <code>yPropertyName</code>
+     *               parameters, respectively.
+     * @param xPropertyName The name of the property for the x coordinate being animated.
+     * @param yPropertyName The name of the property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofInt(Object target, String xPropertyName, String yPropertyName,
+            Path path) {
+        PathKeyframes keyframes = KeyframeSet.ofPath(path);
+        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframes(xPropertyName,
+                keyframes.createXIntKeyframes());
+        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframes(yPropertyName,
+                keyframes.createYIntKeyframes());
+        return ofPropertyValuesHolder(target, x, y);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between int values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -228,8 +266,137 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties.  A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are integers that are set to separate properties, <code>xProperty</code> and
+     * <code>yProperty</code>.
+     *
+     * @param target The object whose properties are to be animated.
+     * @param xProperty The property for the x coordinate being animated.
+     * @param yProperty The property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static <T> ObjectAnimator ofInt(T target, Property<T, Integer> xProperty,
+            Property<T, Integer> yProperty, Path path) {
+        PathKeyframes keyframes = KeyframeSet.ofPath(path);
+        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframes(xProperty,
+                keyframes.createXIntKeyframes());
+        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframes(yProperty,
+                keyframes.createYIntKeyframes());
+        return ofPropertyValuesHolder(target, x, y);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over int values for a multiple
+     * parameters setter. Only public methods that take only int parameters are supported.
+     * Each <code>int[]</code> contains a complete set of parameters to the setter method.
+     * At least two <code>int[]</code> values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static ObjectAnimator ofMultiInt(Object target, String propertyName, int[][] values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, values);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates the target using a multi-int setter
+     * along the given <code>Path</code>. A <code>Path</code></> animation moves in two dimensions,
+     * animating coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are integer x and y coordinates used in the first and second parameter of the
+     * setter, respectively.
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofMultiInt(Object target, String propertyName, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over values for a multiple int
+     * parameters setter. Only public methods that take only int parameters are supported.
+     * <p>At least two values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).</p>
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param converter Converts T objects into int parameters for the multi-value setter.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T> ObjectAnimator ofMultiInt(Object target, String propertyName,
+            TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, converter,
+                evaluator, values);
+        return ObjectAnimator.ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates between color values. A single
+     * value implies that that value is the one being animated to. Two values imply starting
+     * and ending values. More than two values imply a starting value, values to animate through
+     * along the way, and an ending value (these values will be distributed evenly across
+     * the duration of the animation).
+     *
+     * @param target The object whose property is to be animated. This object should
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter.
+     * @param propertyName The name of the property being animated.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static ObjectAnimator ofArgb(Object target, String propertyName, int... values) {
+        ObjectAnimator animator = ofInt(target, propertyName, values);
+        animator.setEvaluator(ArgbEvaluator.getInstance());
+        return animator;
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates between color values. A single
+     * value implies that that value is the one being animated to. Two values imply starting
+     * and ending values. More than two values imply a starting value, values to animate through
+     * along the way, and an ending value (these values will be distributed evenly across
+     * the duration of the animation).
+     *
+     * @param target The object whose property is to be animated.
+     * @param property The property being animated.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T> ObjectAnimator ofArgb(T target, Property<T, Integer> property,
+            int... values) {
+        ObjectAnimator animator = ofInt(target, property, values);
+        animator.setEvaluator(ArgbEvaluator.getInstance());
+        return animator;
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between float values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -248,8 +415,35 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are floats that are set to separate properties designated by
+     * <code>xPropertyName</code> and <code>yPropertyName</code>.
+     *
+     * @param target The object whose properties are to be animated. This object should
+     *               have public methods on it called <code>setNameX()</code> and
+     *               <code>setNameY</code>, where <code>nameX</code> and <code>nameY</code>
+     *               are the value of the <code>xPropertyName</code> and <code>yPropertyName</code>
+     *               parameters, respectively.
+     * @param xPropertyName The name of the property for the x coordinate being animated.
+     * @param yPropertyName The name of the property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofFloat(Object target, String xPropertyName, String yPropertyName,
+            Path path) {
+        PathKeyframes keyframes = KeyframeSet.ofPath(path);
+        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframes(xPropertyName,
+                keyframes.createXFloatKeyframes());
+        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframes(yPropertyName,
+                keyframes.createYFloatKeyframes());
+        return ofPropertyValuesHolder(target, x, y);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between float values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -267,8 +461,99 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are floats that are set to separate properties, <code>xProperty</code> and
+     * <code>yProperty</code>.
+     *
+     * @param target The object whose properties are to be animated.
+     * @param xProperty The property for the x coordinate being animated.
+     * @param yProperty The property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static <T> ObjectAnimator ofFloat(T target, Property<T, Float> xProperty,
+            Property<T, Float> yProperty, Path path) {
+        PathKeyframes keyframes = KeyframeSet.ofPath(path);
+        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframes(xProperty,
+                keyframes.createXFloatKeyframes());
+        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframes(yProperty,
+                keyframes.createYFloatKeyframes());
+        return ofPropertyValuesHolder(target, x, y);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over float values for a multiple
+     * parameters setter. Only public methods that take only float parameters are supported.
+     * Each <code>float[]</code> contains a complete set of parameters to the setter method.
+     * At least two <code>float[]</code> values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static ObjectAnimator ofMultiFloat(Object target, String propertyName,
+            float[][] values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, values);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates the target using a multi-float setter
+     * along the given <code>Path</code>. A <code>Path</code></> animation moves in two dimensions,
+     * animating coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are float x and y coordinates used in the first and second parameter of the
+     * setter, respectively.
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofMultiFloat(Object target, String propertyName, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over values for a multiple float
+     * parameters setter. Only public methods that take only float parameters are supported.
+     * <p>At least two values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).</p>
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param converter Converts T objects into float parameters for the multi-value setter.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T> ObjectAnimator ofMultiFloat(Object target, String propertyName,
+            TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, T... values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, converter,
+                evaluator, values);
+        return ObjectAnimator.ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between Object values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -292,8 +577,33 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates a property along a <code>Path</code>.
+     * A <code>Path</code></> animation moves in two dimensions, animating coordinates
+     * <code>(x, y)</code> together to follow the line. This variant animates the coordinates
+     * in a <code>PointF</code> to follow the <code>Path</code>. If the <code>Property</code>
+     * associated with <code>propertyName</code> uses a type other than <code>PointF</code>,
+     * <code>converter</code> can be used to change from <code>PointF</code> to the type
+     * associated with the <code>Property</code>.
+     *
+     * @param target The object whose property is to be animated. This object should
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter.
+     * @param propertyName The name of the property being animated.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    @NonNull
+    public static ObjectAnimator ofObject(Object target, String propertyName,
+            @Nullable TypeConverter<PointF, ?> converter, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(propertyName, converter, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between Object values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -306,6 +616,7 @@
      * @param values A set of values that the animation will animate between over time.
      * @return An ObjectAnimator object that is set up to animate between the given values.
      */
+    @NonNull
     public static <T, V> ObjectAnimator ofObject(T target, Property<T, V> property,
             TypeEvaluator<V> evaluator, V... values) {
         ObjectAnimator anim = new ObjectAnimator(target, property);
@@ -315,6 +626,59 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates between Object values. A single
+     * value implies that that value is the one being animated to. Two values imply starting
+     * and ending values. More than two values imply a starting value, values to animate through
+     * along the way, and an ending value (these values will be distributed evenly across
+     * the duration of the animation). This variant supplies a <code>TypeConverter</code> to
+     * convert from the animated values to the type of the property. If only one value is
+     * supplied, the <code>TypeConverter</code> must be a
+     * {@link android.animation.BidirectionalTypeConverter} to retrieve the current value.
+     *
+     * @param target The object whose property is to be animated.
+     * @param property The property being animated.
+     * @param converter Converts the animated object to the Property type.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    @NonNull
+    public static <T, V, P> ObjectAnimator ofObject(T target, Property<T, P> property,
+            TypeConverter<V, P> converter, TypeEvaluator<V> evaluator, V... values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, evaluator,
+                values);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates a property along a <code>Path</code>.
+     * A <code>Path</code></> animation moves in two dimensions, animating coordinates
+     * <code>(x, y)</code> together to follow the line. This variant animates the coordinates
+     * in a <code>PointF</code> to follow the <code>Path</code>. If <code>property</code>
+     * uses a type other than <code>PointF</code>, <code>converter</code> can be used to change
+     * from <code>PointF</code> to the type associated with the <code>Property</code>.
+     *
+     * <p>The PointF passed to <code>converter</code> or <code>property</code>, if
+     * <code>converter</code> is <code>null</code>, is reused on each animation frame and should
+     * not be stored by the setter or TypeConverter.</p>
+     *
+     * @param target The object whose property is to be animated.
+     * @param property The property being animated. Should not be null.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    @NonNull
+    public static <T, V> ObjectAnimator ofObject(T target, @NonNull Property<T, V> property,
+            @Nullable TypeConverter<PointF, V> converter, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between the sets of values specified
      * in <code>PropertyValueHolder</code> objects. This variant should be used when animating
      * several properties at once with the same ObjectAnimator, since PropertyValuesHolder allows
@@ -331,10 +695,11 @@
      * over time.
      * @return An ObjectAnimator object that is set up to animate between the given values.
      */
+    @NonNull
     public static ObjectAnimator ofPropertyValuesHolder(Object target,
             PropertyValuesHolder... values) {
         ObjectAnimator anim = new ObjectAnimator();
-        anim.mTarget = target;
+        anim.setTarget(target);
         anim.setValues(values);
         return anim;
     }
@@ -400,10 +765,10 @@
         mAutoCancel = cancel;
     }
 
-    private boolean hasSameTargetAndProperties(Animator anim) {
+    private boolean hasSameTargetAndProperties(@Nullable Animator anim) {
         if (anim instanceof ObjectAnimator) {
             PropertyValuesHolder[] theirValues = ((ObjectAnimator) anim).getValues();
-            if (((ObjectAnimator) anim).getTarget() == mTarget &&
+            if (((ObjectAnimator) anim).getTarget() == getTarget() &&
                     mValues.length == theirValues.length) {
                 for (int i = 0; i < mValues.length; ++i) {
                     PropertyValuesHolder pvhMine = mValues[i];
@@ -453,13 +818,12 @@
             }
         }
         if (DBG) {
-            Log.d("ObjectAnimator", "Anim target, duration: " + mTarget + ", " + getDuration());
+            Log.d(LOG_TAG, "Anim target, duration: " + getTarget() + ", " + getDuration());
             for (int i = 0; i < mValues.length; ++i) {
                 PropertyValuesHolder pvh = mValues[i];
-                ArrayList<Keyframe> keyframes = pvh.mKeyframeSet.mKeyframes;
-                Log.d("ObjectAnimator", "   Values[" + i + "]: " +
-                    pvh.getPropertyName() + ", " + keyframes.get(0).getValue() + ", " +
-                    keyframes.get(pvh.mKeyframeSet.mNumKeyframes - 1).getValue());
+                Log.d(LOG_TAG, "   Values[" + i + "]: " +
+                    pvh.getPropertyName() + ", " + pvh.mKeyframes.getValue(0) + ", " +
+                    pvh.mKeyframes.getValue(1));
             }
         }
         super.start();
@@ -482,9 +846,12 @@
         if (!mInitialized) {
             // mValueType may change due to setter/getter setup; do this before calling super.init(),
             // which uses mValueType to set up the default type evaluator.
-            int numValues = mValues.length;
-            for (int i = 0; i < numValues; ++i) {
-                mValues[i].setupSetterAndGetter(mTarget);
+            final Object target = getTarget();
+            if (target != null) {
+                final int numValues = mValues.length;
+                for (int i = 0; i < numValues; ++i) {
+                    mValues[i].setupSetterAndGetter(target);
+                }
             }
             super.initAnimation();
         }
@@ -500,6 +867,7 @@
      * <code>ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start()</code>.
      */
     @Override
+    @NonNull
     public ObjectAnimator setDuration(long duration) {
         super.setDuration(duration);
         return this;
@@ -511,8 +879,9 @@
      *
      * @return The object being animated
      */
+    @Nullable
     public Object getTarget() {
-        return mTarget;
+        return mTarget == null ? null : mTarget.get();
     }
 
     /**
@@ -521,14 +890,11 @@
      * @param target The object being animated
      */
     @Override
-    public void setTarget(Object target) {
-        if (mTarget != target) {
-            final Object oldTarget = mTarget;
-            mTarget = target;
-            if (oldTarget != null && target != null && oldTarget.getClass() == target.getClass()) {
-                return;
-            }
-            // New target type should cause re-initialization prior to starting
+    public void setTarget(@Nullable Object target) {
+        final Object oldTarget = getTarget();
+        if (oldTarget != target) {
+            mTarget = target == null ? null : new WeakReference<Object>(target);
+            // New target should cause re-initialization prior to starting
             mInitialized = false;
         }
     }
@@ -536,18 +902,26 @@
     @Override
     public void setupStartValues() {
         initAnimation();
-        int numValues = mValues.length;
-        for (int i = 0; i < numValues; ++i) {
-            mValues[i].setupStartValue(mTarget);
+
+        final Object target = getTarget();
+        if (target != null) {
+            final int numValues = mValues.length;
+            for (int i = 0; i < numValues; ++i) {
+                mValues[i].setupStartValue(target);
+            }
         }
     }
 
     @Override
     public void setupEndValues() {
         initAnimation();
-        int numValues = mValues.length;
-        for (int i = 0; i < numValues; ++i) {
-            mValues[i].setupEndValue(mTarget);
+
+        final Object target = getTarget();
+        if (target != null) {
+            final int numValues = mValues.length;
+            for (int i = 0; i < numValues; ++i) {
+                mValues[i].setupEndValue(target);
+            }
         }
     }
 
@@ -565,10 +939,17 @@
      */
     @Override
     void animateValue(float fraction) {
+        final Object target = getTarget();
+        if (mTarget != null && target == null) {
+            // We lost the target reference, cancel and clean up.
+            cancel();
+            return;
+        }
+
         super.animateValue(fraction);
         int numValues = mValues.length;
         for (int i = 0; i < numValues; ++i) {
-            mValues[i].setAnimatedValue(mTarget);
+            mValues[i].setAnimatedValue(target);
         }
     }
 
@@ -579,9 +960,10 @@
     }
 
     @Override
+    @NonNull
     public String toString() {
         String returnVal = "ObjectAnimator@" + Integer.toHexString(hashCode()) + ", target " +
-            mTarget;
+            getTarget();
         if (mValues != null) {
             for (int i = 0; i < mValues.length; ++i) {
                 returnVal += "\n    " + mValues[i].toString();
diff --git a/core/java/android/animation/PathKeyframes.java b/core/java/android/animation/PathKeyframes.java
new file mode 100644
index 0000000..2a47b68
--- /dev/null
+++ b/core/java/android/animation/PathKeyframes.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.animation;
+
+import android.graphics.Path;
+import android.graphics.PointF;
+
+import java.util.ArrayList;
+
+/**
+ * PathKeyframes relies on approximating the Path as a series of line segments.
+ * The line segments are recursively divided until there is less than 1/2 pixel error
+ * between the lines and the curve. Each point of the line segment is converted
+ * to a Keyframe and a linear interpolation between Keyframes creates a good approximation
+ * of the curve.
+ * <p>
+ * PathKeyframes is optimized to reduce the number of objects created when there are
+ * many keyframes for a curve.
+ * </p>
+ * <p>
+ * Typically, the returned type is a PointF, but the individual components can be extracted
+ * as either an IntKeyframes or FloatKeyframes.
+ * </p>
+ */
+class PathKeyframes implements Keyframes {
+    private static final int FRACTION_OFFSET = 0;
+    private static final int X_OFFSET = 1;
+    private static final int Y_OFFSET = 2;
+    private static final int NUM_COMPONENTS = 3;
+    private static final ArrayList<Keyframe> EMPTY_KEYFRAMES = new ArrayList<Keyframe>();
+
+    private PointF mTempPointF = new PointF();
+    private float[] mKeyframeData;
+
+    public PathKeyframes(Path path) {
+        this(path, 0.5f);
+    }
+
+    public PathKeyframes(Path path, float error) {
+        if (path == null || path.isEmpty()) {
+            throw new IllegalArgumentException("The path must not be null or empty");
+        }
+        mKeyframeData = path.approximate(error);
+    }
+
+    @Override
+    public ArrayList<Keyframe> getKeyframes() {
+        return EMPTY_KEYFRAMES;
+    }
+
+    @Override
+    public Object getValue(float fraction) {
+        int numPoints = mKeyframeData.length / 3;
+        if (fraction < 0) {
+            return interpolateInRange(fraction, 0, 1);
+        } else if (fraction > 1) {
+            return interpolateInRange(fraction, numPoints - 2, numPoints - 1);
+        } else if (fraction == 0) {
+            return pointForIndex(0);
+        } else if (fraction == 1) {
+            return pointForIndex(numPoints - 1);
+        } else {
+            // Binary search for the correct section
+            int low = 0;
+            int high = numPoints - 1;
+
+            while (low <= high) {
+                int mid = (low + high) / 2;
+                float midFraction = mKeyframeData[(mid * NUM_COMPONENTS) + FRACTION_OFFSET];
+
+                if (fraction < midFraction) {
+                    high = mid - 1;
+                } else if (fraction > midFraction) {
+                    low = mid + 1;
+                } else {
+                    return pointForIndex(mid);
+                }
+            }
+
+            // now high is below the fraction and low is above the fraction
+            return interpolateInRange(fraction, high, low);
+        }
+    }
+
+    private PointF interpolateInRange(float fraction, int startIndex, int endIndex) {
+        int startBase = (startIndex * NUM_COMPONENTS);
+        int endBase = (endIndex * NUM_COMPONENTS);
+
+        float startFraction = mKeyframeData[startBase + FRACTION_OFFSET];
+        float endFraction = mKeyframeData[endBase + FRACTION_OFFSET];
+
+        float intervalFraction = (fraction - startFraction)/(endFraction - startFraction);
+
+        float startX = mKeyframeData[startBase + X_OFFSET];
+        float endX = mKeyframeData[endBase + X_OFFSET];
+        float startY = mKeyframeData[startBase + Y_OFFSET];
+        float endY = mKeyframeData[endBase + Y_OFFSET];
+
+        float x = interpolate(intervalFraction, startX, endX);
+        float y = interpolate(intervalFraction, startY, endY);
+
+        mTempPointF.set(x, y);
+        return mTempPointF;
+    }
+
+    @Override
+    public void invalidateCache() {
+    }
+
+    @Override
+    public void setEvaluator(TypeEvaluator evaluator) {
+    }
+
+    @Override
+    public Class getType() {
+        return PointF.class;
+    }
+
+    @Override
+    public Keyframes clone() {
+        Keyframes clone = null;
+        try {
+            clone = (Keyframes) super.clone();
+        } catch (CloneNotSupportedException e) {}
+        return clone;
+    }
+
+    private PointF pointForIndex(int index) {
+        int base = (index * NUM_COMPONENTS);
+        int xOffset = base + X_OFFSET;
+        int yOffset = base + Y_OFFSET;
+        mTempPointF.set(mKeyframeData[xOffset], mKeyframeData[yOffset]);
+        return mTempPointF;
+    }
+
+    private static float interpolate(float fraction, float startValue, float endValue) {
+        float diff = endValue - startValue;
+        return startValue + (diff * fraction);
+    }
+
+    /**
+     * Returns a FloatKeyframes for the X component of the Path.
+     * @return a FloatKeyframes for the X component of the Path.
+     */
+    public FloatKeyframes createXFloatKeyframes() {
+        return new FloatKeyframesBase() {
+            @Override
+            public float getFloatValue(float fraction) {
+                PointF pointF = (PointF) PathKeyframes.this.getValue(fraction);
+                return pointF.x;
+            }
+        };
+    }
+
+    /**
+     * Returns a FloatKeyframes for the Y component of the Path.
+     * @return a FloatKeyframes for the Y component of the Path.
+     */
+    public FloatKeyframes createYFloatKeyframes() {
+        return new FloatKeyframesBase() {
+            @Override
+            public float getFloatValue(float fraction) {
+                PointF pointF = (PointF) PathKeyframes.this.getValue(fraction);
+                return pointF.y;
+            }
+        };
+    }
+
+    /**
+     * Returns an IntKeyframes for the X component of the Path.
+     * @return an IntKeyframes for the X component of the Path.
+     */
+    public IntKeyframes createXIntKeyframes() {
+        return new IntKeyframesBase() {
+            @Override
+            public int getIntValue(float fraction) {
+                PointF pointF = (PointF) PathKeyframes.this.getValue(fraction);
+                return Math.round(pointF.x);
+            }
+        };
+    }
+
+    /**
+     * Returns an IntKeyframeSet for the Y component of the Path.
+     * @return an IntKeyframeSet for the Y component of the Path.
+     */
+    public IntKeyframes createYIntKeyframes() {
+        return new IntKeyframesBase() {
+            @Override
+            public int getIntValue(float fraction) {
+                PointF pointF = (PointF) PathKeyframes.this.getValue(fraction);
+                return Math.round(pointF.y);
+            }
+        };
+    }
+
+    private abstract static class SimpleKeyframes implements Keyframes {
+        @Override
+        public void setEvaluator(TypeEvaluator evaluator) {
+        }
+
+        @Override
+        public void invalidateCache() {
+        }
+
+        @Override
+        public ArrayList<Keyframe> getKeyframes() {
+            return EMPTY_KEYFRAMES;
+        }
+
+        @Override
+        public Keyframes clone() {
+            Keyframes clone = null;
+            try {
+                clone = (Keyframes) super.clone();
+            } catch (CloneNotSupportedException e) {}
+            return clone;
+        }
+    }
+
+    private abstract static class IntKeyframesBase extends SimpleKeyframes implements IntKeyframes {
+        @Override
+        public Class getType() {
+            return Integer.class;
+        }
+
+        @Override
+        public Object getValue(float fraction) {
+            return getIntValue(fraction);
+        }
+    }
+
+    private abstract static class FloatKeyframesBase extends SimpleKeyframes
+            implements FloatKeyframes {
+        @Override
+        public Class getType() {
+            return Float.class;
+        }
+
+        @Override
+        public Object getValue(float fraction) {
+            return getFloatValue(fraction);
+        }
+    }
+}
diff --git a/core/java/android/animation/PointFEvaluator.java b/core/java/android/animation/PointFEvaluator.java
new file mode 100644
index 0000000..91d501fc
--- /dev/null
+++ b/core/java/android/animation/PointFEvaluator.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.animation;
+
+import android.graphics.PointF;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>PointF</code> values.
+ */
+public class PointFEvaluator implements TypeEvaluator<PointF> {
+
+    /**
+     * When null, a new PointF is returned on every evaluate call. When non-null,
+     * mPoint will be modified and returned on every evaluate.
+     */
+    private PointF mPoint;
+
+    /**
+     * Construct a PointFEvaluator that returns a new PointF on every evaluate call.
+     * To avoid creating an object for each evaluate call,
+     * {@link PointFEvaluator#PointFEvaluator(android.graphics.PointF)} should be used
+     * whenever possible.
+     */
+    public PointFEvaluator() {
+    }
+
+    /**
+     * Constructs a PointFEvaluator that modifies and returns <code>reuse</code>
+     * in {@link #evaluate(float, android.graphics.PointF, android.graphics.PointF)} calls.
+     * The value returned from
+     * {@link #evaluate(float, android.graphics.PointF, android.graphics.PointF)} should
+     * not be cached because it will change over time as the object is reused on each
+     * call.
+     *
+     * @param reuse A PointF to be modified and returned by evaluate.
+     */
+    public PointFEvaluator(PointF reuse) {
+        mPoint = reuse;
+    }
+
+    /**
+     * This function returns the result of linearly interpolating the start and
+     * end PointF values, with <code>fraction</code> representing the proportion
+     * between the start and end values. The calculation is a simple parametric
+     * calculation on each of the separate components in the PointF objects
+     * (x, y).
+     *
+     * <p>If {@link #PointFEvaluator(android.graphics.PointF)} was used to construct
+     * this PointFEvaluator, the object returned will be the <code>reuse</code>
+     * passed into the constructor.</p>
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue The start PointF
+     * @param endValue   The end PointF
+     * @return A linear interpolation between the start and end values, given the
+     *         <code>fraction</code> parameter.
+     */
+    @Override
+    public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
+        float x = startValue.x + (fraction * (endValue.x - startValue.x));
+        float y = startValue.y + (fraction * (endValue.y - startValue.y));
+
+        if (mPoint != null) {
+            mPoint.set(x, y);
+            return mPoint;
+        } else {
+            return new PointF(x, y);
+        }
+    }
+}
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 21f6eda..d372933 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -16,6 +16,8 @@
 
 package android.animation;
 
+import android.graphics.Path;
+import android.graphics.PointF;
 import android.util.FloatProperty;
 import android.util.IntProperty;
 import android.util.Log;
@@ -23,6 +25,7 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
@@ -72,7 +75,7 @@
     /**
      * The set of keyframes (time/value pairs) that define this animation.
      */
-    KeyframeSet mKeyframeSet = null;
+    Keyframes mKeyframes = null;
 
 
     // type evaluators for the primitive types handled by this implementation
@@ -124,6 +127,11 @@
     private Object mAnimatedValue;
 
     /**
+     * Converts from the source Object type to the setter Object type.
+     */
+    private TypeConverter mConverter;
+
+    /**
      * Internal utility constructor, used by the factory methods to set the property name.
      * @param propertyName The name of the property for this holder.
      */
@@ -166,6 +174,102 @@
 
     /**
      * Constructs and returns a PropertyValuesHolder with a given property name and
+     * set of <code>int[]</code> values. At least two <code>int[]</code> values must be supplied,
+     * a start and end value. If more values are supplied, the values will be animated from the
+     * start, through all intermediate values to the end value. When used with ObjectAnimator,
+     * the elements of the array represent the parameters of the setter function.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see IntArrayEvaluator#IntArrayEvaluator(int[])
+     * @see ObjectAnimator#ofMultiInt(Object, String, TypeConverter, TypeEvaluator, Object[])
+     */
+    public static PropertyValuesHolder ofMultiInt(String propertyName, int[][] values) {
+        if (values.length < 2) {
+            throw new IllegalArgumentException("At least 2 values must be supplied");
+        }
+        int numParameters = 0;
+        for (int i = 0; i < values.length; i++) {
+            if (values[i] == null) {
+                throw new IllegalArgumentException("values must not be null");
+            }
+            int length = values[i].length;
+            if (i == 0) {
+                numParameters = length;
+            } else if (length != numParameters) {
+                throw new IllegalArgumentException("Values must all have the same length");
+            }
+        }
+        IntArrayEvaluator evaluator = new IntArrayEvaluator(new int[numParameters]);
+        return new MultiIntValuesHolder(propertyName, null, evaluator, (Object[]) values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name to use
+     * as a multi-int setter. The values are animated along the path, with the first
+     * parameter of the setter set to the x coordinate and the second set to the y coordinate.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     *                     The setter must take exactly two <code>int</code> parameters.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofPropertyValuesHolder(Object, PropertyValuesHolder...)
+     */
+    public static PropertyValuesHolder ofMultiInt(String propertyName, Path path) {
+        Keyframes keyframes = KeyframeSet.ofPath(path);
+        PointFToIntArray converter = new PointFToIntArray();
+        return new MultiIntValuesHolder(propertyName, converter, null, keyframes);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * set of Object values for use with ObjectAnimator multi-value setters. The Object
+     * values are converted to <code>int[]</code> using the converter.
+     *
+     * @param propertyName The property being animated or complete name of the setter.
+     *                     Should not be null.
+     * @param converter Used to convert the animated value to setter parameters.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofMultiInt(Object, String, TypeConverter, TypeEvaluator, Object[])
+     * @see ObjectAnimator#ofPropertyValuesHolder(Object, PropertyValuesHolder...)
+     */
+    public static <V> PropertyValuesHolder ofMultiInt(String propertyName,
+            TypeConverter<V, int[]> converter, TypeEvaluator<V> evaluator, V... values) {
+        return new MultiIntValuesHolder(propertyName, converter, evaluator, values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder object with the specified property name or
+     * setter name for use in a multi-int setter function using ObjectAnimator. The values can be
+     * of any type, but the type should be consistent so that the supplied
+     * {@link android.animation.TypeEvaluator} can be used to to evaluate the animated value. The
+     * <code>converter</code> converts the values to parameters in the setter function.
+     *
+     * <p>At least two values must be supplied, a start and an end value.</p>
+     *
+     * @param propertyName The name of the property to associate with the set of values. This
+     *                     may also be the complete name of a setter function.
+     * @param converter    Converts <code>values</code> into int parameters for the setter.
+     *                     Can be null if the Keyframes have int[] values.
+     * @param evaluator    Used to interpolate between values.
+     * @param values       The values at specific fractional times to evaluate between
+     * @return A PropertyValuesHolder for a multi-int parameter setter.
+     */
+    public static <T> PropertyValuesHolder ofMultiInt(String propertyName,
+            TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, Keyframe... values) {
+        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
+        return new MultiIntValuesHolder(propertyName, converter, evaluator, keyframeSet);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name and
      * set of float values.
      * @param propertyName The name of the property being animated.
      * @param values The values that the named property will animate between.
@@ -188,6 +292,101 @@
 
     /**
      * Constructs and returns a PropertyValuesHolder with a given property name and
+     * set of <code>float[]</code> values. At least two <code>float[]</code> values must be supplied,
+     * a start and end value. If more values are supplied, the values will be animated from the
+     * start, through all intermediate values to the end value. When used with ObjectAnimator,
+     * the elements of the array represent the parameters of the setter function.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see FloatArrayEvaluator#FloatArrayEvaluator(float[])
+     * @see ObjectAnimator#ofMultiFloat(Object, String, TypeConverter, TypeEvaluator, Object[])
+     */
+    public static PropertyValuesHolder ofMultiFloat(String propertyName, float[][] values) {
+        if (values.length < 2) {
+            throw new IllegalArgumentException("At least 2 values must be supplied");
+        }
+        int numParameters = 0;
+        for (int i = 0; i < values.length; i++) {
+            if (values[i] == null) {
+                throw new IllegalArgumentException("values must not be null");
+            }
+            int length = values[i].length;
+            if (i == 0) {
+                numParameters = length;
+            } else if (length != numParameters) {
+                throw new IllegalArgumentException("Values must all have the same length");
+            }
+        }
+        FloatArrayEvaluator evaluator = new FloatArrayEvaluator(new float[numParameters]);
+        return new MultiFloatValuesHolder(propertyName, null, evaluator, (Object[]) values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name to use
+     * as a multi-float setter. The values are animated along the path, with the first
+     * parameter of the setter set to the x coordinate and the second set to the y coordinate.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     *                     The setter must take exactly two <code>float</code> parameters.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofPropertyValuesHolder(Object, PropertyValuesHolder...)
+     */
+    public static PropertyValuesHolder ofMultiFloat(String propertyName, Path path) {
+        Keyframes keyframes = KeyframeSet.ofPath(path);
+        PointFToFloatArray converter = new PointFToFloatArray();
+        return new MultiFloatValuesHolder(propertyName, converter, null, keyframes);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * set of Object values for use with ObjectAnimator multi-value setters. The Object
+     * values are converted to <code>float[]</code> using the converter.
+     *
+     * @param propertyName The property being animated or complete name of the setter.
+     *                     Should not be null.
+     * @param converter Used to convert the animated value to setter parameters.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofMultiFloat(Object, String, TypeConverter, TypeEvaluator, Object[])
+     */
+    public static <V> PropertyValuesHolder ofMultiFloat(String propertyName,
+            TypeConverter<V, float[]> converter, TypeEvaluator<V> evaluator, V... values) {
+        return new MultiFloatValuesHolder(propertyName, converter, evaluator, values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder object with the specified property name or
+     * setter name for use in a multi-float setter function using ObjectAnimator. The values can be
+     * of any type, but the type should be consistent so that the supplied
+     * {@link android.animation.TypeEvaluator} can be used to to evaluate the animated value. The
+     * <code>converter</code> converts the values to parameters in the setter function.
+     *
+     * <p>At least two values must be supplied, a start and an end value.</p>
+     *
+     * @param propertyName The name of the property to associate with the set of values. This
+     *                     may also be the complete name of a setter function.
+     * @param converter    Converts <code>values</code> into float parameters for the setter.
+     *                     Can be null if the Keyframes have float[] values.
+     * @param evaluator    Used to interpolate between values.
+     * @param values       The values at specific fractional times to evaluate between
+     * @return A PropertyValuesHolder for a multi-float parameter setter.
+     */
+    public static <T> PropertyValuesHolder ofMultiFloat(String propertyName,
+            TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, Keyframe... values) {
+        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
+        return new MultiFloatValuesHolder(propertyName, converter, evaluator, keyframeSet);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name and
      * set of Object values. This variant also takes a TypeEvaluator because the system
      * cannot automatically interpolate between objects of unknown type.
      *
@@ -207,6 +406,31 @@
     }
 
     /**
+     * Constructs and returns a PropertyValuesHolder with a given property name and
+     * a Path along which the values should be animated. This variant supports a
+     * <code>TypeConverter</code> to convert from <code>PointF</code> to the target
+     * type.
+     *
+     * <p>The PointF passed to <code>converter</code> or <code>property</code>, if
+     * <code>converter</code> is <code>null</code>, is reused on each animation frame and should
+     * not be stored by the setter or TypeConverter.</p>
+     *
+     * @param propertyName The name of the property being animated.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     */
+    public static PropertyValuesHolder ofObject(String propertyName,
+            TypeConverter<PointF, ?> converter, Path path) {
+        PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
+        pvh.mKeyframes = KeyframeSet.ofPath(path);
+        pvh.mValueType = PointF.class;
+        pvh.setConverter(converter);
+        return pvh;
+    }
+
+    /**
      * Constructs and returns a PropertyValuesHolder with a given property and
      * set of Object values. This variant also takes a TypeEvaluator because the system
      * cannot automatically interpolate between objects of unknown type.
@@ -227,6 +451,59 @@
     }
 
     /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * set of Object values. This variant also takes a TypeEvaluator because the system
+     * cannot automatically interpolate between objects of unknown type. This variant also
+     * takes a <code>TypeConverter</code> to convert from animated values to the type
+     * of the property. If only one value is supplied, the <code>TypeConverter</code>
+     * must be a {@link android.animation.BidirectionalTypeConverter} to retrieve the current
+     * value.
+     *
+     * @param property The property being animated. Should not be null.
+     * @param converter Converts the animated object to the Property type.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see #setConverter(TypeConverter)
+     * @see TypeConverter
+     */
+    public static <T, V> PropertyValuesHolder ofObject(Property<?, V> property,
+            TypeConverter<T, V> converter, TypeEvaluator<T> evaluator, T... values) {
+        PropertyValuesHolder pvh = new PropertyValuesHolder(property);
+        pvh.setConverter(converter);
+        pvh.setObjectValues(values);
+        pvh.setEvaluator(evaluator);
+        return pvh;
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * a Path along which the values should be animated. This variant supports a
+     * <code>TypeConverter</code> to convert from <code>PointF</code> to the target
+     * type.
+     *
+     * <p>The PointF passed to <code>converter</code> or <code>property</code>, if
+     * <code>converter</code> is <code>null</code>, is reused on each animation frame and should
+     * not be stored by the setter or TypeConverter.</p>
+     *
+     * @param property The property being animated. Should not be null.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     */
+    public static <V> PropertyValuesHolder ofObject(Property<?, V> property,
+            TypeConverter<PointF, V> converter, Path path) {
+        PropertyValuesHolder pvh = new PropertyValuesHolder(property);
+        pvh.mKeyframes = KeyframeSet.ofPath(path);
+        pvh.mValueType = PointF.class;
+        pvh.setConverter(converter);
+        return pvh;
+    }
+
+    /**
      * Constructs and returns a PropertyValuesHolder object with the specified property name and set
      * of values. These values can be of any type, but the type should be consistent so that
      * an appropriate {@link android.animation.TypeEvaluator} can be found that matches
@@ -247,17 +524,7 @@
      */
     public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) {
         KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
-        if (keyframeSet instanceof IntKeyframeSet) {
-            return new IntPropertyValuesHolder(propertyName, (IntKeyframeSet) keyframeSet);
-        } else if (keyframeSet instanceof FloatKeyframeSet) {
-            return new FloatPropertyValuesHolder(propertyName, (FloatKeyframeSet) keyframeSet);
-        }
-        else {
-            PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
-            pvh.mKeyframeSet = keyframeSet;
-            pvh.mValueType = ((Keyframe)values[0]).getType();
-            return pvh;
-        }
+        return ofKeyframes(propertyName, keyframeSet);
     }
 
     /**
@@ -278,15 +545,32 @@
      */
     public static PropertyValuesHolder ofKeyframe(Property property, Keyframe... values) {
         KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
-        if (keyframeSet instanceof IntKeyframeSet) {
-            return new IntPropertyValuesHolder(property, (IntKeyframeSet) keyframeSet);
-        } else if (keyframeSet instanceof FloatKeyframeSet) {
-            return new FloatPropertyValuesHolder(property, (FloatKeyframeSet) keyframeSet);
+        return ofKeyframes(property, keyframeSet);
+    }
+
+    static PropertyValuesHolder ofKeyframes(String propertyName, Keyframes keyframes) {
+        if (keyframes instanceof Keyframes.IntKeyframes) {
+            return new IntPropertyValuesHolder(propertyName, (Keyframes.IntKeyframes) keyframes);
+        } else if (keyframes instanceof Keyframes.FloatKeyframes) {
+            return new FloatPropertyValuesHolder(propertyName,
+                    (Keyframes.FloatKeyframes) keyframes);
+        } else {
+            PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
+            pvh.mKeyframes = keyframes;
+            pvh.mValueType = keyframes.getType();
+            return pvh;
         }
-        else {
+    }
+
+    static PropertyValuesHolder ofKeyframes(Property property, Keyframes keyframes) {
+        if (keyframes instanceof Keyframes.IntKeyframes) {
+            return new IntPropertyValuesHolder(property, (Keyframes.IntKeyframes) keyframes);
+        } else if (keyframes instanceof Keyframes.FloatKeyframes) {
+            return new FloatPropertyValuesHolder(property, (Keyframes.FloatKeyframes) keyframes);
+        } else {
             PropertyValuesHolder pvh = new PropertyValuesHolder(property);
-            pvh.mKeyframeSet = keyframeSet;
-            pvh.mValueType = ((Keyframe)values[0]).getType();
+            pvh.mKeyframes = keyframes;
+            pvh.mValueType = keyframes.getType();
             return pvh;
         }
     }
@@ -306,7 +590,7 @@
      */
     public void setIntValues(int... values) {
         mValueType = int.class;
-        mKeyframeSet = KeyframeSet.ofInt(values);
+        mKeyframes = KeyframeSet.ofInt(values);
     }
 
     /**
@@ -324,7 +608,7 @@
      */
     public void setFloatValues(float... values) {
         mValueType = float.class;
-        mKeyframeSet = KeyframeSet.ofFloat(values);
+        mKeyframes = KeyframeSet.ofFloat(values);
     }
 
     /**
@@ -339,7 +623,7 @@
         for (int i = 0; i < numKeyframes; ++i) {
             keyframes[i] = (Keyframe)values[i];
         }
-        mKeyframeSet = new KeyframeSet(keyframes);
+        mKeyframes = new KeyframeSet(keyframes);
     }
 
     /**
@@ -357,7 +641,20 @@
      */
     public void setObjectValues(Object... values) {
         mValueType = values[0].getClass();
-        mKeyframeSet = KeyframeSet.ofObject(values);
+        mKeyframes = KeyframeSet.ofObject(values);
+        if (mEvaluator != null) {
+            mKeyframes.setEvaluator(mEvaluator);
+        }
+    }
+
+    /**
+     * Sets the converter to convert from the values type to the setter's parameter type.
+     * If only one value is supplied, <var>converter</var> must be a
+     * {@link android.animation.BidirectionalTypeConverter}.
+     * @param converter The converter to use to convert values.
+     */
+    public void setConverter(TypeConverter converter) {
+        mConverter = converter;
     }
 
     /**
@@ -389,22 +686,24 @@
         } else {
             args = new Class[1];
             Class typeVariants[];
-            if (mValueType.equals(Float.class)) {
+            if (valueType.equals(Float.class)) {
                 typeVariants = FLOAT_VARIANTS;
-            } else if (mValueType.equals(Integer.class)) {
+            } else if (valueType.equals(Integer.class)) {
                 typeVariants = INTEGER_VARIANTS;
-            } else if (mValueType.equals(Double.class)) {
+            } else if (valueType.equals(Double.class)) {
                 typeVariants = DOUBLE_VARIANTS;
             } else {
                 typeVariants = new Class[1];
-                typeVariants[0] = mValueType;
+                typeVariants[0] = valueType;
             }
             for (Class typeVariant : typeVariants) {
                 args[0] = typeVariant;
                 try {
                     returnVal = targetClass.getMethod(methodName, args);
-                    // change the value type to suit
-                    mValueType = typeVariant;
+                    if (mConverter == null) {
+                        // change the value type to suit
+                        mValueType = typeVariant;
+                    }
                     return returnVal;
                 } catch (NoSuchMethodException e) {
                     // Swallow the error and keep trying other variants
@@ -415,7 +714,7 @@
 
         if (returnVal == null) {
             Log.w("PropertyValuesHolder", "Method " +
-                    getMethodName(prefix, mPropertyName) + "() with type " + mValueType +
+                    getMethodName(prefix, mPropertyName) + "() with type " + valueType +
                     " not found on target class " + targetClass);
         }
 
@@ -465,7 +764,8 @@
      * @param targetClass The Class on which the requested method should exist.
      */
     void setupSetter(Class targetClass) {
-        mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType);
+        Class<?> propertyType = mConverter == null ? mValueType : mConverter.getTargetType();
+        mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", propertyType);
     }
 
     /**
@@ -486,13 +786,21 @@
      * @param target The object on which the setter (and possibly getter) exist.
      */
     void setupSetterAndGetter(Object target) {
+        mKeyframes.invalidateCache();
         if (mProperty != null) {
             // check to make sure that mProperty is on the class of target
             try {
-                Object testValue = mProperty.get(target);
-                for (Keyframe kf : mKeyframeSet.mKeyframes) {
-                    if (!kf.hasValue()) {
-                        kf.setValue(mProperty.get(target));
+                Object testValue = null;
+                ArrayList<Keyframe> keyframes = mKeyframes.getKeyframes();
+                int keyframeCount = keyframes == null ? 0 : keyframes.size();
+                for (int i = 0; i < keyframeCount; i++) {
+                    Keyframe kf = keyframes.get(i);
+                    if (!kf.hasValue() || kf.valueWasSetOnStart()) {
+                        if (testValue == null) {
+                            testValue = convertBack(mProperty.get(target));
+                        }
+                        kf.setValue(testValue);
+                        kf.setValueWasSetOnStart(true);
                     }
                 }
                 return;
@@ -506,8 +814,11 @@
         if (mSetter == null) {
             setupSetter(targetClass);
         }
-        for (Keyframe kf : mKeyframeSet.mKeyframes) {
-            if (!kf.hasValue()) {
+        ArrayList<Keyframe> keyframes = mKeyframes.getKeyframes();
+        int keyframeCount = keyframes == null ? 0 : keyframes.size();
+        for (int i = 0; i < keyframeCount; i++) {
+            Keyframe kf = keyframes.get(i);
+            if (!kf.hasValue() || kf.valueWasSetOnStart()) {
                 if (mGetter == null) {
                     setupGetter(targetClass);
                     if (mGetter == null) {
@@ -516,7 +827,9 @@
                     }
                 }
                 try {
-                    kf.setValue(mGetter.invoke(target));
+                    Object value = convertBack(mGetter.invoke(target));
+                    kf.setValue(value);
+                    kf.setValueWasSetOnStart(true);
                 } catch (InvocationTargetException e) {
                     Log.e("PropertyValuesHolder", e.toString());
                 } catch (IllegalAccessException e) {
@@ -526,6 +839,18 @@
         }
     }
 
+    private Object convertBack(Object value) {
+        if (mConverter != null) {
+            if (!(mConverter instanceof BidirectionalTypeConverter)) {
+                throw new IllegalArgumentException("Converter "
+                        + mConverter.getClass().getName()
+                        + " must be a BidirectionalTypeConverter");
+            }
+            value = ((BidirectionalTypeConverter) mConverter).convertBack(value);
+        }
+        return value;
+    }
+
     /**
      * Utility function to set the value stored in a particular Keyframe. The value used is
      * whatever the value is for the property name specified in the keyframe on the target object.
@@ -535,7 +860,8 @@
      */
     private void setupValue(Object target, Keyframe kf) {
         if (mProperty != null) {
-            kf.setValue(mProperty.get(target));
+            Object value = convertBack(mProperty.get(target));
+            kf.setValue(value);
         }
         try {
             if (mGetter == null) {
@@ -546,7 +872,8 @@
                     return;
                 }
             }
-            kf.setValue(mGetter.invoke(target));
+            Object value = convertBack(mGetter.invoke(target));
+            kf.setValue(value);
         } catch (InvocationTargetException e) {
             Log.e("PropertyValuesHolder", e.toString());
         } catch (IllegalAccessException e) {
@@ -563,7 +890,10 @@
      * @param target The object which holds the start values that should be set.
      */
     void setupStartValue(Object target) {
-        setupValue(target, mKeyframeSet.mKeyframes.get(0));
+        ArrayList<Keyframe> keyframes = mKeyframes.getKeyframes();
+        if (!keyframes.isEmpty()) {
+            setupValue(target, keyframes.get(0));
+        }
     }
 
     /**
@@ -575,7 +905,10 @@
      * @param target The object which holds the start values that should be set.
      */
     void setupEndValue(Object target) {
-        setupValue(target, mKeyframeSet.mKeyframes.get(mKeyframeSet.mKeyframes.size() - 1));
+        ArrayList<Keyframe> keyframes = mKeyframes.getKeyframes();
+        if (!keyframes.isEmpty()) {
+            setupValue(target, keyframes.get(keyframes.size() - 1));
+        }
     }
 
     @Override
@@ -584,7 +917,7 @@
             PropertyValuesHolder newPVH = (PropertyValuesHolder) super.clone();
             newPVH.mPropertyName = mPropertyName;
             newPVH.mProperty = mProperty;
-            newPVH.mKeyframeSet = mKeyframeSet.clone();
+            newPVH.mKeyframes = mKeyframes.clone();
             newPVH.mEvaluator = mEvaluator;
             return newPVH;
         } catch (CloneNotSupportedException e) {
@@ -631,7 +964,7 @@
         if (mEvaluator != null) {
             // KeyframeSet knows how to evaluate the common types - only give it a custom
             // evaluator if one has been set on this class
-            mKeyframeSet.setEvaluator(mEvaluator);
+            mKeyframes.setEvaluator(mEvaluator);
         }
     }
 
@@ -647,7 +980,7 @@
      */
     public void setEvaluator(TypeEvaluator evaluator) {
         mEvaluator = evaluator;
-        mKeyframeSet.setEvaluator(evaluator);
+        mKeyframes.setEvaluator(evaluator);
     }
 
     /**
@@ -657,7 +990,8 @@
      * @param fraction The elapsed, interpolated fraction of the animation.
      */
     void calculateValue(float fraction) {
-        mAnimatedValue = mKeyframeSet.getValue(fraction);
+        Object value = mKeyframes.getValue(fraction);
+        mAnimatedValue = mConverter == null ? value : mConverter.convert(value);
     }
 
     /**
@@ -714,7 +1048,7 @@
 
     @Override
     public String toString() {
-        return mPropertyName + ": " + mKeyframeSet.toString();
+        return mPropertyName + ": " + mKeyframes.toString();
     }
 
     /**
@@ -748,21 +1082,21 @@
         long mJniSetter;
         private IntProperty mIntProperty;
 
-        IntKeyframeSet mIntKeyframeSet;
+        Keyframes.IntKeyframes mIntKeyframes;
         int mIntAnimatedValue;
 
-        public IntPropertyValuesHolder(String propertyName, IntKeyframeSet keyframeSet) {
+        public IntPropertyValuesHolder(String propertyName, Keyframes.IntKeyframes keyframes) {
             super(propertyName);
             mValueType = int.class;
-            mKeyframeSet = keyframeSet;
-            mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
+            mKeyframes = keyframes;
+            mIntKeyframes = keyframes;
         }
 
-        public IntPropertyValuesHolder(Property property, IntKeyframeSet keyframeSet) {
+        public IntPropertyValuesHolder(Property property, Keyframes.IntKeyframes keyframes) {
             super(property);
             mValueType = int.class;
-            mKeyframeSet = keyframeSet;
-            mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
+            mKeyframes = keyframes;
+            mIntKeyframes = keyframes;
             if (property instanceof  IntProperty) {
                 mIntProperty = (IntProperty) mProperty;
             }
@@ -784,12 +1118,12 @@
         @Override
         public void setIntValues(int... values) {
             super.setIntValues(values);
-            mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
+            mIntKeyframes = (Keyframes.IntKeyframes) mKeyframes;
         }
 
         @Override
         void calculateValue(float fraction) {
-            mIntAnimatedValue = mIntKeyframeSet.getIntValue(fraction);
+            mIntAnimatedValue = mIntKeyframes.getIntValue(fraction);
         }
 
         @Override
@@ -800,7 +1134,7 @@
         @Override
         public IntPropertyValuesHolder clone() {
             IntPropertyValuesHolder newPVH = (IntPropertyValuesHolder) super.clone();
-            newPVH.mIntKeyframeSet = (IntKeyframeSet) newPVH.mKeyframeSet;
+            newPVH.mIntKeyframes = (Keyframes.IntKeyframes) newPVH.mKeyframes;
             return newPVH;
         }
 
@@ -885,21 +1219,21 @@
         long mJniSetter;
         private FloatProperty mFloatProperty;
 
-        FloatKeyframeSet mFloatKeyframeSet;
+        Keyframes.FloatKeyframes mFloatKeyframes;
         float mFloatAnimatedValue;
 
-        public FloatPropertyValuesHolder(String propertyName, FloatKeyframeSet keyframeSet) {
+        public FloatPropertyValuesHolder(String propertyName, Keyframes.FloatKeyframes keyframes) {
             super(propertyName);
             mValueType = float.class;
-            mKeyframeSet = keyframeSet;
-            mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
+            mKeyframes = keyframes;
+            mFloatKeyframes = keyframes;
         }
 
-        public FloatPropertyValuesHolder(Property property, FloatKeyframeSet keyframeSet) {
+        public FloatPropertyValuesHolder(Property property, Keyframes.FloatKeyframes keyframes) {
             super(property);
             mValueType = float.class;
-            mKeyframeSet = keyframeSet;
-            mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
+            mKeyframes = keyframes;
+            mFloatKeyframes = keyframes;
             if (property instanceof FloatProperty) {
                 mFloatProperty = (FloatProperty) mProperty;
             }
@@ -921,12 +1255,12 @@
         @Override
         public void setFloatValues(float... values) {
             super.setFloatValues(values);
-            mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
+            mFloatKeyframes = (Keyframes.FloatKeyframes) mKeyframes;
         }
 
         @Override
         void calculateValue(float fraction) {
-            mFloatAnimatedValue = mFloatKeyframeSet.getFloatValue(fraction);
+            mFloatAnimatedValue = mFloatKeyframes.getFloatValue(fraction);
         }
 
         @Override
@@ -937,7 +1271,7 @@
         @Override
         public FloatPropertyValuesHolder clone() {
             FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone();
-            newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet;
+            newPVH.mFloatKeyframes = (Keyframes.FloatKeyframes) newPVH.mKeyframes;
             return newPVH;
         }
 
@@ -1015,8 +1349,263 @@
 
     }
 
+    static class MultiFloatValuesHolder extends PropertyValuesHolder {
+        private long mJniSetter;
+        private static final HashMap<Class, HashMap<String, Long>> sJNISetterPropertyMap =
+                new HashMap<Class, HashMap<String, Long>>();
+
+        public MultiFloatValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, Object... values) {
+            super(propertyName);
+            setConverter(converter);
+            setObjectValues(values);
+            setEvaluator(evaluator);
+        }
+
+        public MultiFloatValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, Keyframes keyframes) {
+            super(propertyName);
+            setConverter(converter);
+            mKeyframes = keyframes;
+            setEvaluator(evaluator);
+        }
+
+        /**
+         * Internal function to set the value on the target object, using the setter set up
+         * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+         * to handle turning the value calculated by ValueAnimator into a value set on the object
+         * according to the name of the property.
+         *
+         * @param target The target object on which the value is set
+         */
+        @Override
+        void setAnimatedValue(Object target) {
+            float[] values = (float[]) getAnimatedValue();
+            int numParameters = values.length;
+            if (mJniSetter != 0) {
+                switch (numParameters) {
+                    case 1:
+                        nCallFloatMethod(target, mJniSetter, values[0]);
+                        break;
+                    case 2:
+                        nCallTwoFloatMethod(target, mJniSetter, values[0], values[1]);
+                        break;
+                    case 4:
+                        nCallFourFloatMethod(target, mJniSetter, values[0], values[1],
+                                values[2], values[3]);
+                        break;
+                    default: {
+                        nCallMultipleFloatMethod(target, mJniSetter, values);
+                        break;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Internal function (called from ObjectAnimator) to set up the setter and getter
+         * prior to running the animation. No getter can be used for multiple parameters.
+         *
+         * @param target The object on which the setter exists.
+         */
+        @Override
+        void setupSetterAndGetter(Object target) {
+            setupSetter(target.getClass());
+        }
+
+        @Override
+        void setupSetter(Class targetClass) {
+            if (mJniSetter != 0) {
+                return;
+            }
+            try {
+                mPropertyMapLock.writeLock().lock();
+                HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass);
+                if (propertyMap != null) {
+                    Long jniSetterLong = propertyMap.get(mPropertyName);
+                    if (jniSetterLong != null) {
+                        mJniSetter = jniSetterLong;
+                    }
+                }
+                if (mJniSetter == 0) {
+                    String methodName = getMethodName("set", mPropertyName);
+                    calculateValue(0f);
+                    float[] values = (float[]) getAnimatedValue();
+                    int numParams = values.length;
+                    try {
+                        mJniSetter = nGetMultipleFloatMethod(targetClass, methodName, numParams);
+                    } catch (NoSuchMethodError e) {
+                        // try without the 'set' prefix
+                        mJniSetter = nGetMultipleFloatMethod(targetClass, mPropertyName, numParams);
+                    }
+                    if (mJniSetter != 0) {
+                        if (propertyMap == null) {
+                            propertyMap = new HashMap<String, Long>();
+                            sJNISetterPropertyMap.put(targetClass, propertyMap);
+                        }
+                        propertyMap.put(mPropertyName, mJniSetter);
+                    }
+                }
+            } finally {
+                mPropertyMapLock.writeLock().unlock();
+            }
+        }
+    }
+
+    static class MultiIntValuesHolder extends PropertyValuesHolder {
+        private long mJniSetter;
+        private static final HashMap<Class, HashMap<String, Long>> sJNISetterPropertyMap =
+                new HashMap<Class, HashMap<String, Long>>();
+
+        public MultiIntValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, Object... values) {
+            super(propertyName);
+            setConverter(converter);
+            setObjectValues(values);
+            setEvaluator(evaluator);
+        }
+
+        public MultiIntValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, Keyframes keyframes) {
+            super(propertyName);
+            setConverter(converter);
+            mKeyframes = keyframes;
+            setEvaluator(evaluator);
+        }
+
+        /**
+         * Internal function to set the value on the target object, using the setter set up
+         * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+         * to handle turning the value calculated by ValueAnimator into a value set on the object
+         * according to the name of the property.
+         *
+         * @param target The target object on which the value is set
+         */
+        @Override
+        void setAnimatedValue(Object target) {
+            int[] values = (int[]) getAnimatedValue();
+            int numParameters = values.length;
+            if (mJniSetter != 0) {
+                switch (numParameters) {
+                    case 1:
+                        nCallIntMethod(target, mJniSetter, values[0]);
+                        break;
+                    case 2:
+                        nCallTwoIntMethod(target, mJniSetter, values[0], values[1]);
+                        break;
+                    case 4:
+                        nCallFourIntMethod(target, mJniSetter, values[0], values[1],
+                                values[2], values[3]);
+                        break;
+                    default: {
+                        nCallMultipleIntMethod(target, mJniSetter, values);
+                        break;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Internal function (called from ObjectAnimator) to set up the setter and getter
+         * prior to running the animation. No getter can be used for multiple parameters.
+         *
+         * @param target The object on which the setter exists.
+         */
+        @Override
+        void setupSetterAndGetter(Object target) {
+            setupSetter(target.getClass());
+        }
+
+        @Override
+        void setupSetter(Class targetClass) {
+            if (mJniSetter != 0) {
+                return;
+            }
+            try {
+                mPropertyMapLock.writeLock().lock();
+                HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass);
+                if (propertyMap != null) {
+                    Long jniSetterLong = propertyMap.get(mPropertyName);
+                    if (jniSetterLong != null) {
+                        mJniSetter = jniSetterLong;
+                    }
+                }
+                if (mJniSetter == 0) {
+                    String methodName = getMethodName("set", mPropertyName);
+                    calculateValue(0f);
+                    int[] values = (int[]) getAnimatedValue();
+                    int numParams = values.length;
+                    try {
+                        mJniSetter = nGetMultipleIntMethod(targetClass, methodName, numParams);
+                    } catch (NoSuchMethodError e) {
+                        // try without the 'set' prefix
+                        mJniSetter = nGetMultipleIntMethod(targetClass, mPropertyName, numParams);
+                    }
+                    if (mJniSetter != 0) {
+                        if (propertyMap == null) {
+                            propertyMap = new HashMap<String, Long>();
+                            sJNISetterPropertyMap.put(targetClass, propertyMap);
+                        }
+                        propertyMap.put(mPropertyName, mJniSetter);
+                    }
+                }
+            } finally {
+                mPropertyMapLock.writeLock().unlock();
+            }
+        }
+    }
+
+    /**
+     * Convert from PointF to float[] for multi-float setters along a Path.
+     */
+    private static class PointFToFloatArray extends TypeConverter<PointF, float[]> {
+        private float[] mCoordinates = new float[2];
+
+        public PointFToFloatArray() {
+            super(PointF.class, float[].class);
+        }
+
+        @Override
+        public float[] convert(PointF value) {
+            mCoordinates[0] = value.x;
+            mCoordinates[1] = value.y;
+            return mCoordinates;
+        }
+    };
+
+    /**
+     * Convert from PointF to int[] for multi-int setters along a Path.
+     */
+    private static class PointFToIntArray extends TypeConverter<PointF, int[]> {
+        private int[] mCoordinates = new int[2];
+
+        public PointFToIntArray() {
+            super(PointF.class, int[].class);
+        }
+
+        @Override
+        public int[] convert(PointF value) {
+            mCoordinates[0] = Math.round(value.x);
+            mCoordinates[1] = Math.round(value.y);
+            return mCoordinates;
+        }
+    };
+
     native static private long nGetIntMethod(Class targetClass, String methodName);
     native static private long nGetFloatMethod(Class targetClass, String methodName);
+    native static private long nGetMultipleIntMethod(Class targetClass, String methodName,
+            int numParams);
+    native static private long nGetMultipleFloatMethod(Class targetClass, String methodName,
+            int numParams);
     native static private void nCallIntMethod(Object target, long methodID, int arg);
     native static private void nCallFloatMethod(Object target, long methodID, float arg);
+    native static private void nCallTwoIntMethod(Object target, long methodID, int arg1, int arg2);
+    native static private void nCallFourIntMethod(Object target, long methodID, int arg1, int arg2,
+            int arg3, int arg4);
+    native static private void nCallMultipleIntMethod(Object target, long methodID, int[] args);
+    native static private void nCallTwoFloatMethod(Object target, long methodID, float arg1,
+            float arg2);
+    native static private void nCallFourFloatMethod(Object target, long methodID, float arg1,
+            float arg2, float arg3, float arg4);
+    native static private void nCallMultipleFloatMethod(Object target, long methodID, float[] args);
 }
diff --git a/core/java/android/animation/RectEvaluator.java b/core/java/android/animation/RectEvaluator.java
index 28d496b..23eb766 100644
--- a/core/java/android/animation/RectEvaluator.java
+++ b/core/java/android/animation/RectEvaluator.java
@@ -23,12 +23,45 @@
 public class RectEvaluator implements TypeEvaluator<Rect> {
 
     /**
+     * When null, a new Rect is returned on every evaluate call. When non-null,
+     * mRect will be modified and returned on every evaluate.
+     */
+    private Rect mRect;
+
+    /**
+     * Construct a RectEvaluator that returns a new Rect on every evaluate call.
+     * To avoid creating an object for each evaluate call,
+     * {@link RectEvaluator#RectEvaluator(android.graphics.Rect)} should be used
+     * whenever possible.
+     */
+    public RectEvaluator() {
+    }
+
+    /**
+     * Constructs a RectEvaluator that modifies and returns <code>reuseRect</code>
+     * in {@link #evaluate(float, android.graphics.Rect, android.graphics.Rect)} calls.
+     * The value returned from
+     * {@link #evaluate(float, android.graphics.Rect, android.graphics.Rect)} should
+     * not be cached because it will change over time as the object is reused on each
+     * call.
+     *
+     * @param reuseRect A Rect to be modified and returned by evaluate.
+     */
+    public RectEvaluator(Rect reuseRect) {
+        mRect = reuseRect;
+    }
+
+    /**
      * This function returns the result of linearly interpolating the start and
      * end Rect values, with <code>fraction</code> representing the proportion
      * between the start and end values. The calculation is a simple parametric
      * calculation on each of the separate components in the Rect objects
      * (left, top, right, and bottom).
      *
+     * <p>If {@link #RectEvaluator(android.graphics.Rect)} was used to construct
+     * this RectEvaluator, the object returned will be the <code>reuseRect</code>
+     * passed into the constructor.</p>
+     *
      * @param fraction   The fraction from the starting to the ending values
      * @param startValue The start Rect
      * @param endValue   The end Rect
@@ -37,9 +70,15 @@
      */
     @Override
     public Rect evaluate(float fraction, Rect startValue, Rect endValue) {
-        return new Rect(startValue.left + (int)((endValue.left - startValue.left) * fraction),
-                startValue.top + (int)((endValue.top - startValue.top) * fraction),
-                startValue.right + (int)((endValue.right - startValue.right) * fraction),
-                startValue.bottom + (int)((endValue.bottom - startValue.bottom) * fraction));
+        int left = startValue.left + (int) ((endValue.left - startValue.left) * fraction);
+        int top = startValue.top + (int) ((endValue.top - startValue.top) * fraction);
+        int right = startValue.right + (int) ((endValue.right - startValue.right) * fraction);
+        int bottom = startValue.bottom + (int) ((endValue.bottom - startValue.bottom) * fraction);
+        if (mRect == null) {
+            return new Rect(left, top, right, bottom);
+        } else {
+            mRect.set(left, top, right, bottom);
+            return mRect;
+        }
     }
 }
diff --git a/core/java/android/animation/RevealAnimator.java b/core/java/android/animation/RevealAnimator.java
new file mode 100644
index 0000000..0f85f4906
--- /dev/null
+++ b/core/java/android/animation/RevealAnimator.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.animation;
+
+import android.view.RenderNodeAnimator;
+import android.view.View;
+
+/**
+ * Reveals a View with an animated clipping circle.
+ * The clipping is implemented efficiently by talking to a private reveal API on View.
+ * This hidden class currently only accessed by the {@link android.view.View}.
+ *
+ * @hide
+ */
+public class RevealAnimator extends RenderNodeAnimator {
+
+    private View mClipView;
+
+    public RevealAnimator(View clipView, int x, int y,
+            float startRadius, float endRadius) {
+        super(x, y, startRadius, endRadius);
+        mClipView = clipView;
+        setTarget(mClipView);
+    }
+
+    @Override
+    protected void onFinished() {
+        mClipView.setRevealClip(false, 0, 0, 0);
+        super.onFinished();
+    }
+
+}
diff --git a/core/java/android/animation/StateListAnimator.java b/core/java/android/animation/StateListAnimator.java
new file mode 100644
index 0000000..7256a06
--- /dev/null
+++ b/core/java/android/animation/StateListAnimator.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.animation;
+
+import android.util.StateSet;
+import android.view.View;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * Lets you define a number of Animators that will run on the attached View depending on the View's
+ * drawable state.
+ * <p>
+ * It can be defined in an XML file with the <code>&lt;selector></code> element.
+ * Each State Animator is defined in a nested <code>&lt;item></code> element.
+ *
+ * @attr ref android.R.styleable#DrawableStates_state_focused
+ * @attr ref android.R.styleable#DrawableStates_state_window_focused
+ * @attr ref android.R.styleable#DrawableStates_state_enabled
+ * @attr ref android.R.styleable#DrawableStates_state_checkable
+ * @attr ref android.R.styleable#DrawableStates_state_checked
+ * @attr ref android.R.styleable#DrawableStates_state_selected
+ * @attr ref android.R.styleable#DrawableStates_state_activated
+ * @attr ref android.R.styleable#DrawableStates_state_active
+ * @attr ref android.R.styleable#DrawableStates_state_single
+ * @attr ref android.R.styleable#DrawableStates_state_first
+ * @attr ref android.R.styleable#DrawableStates_state_middle
+ * @attr ref android.R.styleable#DrawableStates_state_last
+ * @attr ref android.R.styleable#DrawableStates_state_pressed
+ * @attr ref android.R.styleable#StateListAnimatorItem_animation
+ */
+public class StateListAnimator {
+
+    private final ArrayList<Tuple> mTuples = new ArrayList<Tuple>();
+
+    private Tuple mLastMatch = null;
+
+    private Animator mRunningAnimator = null;
+
+    private WeakReference<View> mViewRef;
+
+    private AnimatorListenerAdapter mAnimatorListener = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            animation.setTarget(null);
+            if (mRunningAnimator == animation) {
+                mRunningAnimator = null;
+            }
+        }
+    };
+
+    /**
+     * Associates the given animator with the provided drawable state specs so that it will be run
+     * when the View's drawable state matches the specs.
+     *
+     * @param specs The drawable state specs to match against
+     * @param animator The animator to run when the specs match
+     */
+    public void addState(int[] specs, Animator animator) {
+        Tuple tuple = new Tuple(specs, animator);
+        tuple.mAnimator.addListener(mAnimatorListener);
+        mTuples.add(tuple);
+    }
+
+    /**
+     * Returns the current {@link android.animation.Animator} which is started because of a state
+     * change.
+     *
+     * @return The currently running Animator or null if no Animator is running
+     * @hide
+     */
+    public Animator getRunningAnimator() {
+        return mRunningAnimator;
+    }
+
+    /**
+     * @hide
+     */
+    public View getTarget() {
+        return mViewRef == null ? null : mViewRef.get();
+    }
+
+    /**
+     * Called by View
+     * @hide
+     */
+    public void setTarget(View view) {
+        final View current = getTarget();
+        if (current == view) {
+            return;
+        }
+        if (current != null) {
+            clearTarget();
+        }
+        if (view != null) {
+            mViewRef = new WeakReference<View>(view);
+        }
+
+    }
+
+    private void clearTarget() {
+        final int size = mTuples.size();
+        for (int i = 0; i < size; i++) {
+            mTuples.get(i).mAnimator.setTarget(null);
+        }
+
+        mViewRef = null;
+        mLastMatch = null;
+        mRunningAnimator = null;
+    }
+
+    /**
+     * Called by View
+     * @hide
+     */
+    public void setState(int[] state) {
+        Tuple match = null;
+        final int count = mTuples.size();
+        for (int i = 0; i < count; i++) {
+            final Tuple tuple = mTuples.get(i);
+            if (StateSet.stateSetMatches(tuple.mSpecs, state)) {
+                match = tuple;
+                break;
+            }
+        }
+        if (match == mLastMatch) {
+            return;
+        }
+        if (mLastMatch != null) {
+            cancel();
+        }
+        mLastMatch = match;
+        if (match != null) {
+            start(match);
+        }
+    }
+
+    private void start(Tuple match) {
+        match.mAnimator.setTarget(getTarget());
+        mRunningAnimator = match.mAnimator;
+        mRunningAnimator.start();
+    }
+
+    private void cancel() {
+        if (mRunningAnimator != null) {
+            mRunningAnimator.cancel();
+            mRunningAnimator = null;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public ArrayList<Tuple> getTuples() {
+        return mTuples;
+    }
+
+    /**
+     * If there is an animation running for a recent state change, ends it.
+     * <p>
+     * This causes the animation to assign the end value(s) to the View.
+     */
+    public void jumpToCurrentState() {
+        if (mRunningAnimator != null) {
+            mRunningAnimator.end();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static class Tuple {
+
+        final int[] mSpecs;
+
+        final Animator mAnimator;
+
+        private Tuple(int[] specs, Animator animator) {
+            mSpecs = specs;
+            mAnimator = animator;
+        }
+
+        /**
+         * @hide
+         */
+        public int[] getSpecs() {
+            return mSpecs;
+        }
+
+        /**
+         * @hide
+         */
+        public Animator getAnimator() {
+            return mAnimator;
+        }
+    }
+}
diff --git a/core/java/android/animation/TypeConverter.java b/core/java/android/animation/TypeConverter.java
new file mode 100644
index 0000000..9ead2ad
--- /dev/null
+++ b/core/java/android/animation/TypeConverter.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.animation;
+
+/**
+ * Abstract base class used convert type T to another type V. This
+ * is necessary when the value types of in animation are different
+ * from the property type.
+ * @see PropertyValuesHolder#setConverter(TypeConverter)
+ */
+public abstract class TypeConverter<T, V> {
+    private Class<T> mFromClass;
+    private Class<V> mToClass;
+
+    public TypeConverter(Class<T> fromClass, Class<V> toClass) {
+        mFromClass = fromClass;
+        mToClass = toClass;
+    }
+
+    /**
+     * Returns the target converted type. Used by the animation system to determine
+     * the proper setter function to call.
+     * @return The Class to convert the input to.
+     */
+    Class<V> getTargetType() {
+        return mToClass;
+    }
+
+    /**
+     * Returns the source conversion type.
+     */
+    Class<T> getSourceType() {
+        return mFromClass;
+    }
+
+    /**
+     * Converts a value from one type to another.
+     * @param value The Object to convert.
+     * @return A value of type V, converted from <code>value</code>.
+     */
+    public abstract V convert(T value);
+}
diff --git a/core/java/android/animation/TypeEvaluator.java b/core/java/android/animation/TypeEvaluator.java
index 2640457..429c435 100644
--- a/core/java/android/animation/TypeEvaluator.java
+++ b/core/java/android/animation/TypeEvaluator.java
@@ -29,7 +29,7 @@
     /**
      * This function returns the result of linearly interpolating the start and end values, with
      * <code>fraction</code> representing the proportion between the start and end values. The
-     * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
+     * calculation is a simple parametric calculation: <code>result = x0 + t * (x1 - x0)</code>,
      * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
      * and <code>t</code> is <code>fraction</code>.
      *
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 86da673..9435dfb 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -206,7 +206,7 @@
     /**
      * The set of listeners to be sent events through the life of an animation.
      */
-    private ArrayList<AnimatorUpdateListener> mUpdateListeners = null;
+    ArrayList<AnimatorUpdateListener> mUpdateListeners = null;
 
     /**
      * The property/value sets being animated.
@@ -280,6 +280,24 @@
     }
 
     /**
+     * Constructs and returns a ValueAnimator that animates between color values. A single
+     * value implies that that value is the one being animated to. However, this is not typically
+     * useful in a ValueAnimator object because there is no way for the object to determine the
+     * starting value for the animation (unlike ObjectAnimator, which can derive that value
+     * from the target object and property being animated). Therefore, there should typically
+     * be two or more values.
+     *
+     * @param values A set of values that the animation will animate between over time.
+     * @return A ValueAnimator object that is set up to animate between the given values.
+     */
+    public static ValueAnimator ofArgb(int... values) {
+        ValueAnimator anim = new ValueAnimator();
+        anim.setIntValues(values);
+        anim.setEvaluator(ArgbEvaluator.getInstance());
+        return anim;
+    }
+
+    /**
      * Constructs and returns a ValueAnimator that animates between float values. A single
      * value implies that that value is the one being animated to. However, this is not typically
      * useful in a ValueAnimator object because there is no way for the object to determine the
@@ -1020,6 +1038,7 @@
      * play backwards. This behavior is only set for the current animation; future playing
      * of the animation will use the default behavior of playing forward.
      */
+    @Override
     public void reverse() {
         mPlayingBackwards = !mPlayingBackwards;
         if (mPlayingState == RUNNING) {
@@ -1035,10 +1054,19 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean canReverse() {
+        return true;
+    }
+
+    /**
      * Called internally to end an animation by removing it from the animations list. Must be
      * called on the UI thread.
+     * @hide
      */
-    private void endAnimation(AnimationHandler handler) {
+    protected void endAnimation(AnimationHandler handler) {
         handler.mAnimations.remove(this);
         handler.mPendingAnimations.remove(this);
         handler.mDelayedAnims.remove(this);
@@ -1106,28 +1134,27 @@
         if (!mStartedDelay) {
             mStartedDelay = true;
             mDelayStartTime = currentTime;
-        } else {
-            if (mPaused) {
-                if (mPauseTime < 0) {
-                    mPauseTime = currentTime;
-                }
-                return false;
-            } else if (mResumed) {
-                mResumed = false;
-                if (mPauseTime > 0) {
-                    // Offset by the duration that the animation was paused
-                    mDelayStartTime += (currentTime - mPauseTime);
-                }
+        }
+        if (mPaused) {
+            if (mPauseTime < 0) {
+                mPauseTime = currentTime;
             }
-            long deltaTime = currentTime - mDelayStartTime;
-            if (deltaTime > mStartDelay) {
-                // startDelay ended - start the anim and record the
-                // mStartTime appropriately
-                mStartTime = currentTime - (deltaTime - mStartDelay);
-                mPlayingState = RUNNING;
-                return true;
+            return false;
+        } else if (mResumed) {
+            mResumed = false;
+            if (mPauseTime > 0) {
+                // Offset by the duration that the animation was paused
+                mDelayStartTime += (currentTime - mPauseTime);
             }
         }
+        long deltaTime = currentTime - mDelayStartTime;
+        if (deltaTime > mStartDelay) {
+            // startDelay ended - start the anim and record the
+            // mStartTime appropriately
+            mStartTime = currentTime - (deltaTime - mStartDelay);
+            mPlayingState = RUNNING;
+            return true;
+        }
         return false;
     }
 
@@ -1347,4 +1374,43 @@
         }
         return returnVal;
     }
+
+    /**
+     * <p>Whether or not the ValueAnimator is allowed to run asynchronously off of
+     * the UI thread. This is a hint that informs the ValueAnimator that it is
+     * OK to run the animation off-thread, however ValueAnimator may decide
+     * that it must run the animation on the UI thread anyway. For example if there
+     * is an {@link AnimatorUpdateListener} the animation will run on the UI thread,
+     * regardless of the value of this hint.</p>
+     *
+     * <p>Regardless of whether or not the animation runs asynchronously, all
+     * listener callbacks will be called on the UI thread.</p>
+     *
+     * <p>To be able to use this hint the following must be true:</p>
+     * <ol>
+     * <li>{@link #getAnimatedFraction()} is not needed (it will return undefined values).</li>
+     * <li>The animator is immutable while {@link #isStarted()} is true. Requests
+     *    to change values, duration, delay, etc... may be ignored.</li>
+     * <li>Lifecycle callback events may be asynchronous. Events such as
+     *    {@link Animator.AnimatorListener#onAnimationEnd(Animator)} or
+     *    {@link Animator.AnimatorListener#onAnimationRepeat(Animator)} may end up delayed
+     *    as they must be posted back to the UI thread, and any actions performed
+     *    by those callbacks (such as starting new animations) will not happen
+     *    in the same frame.</li>
+     * <li>State change requests ({@link #cancel()}, {@link #end()}, {@link #reverse()}, etc...)
+     *    may be asynchronous. It is guaranteed that all state changes that are
+     *    performed on the UI thread in the same frame will be applied as a single
+     *    atomic update, however that frame may be the current frame,
+     *    the next frame, or some future frame. This will also impact the observed
+     *    state of the Animator. For example, {@link #isStarted()} may still return true
+     *    after a call to {@link #end()}. Using the lifecycle callbacks is preferred over
+     *    queries to {@link #isStarted()}, {@link #isRunning()}, and {@link #isPaused()}
+     *    for this reason.</li>
+     * </ol>
+     * @hide
+     */
+    @Override
+    public void setAllowRunningAsynchronously(boolean mayRunAsync) {
+        // It is up to subclasses to support this, if they can.
+    }
 }
diff --git a/core/java/android/annotation/AnimRes.java b/core/java/android/annotation/AnimRes.java
new file mode 100644
index 0000000..56f8acf
--- /dev/null
+++ b/core/java/android/annotation/AnimRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be an anim resource reference (e.g. {@link android.R.anim#fade_in}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface AnimRes {
+}
diff --git a/core/java/android/annotation/AnimatorRes.java b/core/java/android/annotation/AnimatorRes.java
new file mode 100644
index 0000000..cd4c189
--- /dev/null
+++ b/core/java/android/annotation/AnimatorRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be an animator resource reference (e.g. {@link android.R.animator#fade_in}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface AnimatorRes {
+}
diff --git a/core/java/android/annotation/AnyRes.java b/core/java/android/annotation/AnyRes.java
new file mode 100644
index 0000000..44411a0
--- /dev/null
+++ b/core/java/android/annotation/AnyRes.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a resource reference of any type. If the specific type is known, use
+ * one of the more specific annotations instead, such as {@link StringRes} or
+ * {@link DrawableRes}.
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface AnyRes {
+}
diff --git a/core/java/android/annotation/ArrayRes.java b/core/java/android/annotation/ArrayRes.java
new file mode 100644
index 0000000..1407af1
--- /dev/null
+++ b/core/java/android/annotation/ArrayRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be an array resource reference (e.g. {@link android.R.array#phoneTypes}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface ArrayRes {
+}
diff --git a/core/java/android/annotation/AttrRes.java b/core/java/android/annotation/AttrRes.java
new file mode 100644
index 0000000..285b80c
--- /dev/null
+++ b/core/java/android/annotation/AttrRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be an attribute reference (e.g. {@link android.R.attr#action}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface AttrRes {
+}
diff --git a/core/java/android/annotation/BoolRes.java b/core/java/android/annotation/BoolRes.java
new file mode 100644
index 0000000..f50785b
--- /dev/null
+++ b/core/java/android/annotation/BoolRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a boolean resource reference.
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface BoolRes {
+}
diff --git a/core/java/android/annotation/ColorRes.java b/core/java/android/annotation/ColorRes.java
new file mode 100644
index 0000000..061faa0
--- /dev/null
+++ b/core/java/android/annotation/ColorRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a color resource reference (e.g. {@link android.R.color#black}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface ColorRes {
+}
diff --git a/core/java/android/annotation/DimenRes.java b/core/java/android/annotation/DimenRes.java
new file mode 100644
index 0000000..02ae00c
--- /dev/null
+++ b/core/java/android/annotation/DimenRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a dimension resource reference (e.g. {@link android.R.dimen#app_icon_size}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface DimenRes {
+}
diff --git a/core/java/android/annotation/DrawableRes.java b/core/java/android/annotation/DrawableRes.java
new file mode 100644
index 0000000..ebefa1d
--- /dev/null
+++ b/core/java/android/annotation/DrawableRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a drawable resource reference (e.g. {@link android.R.attr#alertDialogIcon}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface DrawableRes {
+}
diff --git a/core/java/android/annotation/FractionRes.java b/core/java/android/annotation/FractionRes.java
new file mode 100644
index 0000000..fd84d3e
--- /dev/null
+++ b/core/java/android/annotation/FractionRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a fraction resource reference.
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface FractionRes {
+}
diff --git a/core/java/android/annotation/IdRes.java b/core/java/android/annotation/IdRes.java
new file mode 100644
index 0000000..b286965
--- /dev/null
+++ b/core/java/android/annotation/IdRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be an id resource reference (e.g. {@link android.R.id#copy}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface IdRes {
+}
diff --git a/core/java/android/annotation/IntDef.java b/core/java/android/annotation/IntDef.java
new file mode 100644
index 0000000..3cae9c5
--- /dev/null
+++ b/core/java/android/annotation/IntDef.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element of integer type, represents
+ * a logical type and that its value should be one of the explicitly
+ * named constants. If the {@link #flag()} attribute is set to true,
+ * multiple constants can be combined.
+ * <p>
+ * Example:
+ * <pre>{@code
+ *  &#64;Retention(CLASS)
+ *  &#64;IntDef(&#123;NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS&#125;)
+ *  public &#64;interface NavigationMode &#123;&#125;
+ *  public static final int NAVIGATION_MODE_STANDARD = 0;
+ *  public static final int NAVIGATION_MODE_LIST = 1;
+ *  public static final int NAVIGATION_MODE_TABS = 2;
+ *  ...
+ *  public abstract void setNavigationMode(&#64;NavigationMode int mode);
+ *  &#64;NavigationMode
+ *  public abstract int getNavigationMode();
+ * }</pre>
+ * For a flag, set the flag attribute:
+ * <pre>{@code
+ *  &#64;IntDef(
+ *      flag = true
+ *      value = &#123;NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS&#125;)
+ * }</pre>
+ *
+ * @hide
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE})
+public @interface IntDef {
+    /** Defines the allowed constants for this element */
+    long[] value() default {};
+
+    /** Defines whether the constants can be used as a flag, or just as an enum (the default) */
+    boolean flag() default false;
+}
diff --git a/core/java/android/annotation/IntegerRes.java b/core/java/android/annotation/IntegerRes.java
new file mode 100644
index 0000000..5313f4a
--- /dev/null
+++ b/core/java/android/annotation/IntegerRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be an integer resource reference (e.g. {@link android.R.integer#config_shortAnimTime}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface IntegerRes {
+}
diff --git a/core/java/android/annotation/InterpolatorRes.java b/core/java/android/annotation/InterpolatorRes.java
new file mode 100644
index 0000000..8877a5f
--- /dev/null
+++ b/core/java/android/annotation/InterpolatorRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be an interpolator resource reference (e.g. {@link android.R.interpolator#cycle}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface InterpolatorRes {
+}
diff --git a/core/java/android/annotation/LayoutRes.java b/core/java/android/annotation/LayoutRes.java
new file mode 100644
index 0000000..15ba86f
--- /dev/null
+++ b/core/java/android/annotation/LayoutRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a layout resource reference (e.g. {@link android.R.layout#list_content}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface LayoutRes {
+}
diff --git a/core/java/android/annotation/MenuRes.java b/core/java/android/annotation/MenuRes.java
new file mode 100644
index 0000000..b6dcc46
--- /dev/null
+++ b/core/java/android/annotation/MenuRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a menu resource reference.
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface MenuRes {
+}
diff --git a/core/java/android/annotation/NonNull.java b/core/java/android/annotation/NonNull.java
new file mode 100644
index 0000000..3ca9eea
--- /dev/null
+++ b/core/java/android/annotation/NonNull.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that a parameter, field or method return value can never be null.
+ * <p>
+ * This is a marker annotation and it has no specific attributes.
+ *
+ * @hide
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface NonNull {
+}
diff --git a/core/java/android/annotation/Nullable.java b/core/java/android/annotation/Nullable.java
new file mode 100644
index 0000000..43f42fa
--- /dev/null
+++ b/core/java/android/annotation/Nullable.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that a parameter, field or method return value can be null.
+ * <p>
+ * When decorating a method call parameter, this denotes that the parameter can
+ * legitimately be null and the method will gracefully deal with it. Typically
+ * used on optional parameters.
+ * <p>
+ * When decorating a method, this denotes the method might legitimately return
+ * null.
+ * <p>
+ * This is a marker annotation and it has no specific attributes.
+ *
+ * @hide
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface Nullable {
+}
diff --git a/core/java/android/annotation/PluralsRes.java b/core/java/android/annotation/PluralsRes.java
new file mode 100644
index 0000000..31ac729
--- /dev/null
+++ b/core/java/android/annotation/PluralsRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a plurals resource reference.
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface PluralsRes {
+}
diff --git a/core/java/android/annotation/PrivateApi.java b/core/java/android/annotation/PrivateApi.java
deleted file mode 100644
index 985eafe..0000000
--- a/core/java/android/annotation/PrivateApi.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Indicates an API is exposed for use by bundled applications.
- * <p>
- * These APIs are not guaranteed to remain consistent release-to-release,
- * and are not for use by apps linking against the SDK.
- * @hide
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface PrivateApi {
-}
diff --git a/core/java/android/annotation/RawRes.java b/core/java/android/annotation/RawRes.java
new file mode 100644
index 0000000..39970b3
--- /dev/null
+++ b/core/java/android/annotation/RawRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a raw resource reference.
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface RawRes {
+}
diff --git a/core/java/android/annotation/StringDef.java b/core/java/android/annotation/StringDef.java
new file mode 100644
index 0000000..5f7f380
--- /dev/null
+++ b/core/java/android/annotation/StringDef.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated String element, represents a logical
+ * type and that its value should be one of the explicitly named constants.
+ * <p>
+ * Example:
+ * <pre>{@code
+ *  &#64;Retention(SOURCE)
+ *  &#64;StringDef(&#123;
+ *     POWER_SERVICE,
+ *     WINDOW_SERVICE,
+ *     LAYOUT_INFLATER_SERVICE
+ *  &#125;)
+ *  public &#64;interface ServiceName &#123;&#125;
+ *  public static final String POWER_SERVICE = "power";
+ *  public static final String WINDOW_SERVICE = "window";
+ *  public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
+ *  ...
+ *  public abstract Object getSystemService(&#64;ServiceName String name);
+ * }</pre>
+ *
+ * @hide
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE})
+public @interface StringDef {
+    /** Defines the allowed constants for this element */
+    String[] value() default {};
+}
diff --git a/core/java/android/annotation/StringRes.java b/core/java/android/annotation/StringRes.java
new file mode 100644
index 0000000..190b68a
--- /dev/null
+++ b/core/java/android/annotation/StringRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a String resource reference (e.g. {@link android.R.string#ok}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface StringRes {
+}
diff --git a/core/java/android/annotation/StyleRes.java b/core/java/android/annotation/StyleRes.java
new file mode 100644
index 0000000..4453b8d
--- /dev/null
+++ b/core/java/android/annotation/StyleRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that a integer parameter, field or method return value is expected
+ * to be a style resource reference (e.g. {@link android.R.style#TextAppearance}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface StyleRes {
+}
diff --git a/core/java/android/annotation/StyleableRes.java b/core/java/android/annotation/StyleableRes.java
new file mode 100644
index 0000000..3c1895e
--- /dev/null
+++ b/core/java/android/annotation/StyleableRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that a integer parameter, field or method return value is expected
+ * to be a styleable resource reference (e.g. {@link android.R.styleable#TextView_text}).
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface StyleableRes {
+}
diff --git a/core/java/android/annotation/SystemApi.java b/core/java/android/annotation/SystemApi.java
new file mode 100644
index 0000000..55028eb
--- /dev/null
+++ b/core/java/android/annotation/SystemApi.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.annotation;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates an API is exposed for use by bundled system applications.
+ * <p>
+ * These APIs are not guaranteed to remain consistent release-to-release,
+ * and are not for use by apps linking against the Android SDK.
+ * </p><p>
+ * This annotation should only appear on API that is already marked <pre>@hide</pre>.
+ * </p>
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface SystemApi {
+}
diff --git a/core/java/android/annotation/XmlRes.java b/core/java/android/annotation/XmlRes.java
new file mode 100644
index 0000000..5fb8a4a
--- /dev/null
+++ b/core/java/android/annotation/XmlRes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be an XML resource reference.
+ *
+ * {@hide}
+ */
+@Documented
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface XmlRes {
+}
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index c4ddf1f..014a7af 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -16,39 +16,74 @@
 
 package android.app;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.view.ActionMode;
 import android.view.Gravity;
+import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.ViewGroup.MarginLayoutParams;
 import android.view.Window;
 import android.widget.SpinnerAdapter;
+import android.widget.Toolbar;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Map;
 
 /**
- * A window feature at the top of the activity that may display the activity title, navigation
- * modes, and other interactive items.
+ * A primary toolbar within the activity that may display the activity title, application-level
+ * navigation affordances, and other interactive items.
+ *
  * <p>Beginning with Android 3.0 (API level 11), the action bar appears at the top of an
  * activity's window when the activity uses the system's {@link
  * android.R.style#Theme_Holo Holo} theme (or one of its descendant themes), which is the default.
  * You may otherwise add the action bar by calling {@link
  * android.view.Window#requestFeature requestFeature(FEATURE_ACTION_BAR)} or by declaring it in a
  * custom theme with the {@link android.R.styleable#Theme_windowActionBar windowActionBar} property.
- * <p>By default, the action bar shows the application icon on
+ * </p>
+ *
+ * <p>Beginning with Android L (API level 21), the action bar may be represented by any
+ * Toolbar widget within the application layout. The application may signal to the Activity
+ * which Toolbar should be treated as the Activity's action bar. Activities that use this
+ * feature should use one of the supplied <code>.NoActionBar</code> themes, set the
+ * {@link android.R.styleable#Theme_windowActionBar windowActionBar} attribute to <code>false</code>
+ * or otherwise not request the window feature.</p>
+ *
+ * <p>By adjusting the window features requested by the theme and the layouts used for
+ * an Activity's content view, an app can use the standard system action bar on older platform
+ * releases and the newer inline toolbars on newer platform releases. The <code>ActionBar</code>
+ * object obtained from the Activity can be used to control either configuration transparently.</p>
+ *
+ * <p>When using the Holo themes the action bar shows the application icon on
  * the left, followed by the activity title. If your activity has an options menu, you can make
  * select items accessible directly from the action bar as "action items". You can also
  * modify various characteristics of the action bar or remove it completely.</p>
+ *
+ * <p>When using the Material themes (default in API 21 or newer) the navigation button
+ * (formerly "Home") takes over the space previously occupied by the application icon.
+ * Apps wishing to express a stronger branding should use their brand colors heavily
+ * in the action bar and other application chrome or use a {@link #setLogo(int) logo}
+ * in place of their standard title text.</p>
+ *
  * <p>From your activity, you can retrieve an instance of {@link ActionBar} by calling {@link
  * android.app.Activity#getActionBar getActionBar()}.</p>
+ *
  * <p>In some cases, the action bar may be overlayed by another bar that enables contextual actions,
  * using an {@link android.view.ActionMode}. For example, when the user selects one or more items in
  * your activity, you can enable an action mode that offers actions specific to the selected
  * items, with a UI that temporarily replaces the action bar. Although the UI may occupy the
  * same space, the {@link android.view.ActionMode} APIs are distinct and independent from those for
- * {@link ActionBar}.
+ * {@link ActionBar}.</p>
+ *
  * <div class="special reference">
  * <h3>Developer Guides</h3>
  * <p>For information about how to use the action bar, including how to add action items, navigation
@@ -57,11 +92,21 @@
  * </div>
  */
 public abstract class ActionBar {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
+    public @interface NavigationMode {}
+
     /**
      * Standard navigation mode. Consists of either a logo or icon
      * and title text with an optional subtitle. Clicking any of these elements
      * will dispatch onOptionsItemSelected to the host Activity with
      * a MenuItem with item ID android.R.id.home.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public static final int NAVIGATION_MODE_STANDARD = 0;
     
@@ -69,15 +114,38 @@
      * List navigation mode. Instead of static title text this mode
      * presents a list menu for navigation within the activity.
      * e.g. this might be presented to the user as a dropdown list.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public static final int NAVIGATION_MODE_LIST = 1;
     
     /**
      * Tab navigation mode. Instead of static title text this mode
      * presents a series of tabs for navigation within the activity.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public static final int NAVIGATION_MODE_TABS = 2;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true,
+            value = {
+                    DISPLAY_USE_LOGO,
+                    DISPLAY_SHOW_HOME,
+                    DISPLAY_HOME_AS_UP,
+                    DISPLAY_SHOW_TITLE,
+                    DISPLAY_SHOW_CUSTOM,
+                    DISPLAY_TITLE_MULTIPLE_LINES
+            })
+    public @interface DisplayOptions {}
+
     /**
      * Use logo instead of icon if available. This flag will cause appropriate
      * navigation modes to use a wider logo in place of the standard icon.
@@ -264,6 +332,11 @@
      *                within the dropdown navigation menu.
      * @param callback An OnNavigationListener that will receive events when the user
      *                 selects a navigation item.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract void setListNavigationCallbacks(SpinnerAdapter adapter,
             OnNavigationListener callback);
@@ -272,6 +345,11 @@
      * Set the selected navigation item in list or tabbed navigation modes.
      *
      * @param position Position of the item to select.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract void setSelectedNavigationItem(int position);
 
@@ -279,6 +357,11 @@
      * Get the position of the selected navigation item in list or tabbed navigation modes.
      *
      * @return Position of the selected item.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract int getSelectedNavigationIndex();
 
@@ -286,6 +369,11 @@
      * Get the number of navigation items present in the current navigation mode.
      *
      * @return Number of navigation items.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract int getNavigationItemCount();
 
@@ -341,7 +429,7 @@
      * @param options A combination of the bits defined by the DISPLAY_ constants
      *                defined in ActionBar.
      */
-    public abstract void setDisplayOptions(int options);
+    public abstract void setDisplayOptions(@DisplayOptions int options);
     
     /**
      * Set selected display options. Only the options specified by mask will be changed.
@@ -356,7 +444,7 @@
      *                defined in ActionBar.
      * @param mask A bit mask declaring which display options should be changed.
      */
-    public abstract void setDisplayOptions(int options, int mask);
+    public abstract void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask);
 
     /**
      * Set whether to display the activity logo rather than the activity icon.
@@ -431,7 +519,7 @@
      * @see #setStackedBackgroundDrawable(Drawable)
      * @see #setSplitBackgroundDrawable(Drawable)
      */
-    public abstract void setBackgroundDrawable(Drawable d);
+    public abstract void setBackgroundDrawable(@Nullable Drawable d);
 
     /**
      * Set the ActionBar's stacked background. This will appear
@@ -483,7 +571,13 @@
      * </ul>
      *
      * @return The current navigation mode.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
+    @NavigationMode
     public abstract int getNavigationMode();
 
     /**
@@ -493,8 +587,13 @@
      * @see #NAVIGATION_MODE_STANDARD
      * @see #NAVIGATION_MODE_LIST
      * @see #NAVIGATION_MODE_TABS
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
-    public abstract void setNavigationMode(int mode);
+    public abstract void setNavigationMode(@NavigationMode int mode);
 
     /**
      * @return The current set of display options. 
@@ -514,6 +613,11 @@
      * @return A new Tab
      *
      * @see #addTab(Tab)
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract Tab newTab();
 
@@ -522,6 +626,11 @@
      * If this is the first tab to be added it will become the selected tab.
      *
      * @param tab Tab to add
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract void addTab(Tab tab);
 
@@ -530,6 +639,11 @@
      *
      * @param tab Tab to add
      * @param setSelected True if the added tab should become the selected tab.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract void addTab(Tab tab, boolean setSelected);
 
@@ -540,6 +654,11 @@
      *
      * @param tab The tab to add
      * @param position The new position of the tab
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract void addTab(Tab tab, int position);
 
@@ -550,6 +669,11 @@
      * @param tab The tab to add
      * @param position The new position of the tab
      * @param setSelected True if the added tab should become the selected tab.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract void addTab(Tab tab, int position, boolean setSelected);
 
@@ -558,6 +682,11 @@
      * and another tab will be selected if present.
      *
      * @param tab The tab to remove
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract void removeTab(Tab tab);
 
@@ -566,11 +695,21 @@
      * and another tab will be selected if present.
      *
      * @param position Position of the tab to remove
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract void removeTabAt(int position);
 
     /**
      * Remove all tabs from the action bar and deselect the current tab.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract void removeAllTabs();
 
@@ -580,6 +719,11 @@
      * <p>Note: If you want to select by index, use {@link #setSelectedNavigationItem(int)}.</p>
      *
      * @param tab Tab to select
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract void selectTab(Tab tab);
 
@@ -588,6 +732,11 @@
      * one tab present.
      *
      * @return The currently selected tab or null
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract Tab getSelectedTab();
 
@@ -596,12 +745,22 @@
      *
      * @param index Index value in the range 0-get
      * @return
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract Tab getTabAt(int index);
 
     /**
      * Returns the number of tabs currently registered with the action bar.
      * @return Tab count
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public abstract int getTabCount();
 
@@ -775,7 +934,144 @@
     public void setHomeActionContentDescription(int resId) { }
 
     /**
+     * Enable hiding the action bar on content scroll.
+     *
+     * <p>If enabled, the action bar will scroll out of sight along with a
+     * {@link View#setNestedScrollingEnabled(boolean) nested scrolling child} view's content.
+     * The action bar must be in {@link Window#FEATURE_ACTION_BAR_OVERLAY overlay mode}
+     * to enable hiding on content scroll.</p>
+     *
+     * <p>When partially scrolled off screen the action bar is considered
+     * {@link #hide() hidden}. A call to {@link #show() show} will cause it to return to full view.
+     * </p>
+     * @param hideOnContentScroll true to enable hiding on content scroll.
+     */
+    public void setHideOnContentScrollEnabled(boolean hideOnContentScroll) {
+        if (hideOnContentScroll) {
+            throw new UnsupportedOperationException("Hide on content scroll is not supported in " +
+                    "this action bar configuration.");
+        }
+    }
+
+    /**
+     * Return whether the action bar is configured to scroll out of sight along with
+     * a {@link View#setNestedScrollingEnabled(boolean) nested scrolling child}.
+     *
+     * @return true if hide-on-content-scroll is enabled
+     * @see #setHideOnContentScrollEnabled(boolean)
+     */
+    public boolean isHideOnContentScrollEnabled() {
+        return false;
+    }
+
+    /**
+     * Return the current vertical offset of the action bar.
+     *
+     * <p>The action bar's current hide offset is the distance that the action bar is currently
+     * scrolled offscreen in pixels. The valid range is 0 (fully visible) to the action bar's
+     * current measured {@link #getHeight() height} (fully invisible).</p>
+     *
+     * @return The action bar's offset toward its fully hidden state in pixels
+     */
+    public int getHideOffset() {
+        return 0;
+    }
+
+    /**
+     * Set the current hide offset of the action bar.
+     *
+     * <p>The action bar's current hide offset is the distance that the action bar is currently
+     * scrolled offscreen in pixels. The valid range is 0 (fully visible) to the action bar's
+     * current measured {@link #getHeight() height} (fully invisible).</p>
+     *
+     * @param offset The action bar's offset toward its fully hidden state in pixels.
+     */
+    public void setHideOffset(int offset) {
+        if (offset != 0) {
+            throw new UnsupportedOperationException("Setting an explicit action bar hide offset " +
+                    "is not supported in this action bar configuration.");
+        }
+    }
+
+    /**
+     * Set the Z-axis elevation of the action bar in pixels.
+     *
+     * <p>The action bar's elevation is the distance it is placed from its parent surface. Higher
+     * values are closer to the user.</p>
+     *
+     * @param elevation Elevation value in pixels
+     */
+    public void setElevation(float elevation) {
+        if (elevation != 0) {
+            throw new UnsupportedOperationException("Setting a non-zero elevation is " +
+                    "not supported in this action bar configuration.");
+        }
+    }
+
+    /**
+     * Get the Z-axis elevation of the action bar in pixels.
+     *
+     * <p>The action bar's elevation is the distance it is placed from its parent surface. Higher
+     * values are closer to the user.</p>
+     *
+     * @return Elevation value in pixels
+     */
+    public float getElevation() {
+        return 0;
+    }
+
+    /** @hide */
+    public void setDefaultDisplayHomeAsUpEnabled(boolean enabled) {
+    }
+
+    /** @hide */
+    public void setShowHideAnimationEnabled(boolean enabled) {
+    }
+
+    /** @hide */
+    public void onConfigurationChanged(Configuration config) {
+    }
+
+    /** @hide */
+    public void dispatchMenuVisibilityChanged(boolean visible) {
+    }
+
+    /** @hide */
+    public ActionMode startActionMode(ActionMode.Callback callback) {
+        return null;
+    }
+
+    /** @hide */
+    public boolean openOptionsMenu() {
+        return false;
+    }
+
+    /** @hide */
+    public boolean invalidateOptionsMenu() {
+        return false;
+    }
+
+    /** @hide */
+    public boolean onMenuKeyEvent(KeyEvent event) {
+        return false;
+    }
+
+    /** @hide */
+    public boolean collapseActionView() {
+        return false;
+    }
+
+    /** @hide */
+    public void setWindowTitle(CharSequence title) {
+    }
+
+    /**
      * Listener interface for ActionBar navigation events.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public interface OnNavigationListener {
         /**
@@ -808,6 +1104,11 @@
      * A tab in the action bar.
      *
      * <p>Tabs manage the hiding and showing of {@link Fragment}s.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public static abstract class Tab {
         /**
@@ -959,6 +1260,11 @@
 
     /**
      * Callback interface invoked when a tab is focused, unfocused, added, or removed.
+     *
+     * @deprecated Action bar navigation modes are deprecated and not supported by inline
+     * toolbar action bars. Consider using other
+     * <a href="http://developer.android.com/design/patterns/navigation.html">common
+     * navigation patterns</a> instead.
      */
     public interface TabListener {
         /**
@@ -1000,31 +1306,31 @@
      *
      * @attr ref android.R.styleable#ActionBar_LayoutParams_layout_gravity
      */
-    public static class LayoutParams extends MarginLayoutParams {
+    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
         /**
          * Gravity for the view associated with these LayoutParams.
          *
          * @see android.view.Gravity
          */
         @ViewDebug.ExportedProperty(category = "layout", mapping = {
-            @ViewDebug.IntToString(from =  -1,                       to = "NONE"),
-            @ViewDebug.IntToString(from = Gravity.NO_GRAVITY,        to = "NONE"),
-            @ViewDebug.IntToString(from = Gravity.TOP,               to = "TOP"),
-            @ViewDebug.IntToString(from = Gravity.BOTTOM,            to = "BOTTOM"),
-            @ViewDebug.IntToString(from = Gravity.LEFT,              to = "LEFT"),
-            @ViewDebug.IntToString(from = Gravity.RIGHT,             to = "RIGHT"),
-            @ViewDebug.IntToString(from = Gravity.START,             to = "START"),
-            @ViewDebug.IntToString(from = Gravity.END,               to = "END"),
-            @ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL,   to = "CENTER_VERTICAL"),
-            @ViewDebug.IntToString(from = Gravity.FILL_VERTICAL,     to = "FILL_VERTICAL"),
-            @ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"),
-            @ViewDebug.IntToString(from = Gravity.FILL_HORIZONTAL,   to = "FILL_HORIZONTAL"),
-            @ViewDebug.IntToString(from = Gravity.CENTER,            to = "CENTER"),
-            @ViewDebug.IntToString(from = Gravity.FILL,              to = "FILL")
+                @ViewDebug.IntToString(from =  -1,                       to = "NONE"),
+                @ViewDebug.IntToString(from = Gravity.NO_GRAVITY,        to = "NONE"),
+                @ViewDebug.IntToString(from = Gravity.TOP,               to = "TOP"),
+                @ViewDebug.IntToString(from = Gravity.BOTTOM,            to = "BOTTOM"),
+                @ViewDebug.IntToString(from = Gravity.LEFT,              to = "LEFT"),
+                @ViewDebug.IntToString(from = Gravity.RIGHT,             to = "RIGHT"),
+                @ViewDebug.IntToString(from = Gravity.START,             to = "START"),
+                @ViewDebug.IntToString(from = Gravity.END,               to = "END"),
+                @ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL,   to = "CENTER_VERTICAL"),
+                @ViewDebug.IntToString(from = Gravity.FILL_VERTICAL,     to = "FILL_VERTICAL"),
+                @ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"),
+                @ViewDebug.IntToString(from = Gravity.FILL_HORIZONTAL,   to = "FILL_HORIZONTAL"),
+                @ViewDebug.IntToString(from = Gravity.CENTER,            to = "CENTER"),
+                @ViewDebug.IntToString(from = Gravity.FILL,              to = "FILL")
         })
         public int gravity = Gravity.NO_GRAVITY;
 
-        public LayoutParams(Context c, AttributeSet attrs) {
+        public LayoutParams(@NonNull Context c, AttributeSet attrs) {
             super(c, attrs);
 
             TypedArray a = c.obtainStyledAttributes(attrs,
@@ -1042,6 +1348,7 @@
 
         public LayoutParams(int width, int height, int gravity) {
             super(width, height);
+
             this.gravity = gravity;
         }
 
@@ -1051,12 +1358,21 @@
 
         public LayoutParams(LayoutParams source) {
             super(source);
-
             this.gravity = source.gravity;
         }
 
         public LayoutParams(ViewGroup.LayoutParams source) {
             super(source);
         }
+
+        /*
+         * Note for framework developers:
+         *
+         * You might notice that ActionBar.LayoutParams is missing a constructor overload
+         * for MarginLayoutParams. While it may seem like a good idea to add one, at this
+         * point it's dangerous for source compatibility. Upon building against a new
+         * version of the SDK an app can end up statically linking to the new MarginLayoutParams
+         * overload, causing a crash when running on older platform versions with no other changes.
+         */
     }
 }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e8b3bb9c..9f683e3 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,11 +16,23 @@
 
 package android.app;
 
+import android.annotation.NonNull;
+import android.os.PersistableBundle;
+import android.transition.Scene;
+import android.transition.TransitionManager;
 import android.util.ArrayMap;
 import android.util.SuperNotCalledException;
-import com.android.internal.app.ActionBarImpl;
+import android.widget.Toolbar;
+
+import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.app.WindowDecorActionBar;
+import com.android.internal.app.ToolbarActionBar;
 import com.android.internal.policy.PolicyManager;
 
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.admin.DevicePolicyManager;
 import android.content.ComponentCallbacks2;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -41,6 +53,7 @@
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
+import android.media.session.MediaController;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -84,6 +97,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
 
@@ -97,14 +112,14 @@
  * or embedded inside of another activity (using {@link ActivityGroup}).
  *
  * There are two methods almost all subclasses of Activity will implement:
- * 
+ *
  * <ul>
  *     <li> {@link #onCreate} is where you initialize your activity.  Most
  *     importantly, here you will usually call {@link #setContentView(int)}
  *     with a layout resource defining your UI, and using {@link #findViewById}
  *     to retrieve the widgets in that UI that you need to interact with
  *     programmatically.
- * 
+ *
  *     <li> {@link #onPause} is where you deal with the user leaving your
  *     activity.  Most importantly, any changes made by the user should at this
  *     point be committed (usually to the
@@ -115,7 +130,7 @@
  * activity classes must have a corresponding
  * {@link android.R.styleable#AndroidManifestActivity &lt;activity&gt;}
  * declaration in their package's <code>AndroidManifest.xml</code>.</p>
- * 
+ *
  * <p>Topics covered here:
  * <ol>
  * <li><a href="#Fragments">Fragments</a>
@@ -158,14 +173,14 @@
  * and becomes the running activity -- the previous activity always remains
  * below it in the stack, and will not come to the foreground again until
  * the new activity exits.</p>
- * 
+ *
  * <p>An activity has essentially four states:</p>
  * <ul>
  *     <li> If an activity in the foreground of the screen (at the top of
  *         the stack),
  *         it is <em>active</em> or  <em>running</em>. </li>
  *     <li>If an activity has lost focus but is still visible (that is, a new non-full-sized
- *         or transparent activity has focus on top of your activity), it 
+ *         or transparent activity has focus on top of your activity), it
  *         is <em>paused</em>. A paused activity is completely alive (it
  *         maintains all state and member information and remains attached to
  *         the window manager), but can be killed by the system in extreme
@@ -185,13 +200,13 @@
  * The square rectangles represent callback methods you can implement to
  * perform operations when the Activity moves between states.  The colored
  * ovals are major states the Activity can be in.</p>
- * 
+ *
  * <p><img src="../../../images/activity_lifecycle.png"
  *      alt="State diagram for an Android Activity Lifecycle." border="0" /></p>
- * 
+ *
  * <p>There are three key loops you may be interested in monitoring within your
  * activity:
- * 
+ *
  * <ul>
  * <li>The <b>entire lifetime</b> of an activity happens between the first call
  * to {@link android.app.Activity#onCreate} through to a single final call
@@ -200,7 +215,7 @@
  * onDestroy().  For example, if it has a thread running in the background
  * to download data from the network, it may create that thread in onCreate()
  * and then stop the thread in onDestroy().
- * 
+ *
  * <li>The <b>visible lifetime</b> of an activity happens between a call to
  * {@link android.app.Activity#onStart} until a corresponding call to
  * {@link android.app.Activity#onStop}.  During this time the user can see the
@@ -212,7 +227,7 @@
  * longer sees what you are displaying.  The onStart() and onStop() methods
  * can be called multiple times, as the activity becomes visible and hidden
  * to the user.
- * 
+ *
  * <li>The <b>foreground lifetime</b> of an activity happens between a call to
  * {@link android.app.Activity#onResume} until a corresponding call to
  * {@link android.app.Activity#onPause}.  During this time the activity is
@@ -222,7 +237,7 @@
  * intent is delivered -- so the code in these methods should be fairly
  * lightweight.
  * </ul>
- * 
+ *
  * <p>The entire lifecycle of an activity is defined by the following
  * Activity methods.  All of these are hooks that you can override
  * to do appropriate work when the activity changes state.  All
@@ -238,7 +253,7 @@
  *     protected void onCreate(Bundle savedInstanceState);
  *
  *     protected void onStart();
- *     
+ *
  *     protected void onRestart();
  *
  *     protected void onResume();
@@ -354,7 +369,7 @@
  * {@link #onSaveInstanceState(Bundle)} is called before placing the activity
  * in such a background state, allowing you to save away any dynamic instance
  * state in your activity into the given Bundle, to be later received in
- * {@link #onCreate} if the activity needs to be re-created.  
+ * {@link #onCreate} if the activity needs to be re-created.
  * See the <a href="#ProcessLifecycle">Process Lifecycle</a>
  * section for more information on how the lifecycle of a process is tied
  * to the activities it is hosting.  Note that it is important to save
@@ -378,14 +393,14 @@
  *
  * <a name="ConfigurationChanges"></a>
  * <h3>Configuration Changes</h3>
- * 
+ *
  * <p>If the configuration of the device (as defined by the
  * {@link Configuration Resources.Configuration} class) changes,
  * then anything displaying a user interface will need to update to match that
  * configuration.  Because Activity is the primary mechanism for interacting
  * with the user, it includes special support for handling configuration
  * changes.</p>
- * 
+ *
  * <p>Unless you specify otherwise, a configuration change (such as a change
  * in screen orientation, language, input devices, etc) will cause your
  * current activity to be <em>destroyed</em>, going through the normal activity
@@ -395,7 +410,7 @@
  * called in that instance then a new instance of the activity will be
  * created, with whatever savedInstanceState the previous instance had generated
  * from {@link #onSaveInstanceState}.</p>
- * 
+ *
  * <p>This is done because any application resource,
  * including layout files, can change based on any configuration value.  Thus
  * the only safe way to handle a configuration change is to re-retrieve all
@@ -403,7 +418,7 @@
  * must already know how to save their state and re-create themselves from
  * that state, this is a convenient way to have an activity restart itself
  * with a new configuration.</p>
- * 
+ *
  * <p>In some special cases, you may want to bypass restarting of your
  * activity based on one or more types of configuration changes.  This is
  * done with the {@link android.R.attr#configChanges android:configChanges}
@@ -413,7 +428,7 @@
  * a configuration change involves any that you do not handle, however, the
  * activity will still be restarted and {@link #onConfigurationChanged}
  * will not be called.</p>
- * 
+ *
  * <a name="StartingActivities"></a>
  * <h3>Starting Activities and Getting Results</h3>
  *
@@ -428,10 +443,10 @@
  * ends.  For example, you may start an activity that lets the user pick
  * a person in a list of contacts; when it ends, it returns the person
  * that was selected.  To do this, you call the
- * {@link android.app.Activity#startActivityForResult(Intent, int)} 
- * version with a second integer parameter identifying the call.  The result 
+ * {@link android.app.Activity#startActivityForResult(Intent, int)}
+ * version with a second integer parameter identifying the call.  The result
  * will come back through your {@link android.app.Activity#onActivityResult}
- * method.</p> 
+ * method.</p>
  *
  * <p>When an activity exits, it can call
  * {@link android.app.Activity#setResult(int)}
@@ -452,7 +467,7 @@
  *
  *     static final int PICK_CONTACT_REQUEST = 0;
  *
- *     protected boolean onKeyDown(int keyCode, KeyEvent event) {
+ *     public boolean onKeyDown(int keyCode, KeyEvent event) {
  *         if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
  *             // When the user center presses, let them pick a contact.
  *             startActivityForResult(
@@ -558,17 +573,17 @@
  *
  *     protected void onPause() {
  *         super.onPause();
- * 
+ *
  *         SharedPreferences.Editor ed = mPrefs.edit();
  *         ed.putInt("view_mode", mCurViewMode);
  *         ed.commit();
  *     }
  * }
  * </pre>
- * 
+ *
  * <a name="Permissions"></a>
  * <h3>Permissions</h3>
- * 
+ *
  * <p>The ability to start a particular Activity can be enforced when it is
  * declared in its
  * manifest's {@link android.R.styleable#AndroidManifestActivity &lt;activity&gt;}
@@ -589,10 +604,10 @@
  *
  * <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>
  * document for more information on permissions and security in general.
- * 
+ *
  * <a name="ProcessLifecycle"></a>
  * <h3>Process Lifecycle</h3>
- * 
+ *
  * <p>The Android system attempts to keep application process around for as
  * long as possible, but eventually will need to remove old processes when
  * memory runs low.  As described in <a href="#ActivityLifecycle">Activity
@@ -602,7 +617,7 @@
  * listed here in order of importance.  The system will kill less important
  * processes (the last ones) before it resorts to killing more important
  * processes (the first ones).
- * 
+ *
  * <ol>
  * <li> <p>The <b>foreground activity</b> (the activity at the top of the screen
  * that the user is currently interacting with) is considered the most important.
@@ -630,7 +645,7 @@
  * context of an activity BroadcastReceiver or Service to ensure that the system
  * knows it needs to keep your process around.
  * </ol>
- * 
+ *
  * <p>Sometimes an Activity may need to do a long-running operation that exists
  * independently of the activity lifecycle itself.  An example may be a camera
  * application that allows you to upload a picture to a web site.  The upload
@@ -705,9 +720,10 @@
         HashMap<String, Object> children;
         ArrayList<Fragment> fragments;
         ArrayMap<String, LoaderManagerImpl> loaders;
+        VoiceInteractor voiceInteractor;
     }
     /* package */ NonConfigurationInstances mLastNonConfigurationInstances;
-    
+
     private Window mWindow;
 
     private WindowManager mWindowManager;
@@ -715,9 +731,11 @@
     /*package*/ boolean mWindowAdded = false;
     /*package*/ boolean mVisibleFromServer = false;
     /*package*/ boolean mVisibleFromClient = true;
-    /*package*/ ActionBarImpl mActionBar = null;
+    /*package*/ ActionBar mActionBar = null;
     private boolean mEnableDefaultActionBarUp;
 
+    private VoiceInteractor mVoiceInteractor;
+
     private CharSequence mTitle;
     private int mTitleColor = 0;
 
@@ -727,11 +745,19 @@
         public View findViewById(int id) {
             return Activity.this.findViewById(id);
         }
+        @Override
+        public boolean hasView() {
+            Window window = Activity.this.getWindow();
+            return (window != null && window.peekDecorView() != null);
+        }
     };
-    
+
+    // Most recent call to requestVisibleBehind().
+    boolean mVisibleBehind;
+
     ArrayMap<String, LoaderManagerImpl> mAllLoaderManagers;
     LoaderManagerImpl mLoaderManager;
-    
+
     private static final class ManagedCursor {
         ManagedCursor(Cursor cursor) {
             mCursor = cursor;
@@ -746,9 +772,10 @@
     private final ArrayList<ManagedCursor> mManagedCursors =
         new ArrayList<ManagedCursor>();
 
-    // protected by synchronized (this) 
+    // protected by synchronized (this)
     int mResultCode = RESULT_CANCELED;
     Intent mResultData = null;
+
     private TranslucentConversionListener mTranslucentCallback;
     private boolean mChangeCanvasToTranslucent;
 
@@ -756,7 +783,7 @@
 
     private int mDefaultKeyMode = DEFAULT_KEYS_DISABLE;
     private SpannableStringBuilder mDefaultKeySsb = null;
-    
+
     protected static final int[] FOCUSED_STATE_SET = {com.android.internal.R.attr.state_focused};
 
     @SuppressWarnings("unused")
@@ -765,21 +792,25 @@
     private Thread mUiThread;
     final Handler mHandler = new Handler();
 
+    ActivityTransitionState mActivityTransitionState = new ActivityTransitionState();
+    SharedElementCallback mEnterTransitionListener = SharedElementCallback.NULL_CALLBACK;
+    SharedElementCallback mExitTransitionListener = SharedElementCallback.NULL_CALLBACK;
+
     /** Return the intent that started this activity. */
     public Intent getIntent() {
         return mIntent;
     }
 
-    /** 
-     * Change the intent returned by {@link #getIntent}.  This holds a 
-     * reference to the given intent; it does not copy it.  Often used in 
-     * conjunction with {@link #onNewIntent}. 
-     *  
-     * @param newIntent The new Intent object to return from getIntent 
-     * 
+    /**
+     * Change the intent returned by {@link #getIntent}.  This holds a
+     * reference to the given intent; it does not copy it.  Often used in
+     * conjunction with {@link #onNewIntent}.
+     *
+     * @param newIntent The new Intent object to return from getIntent
+     *
      * @see #getIntent
      * @see #onNewIntent
-     */ 
+     */
     public void setIntent(Intent newIntent) {
         mIntent = newIntent;
     }
@@ -793,7 +824,7 @@
     public final boolean isChild() {
         return mParent != null;
     }
-    
+
     /** Return the parent activity if this view is an embedded child. */
     public final Activity getParent() {
         return mParent;
@@ -808,7 +839,7 @@
      * Retrieve the current {@link android.view.Window} for the activity.
      * This can be used to directly access parts of the Window API that
      * are not available through Activity/Screen.
-     * 
+     *
      * @return Window The current window, or null if the activity is not
      *         visual.
      */
@@ -827,7 +858,7 @@
         mLoaderManager = getLoaderManager("(root)", mLoadersStarted, true);
         return mLoaderManager;
     }
-    
+
     LoaderManagerImpl getLoaderManager(String who, boolean started, boolean create) {
         if (mAllLoaderManagers == null) {
             mAllLoaderManagers = new ArrayMap<String, LoaderManagerImpl>();
@@ -843,16 +874,17 @@
         }
         return lm;
     }
-    
+
     /**
      * Calls {@link android.view.Window#getCurrentFocus} on the
      * Window of this Activity to return the currently focused view.
-     * 
+     *
      * @return View The current View with focus or null.
-     * 
+     *
      * @see #getWindow
      * @see android.view.Window#getCurrentFocus
      */
+    @Nullable
     public View getCurrentFocus() {
         return mWindow != null ? mWindow.getCurrentFocus() : null;
     }
@@ -864,26 +896,26 @@
      * with widgets in the UI, calling
      * {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve
      * cursors for data being displayed, etc.
-     * 
+     *
      * <p>You can call {@link #finish} from within this function, in
      * which case onDestroy() will be immediately called without any of the rest
      * of the activity lifecycle ({@link #onStart}, {@link #onResume},
      * {@link #onPause}, etc) executing.
-     * 
+     *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
      * thrown.</em></p>
-     * 
+     *
      * @param savedInstanceState If the activity is being re-initialized after
      *     previously being shut down then this Bundle contains the data it most
      *     recently supplied in {@link #onSaveInstanceState}.  <b><i>Note: Otherwise it is null.</i></b>
-     * 
+     *
      * @see #onStart
      * @see #onSaveInstanceState
      * @see #onRestoreInstanceState
      * @see #onPostCreate
      */
-    protected void onCreate(Bundle savedInstanceState) {
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
         if (mLastNonConfigurationInstances != null) {
             mAllLoaderManagers = mLastNonConfigurationInstances.loaders;
@@ -902,10 +934,38 @@
         }
         mFragments.dispatchCreate();
         getApplication().dispatchActivityCreated(this, savedInstanceState);
+        if (mVoiceInteractor != null) {
+            mVoiceInteractor.attachActivity(this);
+        }
         mCalled = true;
     }
 
     /**
+     * Same as {@link #onCreate(android.os.Bundle)} but called for those activities created with
+     * the attribute {@link android.R.attr#persistableMode} set to
+     * <code>persistAcrossReboots</code>.
+     *
+     * @param savedInstanceState if the activity is being re-initialized after
+     *     previously being shut down then this Bundle contains the data it most
+     *     recently supplied in {@link #onSaveInstanceState}.
+     *     <b><i>Note: Otherwise it is null.</i></b>
+     * @param persistentState if the activity is being re-initialized after
+     *     previously being shut down or powered off then this Bundle contains the data it most
+     *     recently supplied to outPersistentState in {@link #onSaveInstanceState}.
+     *     <b><i>Note: Otherwise it is null.</i></b>
+     *
+     * @see #onCreate(android.os.Bundle)
+     * @see #onStart
+     * @see #onSaveInstanceState
+     * @see #onRestoreInstanceState
+     * @see #onPostCreate
+     */
+    public void onCreate(@Nullable Bundle savedInstanceState,
+            @Nullable PersistableBundle persistentState) {
+        onCreate(savedInstanceState);
+    }
+
+    /**
      * The hook for {@link ActivityThread} to restore the state of this activity.
      *
      * Calls {@link #onSaveInstanceState(android.os.Bundle)} and
@@ -919,6 +979,23 @@
     }
 
     /**
+     * The hook for {@link ActivityThread} to restore the state of this activity.
+     *
+     * Calls {@link #onSaveInstanceState(android.os.Bundle)} and
+     * {@link #restoreManagedDialogs(android.os.Bundle)}.
+     *
+     * @param savedInstanceState contains the saved state
+     * @param persistentState contains the persistable saved state
+     */
+    final void performRestoreInstanceState(Bundle savedInstanceState,
+            PersistableBundle persistentState) {
+        onRestoreInstanceState(savedInstanceState, persistentState);
+        if (savedInstanceState != null) {
+            restoreManagedDialogs(savedInstanceState);
+        }
+    }
+
+    /**
      * This method is called after {@link #onStart} when the activity is
      * being re-initialized from a previously saved state, given here in
      * <var>savedInstanceState</var>.  Most implementations will simply use {@link #onCreate}
@@ -927,12 +1004,12 @@
      * decide whether to use your default implementation.  The default
      * implementation of this method performs a restore of any view state that
      * had previously been frozen by {@link #onSaveInstanceState}.
-     * 
+     *
      * <p>This method is called between {@link #onStart} and
      * {@link #onPostCreate}.
-     * 
+     *
      * @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}.
-     * 
+     *
      * @see #onCreate
      * @see #onPostCreate
      * @see #onResume
@@ -946,7 +1023,35 @@
             }
         }
     }
-    
+
+    /**
+     * This is the same as {@link #onRestoreInstanceState(Bundle)} but is called for activities
+     * created with the attribute {@link android.R.attr#persistableMode} set to
+     * <code>persistAcrossReboots</code>. The {@link android.os.PersistableBundle} passed
+     * came from the restored PersistableBundle first
+     * saved in {@link #onSaveInstanceState(Bundle, PersistableBundle)}.
+     *
+     * <p>This method is called between {@link #onStart} and
+     * {@link #onPostCreate}.
+     *
+     * <p>If this method is called {@link #onRestoreInstanceState(Bundle)} will not be called.
+     *
+     * @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}.
+     * @param persistentState the data most recently supplied in {@link #onSaveInstanceState}.
+     *
+     * @see #onRestoreInstanceState(Bundle)
+     * @see #onCreate
+     * @see #onPostCreate
+     * @see #onResume
+     * @see #onSaveInstanceState
+     */
+    public void onRestoreInstanceState(Bundle savedInstanceState,
+            PersistableBundle persistentState) {
+        if (savedInstanceState != null) {
+            onRestoreInstanceState(savedInstanceState);
+        }
+    }
+
     /**
      * Restore the state of any saved managed dialogs.
      *
@@ -1001,17 +1106,17 @@
      * and {@link #onRestoreInstanceState} have been called).  Applications will
      * generally not implement this method; it is intended for system
      * classes to do final initialization after application code has run.
-     * 
+     *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
      * thrown.</em></p>
-     * 
+     *
      * @param savedInstanceState If the activity is being re-initialized after
      *     previously being shut down then this Bundle contains the data it most
      *     recently supplied in {@link #onSaveInstanceState}.  <b><i>Note: Otherwise it is null.</i></b>
      * @see #onCreate
      */
-    protected void onPostCreate(Bundle savedInstanceState) {
+    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
         if (!isChild()) {
             mTitleReady = true;
             onTitleChanged(getTitle(), getTitleColor());
@@ -1020,14 +1125,30 @@
     }
 
     /**
-     * Called after {@link #onCreate} &mdash; or after {@link #onRestart} when  
-     * the activity had been stopped, but is now again being displayed to the 
-	 * user.  It will be followed by {@link #onResume}.
+     * This is the same as {@link #onPostCreate(Bundle)} but is called for activities
+     * created with the attribute {@link android.R.attr#persistableMode} set to
+     * <code>persistAcrossReboots</code>.
+     *
+     * @param savedInstanceState The data most recently supplied in {@link #onSaveInstanceState}
+     * @param persistentState The data caming from the PersistableBundle first
+     * saved in {@link #onSaveInstanceState(Bundle, PersistableBundle)}.
+     *
+     * @see #onCreate
+     */
+    public void onPostCreate(@Nullable Bundle savedInstanceState,
+            @Nullable PersistableBundle persistentState) {
+        onPostCreate(savedInstanceState);
+    }
+
+    /**
+     * Called after {@link #onCreate} &mdash; or after {@link #onRestart} when
+     * the activity had been stopped, but is now again being displayed to the
+     * user.  It will be followed by {@link #onResume}.
      *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
      * thrown.</em></p>
-     * 
+     *
      * @see #onCreate
      * @see #onStop
      * @see #onResume
@@ -1035,7 +1156,7 @@
     protected void onStart() {
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this);
         mCalled = true;
-        
+
         if (!mLoadersStarted) {
             mLoadersStarted = true;
             if (mLoaderManager != null) {
@@ -1060,11 +1181,11 @@
      * this is usually the place
      * where the cursor should be requeried (because you had deactivated it in
      * {@link #onStop}.
-     * 
+     *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
      * thrown.</em></p>
-     * 
+     *
      * @see #onStop
      * @see #onStart
      * @see #onResume
@@ -1087,7 +1208,7 @@
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
      * thrown.</em></p>
-     * 
+     *
      * @see #onRestoreInstanceState
      * @see #onRestart
      * @see #onPostResume
@@ -1096,6 +1217,7 @@
     protected void onResume() {
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);
         getApplication().dispatchActivityResumed(this);
+        mActivityTransitionState.onResume();
         mCalled = true;
     }
 
@@ -1104,11 +1226,11 @@
      * been called). Applications will generally not implement this method;
      * it is intended for system classes to do final setup after application
      * resume code has run.
-     * 
+     *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
      * thrown.</em></p>
-     * 
+     *
      * @see #onResume
      */
     protected void onPostResume() {
@@ -1119,25 +1241,46 @@
     }
 
     /**
+     * @hide
+     * Check whether this activity is running as part of a voice interaction with the user.
+     * If true, it should perform its interaction with the user through the
+     * {@link VoiceInteractor} returned by {@link #getVoiceInteractor}.
+     */
+    @SystemApi
+    public boolean isVoiceInteraction() {
+        return mVoiceInteractor != null;
+    }
+
+    /**
+     * @hide
+     * Retrieve the active {@link VoiceInteractor} that the user is going through to
+     * interact with this activity.
+     */
+    @SystemApi
+    public VoiceInteractor getVoiceInteractor() {
+        return mVoiceInteractor;
+    }
+
+    /**
      * This is called for activities that set launchMode to "singleTop" in
      * their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP}
      * flag when calling {@link #startActivity}.  In either case, when the
      * activity is re-launched while at the top of the activity stack instead
      * of a new instance of the activity being started, onNewIntent() will be
      * called on the existing instance with the Intent that was used to
-     * re-launch it. 
-     *  
-     * <p>An activity will always be paused before receiving a new intent, so 
-     * you can count on {@link #onResume} being called after this method. 
-     * 
-     * <p>Note that {@link #getIntent} still returns the original Intent.  You 
-     * can use {@link #setIntent} to update it to this new Intent. 
-     * 
-     * @param intent The new intent that was started for the activity. 
-     *  
+     * re-launch it.
+     *
+     * <p>An activity will always be paused before receiving a new intent, so
+     * you can count on {@link #onResume} being called after this method.
+     *
+     * <p>Note that {@link #getIntent} still returns the original Intent.  You
+     * can use {@link #setIntent} to update it to this new Intent.
+     *
+     * @param intent The new intent that was started for the activity.
+     *
      * @see #getIntent
-     * @see #setIntent 
-     * @see #onResume 
+     * @see #setIntent
+     * @see #onResume
      */
     protected void onNewIntent(Intent intent) {
     }
@@ -1153,10 +1296,27 @@
     final void performSaveInstanceState(Bundle outState) {
         onSaveInstanceState(outState);
         saveManagedDialogs(outState);
+        mActivityTransitionState.saveState(outState);
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
     }
 
     /**
+     * The hook for {@link ActivityThread} to save the state of this activity.
+     *
+     * Calls {@link #onSaveInstanceState(android.os.Bundle)}
+     * and {@link #saveManagedDialogs(android.os.Bundle)}.
+     *
+     * @param outState The bundle to save the state to.
+     * @param outPersistentState The bundle to save persistent state to.
+     */
+    final void performSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
+        onSaveInstanceState(outState, outPersistentState);
+        saveManagedDialogs(outState);
+        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState +
+                ", " + outPersistentState);
+    }
+
+    /**
      * Called to retrieve per-instance state from an activity before being killed
      * so that the state can be restored in {@link #onCreate} or
      * {@link #onRestoreInstanceState} (the {@link Bundle} populated by this method
@@ -1194,9 +1354,9 @@
      *
      * <p>If called, this method will occur before {@link #onStop}.  There are
      * no guarantees about whether it will occur before or after {@link #onPause}.
-     * 
+     *
      * @param outState Bundle in which to place your saved state.
-     * 
+     *
      * @see #onCreate
      * @see #onRestoreInstanceState
      * @see #onPause
@@ -1211,6 +1371,25 @@
     }
 
     /**
+     * This is the same as {@link #onSaveInstanceState} but is called for activities
+     * created with the attribute {@link android.R.attr#persistableMode} set to
+     * <code>persistAcrossReboots</code>. The {@link android.os.PersistableBundle} passed
+     * in will be saved and presented in {@link #onCreate(Bundle, PersistableBundle)}
+     * the first time that this activity is restarted following the next device reboot.
+     *
+     * @param outState Bundle in which to place your saved state.
+     * @param outPersistentState State which will be saved across reboots.
+     *
+     * @see #onSaveInstanceState(Bundle)
+     * @see #onCreate
+     * @see #onRestoreInstanceState(Bundle, PersistableBundle)
+     * @see #onPause
+     */
+    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
+        onSaveInstanceState(outState);
+    }
+
+    /**
      * Save the state of any managed dialogs.
      *
      * @param outState place to store the saved state.
@@ -1262,23 +1441,23 @@
      * noticeable amount of CPU in order to make the switch to the next activity
      * as fast as possible, or to close resources that are exclusive access
      * such as the camera.
-     * 
+     *
      * <p>In situations where the system needs more memory it may kill paused
      * processes to reclaim resources.  Because of this, you should be sure
      * that all of your state is saved by the time you return from
      * this function.  In general {@link #onSaveInstanceState} is used to save
      * per-instance state in the activity and this method is used to store
      * global persistent data (in content providers, files, etc.)
-     * 
+     *
      * <p>After receiving this call you will usually receive a following call
      * to {@link #onStop} (after the next activity has been resumed and
      * displayed), however in some cases there will be a direct call back to
      * {@link #onResume} without going through the stopped state.
-     * 
+     *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
      * thrown.</em></p>
-     * 
+     *
      * @see #onResume
      * @see #onSaveInstanceState
      * @see #onStop
@@ -1297,32 +1476,32 @@
      * brought to the foreground, {@link #onUserLeaveHint} will not be called on
      * the activity being interrupted.  In cases when it is invoked, this method
      * is called right before the activity's {@link #onPause} callback.
-     * 
+     *
      * <p>This callback and {@link #onUserInteraction} are intended to help
      * activities manage status bar notifications intelligently; specifically,
      * for helping activities determine the proper time to cancel a notfication.
-     * 
+     *
      * @see #onUserInteraction()
      */
     protected void onUserLeaveHint() {
     }
-    
+
     /**
      * Generate a new thumbnail for this activity.  This method is called before
      * pausing the activity, and should draw into <var>outBitmap</var> the
      * imagery for the desired thumbnail in the dimensions of that bitmap.  It
      * can use the given <var>canvas</var>, which is configured to draw into the
      * bitmap, for rendering if desired.
-     * 
+     *
      * <p>The default implementation returns fails and does not draw a thumbnail;
      * this will result in the platform creating its own thumbnail if needed.
-     * 
+     *
      * @param outBitmap The bitmap to contain the thumbnail.
      * @param canvas Can be used to render into the bitmap.
-     * 
+     *
      * @return Return true if you have drawn into the bitmap; otherwise after
      *         you return it will be filled with a default thumbnail.
-     * 
+     *
      * @see #onCreateDescription
      * @see #onSaveInstanceState
      * @see #onPause
@@ -1335,19 +1514,20 @@
      * Generate a new description for this activity.  This method is called
      * before pausing the activity and can, if desired, return some textual
      * description of its current state to be displayed to the user.
-     * 
+     *
      * <p>The default implementation returns null, which will cause you to
      * inherit the description from the previous activity.  If all activities
      * return null, generally the label of the top activity will be used as the
      * description.
-     * 
+     *
      * @return A description of what the user is doing.  It should be short and
      *         sweet (only a few words).
-     * 
+     *
      * @see #onCreateThumbnail
      * @see #onSaveInstanceState
      * @see #onPause
      */
+    @Nullable
     public CharSequence onCreateDescription() {
         return null;
     }
@@ -1370,15 +1550,15 @@
      * Called when you are no longer visible to the user.  You will next
      * receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
      * depending on later user activity.
-     * 
+     *
      * <p>Note that this method may never be called, in low memory situations
      * where the system does not have enough memory to keep your activity's
      * process running after its {@link #onPause} method is called.
-     * 
+     *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
      * thrown.</em></p>
-     * 
+     *
      * @see #onRestart
      * @see #onResume
      * @see #onSaveInstanceState
@@ -1387,6 +1567,7 @@
     protected void onStop() {
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this);
         if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
+        mActivityTransitionState.onStop();
         getApplication().dispatchActivityStopped(this);
         mTranslucentCallback = null;
         mCalled = true;
@@ -1398,7 +1579,7 @@
      * {@link #finish} on it, or because the system is temporarily destroying
      * this instance of the activity to save space.  You can distinguish
      * between these two scenarios with the {@link #isFinishing} method.
-     * 
+     *
      * <p><em>Note: do not count on this method being called as a place for
      * saving data! For example, if an activity is editing data in a content
      * provider, those edits should be committed in either {@link #onPause} or
@@ -1410,11 +1591,11 @@
      * calling this method (or any others) in it, so it should not be used to
      * do things that are intended to remain around after the process goes
      * away.
-     * 
+     *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
      * thrown.</em></p>
-     * 
+     *
      * @see #onPause
      * @see #onStop
      * @see #finish
@@ -1488,11 +1669,11 @@
      * by that attribute, then instead of reporting it the system will stop
      * and restart the activity (to have it launched with the new
      * configuration).
-     * 
+     *
      * <p>At the time that this function has been called, your Resources
      * object will have been updated to return resource values matching the
      * new configuration.
-     * 
+     *
      * @param newConfig The new device configuration.
      */
     public void onConfigurationChanged(Configuration newConfig) {
@@ -1512,7 +1693,7 @@
             mActionBar.onConfigurationChanged(newConfig);
         }
     }
-    
+
     /**
      * If this activity is being destroyed because it can not handle a
      * configuration parameter being changed (and thus its
@@ -1522,7 +1703,7 @@
      * destroyed.  Note that there is no guarantee that these will be
      * accurate (other changes could have happened at any time), so you should
      * only use this as an optimization hint.
-     * 
+     *
      * @return Returns a bit field of the configuration parameters that are
      * changing, as defined by the {@link android.content.res.Configuration}
      * class.
@@ -1530,21 +1711,21 @@
     public int getChangingConfigurations() {
         return mConfigChangeFlags;
     }
-    
+
     /**
      * Retrieve the non-configuration instance data that was previously
      * returned by {@link #onRetainNonConfigurationInstance()}.  This will
      * be available from the initial {@link #onCreate} and
      * {@link #onStart} calls to the new instance, allowing you to extract
      * any useful dynamic state from the previous instance.
-     * 
+     *
      * <p>Note that the data you retrieve here should <em>only</em> be used
      * as an optimization for handling configuration changes.  You should always
      * be able to handle getting a null pointer back, and an activity must
      * still be able to restore itself to its previous state (through the
      * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this
      * function returns null.
-     * 
+     *
      * @return Returns the object previously returned by
      * {@link #onRetainNonConfigurationInstance()}.
      *
@@ -1552,12 +1733,13 @@
      * {@link Fragment#setRetainInstance(boolean)} instead; this is also
      * available on older platforms through the Android compatibility package.
      */
+    @Nullable
     @Deprecated
     public Object getLastNonConfigurationInstance() {
         return mLastNonConfigurationInstances != null
                 ? mLastNonConfigurationInstances.activity : null;
     }
-    
+
     /**
      * Called by the system, as part of destroying an
      * activity due to a configuration change, when it is known that a new
@@ -1566,7 +1748,7 @@
      * itself, which can later be retrieved by calling
      * {@link #getLastNonConfigurationInstance()} in the new activity
      * instance.
-     * 
+     *
      * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
      * or later, consider instead using a {@link Fragment} with
      * {@link Fragment#setRetainInstance(boolean)
@@ -1586,14 +1768,14 @@
      * the {@link #getLastNonConfigurationInstance()} method of the following
      * activity instance as described there.
      * </ul>
-     * 
+     *
      * <p>These guarantees are designed so that an activity can use this API
      * to propagate extensive state from the old to new activity instance, from
      * loaded bitmaps, to network connections, to evenly actively running
      * threads.  Note that you should <em>not</em> propagate any data that
      * may change based on the configuration, including any data loaded from
      * resources such as strings, layouts, or drawables.
-     * 
+     *
      * <p>The guarantee of no message handling during the switch to the next
      * activity simplifies use with active objects.  For example if your retained
      * state is an {@link android.os.AsyncTask} you are guaranteed that its
@@ -1613,29 +1795,30 @@
     public Object onRetainNonConfigurationInstance() {
         return null;
     }
-    
+
     /**
      * Retrieve the non-configuration instance data that was previously
      * returned by {@link #onRetainNonConfigurationChildInstances()}.  This will
      * be available from the initial {@link #onCreate} and
      * {@link #onStart} calls to the new instance, allowing you to extract
      * any useful dynamic state from the previous instance.
-     * 
+     *
      * <p>Note that the data you retrieve here should <em>only</em> be used
      * as an optimization for handling configuration changes.  You should always
      * be able to handle getting a null pointer back, and an activity must
      * still be able to restore itself to its previous state (through the
      * normal {@link #onSaveInstanceState(Bundle)} mechanism) even if this
      * function returns null.
-     * 
+     *
      * @return Returns the object previously returned by
      * {@link #onRetainNonConfigurationChildInstances()}
      */
+    @Nullable
     HashMap<String, Object> getLastNonConfigurationChildInstances() {
         return mLastNonConfigurationInstances != null
                 ? mLastNonConfigurationInstances.children : null;
     }
-    
+
     /**
      * This method is similar to {@link #onRetainNonConfigurationInstance()} except that
      * it should return either a mapping from  child activity id strings to arbitrary objects,
@@ -1643,10 +1826,11 @@
      * set of child activities, such as ActivityGroup.  The same guarantees and restrictions apply
      * as for {@link #onRetainNonConfigurationInstance()}.  The default implementation returns null.
      */
+    @Nullable
     HashMap<String,Object> onRetainNonConfigurationChildInstances() {
         return null;
     }
-    
+
     NonConfigurationInstances retainNonConfigurationInstances() {
         Object activity = onRetainNonConfigurationInstance();
         HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
@@ -1670,15 +1854,17 @@
                 }
             }
         }
-        if (activity == null && children == null && fragments == null && !retainLoaders) {
+        if (activity == null && children == null && fragments == null && !retainLoaders
+                && mVoiceInteractor == null) {
             return null;
         }
-        
+
         NonConfigurationInstances nci = new NonConfigurationInstances();
         nci.activity = activity;
         nci.children = children;
         nci.fragments = fragments;
         nci.loaders = mAllLoaderManagers;
+        nci.voiceInteractor = mVoiceInteractor;
         return nci;
     }
 
@@ -1712,7 +1898,7 @@
             }
         }
     }
-    
+
     /**
      * Called when a Fragment is being attached to this activity, immediately
      * after the call to its {@link Fragment#onAttach Fragment.onAttach()}
@@ -1720,14 +1906,14 @@
      */
     public void onAttachFragment(Fragment fragment) {
     }
-    
+
     /**
      * Wrapper around
      * {@link ContentResolver#query(android.net.Uri , String[], String, String[], String)}
      * that gives the resulting {@link Cursor} to call
      * {@link #startManagingCursor} so that the activity will manage its
      * lifecycle for you.
-     * 
+     *
      * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
      * or later, consider instead using {@link LoaderManager} instead, available
      * via {@link #getLoaderManager()}.</em>
@@ -1737,14 +1923,14 @@
      * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will
      * not</em> automatically close the cursor and, in that case, you must call
      * {@link Cursor#close()}.</p>
-     * 
+     *
      * @param uri The URI of the content provider to query.
      * @param projection List of columns to return.
      * @param selection SQL WHERE clause.
      * @param sortOrder SQL ORDER BY clause.
-     * 
+     *
      * @return The Cursor that was returned by query().
-     * 
+     *
      * @see ContentResolver#query(android.net.Uri , String[], String, String[], String)
      * @see #startManagingCursor
      * @hide
@@ -1767,7 +1953,7 @@
      * that gives the resulting {@link Cursor} to call
      * {@link #startManagingCursor} so that the activity will manage its
      * lifecycle for you.
-     * 
+     *
      * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
      * or later, consider instead using {@link LoaderManager} instead, available
      * via {@link #getLoaderManager()}.</em>
@@ -1777,15 +1963,15 @@
      * you call {@link #stopManagingCursor} on a cursor from a managed query, the system <em>will
      * not</em> automatically close the cursor and, in that case, you must call
      * {@link Cursor#close()}.</p>
-     * 
+     *
      * @param uri The URI of the content provider to query.
      * @param projection List of columns to return.
      * @param selection SQL WHERE clause.
      * @param selectionArgs The arguments to selection, if any ?s are pesent
      * @param sortOrder SQL ORDER BY clause.
-     * 
+     *
      * @return The Cursor that was returned by query().
-     * 
+     *
      * @see ContentResolver#query(android.net.Uri , String[], String, String[], String)
      * @see #startManagingCursor
      *
@@ -1808,7 +1994,7 @@
      * {@link Cursor#deactivate} on the given Cursor, and when it is later restarted
      * it will call {@link Cursor#requery} for you.  When the activity is
      * destroyed, all managed Cursors will be closed automatically.
-     * 
+     *
      * <em>If you are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
      * or later, consider instead using {@link LoaderManager} instead, available
      * via {@link #getLoaderManager()}.</em>
@@ -1818,9 +2004,9 @@
      * However, if you call {@link #stopManagingCursor} on a cursor from a managed query, the system
      * <em>will not</em> automatically close the cursor and, in that case, you must call
      * {@link Cursor#close()}.</p>
-     * 
+     *
      * @param c The Cursor to be managed.
-     * 
+     *
      * @see #managedQuery(android.net.Uri , String[], String, String[], String)
      * @see #stopManagingCursor
      *
@@ -1839,13 +2025,13 @@
      * Given a Cursor that was previously given to
      * {@link #startManagingCursor}, stop the activity's management of that
      * cursor.
-     * 
+     *
      * <p><strong>Warning:</strong> After calling this method on a cursor from a managed query,
-     * the system <em>will not</em> automatically close the cursor and you must call 
+     * the system <em>will not</em> automatically close the cursor and you must call
      * {@link Cursor#close()}.</p>
-     * 
+     *
      * @param c The Cursor that was being managed.
-     * 
+     *
      * @see #startManagingCursor
      *
      * @deprecated Use the new {@link android.content.CursorLoader} class with
@@ -1884,22 +2070,50 @@
     public View findViewById(int id) {
         return getWindow().findViewById(id);
     }
-    
+
     /**
      * Retrieve a reference to this activity's ActionBar.
      *
      * @return The Activity's ActionBar, or null if it does not have one.
      */
+    @Nullable
     public ActionBar getActionBar() {
-        initActionBar();
+        initWindowDecorActionBar();
         return mActionBar;
     }
-    
+
+    /**
+     * Set a {@link android.widget.Toolbar Toolbar} to act as the {@link ActionBar} for this
+     * Activity window.
+     *
+     * <p>When set to a non-null value the {@link #getActionBar()} method will return
+     * an {@link ActionBar} object that can be used to control the given toolbar as if it were
+     * a traditional window decor action bar. The toolbar's menu will be populated with the
+     * Activity's options menu and the navigation button will be wired through the standard
+     * {@link android.R.id#home home} menu select action.</p>
+     *
+     * <p>In order to use a Toolbar within the Activity's window content the application
+     * must not request the window feature {@link Window#FEATURE_ACTION_BAR FEATURE_ACTION_BAR}.</p>
+     *
+     * @param toolbar Toolbar to set as the Activity's action bar
+     */
+    public void setActionBar(@Nullable Toolbar toolbar) {
+        if (getActionBar() instanceof WindowDecorActionBar) {
+            throw new IllegalStateException("This Activity already has an action bar supplied " +
+                    "by the window decor. Do not request Window.FEATURE_ACTION_BAR and set " +
+                    "android:windowActionBar to false in your theme to use a Toolbar instead.");
+        }
+        ToolbarActionBar tbab = new ToolbarActionBar(toolbar, getTitle(), this);
+        mActionBar = tbab;
+        mWindow.setCallback(tbab.getWrappedWindowCallback());
+        mActionBar.invalidateOptionsMenu();
+    }
+
     /**
      * Creates a new ActionBar, locates the inflated ActionBarView,
      * initializes the ActionBar with the view, and sets mActionBar.
      */
-    private void initActionBar() {
+    private void initWindowDecorActionBar() {
         Window window = getWindow();
 
         // Initializing the window decor can change window feature flags.
@@ -1910,25 +2124,25 @@
             return;
         }
 
-        mActionBar = new ActionBarImpl(this);
+        mActionBar = new WindowDecorActionBar(this);
         mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
 
         mWindow.setDefaultIcon(mActivityInfo.getIconResource());
         mWindow.setDefaultLogo(mActivityInfo.getLogoResource());
     }
-    
+
     /**
      * Set the activity content from a layout resource.  The resource will be
      * inflated, adding all top-level views to the activity.
      *
      * @param layoutResID Resource ID to be inflated.
-     * 
+     *
      * @see #setContentView(android.view.View)
      * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
      */
     public void setContentView(int layoutResID) {
         getWindow().setContentView(layoutResID);
-        initActionBar();
+        initWindowDecorActionBar();
     }
 
     /**
@@ -1940,7 +2154,7 @@
      * your own layout parameters, invoke
      * {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}
      * instead.
-     * 
+     *
      * @param view The desired content to display.
      *
      * @see #setContentView(int)
@@ -1948,14 +2162,14 @@
      */
     public void setContentView(View view) {
         getWindow().setContentView(view);
-        initActionBar();
+        initWindowDecorActionBar();
     }
 
     /**
      * Set the activity content to an explicit view.  This view is placed
      * directly into the activity's view hierarchy.  It can itself be a complex
      * view hierarchy.
-     * 
+     *
      * @param view The desired content to display.
      * @param params Layout parameters for the view.
      *
@@ -1964,19 +2178,54 @@
      */
     public void setContentView(View view, ViewGroup.LayoutParams params) {
         getWindow().setContentView(view, params);
-        initActionBar();
+        initWindowDecorActionBar();
     }
 
     /**
      * Add an additional content view to the activity.  Added after any existing
      * ones in the activity -- existing views are NOT removed.
-     * 
+     *
      * @param view The desired content to display.
      * @param params Layout parameters for the view.
      */
     public void addContentView(View view, ViewGroup.LayoutParams params) {
         getWindow().addContentView(view, params);
-        initActionBar();
+        initWindowDecorActionBar();
+    }
+
+    /**
+     * Retrieve the {@link TransitionManager} responsible for default transitions in this window.
+     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * <p>This method will return non-null after content has been initialized (e.g. by using
+     * {@link #setContentView}) if {@link Window#FEATURE_CONTENT_TRANSITIONS} has been granted.</p>
+     *
+     * @return This window's content TransitionManager or null if none is set.
+     */
+    public TransitionManager getContentTransitionManager() {
+        return getWindow().getTransitionManager();
+    }
+
+    /**
+     * Set the {@link TransitionManager} to use for default transitions in this window.
+     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * @param tm The TransitionManager to use for scene changes.
+     */
+    public void setContentTransitionManager(TransitionManager tm) {
+        getWindow().setTransitionManager(tm);
+    }
+
+    /**
+     * Retrieve the {@link Scene} representing this window's current content.
+     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * <p>This method will return null if the current content is not represented by a Scene.</p>
+     *
+     * @return Current Scene being shown or null
+     */
+    public Scene getContentScene() {
+        return getWindow().getContentScene();
     }
 
     /**
@@ -1986,27 +2235,37 @@
     public void setFinishOnTouchOutside(boolean finish) {
         mWindow.setCloseOnTouchOutside(finish);
     }
-    
+
+    /** @hide */
+    @IntDef({
+            DEFAULT_KEYS_DISABLE,
+            DEFAULT_KEYS_DIALER,
+            DEFAULT_KEYS_SHORTCUT,
+            DEFAULT_KEYS_SEARCH_LOCAL,
+            DEFAULT_KEYS_SEARCH_GLOBAL})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface DefaultKeyMode {}
+
     /**
      * Use with {@link #setDefaultKeyMode} to turn off default handling of
      * keys.
-     * 
+     *
      * @see #setDefaultKeyMode
      */
     static public final int DEFAULT_KEYS_DISABLE = 0;
     /**
      * Use with {@link #setDefaultKeyMode} to launch the dialer during default
      * key handling.
-     * 
+     *
      * @see #setDefaultKeyMode
      */
     static public final int DEFAULT_KEYS_DIALER = 1;
     /**
      * Use with {@link #setDefaultKeyMode} to execute a menu shortcut in
      * default key handling.
-     * 
+     *
      * <p>That is, the user does not need to hold down the menu key to execute menu shortcuts.
-     * 
+     *
      * @see #setDefaultKeyMode
      */
     static public final int DEFAULT_KEYS_SHORTCUT = 2;
@@ -2014,9 +2273,9 @@
      * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes
      * will start an application-defined search.  (If the application or activity does not
      * actually define a search, the the keys will be ignored.)
-     * 
+     *
      * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details.
-     * 
+     *
      * @see #setDefaultKeyMode
      */
     static public final int DEFAULT_KEYS_SEARCH_LOCAL = 3;
@@ -2025,9 +2284,9 @@
      * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes
      * will start a global search (typically web search, but some platforms may define alternate
      * methods for global search)
-     * 
+     *
      * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details.
-     * 
+     *
      * @see #setDefaultKeyMode
      */
     static public final int DEFAULT_KEYS_SEARCH_GLOBAL = 4;
@@ -2039,16 +2298,16 @@
      * floor. Other modes allow you to launch the dialer
      * ({@link #DEFAULT_KEYS_DIALER}), execute a shortcut in your options
      * menu without requiring the menu key be held down
-     * ({@link #DEFAULT_KEYS_SHORTCUT}), or launch a search ({@link #DEFAULT_KEYS_SEARCH_LOCAL} 
+     * ({@link #DEFAULT_KEYS_SHORTCUT}), or launch a search ({@link #DEFAULT_KEYS_SEARCH_LOCAL}
      * and {@link #DEFAULT_KEYS_SEARCH_GLOBAL}).
-     * 
+     *
      * <p>Note that the mode selected here does not impact the default
      * handling of system keys, such as the "back" and "menu" keys, and your
      * activity and its views always get a first chance to receive and handle
      * all application keys.
-     * 
+     *
      * @param mode The desired default key mode constant.
-     * 
+     *
      * @see #DEFAULT_KEYS_DISABLE
      * @see #DEFAULT_KEYS_DIALER
      * @see #DEFAULT_KEYS_SHORTCUT
@@ -2056,9 +2315,9 @@
      * @see #DEFAULT_KEYS_SEARCH_GLOBAL
      * @see #onKeyDown
      */
-    public final void setDefaultKeyMode(int mode) {
+    public final void setDefaultKeyMode(@DefaultKeyMode int mode) {
         mDefaultKeyMode = mode;
-        
+
         // Some modes use a SpannableStringBuilder to track & dispatch input events
         // This list must remain in sync with the switch in onKeyDown()
         switch (mode) {
@@ -2079,10 +2338,10 @@
 
     /**
      * Called when a key was pressed down and not handled by any of the views
-     * inside of the activity. So, for example, key presses while the cursor 
+     * inside of the activity. So, for example, key presses while the cursor
      * is inside a TextView will not trigger the event (unless it is a navigation
      * to another object) because TextView handles its own key presses.
-     * 
+     *
      * <p>If the focused view didn't want this event, this method is called.
      *
      * <p>The default implementation takes care of {@link KeyEvent#KEYCODE_BACK}
@@ -2093,12 +2352,12 @@
      * will be performed; for earlier applications, it will perform the
      * action immediately in on-down, as those versions of the platform
      * behaved.
-     * 
+     *
      * <p>Other additional default key handling may be performed
      * if configured with {@link #setDefaultKeyMode}.
-     * 
+     *
      * @return Return <code>true</code> to prevent this event from being propagated
-     * further, or <code>false</code> to indicate that you have not handled 
+     * further, or <code>false</code> to indicate that you have not handled
      * this event and it should continue to be propagated.
      * @see #onKeyUp
      * @see android.view.KeyEvent
@@ -2113,11 +2372,11 @@
             }
             return true;
         }
-        
+
         if (mDefaultKeyMode == DEFAULT_KEYS_DISABLE) {
             return false;
         } else if (mDefaultKeyMode == DEFAULT_KEYS_SHORTCUT) {
-            if (getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL, 
+            if (getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL,
                     keyCode, event, Menu.FLAG_ALWAYS_PERFORM_CLOSE)) {
                 return true;
             }
@@ -2137,12 +2396,12 @@
 
                     final String str = mDefaultKeySsb.toString();
                     clearSpannable = true;
-                    
+
                     switch (mDefaultKeyMode) {
                     case DEFAULT_KEYS_DIALER:
                         Intent intent = new Intent(Intent.ACTION_DIAL,  Uri.parse("tel:" + str));
                         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                        startActivity(intent);    
+                        startActivity(intent);
                         break;
                     case DEFAULT_KEYS_SEARCH_LOCAL:
                         startSearch(str, false, null, false);
@@ -2173,16 +2432,16 @@
 
     /**
      * Called when a key was released and not handled by any of the views
-     * inside of the activity. So, for example, key presses while the cursor 
+     * inside of the activity. So, for example, key presses while the cursor
      * is inside a TextView will not trigger the event (unless it is a navigation
      * to another object) because TextView handles its own key presses.
-     * 
+     *
      * <p>The default implementation handles KEYCODE_BACK to stop the activity
      * and go back.
-     * 
+     *
      * @return Return <code>true</code> to prevent this event from being propagated
-     * further, or <code>false</code> to indicate that you have not handled 
-     * this event and it should continue to be propagated. 
+     * further, or <code>false</code> to indicate that you have not handled
+     * this event and it should continue to be propagated.
      * @see #onKeyDown
      * @see KeyEvent
      */
@@ -2206,15 +2465,19 @@
     public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
         return false;
     }
-    
+
     /**
      * Called when the activity has detected the user's press of the back
      * key.  The default implementation simply finishes the current activity,
      * but you can override this to do whatever you want.
      */
     public void onBackPressed() {
+        if (mActionBar != null && mActionBar.collapseActionView()) {
+            return;
+        }
+
         if (!mFragments.popBackStackImmediate()) {
-            finish();
+            finishAfterTransition();
         }
     }
 
@@ -2236,9 +2499,9 @@
      * Called when a touch screen event was not handled by any of the views
      * under it.  This is most useful to process touch events that happen
      * outside of your window bounds, where there is no view to receive it.
-     * 
+     *
      * @param event The touch screen event being processed.
-     * 
+     *
      * @return Return true if you have consumed the event, false if you haven't.
      * The default implementation always returns false.
      */
@@ -2247,10 +2510,10 @@
             finish();
             return true;
         }
-        
+
         return false;
     }
-    
+
     /**
      * Called when the trackball was moved and not handled by any of the
      * views inside of the activity.  So, for example, if the trackball moves
@@ -2259,9 +2522,9 @@
      * here happens <em>before</em> trackball movements are converted to
      * DPAD key events, which then get sent back to the view hierarchy, and
      * will be processed at the point for things like focus navigation.
-     * 
+     *
      * @param event The trackball event being processed.
-     * 
+     *
      * @return Return true if you have consumed the event, false if you haven't.
      * The default implementation always returns false.
      */
@@ -2305,21 +2568,21 @@
      * This callback and {@link #onUserLeaveHint} are intended to help
      * activities manage status bar notifications intelligently; specifically,
      * for helping activities determine the proper time to cancel a notfication.
-     * 
+     *
      * <p>All calls to your activity's {@link #onUserLeaveHint} callback will
      * be accompanied by calls to {@link #onUserInteraction}.  This
      * ensures that your activity will be told of relevant user activity such
      * as pulling down the notification pane and touching an item there.
-     * 
+     *
      * <p>Note that this callback will be invoked for the touch down action
      * that begins a touch gesture, but may not be invoked for the touch-moved
      * and touch-up actions that follow.
-     * 
+     *
      * @see #onUserLeaveHint()
      */
     public void onUserInteraction() {
     }
-    
+
     public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
         // Update window manager if: we have a view, that view is
         // attached to its parent (which will be a RootView), and
@@ -2340,14 +2603,14 @@
      * focus.  This is the best indicator of whether this activity is visible
      * to the user.  The default implementation clears the key tracking
      * state, so should always be called.
-     * 
+     *
      * <p>Note that this provides information about global focus state, which
      * is managed independently of activity lifecycles.  As such, while focus
      * changes will generally have some relation to lifecycle changes (an
      * activity that is stopped will not generally get window focus), you
      * should not rely on any particular order between the callbacks here and
      * those in the other lifecycle methods such as {@link #onResume}.
-     * 
+     *
      * <p>As a general rule, however, a resumed activity will have window
      * focus...  unless it has displayed other dialogs or popups that take
      * input focus, in which case the activity itself will not have focus
@@ -2357,14 +2620,14 @@
      * pausing the foreground activity.
      *
      * @param hasFocus Whether the window of this activity has focus.
-     * 
+     *
      * @see #hasWindowFocus()
      * @see #onResume
      * @see View#onWindowFocusChanged(boolean)
      */
     public void onWindowFocusChanged(boolean hasFocus) {
     }
-    
+
     /**
      * Called when the main window associated with the activity has been
      * attached to the window manager.
@@ -2374,7 +2637,7 @@
      */
     public void onAttachedToWindow() {
     }
-    
+
     /**
      * Called when the main window associated with the activity has been
      * detached from the window manager.
@@ -2384,13 +2647,13 @@
      */
     public void onDetachedFromWindow() {
     }
-    
+
     /**
      * Returns true if this activity's <em>main</em> window currently has window focus.
      * Note that this is not the same as the view itself having focus.
-     * 
+     *
      * @return True if this activity's main window currently has window focus.
-     * 
+     *
      * @see #onWindowAttributesChanged(android.view.WindowManager.LayoutParams)
      */
     public boolean hasWindowFocus() {
@@ -2412,18 +2675,26 @@
     public void onWindowDismissed() {
         finish();
     }
-    
+
     /**
-     * Called to process key events.  You can override this to intercept all 
-     * key events before they are dispatched to the window.  Be sure to call 
+     * Called to process key events.  You can override this to intercept all
+     * key events before they are dispatched to the window.  Be sure to call
      * this implementation for key events that should be handled normally.
-     * 
+     *
      * @param event The key event.
-     * 
+     *
      * @return boolean Return true if this event was consumed.
      */
     public boolean dispatchKeyEvent(KeyEvent event) {
         onUserInteraction();
+
+        // Let action bars open menus in response to the menu key prioritized over
+        // the window handling it
+        if (event.getKeyCode() == KeyEvent.KEYCODE_MENU &&
+                mActionBar != null && mActionBar.onMenuKeyEvent(event)) {
+            return true;
+        }
+
         Window win = getWindow();
         if (win.superDispatchKeyEvent(event)) {
             return true;
@@ -2456,9 +2727,9 @@
      * intercept all touch screen events before they are dispatched to the
      * window.  Be sure to call this implementation for touch screen events
      * that should be handled normally.
-     * 
+     *
      * @param ev The touch screen event.
-     * 
+     *
      * @return boolean Return true if this event was consumed.
      */
     public boolean dispatchTouchEvent(MotionEvent ev) {
@@ -2470,15 +2741,15 @@
         }
         return onTouchEvent(ev);
     }
-    
+
     /**
      * Called to process trackball events.  You can override this to
      * intercept all trackball events before they are dispatched to the
      * window.  Be sure to call this implementation for trackball events
      * that should be handled normally.
-     * 
+     *
      * @param ev The trackball event.
-     * 
+     *
      * @return boolean Return true if this event was consumed.
      */
     public boolean dispatchTrackballEvent(MotionEvent ev) {
@@ -2531,6 +2802,7 @@
      * simply returns null so that all panel sub-windows will have the default
      * menu behavior.
      */
+    @Nullable
     public View onCreatePanelView(int featureId) {
         return null;
     }
@@ -2572,12 +2844,12 @@
 
     /**
      * {@inheritDoc}
-     * 
+     *
      * @return The default implementation returns true.
      */
     public boolean onMenuOpened(int featureId, Menu menu) {
         if (featureId == Window.FEATURE_ACTION_BAR) {
-            initActionBar();
+            initWindowDecorActionBar();
             if (mActionBar != null) {
                 mActionBar.dispatchMenuVisibilityChanged(true);
             } else {
@@ -2622,7 +2894,7 @@
                     }
                 }
                 return false;
-                
+
             case Window.FEATURE_CONTEXT_MENU:
                 if(titleCondensed != null) {
                     EventLog.writeEvent(50000, 1, titleCondensed.toString());
@@ -2636,7 +2908,7 @@
                 return false;
         }
     }
-    
+
     /**
      * Default implementation of
      * {@link android.view.Window.Callback#onPanelClosed(int, Menu)} for
@@ -2652,13 +2924,13 @@
                 mFragments.dispatchOptionsMenuClosed(menu);
                 onOptionsMenuClosed(menu);
                 break;
-                
+
             case Window.FEATURE_CONTEXT_MENU:
                 onContextMenuClosed(menu);
                 break;
 
             case Window.FEATURE_ACTION_BAR:
-                initActionBar();
+                initWindowDecorActionBar();
                 mActionBar.dispatchMenuVisibilityChanged(false);
                 break;
         }
@@ -2670,34 +2942,36 @@
      * time it needs to be displayed.
      */
     public void invalidateOptionsMenu() {
-        mWindow.invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL);
+        if (mActionBar == null || !mActionBar.invalidateOptionsMenu()) {
+            mWindow.invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL);
+        }
     }
-    
+
     /**
      * Initialize the contents of the Activity's standard options menu.  You
      * should place your menu items in to <var>menu</var>.
-     * 
+     *
      * <p>This is only called once, the first time the options menu is
      * displayed.  To update the menu every time it is displayed, see
      * {@link #onPrepareOptionsMenu}.
-     * 
+     *
      * <p>The default implementation populates the menu with standard system
-     * menu items.  These are placed in the {@link Menu#CATEGORY_SYSTEM} group so that 
-     * they will be correctly ordered with application-defined menu items. 
-     * Deriving classes should always call through to the base implementation. 
-     * 
+     * menu items.  These are placed in the {@link Menu#CATEGORY_SYSTEM} group so that
+     * they will be correctly ordered with application-defined menu items.
+     * Deriving classes should always call through to the base implementation.
+     *
      * <p>You can safely hold on to <var>menu</var> (and any items created
      * from it), making modifications to it as desired, until the next
      * time onCreateOptionsMenu() is called.
-     * 
+     *
      * <p>When you add items to the menu, you can implement the Activity's
      * {@link #onOptionsItemSelected} method to handle them there.
-     * 
+     *
      * @param menu The options menu in which you place your items.
-     * 
+     *
      * @return You must return true for the menu to be displayed;
      *         if you return false it will not be shown.
-     * 
+     *
      * @see #onPrepareOptionsMenu
      * @see #onOptionsItemSelected
      */
@@ -2713,17 +2987,17 @@
      * called right before the menu is shown, every time it is shown.  You can
      * use this method to efficiently enable/disable items or otherwise
      * dynamically modify the contents.
-     * 
+     *
      * <p>The default implementation updates the system menu items based on the
      * activity's state.  Deriving classes should always call through to the
      * base class implementation.
-     * 
+     *
      * @param menu The options menu as last shown or first initialized by
      *             onCreateOptionsMenu().
-     * 
+     *
      * @return You must return true for the menu to be displayed;
      *         if you return false it will not be shown.
-     * 
+     *
      * @see #onCreateOptionsMenu
      */
     public boolean onPrepareOptionsMenu(Menu menu) {
@@ -2740,15 +3014,15 @@
      * its Handler as appropriate).  You can use this method for any items
      * for which you would like to do processing without those other
      * facilities.
-     * 
+     *
      * <p>Derived classes should call through to the base class for it to
      * perform the default menu handling.</p>
-     * 
+     *
      * @param item The menu item that was selected.
-     * 
+     *
      * @return boolean Return false to allow normal menu processing to
      *         proceed, true to consume it here.
-     * 
+     *
      * @see #onCreateOptionsMenu
      */
     public boolean onOptionsItemSelected(MenuItem item) {
@@ -2865,7 +3139,7 @@
     /**
      * This hook is called whenever the options menu is being closed (either by the user canceling
      * the menu with the back/menu button, or when an item is selected).
-     *  
+     *
      * @param menu The options menu as last shown or first initialized by
      *             onCreateOptionsMenu().
      */
@@ -2874,15 +3148,17 @@
             mParent.onOptionsMenuClosed(menu);
         }
     }
-    
+
     /**
      * Programmatically opens the options menu. If the options menu is already
      * open, this method does nothing.
      */
     public void openOptionsMenu() {
-        mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null);
+        if (mActionBar == null || !mActionBar.openOptionsMenu()) {
+            mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null);
+        }
     }
-    
+
     /**
      * Progammatically closes the options menu. If the options menu is already
      * closed, this method does nothing.
@@ -2913,43 +3189,43 @@
      * {@link OnCreateContextMenuListener} on the view to this activity, so
      * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be
      * called when it is time to show the context menu.
-     * 
+     *
      * @see #unregisterForContextMenu(View)
      * @param view The view that should show a context menu.
      */
     public void registerForContextMenu(View view) {
         view.setOnCreateContextMenuListener(this);
     }
-    
+
     /**
      * Prevents a context menu to be shown for the given view. This method will remove the
      * {@link OnCreateContextMenuListener} on the view.
-     * 
+     *
      * @see #registerForContextMenu(View)
      * @param view The view that should stop showing a context menu.
      */
     public void unregisterForContextMenu(View view) {
         view.setOnCreateContextMenuListener(null);
     }
-    
+
     /**
      * Programmatically opens the context menu for a particular {@code view}.
      * The {@code view} should have been added via
      * {@link #registerForContextMenu(View)}.
-     * 
+     *
      * @param view The view to show the context menu for.
      */
     public void openContextMenu(View view) {
         view.showContextMenu();
     }
-    
+
     /**
      * Programmatically closes the most recently opened context menu, if showing.
      */
     public void closeContextMenu() {
         mWindow.closePanel(Window.FEATURE_CONTEXT_MENU);
     }
-    
+
     /**
      * This hook is called whenever an item in a context menu is selected. The
      * default implementation simply returns false to have the normal processing
@@ -2962,7 +3238,7 @@
      * <p>
      * Derived classes should call through to the base class for it to perform
      * the default menu handling.
-     * 
+     *
      * @param item The context menu item that was selected.
      * @return boolean Return false to allow normal context menu processing to
      *         proceed, true to consume it here.
@@ -2978,7 +3254,7 @@
      * This hook is called whenever the context menu is being closed (either by
      * the user canceling the menu with the back/menu button, or when an item is
      * selected).
-     * 
+     *
      * @param menu The context menu that is being closed.
      */
     public void onContextMenuClosed(Menu menu) {
@@ -3028,6 +3304,7 @@
      * {@link FragmentManager} instead; this is also
      * available on older platforms through the Android compatibility package.
      */
+    @Nullable
     @Deprecated
     protected Dialog onCreateDialog(int id, Bundle args) {
         return onCreateDialog(id);
@@ -3046,14 +3323,14 @@
      * Provides an opportunity to prepare a managed dialog before it is being
      * shown.  The default implementation calls through to
      * {@link #onPrepareDialog(int, Dialog)} for compatibility.
-     * 
+     *
      * <p>
      * Override this if you need to update a managed dialog based on the state
      * of the application each time it is shown. For example, a time picker
      * dialog might want to be updated with the current time. You should call
      * through to the superclass's implementation. The default implementation
      * will set this Activity as the owner activity on the Dialog.
-     * 
+     *
      * @param id The id of the managed dialog.
      * @param dialog The dialog.
      * @param args The dialog arguments provided to {@link #showDialog(int, Bundle)}.
@@ -3104,7 +3381,7 @@
      * If you need to rebuild the dialog, call {@link #removeDialog(int)} first.
      * @return Returns true if the Dialog was created; false is returned if
      * it is not created because {@link #onCreateDialog(int, Bundle)} returns false.
-     * 
+     *
      * @see Dialog
      * @see #onCreateDialog(int, Bundle)
      * @see #onPrepareDialog(int, Dialog, Bundle)
@@ -3115,6 +3392,7 @@
      * {@link FragmentManager} instead; this is also
      * available on older platforms through the Android compatibility package.
      */
+    @Nullable
     @Deprecated
     public final boolean showDialog(int id, Bundle args) {
         if (mManagedDialogs == null) {
@@ -3129,7 +3407,7 @@
             }
             mManagedDialogs.put(id, md);
         }
-        
+
         md.mArgs = args;
         onPrepareDialog(id, md.mDialog, args);
         md.mDialog.show();
@@ -3158,7 +3436,7 @@
         if (mManagedDialogs == null) {
             throw missingDialog(id);
         }
-        
+
         final ManagedDialog md = mManagedDialogs.get(id);
         if (md == null) {
             throw missingDialog(id);
@@ -3185,7 +3463,7 @@
      * <p>As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, this function
      * will not throw an exception if you try to remove an ID that does not
      * currently have an associated dialog.</p>
-     * 
+     *
      * @param id The id of the managed dialog.
      *
      * @see #onCreateDialog(int, Bundle)
@@ -3210,61 +3488,61 @@
 
     /**
      * This hook is called when the user signals the desire to start a search.
-     * 
+     *
      * <p>You can use this function as a simple way to launch the search UI, in response to a
-     * menu item, search button, or other widgets within your activity. Unless overidden, 
+     * menu item, search button, or other widgets within your activity. Unless overidden,
      * calling this function is the same as calling
      * {@link #startSearch startSearch(null, false, null, false)}, which launches
      * search for the current activity as specified in its manifest, see {@link SearchManager}.
-     * 
+     *
      * <p>You can override this function to force global search, e.g. in response to a dedicated
      * search key, or to block search entirely (by simply returning false).
-     * 
+     *
      * @return Returns {@code true} if search launched, and {@code false} if activity blocks it.
      *         The default implementation always returns {@code true}.
-     * 
+     *
      * @see android.app.SearchManager
      */
     public boolean onSearchRequested() {
-        startSearch(null, false, null, false); 
+        startSearch(null, false, null, false);
         return true;
     }
-    
+
     /**
      * This hook is called to launch the search UI.
-     * 
-     * <p>It is typically called from onSearchRequested(), either directly from 
-     * Activity.onSearchRequested() or from an overridden version in any given 
+     *
+     * <p>It is typically called from onSearchRequested(), either directly from
+     * Activity.onSearchRequested() or from an overridden version in any given
      * Activity.  If your goal is simply to activate search, it is preferred to call
-     * onSearchRequested(), which may have been overriden elsewhere in your Activity.  If your goal
+     * onSearchRequested(), which may have been overridden elsewhere in your Activity.  If your goal
      * is to inject specific data such as context data, it is preferred to <i>override</i>
      * onSearchRequested(), so that any callers to it will benefit from the override.
-     * 
-     * @param initialQuery Any non-null non-empty string will be inserted as 
+     *
+     * @param initialQuery Any non-null non-empty string will be inserted as
      * pre-entered text in the search query box.
-     * @param selectInitialQuery If true, the intial query will be preselected, which means that
+     * @param selectInitialQuery If true, the initial query will be preselected, which means that
      * any further typing will replace it.  This is useful for cases where an entire pre-formed
      * query is being inserted.  If false, the selection point will be placed at the end of the
      * inserted query.  This is useful when the inserted query is text that the user entered,
      * and the user would expect to be able to keep typing.  <i>This parameter is only meaningful
      * if initialQuery is a non-empty string.</i>
-     * @param appSearchData An application can insert application-specific 
-     * context here, in order to improve quality or specificity of its own 
+     * @param appSearchData An application can insert application-specific
+     * context here, in order to improve quality or specificity of its own
      * searches.  This data will be returned with SEARCH intent(s).  Null if
      * no extra data is required.
      * @param globalSearch If false, this will only launch the search that has been specifically
-     * defined by the application (which is usually defined as a local search).  If no default 
+     * defined by the application (which is usually defined as a local search).  If no default
      * search is defined in the current application or activity, global search will be launched.
      * If true, this will always launch a platform-global (e.g. web-based) search instead.
-     * 
+     *
      * @see android.app.SearchManager
      * @see #onSearchRequested
      */
-    public void startSearch(String initialQuery, boolean selectInitialQuery, 
-            Bundle appSearchData, boolean globalSearch) {
+    public void startSearch(@Nullable String initialQuery, boolean selectInitialQuery,
+            @Nullable Bundle appSearchData, boolean globalSearch) {
         ensureSearchManager();
         mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(),
-                        appSearchData, globalSearch); 
+                appSearchData, globalSearch);
     }
 
     /**
@@ -3277,7 +3555,7 @@
      * searches.  This data will be returned with SEARCH intent(s).  Null if
      * no extra data is required.
      */
-    public void triggerSearch(String query, Bundle appSearchData) {
+    public void triggerSearch(String query, @Nullable Bundle appSearchData) {
         ensureSearchManager();
         mSearchManager.triggerSearch(query, getComponentName(), appSearchData);
     }
@@ -3286,7 +3564,7 @@
      * Request that key events come to this activity. Use this if your
      * activity has no views with focus, but the activity still wants
      * a chance to process key events.
-     * 
+     *
      * @see android.view.Window#takeKeyEvents
      */
     public void takeKeyEvents(boolean get) {
@@ -3296,12 +3574,12 @@
     /**
      * Enable extended window features.  This is a convenience for calling
      * {@link android.view.Window#requestFeature getWindow().requestFeature()}.
-     * 
+     *
      * @param featureId The desired feature as defined in
      *                  {@link android.view.Window}.
      * @return Returns true if the requested feature is supported and now
      *         enabled.
-     * 
+     *
      * @see android.view.Window#requestFeature
      */
     public final boolean requestWindowFeature(int featureId) {
@@ -3344,6 +3622,7 @@
      * Convenience for calling
      * {@link android.view.Window#getLayoutInflater}.
      */
+    @NonNull
     public LayoutInflater getLayoutInflater() {
         return getWindow().getLayoutInflater();
     }
@@ -3351,10 +3630,11 @@
     /**
      * Returns a {@link MenuInflater} with this context.
      */
+    @NonNull
     public MenuInflater getMenuInflater() {
         // Make sure that action views can get an appropriate theme.
         if (mMenuInflater == null) {
-            initActionBar();
+            initWindowDecorActionBar();
             if (mActionBar != null) {
                 mMenuInflater = new MenuInflater(mActionBar.getThemedContext(), this);
             } else {
@@ -3377,6 +3657,18 @@
             }
             theme.applyStyle(resid, false);
         }
+
+        // Get the primary color and update the TaskDescription for this activity
+        if (theme != null) {
+            TypedArray a = theme.obtainStyledAttributes(com.android.internal.R.styleable.Theme);
+            int colorPrimary = a.getColor(com.android.internal.R.styleable.Theme_colorPrimary, 0);
+            a.recycle();
+            if (colorPrimary != 0) {
+                ActivityManager.TaskDescription v = new ActivityManager.TaskDescription(null, null,
+                        colorPrimary);
+                setTaskDescription(v);
+            }
+        }
     }
 
     /**
@@ -3389,7 +3681,7 @@
      *
      * @throws android.content.ActivityNotFoundException
      *
-     * @see #startActivity 
+     * @see #startActivity
      */
     public void startActivityForResult(Intent intent, int requestCode) {
         startActivityForResult(intent, requestCode, null);
@@ -3398,8 +3690,8 @@
     /**
      * Launch an activity for which you would like a result when it finished.
      * When this activity exits, your
-     * onActivityResult() method will be called with the given requestCode. 
-     * Using a negative requestCode is the same as calling 
+     * onActivityResult() method will be called with the given requestCode.
+     * Using a negative requestCode is the same as calling
      * {@link #startActivity} (the activity is not launched as a sub-activity).
      *
      * <p>Note that this method should only be used with Intent protocols
@@ -3409,11 +3701,11 @@
      * are launching uses the singleTask launch mode, it will not run in your
      * task and thus you will immediately receive a cancel result.
      *
-     * <p>As a special case, if you call startActivityForResult() with a requestCode 
+     * <p>As a special case, if you call startActivityForResult() with a requestCode
      * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
-     * activity, then your window will not be displayed until a result is 
-     * returned back from the started activity.  This is to avoid visible 
-     * flickering when redirecting to another activity. 
+     * activity, then your window will not be displayed until a result is
+     * returned back from the started activity.  This is to avoid visible
+     * flickering when redirecting to another activity.
      *
      * <p>This method throws {@link android.content.ActivityNotFoundException}
      * if there was no Activity found to run the given Intent.
@@ -3427,9 +3719,9 @@
      *
      * @throws android.content.ActivityNotFoundException
      *
-     * @see #startActivity 
+     * @see #startActivity
      */
-    public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
+    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
         if (mParent == null) {
             Instrumentation.ActivityResult ar =
                 mInstrumentation.execStartActivity(
@@ -3465,6 +3757,51 @@
                 mParent.startActivityFromChild(this, intent, requestCode);
             }
         }
+        if (options != null && !isTopOfTask()) {
+            mActivityTransitionState.startExitOutTransition(this, options);
+        }
+    }
+
+    /**
+     * @hide Implement to provide correct calling token.
+     */
+    public void startActivityForResultAsUser(Intent intent, int requestCode, UserHandle user) {
+        startActivityForResultAsUser(intent, requestCode, null, user);
+    }
+
+    /**
+     * @hide Implement to provide correct calling token.
+     */
+    public void startActivityForResultAsUser(Intent intent, int requestCode,
+            @Nullable Bundle options, UserHandle user) {
+        if (options != null) {
+            mActivityTransitionState.startExitOutTransition(this, options);
+        }
+        if (mParent != null) {
+            throw new RuntimeException("Can't be called from a child");
+        }
+        Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
+                this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode,
+                options, user);
+        if (ar != null) {
+            mMainThread.sendActivityResult(
+                mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());
+        }
+        if (requestCode >= 0) {
+            // If this start is requesting a result, we can avoid making
+            // the activity visible until the result is received.  Setting
+            // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
+            // activity hidden during this time, to avoid flickering.
+            // This can only be done when a result is requested because
+            // that guarantees we will get information back when the
+            // activity is finished, no matter what happens to it.
+            mStartedActivity = true;
+        }
+
+        final View decor = mWindow != null ? mWindow.peekDecorView() : null;
+        if (decor != null) {
+            decor.cancelPendingInputEvents();
+        }
     }
 
     /**
@@ -3479,7 +3816,7 @@
      */
     public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
         if (mParent != null) {
-            throw new RuntimeException("Called be called from a child");
+            throw new RuntimeException("Can't be called from a child");
         }
         Instrumentation.ActivityResult ar =
                 mInstrumentation.execStartActivity(
@@ -3493,6 +3830,29 @@
     }
 
     /**
+     * Start a new activity as if it was started by the activity that started our
+     * current activity.  This is for the resolver and chooser activities, which operate
+     * as intermediaries that dispatch their intent to the target the user selects -- to
+     * do this, they must perform all security checks including permission grants as if
+     * their launch had come from the original activity.
+     * @hide
+     */
+    public void startActivityAsCaller(Intent intent, @Nullable Bundle options) {
+        if (mParent != null) {
+            throw new RuntimeException("Can't be called from a child");
+        }
+        Instrumentation.ActivityResult ar =
+                mInstrumentation.execStartActivityAsCaller(
+                        this, mMainThread.getApplicationThread(), mToken, this,
+                        intent, -1, options);
+        if (ar != null) {
+            mMainThread.sendActivityResult(
+                mToken, mEmbeddedID, -1, ar.getResultCode(),
+                ar.getResultData());
+        }
+    }
+
+    /**
      * Same as calling {@link #startIntentSenderForResult(IntentSender, int,
      * Intent, int, int, int, Bundle)} with no options.
      *
@@ -3508,7 +3868,7 @@
      * @param extraFlags Always set to 0.
      */
     public void startIntentSenderForResult(IntentSender intent, int requestCode,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
             throws IntentSender.SendIntentException {
         startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
                 flagsValues, extraFlags, null);
@@ -3522,7 +3882,7 @@
      * here; otherwise, its associated action will be executed (such as
      * sending a broadcast) as if you had called
      * {@link IntentSender#sendIntent IntentSender.sendIntent} on it.
-     * 
+     *
      * @param intent The IntentSender to launch.
      * @param requestCode If >= 0, this code will be returned in
      *                    onActivityResult() when the activity exits.
@@ -3540,7 +3900,7 @@
      * override any that conflict with those given by the IntentSender.
      */
     public void startIntentSenderForResult(IntentSender intent, int requestCode,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
             Bundle options) throws IntentSender.SendIntentException {
         if (mParent == null) {
             startIntentSenderForResultInner(intent, requestCode, fillInIntent,
@@ -3602,7 +3962,7 @@
      */
     @Override
     public void startActivity(Intent intent) {
-        startActivity(intent, null);
+        this.startActivity(intent, null);
     }
 
     /**
@@ -3613,22 +3973,22 @@
      * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not
      * required; if not specified, the new activity will be added to the
      * task of the caller.
-     * 
+     *
      * <p>This method throws {@link android.content.ActivityNotFoundException}
      * if there was no Activity found to run the given Intent.
-     * 
-     * @param intent The intent to start. 
+     *
+     * @param intent The intent to start.
      * @param options Additional options for how the Activity should be started.
      * See {@link android.content.Context#startActivity(Intent, Bundle)
      * Context.startActivity(Intent, Bundle)} for more details.
-     * 
+     *
      * @throws android.content.ActivityNotFoundException
      *
      * @see {@link #startActivity(Intent)}
-     * @see #startActivityForResult 
+     * @see #startActivityForResult
      */
     @Override
-    public void startActivity(Intent intent, Bundle options) {
+    public void startActivity(Intent intent, @Nullable Bundle options) {
         if (options != null) {
             startActivityForResult(intent, -1, options);
         } else {
@@ -3677,7 +4037,7 @@
      * @see #startActivityForResult
      */
     @Override
-    public void startActivities(Intent[] intents, Bundle options) {
+    public void startActivities(Intent[] intents, @Nullable Bundle options) {
         mInstrumentation.execStartActivities(this, mMainThread.getApplicationThread(),
                 mToken, this, intents, options);
     }
@@ -3685,7 +4045,7 @@
     /**
      * Same as calling {@link #startIntentSender(IntentSender, Intent, int, int, int, Bundle)}
      * with no options.
-     * 
+     *
      * @param intent The IntentSender to launch.
      * @param fillInIntent If non-null, this will be provided as the
      * intent parameter to {@link IntentSender#sendIntent}.
@@ -3696,7 +4056,7 @@
      * @param extraFlags Always set to 0.
      */
     public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
             throws IntentSender.SendIntentException {
         startIntentSender(intent, fillInIntent, flagsMask, flagsValues,
                 extraFlags, null);
@@ -3723,7 +4083,7 @@
      * override any that conflict with those given by the IntentSender.
      */
     public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
             Bundle options) throws IntentSender.SendIntentException {
         if (options != null) {
             startIntentSenderForResult(intent, -1, fillInIntent, flagsMask,
@@ -3751,26 +4111,26 @@
      * @see #startActivity
      * @see #startActivityForResult
      */
-    public boolean startActivityIfNeeded(Intent intent, int requestCode) {
+    public boolean startActivityIfNeeded(@NonNull Intent intent, int requestCode) {
         return startActivityIfNeeded(intent, requestCode, null);
     }
 
     /**
      * A special variation to launch an activity only if a new activity
      * instance is needed to handle the given Intent.  In other words, this is
-     * just like {@link #startActivityForResult(Intent, int)} except: if you are 
+     * just like {@link #startActivityForResult(Intent, int)} except: if you are
      * using the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag, or
-     * singleTask or singleTop 
+     * singleTask or singleTop
      * {@link android.R.styleable#AndroidManifestActivity_launchMode launchMode},
-     * and the activity 
-     * that handles <var>intent</var> is the same as your currently running 
-     * activity, then a new instance is not needed.  In this case, instead of 
-     * the normal behavior of calling {@link #onNewIntent} this function will 
-     * return and you can handle the Intent yourself. 
-     * 
+     * and the activity
+     * that handles <var>intent</var> is the same as your currently running
+     * activity, then a new instance is not needed.  In this case, instead of
+     * the normal behavior of calling {@link #onNewIntent} this function will
+     * return and you can handle the Intent yourself.
+     *
      * <p>This function can only be called from a top-level activity; if it is
      * called from a child activity, a runtime exception will be thrown.
-     * 
+     *
      * @param intent The intent to start.
      * @param requestCode If >= 0, this code will be returned in
      *         onActivityResult() when the activity exits, as described in
@@ -3778,14 +4138,15 @@
      * @param options Additional options for how the Activity should be started.
      * See {@link android.content.Context#startActivity(Intent, Bundle)
      * Context.startActivity(Intent, Bundle)} for more details.
-     * 
+     *
      * @return If a new activity was launched then true is returned; otherwise
      *         false is returned and you must handle the Intent yourself.
-     *  
+     *
      * @see #startActivity
      * @see #startActivityForResult
      */
-    public boolean startActivityIfNeeded(Intent intent, int requestCode, Bundle options) {
+    public boolean startActivityIfNeeded(@NonNull Intent intent, int requestCode,
+            @Nullable Bundle options) {
         if (mParent == null) {
             int result = ActivityManager.START_RETURN_INTENT_TO_CALLER;
             try {
@@ -3793,10 +4154,9 @@
                 intent.prepareToLeaveProcess();
                 result = ActivityManagerNative.getDefault()
                     .startActivity(mMainThread.getApplicationThread(), getBasePackageName(),
-                            intent, intent.resolveTypeIfNeeded(getContentResolver()),
-                            mToken, mEmbeddedID, requestCode,
-                            ActivityManager.START_FLAG_ONLY_IF_NEEDED, null, null,
-                            options);
+                            intent, intent.resolveTypeIfNeeded(getContentResolver()), mToken,
+                            mEmbeddedID, requestCode, ActivityManager.START_FLAG_ONLY_IF_NEEDED,
+                            null, options);
             } catch (RemoteException e) {
                 // Empty
             }
@@ -3834,7 +4194,7 @@
      * wasn't.  In general, if true is returned you will then want to call
      * finish() on yourself.
      */
-    public boolean startNextMatchingActivity(Intent intent) {
+    public boolean startNextMatchingActivity(@NonNull Intent intent) {
         return startNextMatchingActivity(intent, null);
     }
 
@@ -3843,7 +4203,7 @@
      * other activity components.  You can use this to hand the Intent off
      * to the next Activity that can handle it.  You typically call this in
      * {@link #onCreate} with the Intent returned by {@link #getIntent}.
-     * 
+     *
      * @param intent The intent to dispatch to the next activity.  For
      * correct behavior, this must be the same as the Intent that started
      * your own activity; the only changes you can make are to the extras
@@ -3851,13 +4211,13 @@
      * @param options Additional options for how the Activity should be started.
      * See {@link android.content.Context#startActivity(Intent, Bundle)
      * Context.startActivity(Intent, Bundle)} for more details.
-     * 
+     *
      * @return Returns a boolean indicating whether there was another Activity
      * to start: true if there was a next activity to start, false if there
      * wasn't.  In general, if true is returned you will then want to call
      * finish() on yourself.
      */
-    public boolean startNextMatchingActivity(Intent intent, Bundle options) {
+    public boolean startNextMatchingActivity(@NonNull Intent intent, @Nullable Bundle options) {
         if (mParent == null) {
             try {
                 intent.migrateExtraStreamToClipData();
@@ -3887,32 +4247,32 @@
      * @see #startActivity
      * @see #startActivityForResult
      */
-    public void startActivityFromChild(Activity child, Intent intent,
+    public void startActivityFromChild(@NonNull Activity child, Intent intent,
             int requestCode) {
         startActivityFromChild(child, intent, requestCode, null);
     }
 
     /**
-     * This is called when a child activity of this one calls its 
+     * This is called when a child activity of this one calls its
      * {@link #startActivity} or {@link #startActivityForResult} method.
-     * 
+     *
      * <p>This method throws {@link android.content.ActivityNotFoundException}
      * if there was no Activity found to run the given Intent.
-     * 
+     *
      * @param child The activity making the call.
      * @param intent The intent to start.
      * @param requestCode Reply request code.  < 0 if reply is not requested.
      * @param options Additional options for how the Activity should be started.
      * See {@link android.content.Context#startActivity(Intent, Bundle)
      * Context.startActivity(Intent, Bundle)} for more details.
-     * 
+     *
      * @throws android.content.ActivityNotFoundException
-     * 
-     * @see #startActivity 
-     * @see #startActivityForResult 
+     *
+     * @see #startActivity
+     * @see #startActivityForResult
      */
-    public void startActivityFromChild(Activity child, Intent intent, 
-            int requestCode, Bundle options) {
+    public void startActivityFromChild(@NonNull Activity child, Intent intent,
+            int requestCode, @Nullable Bundle options) {
         Instrumentation.ActivityResult ar =
             mInstrumentation.execStartActivity(
                 this, mMainThread.getApplicationThread(), mToken, child,
@@ -3937,33 +4297,36 @@
      * @see Fragment#startActivity
      * @see Fragment#startActivityForResult
      */
-    public void startActivityFromFragment(Fragment fragment, Intent intent, 
+    public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
             int requestCode) {
         startActivityFromFragment(fragment, intent, requestCode, null);
     }
 
     /**
-     * This is called when a Fragment in this activity calls its 
+     * This is called when a Fragment in this activity calls its
      * {@link Fragment#startActivity} or {@link Fragment#startActivityForResult}
      * method.
-     * 
+     *
      * <p>This method throws {@link android.content.ActivityNotFoundException}
      * if there was no Activity found to run the given Intent.
-     * 
+     *
      * @param fragment The fragment making the call.
      * @param intent The intent to start.
-     * @param requestCode Reply request code.  < 0 if reply is not requested. 
+     * @param requestCode Reply request code.  < 0 if reply is not requested.
      * @param options Additional options for how the Activity should be started.
      * See {@link android.content.Context#startActivity(Intent, Bundle)
      * Context.startActivity(Intent, Bundle)} for more details.
-     * 
+     *
      * @throws android.content.ActivityNotFoundException
-     * 
-     * @see Fragment#startActivity 
-     * @see Fragment#startActivityForResult 
+     *
+     * @see Fragment#startActivity
+     * @see Fragment#startActivityForResult
      */
-    public void startActivityFromFragment(Fragment fragment, Intent intent, 
-            int requestCode, Bundle options) {
+    public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
+            int requestCode, @Nullable Bundle options) {
+        if (options != null) {
+            mActivityTransitionState.startExitOutTransition(this, options);
+        }
         Instrumentation.ActivityResult ar =
             mInstrumentation.execStartActivity(
                 this, mMainThread.getApplicationThread(), mToken, fragment,
@@ -3995,7 +4358,7 @@
      */
     public void startIntentSenderFromChild(Activity child, IntentSender intent,
             int requestCode, Intent fillInIntent, int flagsMask, int flagsValues,
-            int extraFlags, Bundle options)
+            int extraFlags, @Nullable Bundle options)
             throws IntentSender.SendIntentException {
         startIntentSenderForResultInner(intent, requestCode, fillInIntent,
                 flagsMask, flagsValues, child, options);
@@ -4025,14 +4388,14 @@
         } catch (RemoteException e) {
         }
     }
-    
+
     /**
      * Call this to set the result that your activity will return to its
      * caller.
-     * 
+     *
      * @param resultCode The result code to propagate back to the originating
      *                   activity, often RESULT_CANCELED or RESULT_OK
-     * 
+     *
      * @see #RESULT_CANCELED
      * @see #RESULT_OK
      * @see #RESULT_FIRST_USER
@@ -4061,7 +4424,7 @@
      * @param resultCode The result code to propagate back to the originating
      *                   activity, often RESULT_CANCELED or RESULT_OK
      * @param data The data to propagate back to the originating activity.
-     * 
+     *
      * @see #RESULT_CANCELED
      * @see #RESULT_OK
      * @see #RESULT_FIRST_USER
@@ -4079,10 +4442,10 @@
      * the data in {@link #setResult setResult()} will be sent to.  You can
      * use this information to validate that the recipient is allowed to
      * receive the data.
-     * 
+     *
      * <p class="note">Note: if the calling activity is not expecting a result (that is it
-     * did not use the {@link #startActivityForResult} 
-     * form that includes a request code), then the calling package will be 
+     * did not use the {@link #startActivityForResult}
+     * form that includes a request code), then the calling package will be
      * null.</p>
      *
      * <p class="note">Note: prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
@@ -4090,10 +4453,11 @@
      * package was no longer running, it would return null instead of the proper package
      * name.  You can use {@link #getCallingActivity()} and retrieve the package name
      * from that instead.</p>
-     * 
+     *
      * @return The package of the activity that will receive your
      *         reply, or null if none.
      */
+    @Nullable
     public String getCallingPackage() {
         try {
             return ActivityManagerNative.getDefault().getCallingPackage(mToken);
@@ -4107,15 +4471,16 @@
      * who the data in {@link #setResult setResult()} will be sent to.  You
      * can use this information to validate that the recipient is allowed to
      * receive the data.
-     * 
+     *
      * <p class="note">Note: if the calling activity is not expecting a result (that is it
-     * did not use the {@link #startActivityForResult} 
-     * form that includes a request code), then the calling package will be 
-     * null. 
-     * 
+     * did not use the {@link #startActivityForResult}
+     * form that includes a request code), then the calling package will be
+     * null.
+     *
      * @return The ComponentName of the activity that will receive your
      *         reply, or null if none.
      */
+    @Nullable
     public ComponentName getCallingActivity() {
         try {
             return ActivityManagerNative.getDefault().getCallingActivity(mToken);
@@ -4130,7 +4495,7 @@
      * UI itself, but can't just finish prior to onResume() because it needs
      * to wait for a service binding or such.  Setting this to false allows
      * you to prevent your UI from being shown during that time.
-     * 
+     *
      * <p>The default value for this is taken from the
      * {@link android.R.attr#windowNoDisplay} attribute of the activity's theme.
      */
@@ -4143,7 +4508,7 @@
             }
         }
     }
-    
+
     void makeVisible() {
         if (!mWindowAdded) {
             ViewManager wm = getWindowManager();
@@ -4152,16 +4517,16 @@
         }
         mDecor.setVisibility(View.VISIBLE);
     }
-    
+
     /**
      * Check to see whether this activity is in the process of finishing,
      * either because you called {@link #finish} on it or someone else
      * has requested that it finished.  This is often used in
      * {@link #onPause} to determine whether the activity is simply pausing or
      * completely finishing.
-     * 
+     *
      * @return If the activity is finishing, returns true; else returns false.
-     * 
+     *
      * @see #finish
      */
     public boolean isFinishing() {
@@ -4181,7 +4546,7 @@
      * recreated with a new configuration. This is often used in
      * {@link #onStop} to determine whether the state needs to be cleaned up or will be passed
      * on to the next instance of the activity via {@link #onRetainNonConfigurationInstance()}.
-     * 
+     *
      * @return If the activity is being torn down in order to be recreated with a new configuration,
      * returns true; else returns false.
      */
@@ -4206,11 +4571,10 @@
     }
 
     /**
-     * Call this when your activity is done and should be closed.  The
-     * ActivityResult is propagated back to whoever launched you via
-     * onActivityResult().
+     * Finishes the current activity and specifies whether to remove the task associated with this
+     * activity.
      */
-    public void finish() {
+    private void finish(boolean finishTask) {
         if (mParent == null) {
             int resultCode;
             Intent resultData;
@@ -4224,7 +4588,7 @@
                     resultData.prepareToLeaveProcess();
                 }
                 if (ActivityManagerNative.getDefault()
-                    .finishActivity(mToken, resultCode, resultData)) {
+                        .finishActivity(mToken, resultCode, resultData, finishTask)) {
                     mFinished = true;
                 }
             } catch (RemoteException e) {
@@ -4236,6 +4600,15 @@
     }
 
     /**
+     * Call this when your activity is done and should be closed.  The
+     * ActivityResult is propagated back to whoever launched you via
+     * onActivityResult().
+     */
+    public void finish() {
+        finish(false);
+    }
+
+    /**
      * Finish this activity as well as all activities immediately below it
      * in the current task that have the same affinity.  This is typically
      * used when an application can be launched on to another task (such as
@@ -4266,12 +4639,12 @@
     }
 
     /**
-     * This is called when a child activity of this one calls its 
+     * This is called when a child activity of this one calls its
      * {@link #finish} method.  The default implementation simply calls
      * finish() on this activity (the parent), finishing the entire group.
-     * 
+     *
      * @param child The activity making the call.
-     * 
+     *
      * @see #finish
      */
     public void finishFromChild(Activity child) {
@@ -4279,9 +4652,22 @@
     }
 
     /**
+     * Reverses the Activity Scene entry Transition and triggers the calling Activity
+     * to reverse its exit Transition. When the exit Transition completes,
+     * {@link #finish()} is called. If no entry Transition was used, finish() is called
+     * immediately and the Activity exit Transition is run.
+     * @see android.app.ActivityOptions#makeSceneTransitionAnimation(Activity, android.util.Pair[])
+     */
+    public void finishAfterTransition() {
+        if (!mActivityTransitionState.startExitBackTransition(this)) {
+            finish();
+        }
+    }
+
+    /**
      * Force finish another activity that you had previously started with
      * {@link #startActivityForResult}.
-     * 
+     *
      * @param requestCode The request code of the activity that you had
      *                    given to startActivityForResult().  If there are multiple
      *                    activities started with this request code, they
@@ -4303,12 +4689,12 @@
     /**
      * This is called when a child activity of this one calls its
      * finishActivity().
-     * 
+     *
      * @param child The activity making the call.
      * @param requestCode Request code that had been used to start the
      *                    activity.
      */
-    public void finishActivityFromChild(Activity child, int requestCode) {
+    public void finishActivityFromChild(@NonNull Activity child, int requestCode) {
         try {
             ActivityManagerNative.getDefault()
                 .finishSubActivity(mToken, child.mEmbeddedID, requestCode);
@@ -4318,15 +4704,43 @@
     }
 
     /**
+     * Call this when your activity is done and should be closed and the task should be completely
+     * removed as a part of finishing the Activity.
+     */
+    public void finishAndRemoveTask() {
+        finish(true);
+    }
+
+    /**
+     * Ask that the local app instance of this activity be released to free up its memory.
+     * This is asking for the activity to be destroyed, but does <b>not</b> finish the activity --
+     * a new instance of the activity will later be re-created if needed due to the user
+     * navigating back to it.
+     *
+     * @return Returns true if the activity was in a state that it has started the process
+     * of destroying its current instance; returns false if for any reason this could not
+     * be done: it is currently visible to the user, it is already being destroyed, it is
+     * being finished, it hasn't yet saved its state, etc.
+     */
+    public boolean releaseInstance() {
+        try {
+            return ActivityManagerNative.getDefault().releaseActivityInstance(mToken);
+        } catch (RemoteException e) {
+            // Empty
+        }
+        return false;
+    }
+
+    /**
      * Called when an activity you launched exits, giving you the requestCode
      * you started it with, the resultCode it returned, and any additional
      * data from it.  The <var>resultCode</var> will be
      * {@link #RESULT_CANCELED} if the activity explicitly returned that,
      * didn't return any result, or crashed during its operation.
-     * 
+     *
      * <p>You will receive this call immediately before onResume() when your
      * activity is re-starting.
-     * 
+     *
      * @param requestCode The integer request code originally supplied to
      *                    startActivityForResult(), allowing you to identify who this
      *                    result came from.
@@ -4334,7 +4748,7 @@
      *                   through its setResult().
      * @param data An Intent, which can return result data to the caller
      *               (various data can be attached to Intent "extras").
-     * 
+     *
      * @see #startActivityForResult
      * @see #createPendingResult
      * @see #setResult(int)
@@ -4343,12 +4757,33 @@
     }
 
     /**
-     * Create a new PendingIntent object which you can hand to others 
-     * for them to use to send result data back to your 
-     * {@link #onActivityResult} callback.  The created object will be either 
-     * one-shot (becoming invalid after a result is sent back) or multiple 
-     * (allowing any number of results to be sent through it). 
-     *  
+     * Called when an activity you launched with an activity transition exposes this
+     * Activity through a returning activity transition, giving you the resultCode
+     * and any additional data from it. This method will only be called if the activity
+     * set a result code other than {@link #RESULT_CANCELED} and it supports activity
+     * transitions with {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
+     *
+     * <p>The purpose of this function is to let the called Activity send a hint about
+     * its state so that this underlying Activity can prepare to be exposed. A call to
+     * this method does not guarantee that the called Activity has or will be exiting soon.
+     * It only indicates that it will expose this Activity's Window and it has
+     * some data to pass to prepare it.</p>
+     *
+     * @param resultCode The integer result code returned by the child activity
+     *                   through its setResult().
+     * @param data An Intent, which can return result data to the caller
+     *               (various data can be attached to Intent "extras").
+     */
+    public void onActivityReenter(int resultCode, Intent data) {
+    }
+
+    /**
+     * Create a new PendingIntent object which you can hand to others
+     * for them to use to send result data back to your
+     * {@link #onActivityResult} callback.  The created object will be either
+     * one-shot (becoming invalid after a result is sent back) or multiple
+     * (allowing any number of results to be sent through it).
+     *
      * @param requestCode Private request code for the sender that will be
      * associated with the result data when it is returned.  The sender can not
      * modify this value, allowing you to identify incoming results.
@@ -4361,16 +4796,16 @@
      * or any of the flags as supported by
      * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
      * of the intent that can be supplied when the actual send happens.
-     * 
+     *
      * @return Returns an existing or new PendingIntent matching the given
      * parameters.  May return null only if
      * {@link PendingIntent#FLAG_NO_CREATE PendingIntent.FLAG_NO_CREATE} has been
      * supplied.
-     * 
+     *
      * @see PendingIntent
      */
-    public PendingIntent createPendingResult(int requestCode, Intent data,
-            int flags) {
+    public PendingIntent createPendingResult(int requestCode, @NonNull Intent data,
+            @PendingIntent.Flags int flags) {
         String packageName = getPackageName();
         try {
             data.prepareToLeaveProcess();
@@ -4393,11 +4828,11 @@
      * orientation, the screen will immediately be changed (possibly causing
      * the activity to be restarted). Otherwise, this will be used the next
      * time the activity is visible.
-     * 
+     *
      * @param requestedOrientation An orientation constant as used in
      * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
      */
-    public void setRequestedOrientation(int requestedOrientation) {
+    public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
         if (mParent == null) {
             try {
                 ActivityManagerNative.getDefault().setRequestedOrientation(
@@ -4409,16 +4844,17 @@
             mParent.setRequestedOrientation(requestedOrientation);
         }
     }
-    
+
     /**
      * Return the current requested orientation of the activity.  This will
      * either be the orientation requested in its component's manifest, or
      * the last requested orientation given to
      * {@link #setRequestedOrientation(int)}.
-     * 
+     *
      * @return Returns an orientation constant as used in
      * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
      */
+    @ActivityInfo.ScreenOrientation
     public int getRequestedOrientation() {
         if (mParent == null) {
             try {
@@ -4432,11 +4868,11 @@
         }
         return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     }
-    
+
     /**
      * Return the identifier of the task this activity is in.  This identifier
      * will remain the same for the lifetime of the activity.
-     * 
+     *
      * @return Task identifier, an opaque integer.
      */
     public int getTaskId() {
@@ -4451,7 +4887,7 @@
     /**
      * Return whether this activity is the root of a task.  The root is the
      * first activity in a task.
-     * 
+     *
      * @return True if this is the root activity, else false.
      */
     public boolean isTaskRoot() {
@@ -4466,11 +4902,11 @@
     /**
      * Move the task containing this activity to the back of the activity
      * stack.  The activity's order within the task is unchanged.
-     * 
+     *
      * @param nonRoot If false then this only works if the activity is the root
      *                of a task; if true it will work for any activity in
      *                a task.
-     * 
+     *
      * @return If the task was moved (or it was already at the
      *         back) true is returned, else false.
      */
@@ -4487,9 +4923,10 @@
     /**
      * Returns class name for this activity with the package prefix removed.
      * This is the default name used to read and write settings.
-     * 
+     *
      * @return The local class name.
      */
+    @NonNull
     public String getLocalClassName() {
         final String pkg = getPackageName();
         final String cls = mComponent.getClassName();
@@ -4500,10 +4937,10 @@
         }
         return cls.substring(packageLen+1);
     }
-    
+
     /**
      * Returns complete component name of this activity.
-     * 
+     *
      * @return Returns the complete component name for this activity
      */
     public ComponentName getComponentName()
@@ -4516,9 +4953,9 @@
      * that are private to this activity.  This simply calls the underlying
      * {@link #getSharedPreferences(String, int)} method by passing in this activity's
      * class name as the preferences name.
-     * 
-     * @param mode Operating mode.  Use {@link #MODE_PRIVATE} for the default 
-     *             operation, {@link #MODE_WORLD_READABLE} and 
+     *
+     * @param mode Operating mode.  Use {@link #MODE_PRIVATE} for the default
+     *             operation, {@link #MODE_WORLD_READABLE} and
      *             {@link #MODE_WORLD_WRITEABLE} to control permissions.
      *
      * @return Returns the single SharedPreferences instance that can be used
@@ -4527,17 +4964,17 @@
     public SharedPreferences getPreferences(int mode) {
         return getSharedPreferences(getLocalClassName(), mode);
     }
-    
+
     private void ensureSearchManager() {
         if (mSearchManager != null) {
             return;
         }
-        
+
         mSearchManager = new SearchManager(this, null);
     }
-    
+
     @Override
-    public Object getSystemService(String name) {
+    public Object getSystemService(@ServiceName @NonNull String name) {
         if (getBaseContext() == null) {
             throw new IllegalStateException(
                     "System services not available to Activities before onCreate()");
@@ -4577,6 +5014,17 @@
         setTitle(getText(titleId));
     }
 
+    /**
+     * Change the color of the title associated with this activity.
+     * <p>
+     * This method is deprecated starting in API Level 11 and replaced by action
+     * bar styles. For information on styling the Action Bar, read the <a
+     * href="{@docRoot} guide/topics/ui/actionbar.html">Action Bar</a> developer
+     * guide.
+     *
+     * @deprecated Use action bar styles instead.
+     */
+    @Deprecated
     public void setTitleColor(int textColor) {
         mTitleColor = textColor;
         onTitleChanged(mTitle, textColor);
@@ -4599,6 +5047,9 @@
                     win.setTitleColor(color);
                 }
             }
+            if (mActionBar != null) {
+                mActionBar.setWindowTitle(title);
+            }
         }
     }
 
@@ -4606,11 +5057,40 @@
     }
 
     /**
+     * Sets information describing the task with this activity for presentation inside the Recents
+     * System UI. When {@link ActivityManager#getRecentTasks} is called, the activities of each task
+     * are traversed in order from the topmost activity to the bottommost. The traversal continues
+     * for each property until a suitable value is found. For each task the taskDescription will be
+     * returned in {@link android.app.ActivityManager.TaskDescription}.
+     *
+     * @see ActivityManager#getRecentTasks
+     * @see android.app.ActivityManager.TaskDescription
+     *
+     * @param taskDescription The TaskDescription properties that describe the task with this activity
+     */
+    public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
+        ActivityManager.TaskDescription td;
+        // Scale the icon down to something reasonable if it is provided
+        if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) {
+            final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
+            final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size, true);
+            td = new ActivityManager.TaskDescription(taskDescription.getLabel(), icon,
+                    taskDescription.getPrimaryColor());
+        } else {
+            td = taskDescription;
+        }
+        try {
+            ActivityManagerNative.getDefault().setTaskDescription(mToken, td);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
      * Sets the visibility of the progress bar in the title.
      * <p>
      * In order for the progress bar to be shown, the feature must be requested
      * via {@link #requestWindowFeature(int)}.
-     * 
+     *
      * @param visible Whether to show the progress bars in the title.
      */
     public final void setProgressBarVisibility(boolean visible) {
@@ -4630,27 +5110,28 @@
         getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
                 visible ? Window.PROGRESS_VISIBILITY_ON : Window.PROGRESS_VISIBILITY_OFF);
     }
-    
+
     /**
      * Sets whether the horizontal progress bar in the title should be indeterminate (the circular
      * is always indeterminate).
      * <p>
      * In order for the progress bar to be shown, the feature must be requested
      * via {@link #requestWindowFeature(int)}.
-     * 
+     *
      * @param indeterminate Whether the horizontal progress bar should be indeterminate.
      */
     public final void setProgressBarIndeterminate(boolean indeterminate) {
         getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
-                indeterminate ? Window.PROGRESS_INDETERMINATE_ON : Window.PROGRESS_INDETERMINATE_OFF);
+                indeterminate ? Window.PROGRESS_INDETERMINATE_ON
+                        : Window.PROGRESS_INDETERMINATE_OFF);
     }
-    
+
     /**
      * Sets the progress for the progress bars in the title.
      * <p>
      * In order for the progress bar to be shown, the feature must be requested
      * via {@link #requestWindowFeature(int)}.
-     * 
+     *
      * @param progress The progress for the progress bar. Valid ranges are from
      *            0 to 10000 (both inclusive). If 10000 is given, the progress
      *            bar will be completely filled and will fade out.
@@ -4658,7 +5139,7 @@
     public final void setProgress(int progress) {
         getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress + Window.PROGRESS_START);
     }
-    
+
     /**
      * Sets the secondary progress for the progress bar in the title. This
      * progress is drawn between the primary progress (set via
@@ -4668,7 +5149,7 @@
      * <p>
      * In order for the progress bar to be shown, the feature must be requested
      * via {@link #requestWindowFeature(int)}.
-     * 
+     *
      * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from
      *            0 to 10000 (both inclusive).
      */
@@ -4682,16 +5163,16 @@
      * volume controls.
      * <p>
      * The suggested audio stream will be tied to the window of this Activity.
-     * If the Activity is switched, the stream set here is no longer the
-     * suggested stream. The client does not need to save and restore the old
-     * suggested stream value in onPause and onResume.
-     * 
+     * Volume requests which are received while the Activity is in the
+     * foreground will affect this stream.
+     * <p>
+     * It is not guaranteed that the hardware volume controls will always change
+     * this stream's volume (for example, if a call is in progress, its stream's
+     * volume may be changed instead). To reset back to the default, use
+     * {@link AudioManager#USE_DEFAULT_STREAM_TYPE}.
+     *
      * @param streamType The type of the audio stream whose volume should be
-     *        changed by the hardware volume controls. It is not guaranteed that
-     *        the hardware volume controls will always change this stream's
-     *        volume (for example, if a call is in progress, its stream's volume
-     *        may be changed instead). To reset back to the default, use
-     *        {@link AudioManager#USE_DEFAULT_STREAM_TYPE}.
+     *            changed by the hardware volume controls.
      */
     public final void setVolumeControlStream(int streamType) {
         getWindow().setVolumeControlStream(streamType);
@@ -4699,8 +5180,8 @@
 
     /**
      * Gets the suggested audio stream whose volume should be changed by the
-     * harwdare volume controls.
-     * 
+     * hardware volume controls.
+     *
      * @return The suggested audio stream type whose volume should be changed by
      *         the hardware volume controls.
      * @see #setVolumeControlStream(int)
@@ -4708,7 +5189,40 @@
     public final int getVolumeControlStream() {
         return getWindow().getVolumeControlStream();
     }
-    
+
+    /**
+     * Sets a {@link MediaController} to send media keys and volume changes to.
+     * <p>
+     * The controller will be tied to the window of this Activity. Media key and
+     * volume events which are received while the Activity is in the foreground
+     * will be forwarded to the controller and used to invoke transport controls
+     * or adjust the volume. This may be used instead of or in addition to
+     * {@link #setVolumeControlStream} to affect a specific session instead of a
+     * specific stream.
+     * <p>
+     * It is not guaranteed that the hardware volume controls will always change
+     * this session's volume (for example, if a call is in progress, its
+     * stream's volume may be changed instead). To reset back to the default use
+     * null as the controller.
+     *
+     * @param controller The controller for the session which should receive
+     *            media keys and volume changes.
+     */
+    public final void setMediaController(MediaController controller) {
+        getWindow().setMediaController(controller);
+    }
+
+    /**
+     * Gets the controller which should be receiving media key and volume events
+     * while this activity is in the foreground.
+     *
+     * @return The controller which should receive events.
+     * @see #setMediaController(android.media.session.MediaController)
+     */
+    public final MediaController getMediaController() {
+        return getWindow().getMediaController();
+    }
+
     /**
      * Runs the specified action on the UI thread. If the current thread is the UI
      * thread, then the action is executed immediately. If the current thread is
@@ -4735,6 +5249,7 @@
      * @see android.view.LayoutInflater#createView
      * @see android.view.Window#getLayoutInflater
      */
+    @Nullable
     public View onCreateView(String name, Context context, AttributeSet attrs) {
         return null;
     }
@@ -4753,79 +5268,8 @@
         if (!"fragment".equals(name)) {
             return onCreateView(name, context, attrs);
         }
-        
-        String fname = attrs.getAttributeValue(null, "class");
-        TypedArray a = 
-            context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Fragment);
-        if (fname == null) {
-            fname = a.getString(com.android.internal.R.styleable.Fragment_name);
-        }
-        int id = a.getResourceId(com.android.internal.R.styleable.Fragment_id, View.NO_ID);
-        String tag = a.getString(com.android.internal.R.styleable.Fragment_tag);
-        a.recycle();
-        
-        int containerId = parent != null ? parent.getId() : 0;
-        if (containerId == View.NO_ID && id == View.NO_ID && tag == null) {
-            throw new IllegalArgumentException(attrs.getPositionDescription()
-                    + ": Must specify unique android:id, android:tag, or have a parent with an id for " + fname);
-        }
 
-        // If we restored from a previous state, we may already have
-        // instantiated this fragment from the state and should use
-        // that instance instead of making a new one.
-        Fragment fragment = id != View.NO_ID ? mFragments.findFragmentById(id) : null;
-        if (fragment == null && tag != null) {
-            fragment = mFragments.findFragmentByTag(tag);
-        }
-        if (fragment == null && containerId != View.NO_ID) {
-            fragment = mFragments.findFragmentById(containerId);
-        }
-
-        if (FragmentManagerImpl.DEBUG) Log.v(TAG, "onCreateView: id=0x"
-                + Integer.toHexString(id) + " fname=" + fname
-                + " existing=" + fragment);
-        if (fragment == null) {
-            fragment = Fragment.instantiate(this, fname);
-            fragment.mFromLayout = true;
-            fragment.mFragmentId = id != 0 ? id : containerId;
-            fragment.mContainerId = containerId;
-            fragment.mTag = tag;
-            fragment.mInLayout = true;
-            fragment.mFragmentManager = mFragments;
-            fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
-            mFragments.addFragment(fragment, true);
-
-        } else if (fragment.mInLayout) {
-            // A fragment already exists and it is not one we restored from
-            // previous state.
-            throw new IllegalArgumentException(attrs.getPositionDescription()
-                    + ": Duplicate id 0x" + Integer.toHexString(id)
-                    + ", tag " + tag + ", or parent id 0x" + Integer.toHexString(containerId)
-                    + " with another fragment for " + fname);
-        } else {
-            // This fragment was retained from a previous instance; get it
-            // going now.
-            fragment.mInLayout = true;
-            // If this fragment is newly instantiated (either right now, or
-            // from last saved state), then give it the attributes to
-            // initialize itself.
-            if (!fragment.mRetaining) {
-                fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
-            }
-            mFragments.moveToState(fragment);
-        }
-
-        if (fragment.mView == null) {
-            throw new IllegalStateException("Fragment " + fname
-                    + " did not create a view.");
-        }
-        if (id != 0) {
-            fragment.mView.setId(id);
-        }
-        if (fragment.mView.getTag() == null) {
-            fragment.mView.setTag(tag);
-        }
-        return fragment.mView;
+        return mFragments.onCreateView(parent, name, context, attrs);
     }
 
     /**
@@ -4896,6 +5340,21 @@
     }
 
     /**
+     * Indication of whether this is the highest level activity in this task. Can be used to
+     * determine whether an activity launched by this activity was placed in the same task or
+     * another task.
+     *
+     * @return true if this is the topmost, non-finishing activity in its task.
+     */
+    private boolean isTopOfTask() {
+        try {
+            return ActivityManagerNative.getDefault().isTopOfTask(mToken);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
      * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} to a
      * fullscreen opaque Activity.
      * <p>
@@ -4905,11 +5364,13 @@
      * This call has no effect on non-translucent activities or on activities with the
      * {@link android.R.attr#windowIsFloating} attribute.
      *
-     * @see #convertToTranslucent(TranslucentConversionListener)
+     * @see #convertToTranslucent(android.app.Activity.TranslucentConversionListener,
+     * ActivityOptions)
      * @see TranslucentConversionListener
      *
      * @hide
      */
+    @SystemApi
     public void convertFromTranslucent() {
         try {
             mTranslucentCallback = null;
@@ -4936,20 +5397,36 @@
      *
      * @param callback the method to call when all visible Activities behind this one have been
      * drawn and it is safe to make this Activity translucent again.
+     * @param options activity options delivered to the activity below this one. The options
+     * are retrieved using {@link #getActivityOptions}.
+     * @return <code>true</code> if Window was opaque and will become translucent or
+     * <code>false</code> if window was translucent and no change needed to be made.
      *
      * @see #convertFromTranslucent()
      * @see TranslucentConversionListener
      *
      * @hide
      */
-    public void convertToTranslucent(TranslucentConversionListener callback) {
+    @SystemApi
+    public boolean convertToTranslucent(TranslucentConversionListener callback,
+            ActivityOptions options) {
+        boolean drawComplete;
         try {
             mTranslucentCallback = callback;
             mChangeCanvasToTranslucent =
-                    ActivityManagerNative.getDefault().convertToTranslucent(mToken);
+                    ActivityManagerNative.getDefault().convertToTranslucent(mToken, options);
+            WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
+            drawComplete = true;
         } catch (RemoteException e) {
-            // pass
+            // Make callback return as though it timed out.
+            mChangeCanvasToTranslucent = false;
+            drawComplete = false;
         }
+        if (!mChangeCanvasToTranslucent && mTranslucentCallback != null) {
+            // Window is already translucent.
+            mTranslucentCallback.onTranslucentConversionComplete(drawComplete);
+        }
+        return mChangeCanvasToTranslucent;
     }
 
     /** @hide */
@@ -4963,6 +5440,141 @@
         }
     }
 
+    /** @hide */
+    public void onNewActivityOptions(ActivityOptions options) {
+        mActivityTransitionState.setEnterActivityOptions(this, options);
+        if (!mStopped) {
+            mActivityTransitionState.enterReady(this);
+        }
+    }
+
+    /**
+     * Retrieve the ActivityOptions passed in from the launching activity or passed back
+     * from an activity launched by this activity in its call to {@link
+     * #convertToTranslucent(TranslucentConversionListener, ActivityOptions)}
+     *
+     * @return The ActivityOptions passed to {@link #convertToTranslucent}.
+     * @hide
+     */
+    ActivityOptions getActivityOptions() {
+        try {
+            return ActivityManagerNative.getDefault().getActivityOptions(mToken);
+        } catch (RemoteException e) {
+        }
+        return null;
+    }
+
+    /**
+     * Activities that want to remain visible behind a translucent activity above them must call
+     * this method anytime between the start of {@link #onResume()} and the return from
+     * {@link #onPause()}. If this call is successful then the activity will remain visible after
+     * {@link #onPause()} is called, and is allowed to continue playing media in the background.
+     *
+     * <p>The actions of this call are reset each time that this activity is brought to the
+     * front. That is, every time {@link #onResume()} is called the activity will be assumed
+     * to not have requested visible behind. Therefore, if you want this activity to continue to
+     * be visible in the background you must call this method again.
+     *
+     * <p>Only fullscreen opaque activities may make this call. I.e. this call is a nop
+     * for dialog and translucent activities.
+     *
+     * <p>Under all circumstances, the activity must stop playing and release resources prior to or
+     * within a call to {@link #onVisibleBehindCanceled()} or if this call returns false.
+     *
+     * <p>False will be returned any time this method is called between the return of onPause and
+     *      the next call to onResume.
+     *
+     * @param visible true to notify the system that the activity wishes to be visible behind other
+     *                translucent activities, false to indicate otherwise. Resources must be
+     *                released when passing false to this method.
+     * @return the resulting visibiity state. If true the activity will remain visible beyond
+     *      {@link #onPause()} if the next activity is translucent or not fullscreen. If false
+     *      then the activity may not count on being visible behind other translucent activities,
+     *      and must stop any media playback and release resources.
+     *      Returning false may occur in lieu of a call to {@link #onVisibleBehindCanceled()} so
+     *      the return value must be checked.
+     *
+     * @see #onVisibleBehindCanceled()
+     * @see #onBackgroundVisibleBehindChanged(boolean)
+     */
+    public boolean requestVisibleBehind(boolean visible) {
+        if (!mResumed) {
+            // Do not permit paused or stopped activities to do this.
+            visible = false;
+        }
+        try {
+            mVisibleBehind = ActivityManagerNative.getDefault()
+                    .requestVisibleBehind(mToken, visible) && visible;
+        } catch (RemoteException e) {
+            mVisibleBehind = false;
+        }
+        return mVisibleBehind;
+    }
+
+    /**
+     * Called when a translucent activity over this activity is becoming opaque or another
+     * activity is being launched. Activities that override this method must call
+     * <code>super.onVisibleBehindCanceled()</code> or a SuperNotCalledException will be thrown.
+     *
+     * <p>When this method is called the activity has 500 msec to release any resources it may be
+     * using while visible in the background.
+     * If the activity has not returned from this method in 500 msec the system will destroy
+     * the activity and kill the process in order to recover the resources for another
+     * process. Otherwise {@link #onStop()} will be called following return.
+     *
+     * @see #requestVisibleBehind(boolean)
+     * @see #onBackgroundVisibleBehindChanged(boolean)
+     */
+    public void onVisibleBehindCanceled() {
+        mCalled = true;
+    }
+
+    /**
+     * Translucent activities may call this to determine if there is an activity below them that
+     * is currently set to be visible in the background.
+     *
+     * @return true if an activity below is set to visible according to the most recent call to
+     * {@link #requestVisibleBehind(boolean)}, false otherwise.
+     *
+     * @see #requestVisibleBehind(boolean)
+     * @see #onVisibleBehindCanceled()
+     * @see #onBackgroundVisibleBehindChanged(boolean)
+     * @hide
+     */
+    @SystemApi
+    public boolean isBackgroundVisibleBehind() {
+        try {
+            return ActivityManagerNative.getDefault().isBackgroundVisibleBehind(mToken);
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    /**
+     * The topmost foreground activity will receive this call when the background visibility state
+     * of the activity below it changes.
+     *
+     * This call may be a consequence of {@link #requestVisibleBehind(boolean)} or might be
+     * due to a background activity finishing itself.
+     *
+     * @param visible true if a background activity is visible, false otherwise.
+     *
+     * @see #requestVisibleBehind(boolean)
+     * @see #onVisibleBehindCanceled()
+     * @hide
+     */
+    @SystemApi
+    public void onBackgroundVisibleBehindChanged(boolean visible) {
+    }
+
+    /**
+     * Activities cannot draw during the period that their windows are animating in. In order
+     * to know when it is safe to begin drawing they can override this method which will be
+     * called when the entering animation has completed.
+     */
+    public void onEnterAnimationComplete() {
+    }
+
     /**
      * Adjust the current immersive mode setting.
      *
@@ -4993,6 +5605,7 @@
      *
      * @see ActionMode
      */
+    @Nullable
     public ActionMode startActionMode(ActionMode.Callback callback) {
         return mWindow.getDecorView().startActionMode(callback);
     }
@@ -5008,9 +5621,10 @@
      * @return The new action mode, or <code>null</code> if the activity does not want to
      *         provide special handling for this action mode. (It will be handled by the system.)
      */
+    @Nullable
     @Override
     public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
-        initActionBar();
+        initWindowDecorActionBar();
         if (mActionBar != null) {
             return mActionBar.startActionMode(callback);
         }
@@ -5061,8 +5675,8 @@
             if (info.taskAffinity == null) {
                 return false;
             }
-            return !ActivityManagerNative.getDefault()
-                    .targetTaskAffinityMatchesActivity(mToken, info.taskAffinity);
+            return ActivityManagerNative.getDefault()
+                    .shouldUpRecreateTask(mToken, info.taskAffinity);
         } catch (RemoteException e) {
             return false;
         } catch (NameNotFoundException e) {
@@ -5151,6 +5765,7 @@
      * @return a new Intent targeting the defined parent of this activity or null if
      *         there is no valid parent.
      */
+    @Nullable
     public Intent getParentActivityIntent() {
         final String parentName = mActivityInfo.parentActivityName;
         if (TextUtils.isEmpty(parentName)) {
@@ -5173,30 +5788,81 @@
         }
     }
 
+    /**
+     * When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+     * android.view.View, String)} was used to start an Activity, <var>callback</var>
+     * will be called to handle shared elements on the <i>launched</i> Activity. This requires
+     * {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
+     *
+     * @param callback Used to manipulate shared element transitions on the launched Activity.
+     */
+    public void setEnterSharedElementCallback(SharedElementCallback callback) {
+        if (callback == null) {
+            callback = SharedElementCallback.NULL_CALLBACK;
+        }
+        mEnterTransitionListener = callback;
+    }
+
+    /**
+     * When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+     * android.view.View, String)} was used to start an Activity, <var>callback</var>
+     * will be called to handle shared elements on the <i>launching</i> Activity. Most
+     * calls will only come when returning from the started Activity.
+     * This requires {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
+     *
+     * @param callback Used to manipulate shared element transitions on the launching Activity.
+     */
+    public void setExitSharedElementCallback(SharedElementCallback callback) {
+        if (callback == null) {
+            callback = SharedElementCallback.NULL_CALLBACK;
+        }
+        mExitTransitionListener = callback;
+    }
+
+    /**
+     * Postpone the entering activity transition when Activity was started with
+     * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+     * android.util.Pair[])}.
+     * <p>This method gives the Activity the ability to delay starting the entering and
+     * shared element transitions until all data is loaded. Until then, the Activity won't
+     * draw into its window, leaving the window transparent. This may also cause the
+     * returning animation to be delayed until data is ready. This method should be
+     * called in {@link #onCreate(android.os.Bundle)} or in
+     * {@link #onActivityReenter(int, android.content.Intent)}.
+     * {@link #startPostponedEnterTransition()} must be called to allow the Activity to
+     * start the transitions. If the Activity did not use
+     * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+     * android.util.Pair[])}, then this method does nothing.</p>
+     */
+    public void postponeEnterTransition() {
+        mActivityTransitionState.postponeEnterTransition();
+    }
+
+    /**
+     * Begin postponed transitions after {@link #postponeEnterTransition()} was called.
+     * If postponeEnterTransition() was called, you must call startPostponedEnterTransition()
+     * to have your Activity start drawing.
+     */
+    public void startPostponedEnterTransition() {
+        mActivityTransitionState.startPostponedEnterTransition();
+    }
+
     // ------------------ Internal API ------------------
-    
+
     final void setParent(Activity parent) {
         mParent = parent;
     }
 
-    final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token,
-            Application application, Intent intent, ActivityInfo info, CharSequence title, 
-            Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances,
-            Configuration config) {
-        attach(context, aThread, instr, token, 0, application, intent, info, title, parent, id,
-            lastNonConfigurationInstances, config);
-    }
-    
     final void attach(Context context, ActivityThread aThread,
             Instrumentation instr, IBinder token, int ident,
             Application application, Intent intent, ActivityInfo info,
             CharSequence title, Activity parent, String id,
             NonConfigurationInstances lastNonConfigurationInstances,
-            Configuration config) {
+            Configuration config, IVoiceInteractor voiceInteractor) {
         attachBaseContext(context);
 
         mFragments.attachActivity(this, mContainer, null);
-        
+
         mWindow = PolicyManager.makeNewWindow(this);
         mWindow.setCallback(this);
         mWindow.setOnWindowDismissedCallback(this);
@@ -5208,7 +5874,7 @@
             mWindow.setUiOptions(info.uiOptions);
         }
         mUiThread = Thread.currentThread();
-        
+
         mMainThread = aThread;
         mInstrumentation = instr;
         mToken = token;
@@ -5221,6 +5887,14 @@
         mParent = parent;
         mEmbeddedID = id;
         mLastNonConfigurationInstances = lastNonConfigurationInstances;
+        if (voiceInteractor != null) {
+            if (lastNonConfigurationInstances != null) {
+                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
+            } else {
+                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
+                        Looper.myLooper());
+            }
+        }
 
         mWindow.setWindowManager(
                 (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
@@ -5238,14 +5912,27 @@
         return mParent != null ? mParent.getActivityToken() : mToken;
     }
 
-    final void performCreate(Bundle icicle) {
-        onCreate(icicle);
+    final void performCreateCommon() {
         mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                 com.android.internal.R.styleable.Window_windowNoDisplay, false);
         mFragments.dispatchActivityCreated();
+        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
     }
-    
+
+    final void performCreate(Bundle icicle) {
+        onCreate(icicle);
+        mActivityTransitionState.readState(icicle);
+        performCreateCommon();
+    }
+
+    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
+        onCreate(icicle, persistentState);
+        mActivityTransitionState.readState(icicle);
+        performCreateCommon();
+    }
+
     final void performStart() {
+        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
         mFragments.noteStateNotSaved();
         mCalled = false;
         mFragments.execPendingActions();
@@ -5268,8 +5955,9 @@
                 lm.doReportStart();
             }
         }
+        mActivityTransitionState.enterReady(this);
     }
-    
+
     final void performRestart() {
         mFragments.noteStateNotSaved();
 
@@ -5308,14 +5996,14 @@
             performStart();
         }
     }
-    
+
     final void performResume() {
         performRestart();
-        
+
         mFragments.execPendingActions();
-        
+
         mLastNonConfigurationInstances = null;
-        
+
         mCalled = false;
         // mResumed is set by the instrumentation
         mInstrumentation.callActivityOnResume(this);
@@ -5327,10 +6015,10 @@
 
         // Now really resume, and install the current status bar and menu.
         mCalled = false;
-        
+
         mFragments.dispatchResume();
         mFragments.execPendingActions();
-        
+
         onPostResume();
         if (!mCalled) {
             throw new SuperNotCalledException(
@@ -5353,12 +6041,12 @@
         }
         mResumed = false;
     }
-    
+
     final void performUserLeaving() {
         onUserInteraction();
         onUserLeaveHint();
     }
-    
+
     final void performStop() {
         mDoReportFullyDrawn = false;
         if (mLoadersStarted) {
@@ -5371,7 +6059,7 @@
                 }
             }
         }
-        
+
         if (!mStopped) {
             if (mWindow != null) {
                 mWindow.closeAllPanels();
@@ -5380,9 +6068,9 @@
             if (mToken != null && mParent == null) {
                 WindowManagerGlobal.getInstance().setStoppedState(mToken, true);
             }
-            
+
             mFragments.dispatchStop();
-            
+
             mCalled = false;
             mInstrumentation.callActivityOnStop(this);
             if (!mCalled) {
@@ -5390,7 +6078,7 @@
                     "Activity " + mComponent.toShortString() +
                     " did not call through to super.onStop()");
             }
-    
+
             synchronized (mManagedCursors) {
                 final int N = mManagedCursors.size();
                 for (int i=0; i<N; i++) {
@@ -5401,7 +6089,7 @@
                     }
                 }
             }
-    
+
             mStopped = true;
         }
         mResumed = false;
@@ -5415,8 +6103,11 @@
         if (mLoaderManager != null) {
             mLoaderManager.doDestroy();
         }
+        if (mVoiceInteractor != null) {
+            mVoiceInteractor.detachActivity();
+        }
     }
-    
+
     /**
      * @hide
      */
@@ -5424,7 +6115,7 @@
         return mResumed;
     }
 
-    void dispatchActivityResult(String who, int requestCode, 
+    void dispatchActivityResult(String who, int requestCode,
         int resultCode, Intent data) {
         if (false) Log.v(
             TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode
@@ -5441,14 +6132,56 @@
     }
 
     /**
+     * Request to put this Activity in a mode where the user is locked to the
+     * current task.
+     *
+     * This will prevent the user from launching other apps, going to settings,
+     * or reaching the home screen.
+     *
+     * If {@link DevicePolicyManager#isLockTaskPermitted(String)} returns true
+     * for this component then the app will go directly into Lock Task mode.  The user
+     * will not be able to exit this mode until {@link Activity#stopLockTask()} is called.
+     *
+     * If {@link DevicePolicyManager#isLockTaskPermitted(String)} returns false
+     * then the system will prompt the user with a dialog requesting permission to enter
+     * this mode.  When entered through this method the user can exit at any time through
+     * an action described by the request dialog.  Calling stopLockTask will also exit the
+     * mode.
+     */
+    public void startLockTask() {
+        try {
+            ActivityManagerNative.getDefault().startLockTaskMode(mToken);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Allow the user to switch away from the current task.
+     *
+     * Called to end the mode started by {@link Activity#startLockTask}. This
+     * can only be called by activities that have successfully called
+     * startLockTask previously.
+     *
+     * This will allow the user to exit this app and move onto other activities.
+     */
+    public void stopLockTask() {
+        try {
+            ActivityManagerNative.getDefault().stopLockTaskMode();
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
      * Interface for informing a translucent {@link Activity} once all visible activities below it
      * have completed drawing. This is necessary only after an {@link Activity} has been made
      * opaque using {@link Activity#convertFromTranslucent()} and before it has been drawn
      * translucent again following a call to {@link
-     * Activity#convertToTranslucent(TranslucentConversionListener)}.
+     * Activity#convertToTranslucent(android.app.Activity.TranslucentConversionListener,
+     * ActivityOptions)}
      *
      * @hide
      */
+    @SystemApi
     public interface TranslucentConversionListener {
         /**
          * Callback made following {@link Activity#convertToTranslucent} once all visible Activities
@@ -5459,7 +6192,7 @@
          * occurred waiting for the Activity to complete drawing.
          *
          * @see Activity#convertFromTranslucent()
-         * @see Activity#convertToTranslucent(TranslucentConversionListener)
+         * @see Activity#convertToTranslucent(TranslucentConversionListener, ActivityOptions)
          */
         public void onTranslucentConversionComplete(boolean drawComplete);
     }
diff --git a/core/java/android/app/ActivityManager.aidl b/core/java/android/app/ActivityManager.aidl
new file mode 100644
index 0000000..92350da
--- /dev/null
+++ b/core/java/android/app/ActivityManager.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+parcelable ActivityManager.RecentTaskInfo;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c877cd3..cd6088f 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -16,11 +16,17 @@
 
 package android.app;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Point;
 import android.os.BatteryStats;
 import android.os.IBinder;
-import com.android.internal.app.IUsageStats;
+import android.os.ParcelFileDescriptor;
+
 import com.android.internal.app.ProcessStats;
-import com.android.internal.os.PkgUsageStats;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.util.FastPrintWriter;
 
@@ -34,6 +40,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Debug;
@@ -47,15 +54,16 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
-import android.util.Log;
+import android.util.Size;
 import android.util.Slog;
+import org.xmlpull.v1.XmlSerializer;
 
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.HashMap;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Interact with the overall activities running in the system.
@@ -64,6 +72,8 @@
     private static String TAG = "ActivityManager";
     private static boolean localLOGV = false;
 
+    private static int gMaxRecentTasks = -1;
+
     private final Context mContext;
     private final Handler mHandler;
 
@@ -76,6 +86,13 @@
     public static final String META_HOME_ALTERNATE = "android.app.home.alternate";
 
     /**
+     * Result for IActivityManager.startActivity: trying to start an activity under voice
+     * control when that activity does not support the VOICE category.
+     * @hide
+     */
+    public static final int START_NOT_VOICE_COMPATIBLE = -7;
+
+    /**
      * Result for IActivityManager.startActivity: an error where the
      * start had to be canceled.
      * @hide
@@ -155,6 +172,13 @@
     public static final int START_SWITCHES_CANCELED = 4;
 
     /**
+     * Result for IActivityManaqer.startActivity: a new activity was attempted to be started
+     * while in Lock Task Mode.
+     * @hide
+     */
+    public static final int START_RETURN_LOCK_TASK_MODE_VIOLATION = 5;
+
+    /**
      * Flag for IActivityManaqer.startActivity: do special start mode where
      * a new activity is launched only if it is needed.
      * @hide
@@ -176,13 +200,6 @@
     public static final int START_FLAG_OPENGL_TRACES = 1<<2;
 
     /**
-     * Flag for IActivityManaqer.startActivity: if the app is being
-     * launched for profiling, automatically stop the profiler once done.
-     * @hide
-     */
-    public static final int START_FLAG_AUTO_STOP_PROFILER = 1<<3;
-
-    /**
      * Result for IActivityManaqer.broadcastIntent: success!
      * @hide
      */
@@ -282,6 +299,8 @@
     /** @hide Process is being cached for later use and is empty. */
     public static final int PROCESS_STATE_CACHED_EMPTY = 13;
 
+    Point mAppTaskThumbnailSize;
+
     /*package*/ ActivityManager(Context context, Handler handler) {
         mContext = context;
         mHandler = handler;
@@ -430,7 +449,7 @@
         // Really brain dead right now -- just take this from the configured
         // vm heap size, and assume it is in megabytes and thus ends with "m".
         String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m");
-        return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+        return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length() - 1));
     }
 
     /**
@@ -461,6 +480,274 @@
     }
 
     /**
+     * Return the maximum number of recents entries that we will maintain and show.
+     * @hide
+     */
+    static public int getMaxRecentTasksStatic() {
+        if (gMaxRecentTasks < 0) {
+            return gMaxRecentTasks = isLowRamDeviceStatic() ? 50 : 100;
+        }
+        return gMaxRecentTasks;
+    }
+
+    /**
+     * Return the default limit on the number of recents that an app can make.
+     * @hide
+     */
+    static public int getDefaultAppRecentsLimitStatic() {
+        return getMaxRecentTasksStatic() / 6;
+    }
+
+    /**
+     * Return the maximum limit on the number of recents that an app can make.
+     * @hide
+     */
+    static public int getMaxAppRecentsLimitStatic() {
+        return getMaxRecentTasksStatic() / 2;
+    }
+
+    /**
+     * Information you can set and retrieve about the current activity within the recent task list.
+     */
+    public static class TaskDescription implements Parcelable {
+        /** @hide */
+        public static final String ATTR_TASKDESCRIPTION_PREFIX = "task_description_";
+        private static final String ATTR_TASKDESCRIPTIONLABEL =
+                ATTR_TASKDESCRIPTION_PREFIX + "label";
+        private static final String ATTR_TASKDESCRIPTIONCOLOR =
+                ATTR_TASKDESCRIPTION_PREFIX + "color";
+        private static final String ATTR_TASKDESCRIPTIONICONFILENAME =
+                ATTR_TASKDESCRIPTION_PREFIX + "icon_filename";
+
+        private String mLabel;
+        private Bitmap mIcon;
+        private String mIconFilename;
+        private int mColorPrimary;
+
+        /**
+         * Creates the TaskDescription to the specified values.
+         *
+         * @param label A label and description of the current state of this task.
+         * @param icon An icon that represents the current state of this task.
+         * @param colorPrimary A color to override the theme's primary color.  This color must be opaque.
+         */
+        public TaskDescription(String label, Bitmap icon, int colorPrimary) {
+            if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
+                throw new RuntimeException("A TaskDescription's primary color should be opaque");
+            }
+
+            mLabel = label;
+            mIcon = icon;
+            mColorPrimary = colorPrimary;
+        }
+
+        /** @hide */
+        public TaskDescription(String label, int colorPrimary, String iconFilename) {
+            this(label, null, colorPrimary);
+            mIconFilename = iconFilename;
+        }
+
+        /**
+         * Creates the TaskDescription to the specified values.
+         *
+         * @param label A label and description of the current state of this activity.
+         * @param icon An icon that represents the current state of this activity.
+         */
+        public TaskDescription(String label, Bitmap icon) {
+            this(label, icon, 0);
+        }
+
+        /**
+         * Creates the TaskDescription to the specified values.
+         *
+         * @param label A label and description of the current state of this activity.
+         */
+        public TaskDescription(String label) {
+            this(label, null, 0);
+        }
+
+        /**
+         * Creates an empty TaskDescription.
+         */
+        public TaskDescription() {
+            this(null, null, 0);
+        }
+
+        /**
+         * Creates a copy of another TaskDescription.
+         */
+        public TaskDescription(TaskDescription td) {
+            mLabel = td.mLabel;
+            mIcon = td.mIcon;
+            mColorPrimary = td.mColorPrimary;
+            mIconFilename = td.mIconFilename;
+        }
+
+        private TaskDescription(Parcel source) {
+            readFromParcel(source);
+        }
+
+        /**
+         * Sets the label for this task description.
+         * @hide
+         */
+        public void setLabel(String label) {
+            mLabel = label;
+        }
+
+        /**
+         * Sets the primary color for this task description.
+         * @hide
+         */
+        public void setPrimaryColor(int primaryColor) {
+            // Ensure that the given color is valid
+            if ((primaryColor != 0) && (Color.alpha(primaryColor) != 255)) {
+                throw new RuntimeException("A TaskDescription's primary color should be opaque");
+            }
+            mColorPrimary = primaryColor;
+        }
+
+        /**
+         * Sets the icon for this task description.
+         * @hide
+         */
+        public void setIcon(Bitmap icon) {
+            mIcon = icon;
+        }
+
+        /**
+         * Moves the icon bitmap reference from an actual Bitmap to a file containing the
+         * bitmap.
+         * @hide
+         */
+        public void setIconFilename(String iconFilename) {
+            mIconFilename = iconFilename;
+            mIcon = null;
+        }
+
+        /**
+         * @return The label and description of the current state of this task.
+         */
+        public String getLabel() {
+            return mLabel;
+        }
+
+        /**
+         * @return The icon that represents the current state of this task.
+         */
+        public Bitmap getIcon() {
+            if (mIcon != null) {
+                return mIcon;
+            }
+            return loadTaskDescriptionIcon(mIconFilename);
+        }
+
+        /** @hide */
+        public String getIconFilename() {
+            return mIconFilename;
+        }
+
+        /** @hide */
+        public Bitmap getInMemoryIcon() {
+            return mIcon;
+        }
+
+        /** @hide */
+        public static Bitmap loadTaskDescriptionIcon(String iconFilename) {
+            if (iconFilename != null) {
+                try {
+                    return ActivityManagerNative.getDefault().
+                            getTaskDescriptionIcon(iconFilename);
+                } catch (RemoteException e) {
+                }
+            }
+            return null;
+        }
+
+        /**
+         * @return The color override on the theme's primary color.
+         */
+        public int getPrimaryColor() {
+            return mColorPrimary;
+        }
+
+        /** @hide */
+        public void saveToXml(XmlSerializer out) throws IOException {
+            if (mLabel != null) {
+                out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, mLabel);
+            }
+            if (mColorPrimary != 0) {
+                out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(mColorPrimary));
+            }
+            if (mIconFilename != null) {
+                out.attribute(null, ATTR_TASKDESCRIPTIONICONFILENAME, mIconFilename);
+            }
+        }
+
+        /** @hide */
+        public void restoreFromXml(String attrName, String attrValue) {
+            if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
+                setLabel(attrValue);
+            } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) {
+                setPrimaryColor((int) Long.parseLong(attrValue, 16));
+            } else if (ATTR_TASKDESCRIPTIONICONFILENAME.equals(attrName)) {
+                setIconFilename(attrValue);
+            }
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            if (mLabel == null) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                dest.writeString(mLabel);
+            }
+            if (mIcon == null) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                mIcon.writeToParcel(dest, 0);
+            }
+            dest.writeInt(mColorPrimary);
+            if (mIconFilename == null) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                dest.writeString(mIconFilename);
+            }
+        }
+
+        public void readFromParcel(Parcel source) {
+            mLabel = source.readInt() > 0 ? source.readString() : null;
+            mIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null;
+            mColorPrimary = source.readInt();
+            mIconFilename = source.readInt() > 0 ? source.readString() : null;
+        }
+
+        public static final Creator<TaskDescription> CREATOR
+                = new Creator<TaskDescription>() {
+            public TaskDescription createFromParcel(Parcel source) {
+                return new TaskDescription(source);
+            }
+            public TaskDescription[] newArray(int size) {
+                return new TaskDescription[size];
+            }
+        };
+
+        @Override
+        public String toString() {
+            return "TaskDescription Label: " + mLabel + " Icon: " + mIcon +
+                    " colorPrimary: " + mColorPrimary;
+        }
+    }
+
+    /**
      * Information you can retrieve about tasks that the user has most recently
      * started or visited.
      */
@@ -502,6 +789,42 @@
          */
         public int stackId;
 
+        /**
+         * The id of the user the task was running as.
+         * @hide
+         */
+        public int userId;
+
+        /**
+         * The first time this task was active.
+         * @hide
+         */
+        public long firstActiveTime;
+
+        /**
+         * The last time this task was active.
+         * @hide
+         */
+        public long lastActiveTime;
+
+        /**
+         * The recent activity values for the highest activity in the stack to have set the values.
+         * {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}.
+         */
+        public TaskDescription taskDescription;
+
+        /**
+         * Task affiliation for grouping with other tasks.
+         */
+        public int affiliatedTaskId;
+
+        /**
+         * Task affiliation color of the source task with the affiliated task id.
+         *
+         * @hide
+         */
+        public int affiliatedTaskColor;
+
         public RecentTaskInfo() {
         }
 
@@ -523,20 +846,34 @@
             ComponentName.writeToParcel(origActivity, dest);
             TextUtils.writeToParcel(description, dest,
                     Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            if (taskDescription != null) {
+                dest.writeInt(1);
+                taskDescription.writeToParcel(dest, 0);
+            } else {
+                dest.writeInt(0);
+            }
             dest.writeInt(stackId);
+            dest.writeInt(userId);
+            dest.writeLong(firstActiveTime);
+            dest.writeLong(lastActiveTime);
+            dest.writeInt(affiliatedTaskId);
+            dest.writeInt(affiliatedTaskColor);
         }
 
         public void readFromParcel(Parcel source) {
             id = source.readInt();
             persistentId = source.readInt();
-            if (source.readInt() != 0) {
-                baseIntent = Intent.CREATOR.createFromParcel(source);
-            } else {
-                baseIntent = null;
-            }
+            baseIntent = source.readInt() > 0 ? Intent.CREATOR.createFromParcel(source) : null;
             origActivity = ComponentName.readFromParcel(source);
             description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+            taskDescription = source.readInt() > 0 ?
+                    TaskDescription.CREATOR.createFromParcel(source) : null;
             stackId = source.readInt();
+            userId = source.readInt();
+            firstActiveTime = source.readLong();
+            lastActiveTime = source.readLong();
+            affiliatedTaskId = source.readInt();
+            affiliatedTaskColor = source.readInt();
         }
 
         public static final Creator<RecentTaskInfo> CREATOR
@@ -560,7 +897,7 @@
      * {@link android.content.Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} flag.
      */
     public static final int RECENT_WITH_EXCLUDED = 0x0001;
-    
+
     /**
      * Provides a list that does not contain any
      * recent tasks that currently are not available to the user.
@@ -568,7 +905,20 @@
     public static final int RECENT_IGNORE_UNAVAILABLE = 0x0002;
 
     /**
-     * Return a list of the tasks that the user has recently launched, with
+     * Provides a list that contains recent tasks for all
+     * profiles of a user.
+     * @hide
+     */
+    public static final int RECENT_INCLUDE_PROFILES = 0x0004;
+
+    /**
+     * Ignores all tasks that are on the home stack.
+     * @hide
+     */
+    public static final int RECENT_IGNORE_HOME_STACK_TASKS = 0x0008;
+
+    /**
+     * <p></p>Return a list of the tasks that the user has recently launched, with
      * the most recent being first and older ones after in order.
      *
      * <p><b>Note: this method is only intended for debugging and presenting
@@ -580,6 +930,15 @@
      * same time, assumptions made about the meaning of the data here for
      * purposes of control flow will be incorrect.</p>
      *
+     * @deprecated As of {@link android.os.Build.VERSION_CODES#L}, this method is
+     * no longer available to third party applications: as the introduction of
+     * document-centric recents means
+     * it can leak personal information to the caller.  For backwards compatibility,
+     * it will still return a small subset of its data: at least the caller's
+     * own tasks (though see {@link #getAppTasks()} for the correct supported
+     * way to retrieve that information), and possibly some other tasks
+     * such as home that are known to not be sensitive.
+     *
      * @param maxNum The maximum number of entries to return in the list.  The
      * actual number returned may be smaller, depending on how many tasks the
      * user has started and the maximum number the system can remember.
@@ -592,6 +951,7 @@
      * @throws SecurityException Throws SecurityException if the caller does
      * not hold the {@link android.Manifest.permission#GET_TASKS} permission.
      */
+    @Deprecated
     public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)
             throws SecurityException {
         try {
@@ -736,41 +1096,113 @@
             readFromParcel(source);
         }
     }
-    
+
     /**
-     * Return a list of the tasks that are currently running, with
-     * the most recent being first and older ones after in order.  Note that
-     * "running" does not mean any of the task's code is currently loaded or
-     * activity -- the task may have been frozen by the system, so that it
-     * can be restarted in its previous state when next brought to the
-     * foreground.
-     * 
-     * @param maxNum The maximum number of entries to return in the list.  The
-     * actual number returned may be smaller, depending on how many tasks the
-     * user has started.
+     * Get the list of tasks associated with the calling application.
      *
-     * @param flags Optional flags
-     * @param receiver Optional receiver for delayed thumbnails
-     *
-     * @return Returns a list of RunningTaskInfo records describing each of
-     * the running tasks.
-     * 
-     * Some thumbnails may not be available at the time of this call. The optional
-     * receiver may be used to receive those thumbnails.
-     *
-     * @throws SecurityException Throws SecurityException if the caller does
-     * not hold the {@link android.Manifest.permission#GET_TASKS} permission.
-     *
-     * @hide
+     * @return The list of tasks associated with the application making this call.
+     * @throws SecurityException
      */
-    public List<RunningTaskInfo> getRunningTasks(int maxNum, int flags, IThumbnailReceiver receiver)
-            throws SecurityException {
+    public List<ActivityManager.AppTask> getAppTasks() {
+        ArrayList<AppTask> tasks = new ArrayList<AppTask>();
+        List<IAppTask> appTasks;
         try {
-            return ActivityManagerNative.getDefault().getTasks(maxNum, flags, receiver);
+            appTasks = ActivityManagerNative.getDefault().getAppTasks(mContext.getPackageName());
         } catch (RemoteException e) {
             // System dead, we will be dead too soon!
             return null;
         }
+        int numAppTasks = appTasks.size();
+        for (int i = 0; i < numAppTasks; i++) {
+            tasks.add(new AppTask(appTasks.get(i)));
+        }
+        return tasks;
+    }
+
+    /**
+     * Return the current design dimensions for {@link AppTask} thumbnails, for use
+     * with {@link #addAppTask}.
+     */
+    public Size getAppTaskThumbnailSize() {
+        synchronized (this) {
+            ensureAppTaskThumbnailSizeLocked();
+            return new Size(mAppTaskThumbnailSize.x, mAppTaskThumbnailSize.y);
+        }
+    }
+
+    private void ensureAppTaskThumbnailSizeLocked() {
+        if (mAppTaskThumbnailSize == null) {
+            try {
+                mAppTaskThumbnailSize = ActivityManagerNative.getDefault().getAppTaskThumbnailSize();
+            } catch (RemoteException e) {
+                throw new IllegalStateException("System dead?", e);
+            }
+        }
+    }
+
+    /**
+     * Add a new {@link AppTask} for the calling application.  This will create a new
+     * recents entry that is added to the <b>end</b> of all existing recents.
+     *
+     * @param activity The activity that is adding the entry.   This is used to help determine
+     * the context that the new recents entry will be in.
+     * @param intent The Intent that describes the recents entry.  This is the same Intent that
+     * you would have used to launch the activity for it.  In generally you will want to set
+     * both {@link Intent#FLAG_ACTIVITY_NEW_DOCUMENT} and
+     * {@link Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS}; the latter is required since this recents
+     * entry will exist without an activity, so it doesn't make sense to not retain it when
+     * its activity disappears.  The given Intent here also must have an explicit ComponentName
+     * set on it.
+     * @param description Optional additional description information.
+     * @param thumbnail Thumbnail to use for the recents entry.  Should be the size given by
+     * {@link #getAppTaskThumbnailSize()}.  If the bitmap is not that exact size, it will be
+     * recreated in your process, probably in a way you don't like, before the recents entry
+     * is added.
+     *
+     * @return Returns the task id of the newly added app task, or -1 if the add failed.  The
+     * most likely cause of failure is that there is no more room for more tasks for your app.
+     */
+    public int addAppTask(@NonNull Activity activity, @NonNull Intent intent,
+            @Nullable TaskDescription description, @NonNull Bitmap thumbnail) {
+        Point size;
+        synchronized (this) {
+            ensureAppTaskThumbnailSizeLocked();
+            size = mAppTaskThumbnailSize;
+        }
+        final int tw = thumbnail.getWidth();
+        final int th = thumbnail.getHeight();
+        if (tw != size.x || th != size.y) {
+            Bitmap bm = Bitmap.createBitmap(size.x, size.y, thumbnail.getConfig());
+
+            // Use ScaleType.CENTER_CROP, except we leave the top edge at the top.
+            float scale;
+            float dx = 0, dy = 0;
+            if (tw * size.x > size.y * th) {
+                scale = (float) size.x / (float) th;
+                dx = (size.y - tw * scale) * 0.5f;
+            } else {
+                scale = (float) size.y / (float) tw;
+                dy = (size.x - th * scale) * 0.5f;
+            }
+            Matrix matrix = new Matrix();
+            matrix.setScale(scale, scale);
+            matrix.postTranslate((int) (dx + 0.5f), 0);
+
+            Canvas canvas = new Canvas(bm);
+            canvas.drawBitmap(thumbnail, matrix, null);
+            canvas.setBitmap(null);
+
+            thumbnail = bm;
+        }
+        if (description == null) {
+            description = new TaskDescription();
+        }
+        try {
+            return ActivityManagerNative.getDefault().addAppTask(activity.getActivityToken(),
+                    intent, description, thumbnail);
+        } catch (RemoteException e) {
+            throw new IllegalStateException("System dead?", e);
+        }
     }
 
     /**
@@ -790,6 +1222,14 @@
      * same time, assumptions made about the meaning of the data here for
      * purposes of control flow will be incorrect.</p>
      *
+     * @deprecated As of {@link android.os.Build.VERSION_CODES#L}, this method
+     * is no longer available to third party
+     * applications: the introduction of document-centric recents means
+     * it can leak person information to the caller.  For backwards compatibility,
+     * it will still retu rn a small subset of its data: at least the caller's
+     * own tasks, and possibly some other tasks
+     * such as home that are known to not be sensitive.
+     *
      * @param maxNum The maximum number of entries to return in the list.  The
      * actual number returned may be smaller, depending on how many tasks the
      * user has started.
@@ -800,30 +1240,14 @@
      * @throws SecurityException Throws SecurityException if the caller does
      * not hold the {@link android.Manifest.permission#GET_TASKS} permission.
      */
+    @Deprecated
     public List<RunningTaskInfo> getRunningTasks(int maxNum)
             throws SecurityException {
-        return getRunningTasks(maxNum, 0, null);
-    }
-
-    /**
-     * Remove some end of a task's activity stack that is not part of
-     * the main application.  The selected activities will be finished, so
-     * they are no longer part of the main task.
-     *
-     * @param taskId The identifier of the task.
-     * @param subTaskIndex The number of the sub-task; this corresponds
-     * to the index of the thumbnail returned by {@link #getTaskThumbnails(int)}.
-     * @return Returns true if the sub-task was found and was removed.
-     *
-     * @hide
-     */
-    public boolean removeSubTask(int taskId, int subTaskIndex)
-            throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().removeSubTask(taskId, subTaskIndex);
+            return ActivityManagerNative.getDefault().getTasks(maxNum, 0);
         } catch (RemoteException e) {
             // System dead, we will be dead too soon!
-            return false;
+            return null;
         }
     }
 
@@ -855,38 +1279,33 @@
     }
 
     /** @hide */
-    public static class TaskThumbnails implements Parcelable {
+    public static class TaskThumbnail implements Parcelable {
         public Bitmap mainThumbnail;
+        public ParcelFileDescriptor thumbnailFileDescriptor;
 
-        public int numSubThumbbails;
-
-        /** @hide */
-        public IThumbnailRetriever retriever;
-
-        public TaskThumbnails() {
-        }
-
-        public Bitmap getSubThumbnail(int index) {
-            try {
-                return retriever.getThumbnail(index);
-            } catch (RemoteException e) {
-                return null;
-            }
+        public TaskThumbnail() {
         }
 
         public int describeContents() {
+            if (thumbnailFileDescriptor != null) {
+                return thumbnailFileDescriptor.describeContents();
+            }
             return 0;
         }
 
         public void writeToParcel(Parcel dest, int flags) {
             if (mainThumbnail != null) {
                 dest.writeInt(1);
-                mainThumbnail.writeToParcel(dest, 0);
+                mainThumbnail.writeToParcel(dest, flags);
             } else {
                 dest.writeInt(0);
             }
-            dest.writeInt(numSubThumbbails);
-            dest.writeStrongInterface(retriever);
+            if (thumbnailFileDescriptor != null) {
+                dest.writeInt(1);
+                thumbnailFileDescriptor.writeToParcel(dest, flags);
+            } else {
+                dest.writeInt(0);
+            }
         }
 
         public void readFromParcel(Parcel source) {
@@ -895,28 +1314,31 @@
             } else {
                 mainThumbnail = null;
             }
-            numSubThumbbails = source.readInt();
-            retriever = IThumbnailRetriever.Stub.asInterface(source.readStrongBinder());
+            if (source.readInt() != 0) {
+                thumbnailFileDescriptor = ParcelFileDescriptor.CREATOR.createFromParcel(source);
+            } else {
+                thumbnailFileDescriptor = null;
+            }
         }
 
-        public static final Creator<TaskThumbnails> CREATOR = new Creator<TaskThumbnails>() {
-            public TaskThumbnails createFromParcel(Parcel source) {
-                return new TaskThumbnails(source);
+        public static final Creator<TaskThumbnail> CREATOR = new Creator<TaskThumbnail>() {
+            public TaskThumbnail createFromParcel(Parcel source) {
+                return new TaskThumbnail(source);
             }
-            public TaskThumbnails[] newArray(int size) {
-                return new TaskThumbnails[size];
+            public TaskThumbnail[] newArray(int size) {
+                return new TaskThumbnail[size];
             }
         };
 
-        private TaskThumbnails(Parcel source) {
+        private TaskThumbnail(Parcel source) {
             readFromParcel(source);
         }
     }
 
     /** @hide */
-    public TaskThumbnails getTaskThumbnails(int id) throws SecurityException {
+    public TaskThumbnail getTaskThumbnail(int id) throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().getTaskThumbnails(id);
+            return ActivityManagerNative.getDefault().getTaskThumbnail(id);
         } catch (RemoteException e) {
             // System dead, we will be dead too soon!
             return null;
@@ -924,12 +1346,12 @@
     }
 
     /** @hide */
-    public Bitmap getTaskTopThumbnail(int id) throws SecurityException {
+    public boolean isInHomeStack(int taskId) {
         try {
-            return ActivityManagerNative.getDefault().getTaskTopThumbnail(id);
+            return ActivityManagerNative.getDefault().isInHomeStack(taskId);
         } catch (RemoteException e) {
             // System dead, we will be dead too soon!
-            return null;
+            return false;
         }
     }
 
@@ -1570,13 +1992,6 @@
         public int lastTrimLevel;
 
         /**
-         * Constant for {@link #importance}: this is a persistent process.
-         * Only used when reporting to process observers.
-         * @hide
-         */
-        public static final int IMPORTANCE_PERSISTENT = 50;
-
-        /**
          * Constant for {@link #importance}: this process is running the
          * foreground UI.
          */
@@ -1621,7 +2036,29 @@
          * actively running code.
          */
         public static final int IMPORTANCE_EMPTY = 500;
-        
+
+        /**
+         * Constant for {@link #importance}: this process does not exist.
+         */
+        public static final int IMPORTANCE_GONE = 1000;
+
+        /** @hide */
+        public static int procStateToImportance(int procState) {
+            if (procState >= ActivityManager.PROCESS_STATE_HOME) {
+                return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
+            } else if (procState >= ActivityManager.PROCESS_STATE_SERVICE) {
+                return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
+            } else if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
+                return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
+            } else if (procState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
+                return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
+            } else if (procState >= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
+                return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
+            } else {
+                return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+            }
+        }
+
         /**
          * The relative importance level that the system places on this
          * process.  May be one of {@link #IMPORTANCE_FOREGROUND},
@@ -1691,9 +2128,16 @@
          */
         public int importanceReasonImportance;
 
+        /**
+         * Current process state, as per PROCESS_STATE_* constants.
+         * @hide
+         */
+        public int processState;
+
         public RunningAppProcessInfo() {
             importance = IMPORTANCE_FOREGROUND;
             importanceReasonCode = REASON_UNKNOWN;
+            processState = PROCESS_STATE_IMPORTANT_FOREGROUND;
         }
         
         public RunningAppProcessInfo(String pProcessName, int pPid, String pArr[]) {
@@ -1719,6 +2163,7 @@
             dest.writeInt(importanceReasonPid);
             ComponentName.writeToParcel(importanceReasonComponent, dest);
             dest.writeInt(importanceReasonImportance);
+            dest.writeInt(processState);
         }
 
         public void readFromParcel(Parcel source) {
@@ -1734,6 +2179,7 @@
             importanceReasonPid = source.readInt();
             importanceReasonComponent = ComponentName.readFromParcel(source);
             importanceReasonImportance = source.readInt();
+            processState = source.readInt();
         }
 
         public static final Creator<RunningAppProcessInfo> CREATOR = 
@@ -1871,19 +2317,27 @@
      * call this method.
      * 
      * @param packageName The name of the package to be stopped.
+     * @param userId The user for which the running package is to be stopped.
      * 
      * @hide This is not available to third party applications due to
      * it allowing them to break other applications by stopping their
      * services, removing their alarms, etc.
      */
-    public void forceStopPackage(String packageName) {
+    public void forceStopPackageAsUser(String packageName, int userId) {
         try {
-            ActivityManagerNative.getDefault().forceStopPackage(packageName,
-                    UserHandle.myUserId());
+            ActivityManagerNative.getDefault().forceStopPackage(packageName, userId);
         } catch (RemoteException e) {
         }
     }
-    
+
+    /**
+     * @see #forceStopPackageAsUser(String, int)
+     * @hide
+     */
+    public void forceStopPackage(String packageName) {
+        forceStopPackageAsUser(packageName, UserHandle.myUserId());
+    }
+
     /**
      * Get the device configuration attributes.
      */
@@ -1938,7 +2392,11 @@
      * @return dimensions of square icons in terms of pixels
      */
     public int getLauncherLargeIconSize() {
-        final Resources res = mContext.getResources();
+        return getLauncherLargeIconSizeInner(mContext);
+    }
+
+    static int getLauncherLargeIconSizeInner(Context context) {
+        final Resources res = context.getResources();
         final int size = res.getDimensionPixelSize(android.R.dimen.app_icon_size);
         final int sw = res.getConfiguration().smallestScreenWidthDp;
 
@@ -1993,7 +2451,7 @@
      *
      * @hide
      */
-    public Map<String, Integer> getAllPackageLaunchCounts() {
+    /*public Map<String, Integer> getAllPackageLaunchCounts() {
         try {
             IUsageStats usageStatsService = IUsageStats.Stub.asInterface(
                     ServiceManager.getService("usagestats"));
@@ -2001,14 +2459,15 @@
                 return new HashMap<String, Integer>();
             }
 
-            PkgUsageStats[] allPkgUsageStats = usageStatsService.getAllPkgUsageStats();
+            UsageStats.PackageStats[] allPkgUsageStats = usageStatsService.getAllPkgUsageStats(
+                    ActivityThread.currentPackageName());
             if (allPkgUsageStats == null) {
                 return new HashMap<String, Integer>();
             }
 
             Map<String, Integer> launchCounts = new HashMap<String, Integer>();
-            for (PkgUsageStats pkgUsageStats : allPkgUsageStats) {
-                launchCounts.put(pkgUsageStats.packageName, pkgUsageStats.launchCount);
+            for (UsageStats.PackageStats pkgUsageStats : allPkgUsageStats) {
+                launchCounts.put(pkgUsageStats.getPackageName(), pkgUsageStats.getLaunchCount());
             }
 
             return launchCounts;
@@ -2016,7 +2475,7 @@
             Log.w(TAG, "Could not query launch counts", e);
             return new HashMap<String, Integer>();
         }
-    }
+    }*/
 
     /** @hide */
     public static int checkComponentPermission(String permission, int uid,
@@ -2106,7 +2565,11 @@
         }
     }
 
-    /** @hide */
+    /**
+     * Gets the userId of the current foreground user. Requires system permissions.
+     * @hide
+     */
+    @SystemApi
     public static int getCurrentUser() {
         UserInfo ui;
         try {
@@ -2118,24 +2581,6 @@
     }
 
     /**
-     * Returns the usage statistics of each installed package.
-     *
-     * @hide
-     */
-    public PkgUsageStats[] getAllPackageUsageStats() {
-        try {
-            IUsageStats usageStatsService = IUsageStats.Stub.asInterface(
-                    ServiceManager.getService("usagestats"));
-            if (usageStatsService != null) {
-                return usageStatsService.getAllPkgUsageStats();
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "Could not query usage stats", e);
-        }
-        return new PkgUsageStats[0];
-    }
-
-    /**
      * @param userid the user's id. Zero indicates the default user 
      * @hide
      */
@@ -2222,4 +2667,132 @@
             e.printStackTrace(pw);
         }
     }
+
+    /**
+     * @hide
+     */
+    public void startLockTaskMode(int taskId) {
+        try {
+            ActivityManagerNative.getDefault().startLockTaskMode(taskId);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void stopLockTaskMode() {
+        try {
+            ActivityManagerNative.getDefault().stopLockTaskMode();
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Return whether currently in lock task mode.  When in this mode
+     * no new tasks can be created or switched to.
+     *
+     * @see Activity#startLockTask()
+     */
+    public boolean isInLockTaskMode() {
+        try {
+            return ActivityManagerNative.getDefault().isInLockTaskMode();
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * The AppTask allows you to manage your own application's tasks.
+     * See {@link android.app.ActivityManager#getAppTasks()}
+     */
+    public static class AppTask {
+        private IAppTask mAppTaskImpl;
+
+        /** @hide */
+        public AppTask(IAppTask task) {
+            mAppTaskImpl = task;
+        }
+
+        /**
+         * Finishes all activities in this task and removes it from the recent tasks list.
+         */
+        public void finishAndRemoveTask() {
+            try {
+                mAppTaskImpl.finishAndRemoveTask();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Invalid AppTask", e);
+            }
+        }
+
+        /**
+         * Get the RecentTaskInfo associated with this task.
+         *
+         * @return The RecentTaskInfo for this task, or null if the task no longer exists.
+         */
+        public RecentTaskInfo getTaskInfo() {
+            try {
+                return mAppTaskImpl.getTaskInfo();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Invalid AppTask", e);
+                return null;
+            }
+        }
+
+        /**
+         * Bring this task to the foreground.  If it contains activities, they will be
+         * brought to the foreground with it and their instances re-created if needed.
+         * If it doesn't contain activities, the root activity of the task will be
+         * re-launched.
+         */
+        public void moveToFront() {
+            try {
+                mAppTaskImpl.moveToFront();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Invalid AppTask", e);
+            }
+        }
+
+        /**
+         * Start an activity in this task.  Brings the task to the foreground.  If this task
+         * is not currently active (that is, its id < 0), then a new activity for the given
+         * Intent will be launched as the root of the task and the task brought to the
+         * foreground.  Otherwise, if this task is currently active and the Intent does not specify
+         * an activity to launch in a new task, then a new activity for the given Intent will
+         * be launched on top of the task and the task brought to the foreground.  If this
+         * task is currently active and the Intent specifies {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+         * or would otherwise be launched in to a new task, then the activity not launched but
+         * this task be brought to the foreground and a new intent delivered to the top
+         * activity if appropriate.
+         *
+         * <p>In other words, you generally want to use an Intent here that does not specify
+         * {@link Intent#FLAG_ACTIVITY_NEW_TASK} or {@link Intent#FLAG_ACTIVITY_NEW_DOCUMENT},
+         * and let the system do the right thing.</p>
+         *
+         * @param intent The Intent describing the new activity to be launched on the task.
+         * @param options Optional launch options.
+         *
+         * @see Activity#startActivity(android.content.Intent, android.os.Bundle)
+         */
+        public void startActivity(Context context, Intent intent, Bundle options) {
+            ActivityThread thread = ActivityThread.currentActivityThread();
+            thread.getInstrumentation().execStartActivityFromAppTask(context,
+                    thread.getApplicationThread(), mAppTaskImpl, intent, options);
+        }
+
+        /**
+         * Modify the {@link Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} flag in the root
+         * Intent of this AppTask.
+         *
+         * @param exclude If true, {@link Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} will
+         * be set; otherwise, it will be cleared.
+         */
+        public void setExcludeFromRecents(boolean exclude) {
+            try {
+                mAppTaskImpl.setExcludeFromRecents(exclude);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Invalid AppTask", e);
+            }
+        }
+    }
 }
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 5262a5f..2a17fa6 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -25,4 +25,6 @@
     // Called by the power manager.
     public abstract void goingToSleep();
     public abstract void wakingUp();
+    public abstract int startIsolatedProcess(String entryPoint, String[] mainArgs,
+            String processName, String abiOverride, int uid, Runnable crashHandler);
 }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index e5ee1fa..11470e3 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.app.ActivityManager.StackInfo;
+import android.app.ProfilerInfo;
 import android.content.ComponentName;
 import android.content.IIntentReceiver;
 import android.content.IIntentSender;
@@ -31,6 +32,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Binder;
@@ -40,12 +42,15 @@
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
+import android.service.voice.IVoiceInteractionSession;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Singleton;
+import com.android.internal.app.IVoiceInteractor;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -101,9 +106,9 @@
         }
     }
 
-    static public void noteWakeupAlarm(PendingIntent ps) {
+    static public void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg) {
         try {
-            getDefault().noteWakeupAlarm(ps.getTarget());
+            getDefault().noteWakeupAlarm(ps.getTarget(), sourceUid, sourcePkg);
         } catch (RemoteException ex) {
         }
     }
@@ -128,14 +133,12 @@
             String resultWho = data.readString();
             int requestCode = data.readInt();
             int startFlags = data.readInt();
-            String profileFile = data.readString();
-            ParcelFileDescriptor profileFd = data.readInt() != 0
-                    ? data.readFileDescriptor() : null;
+            ProfilerInfo profilerInfo = data.readInt() != 0
+                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int result = startActivity(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags,
-                    profileFile, profileFd, options);
+                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
             reply.writeNoException();
             reply.writeInt(result);
             return true;
@@ -153,15 +156,36 @@
             String resultWho = data.readString();
             int requestCode = data.readInt();
             int startFlags = data.readInt();
-            String profileFile = data.readString();
-            ParcelFileDescriptor profileFd = data.readInt() != 0
-                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
+            ProfilerInfo profilerInfo = data.readInt() != 0
+                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int userId = data.readInt();
             int result = startActivityAsUser(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags,
-                    profileFile, profileFd, options, userId);
+                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId);
+            reply.writeNoException();
+            reply.writeInt(result);
+            return true;
+        }
+
+        case START_ACTIVITY_AS_CALLER_TRANSACTION:
+        {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder b = data.readStrongBinder();
+            IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
+            Intent intent = Intent.CREATOR.createFromParcel(data);
+            String resolvedType = data.readString();
+            IBinder resultTo = data.readStrongBinder();
+            String resultWho = data.readString();
+            int requestCode = data.readInt();
+            int startFlags = data.readInt();
+            ProfilerInfo profilerInfo = data.readInt() != 0
+                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
+            Bundle options = data.readInt() != 0
+                    ? Bundle.CREATOR.createFromParcel(data) : null;
+            int result = startActivityAsCaller(app, callingPackage, intent, resolvedType,
+                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
             reply.writeNoException();
             reply.writeInt(result);
             return true;
@@ -179,15 +203,13 @@
             String resultWho = data.readString();
             int requestCode = data.readInt();
             int startFlags = data.readInt();
-            String profileFile = data.readString();
-            ParcelFileDescriptor profileFd = data.readInt() != 0
-                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
+            ProfilerInfo profilerInfo = data.readInt() != 0
+                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int userId = data.readInt();
             WaitResult result = startActivityAndWait(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags,
-                    profileFile, profileFd, options, userId);
+                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId);
             reply.writeNoException();
             result.writeToParcel(reply, 0);
             return true;
@@ -242,6 +264,31 @@
             return true;
         }
 
+        case START_VOICE_ACTIVITY_TRANSACTION:
+        {
+            data.enforceInterface(IActivityManager.descriptor);
+            String callingPackage = data.readString();
+            int callingPid = data.readInt();
+            int callingUid = data.readInt();
+            Intent intent = Intent.CREATOR.createFromParcel(data);
+            String resolvedType = data.readString();
+            IVoiceInteractionSession session = IVoiceInteractionSession.Stub.asInterface(
+                    data.readStrongBinder());
+            IVoiceInteractor interactor = IVoiceInteractor.Stub.asInterface(
+                    data.readStrongBinder());
+            int startFlags = data.readInt();
+            ProfilerInfo profilerInfo = data.readInt() != 0
+                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
+            Bundle options = data.readInt() != 0
+                    ? Bundle.CREATOR.createFromParcel(data) : null;
+            int userId = data.readInt();
+            int result = startVoiceActivity(callingPackage, callingPid, callingUid, intent,
+                    resolvedType, session, interactor, startFlags, profilerInfo, options, userId);
+            reply.writeNoException();
+            reply.writeInt(result);
+            return true;
+        }
+
         case START_NEXT_MATCHING_ACTIVITY_TRANSACTION:
         {
             data.enforceInterface(IActivityManager.descriptor);
@@ -255,6 +302,17 @@
             return true;
         }
 
+        case START_ACTIVITY_FROM_RECENTS_TRANSACTION:
+        {
+            data.enforceInterface(IActivityManager.descriptor);
+            int taskId = data.readInt();
+            Bundle options = data.readInt() == 0 ? null : Bundle.CREATOR.createFromParcel(data);
+            int result = startActivityFromRecents(taskId, options);
+            reply.writeNoException();
+            reply.writeInt(result);
+            return true;
+        }
+
         case FINISH_ACTIVITY_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -263,7 +321,8 @@
             if (data.readInt() != 0) {
                 resultData = Intent.CREATOR.createFromParcel(data);
             }
-            boolean res = finishActivity(token, resultCode, resultData);
+            boolean finishTask = (data.readInt() != 0);
+            boolean res = finishActivity(token, resultCode, resultData, finishTask);
             reply.writeNoException();
             reply.writeInt(res ? 1 : 0);
             return true;
@@ -288,6 +347,32 @@
             return true;
         }
 
+        case FINISH_VOICE_TASK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IVoiceInteractionSession session = IVoiceInteractionSession.Stub.asInterface(
+                    data.readStrongBinder());
+            finishVoiceTask(session);
+            reply.writeNoException();
+            return true;
+        }
+
+        case RELEASE_ACTIVITY_INSTANCE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            boolean res = releaseActivityInstance(token);
+            reply.writeNoException();
+            reply.writeInt(res ? 1 : 0);
+            return true;
+        }
+
+        case RELEASE_SOME_ACTIVITIES_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IApplicationThread app = ApplicationThreadNative.asInterface(data.readStrongBinder());
+            releaseSomeActivities(app);
+            reply.writeNoException();
+            return true;
+        }
+
         case WILL_ACTIVITY_BE_VISIBLE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -433,10 +518,9 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
             Bundle map = data.readBundle();
-            Bitmap thumbnail = data.readInt() != 0
-                ? Bitmap.CREATOR.createFromParcel(data) : null;
+            PersistableBundle persistentState = data.readPersistableBundle();
             CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data);
-            activityStopped(token, map, thumbnail, description);
+            activityStopped(token, map, persistentState, description);
             reply.writeNoException();
             return true;
         }
@@ -475,15 +559,47 @@
             return true;
         }
 
+        case GET_APP_TASKS_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            String callingPackage = data.readString();
+            List<IAppTask> list = getAppTasks(callingPackage);
+            reply.writeNoException();
+            int N = list != null ? list.size() : -1;
+            reply.writeInt(N);
+            int i;
+            for (i=0; i<N; i++) {
+                IAppTask task = list.get(i);
+                reply.writeStrongBinder(task.asBinder());
+            }
+            return true;
+        }
+
+        case ADD_APP_TASK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder activityToken = data.readStrongBinder();
+            Intent intent = Intent.CREATOR.createFromParcel(data);
+            ActivityManager.TaskDescription descr
+                    = ActivityManager.TaskDescription.CREATOR.createFromParcel(data);
+            Bitmap thumbnail = Bitmap.CREATOR.createFromParcel(data);
+            int res = addAppTask(activityToken, intent, descr, thumbnail);
+            reply.writeNoException();
+            reply.writeInt(res);
+            return true;
+        }
+
+        case GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            Point size = getAppTaskThumbnailSize();
+            reply.writeNoException();
+            size.writeToParcel(reply, 0);
+            return true;
+        }
+
         case GET_TASKS_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int maxNum = data.readInt();
             int fl = data.readInt();
-            IBinder receiverBinder = data.readStrongBinder();
-            IThumbnailReceiver receiver = receiverBinder != null
-                ? IThumbnailReceiver.Stub.asInterface(receiverBinder)
-                : null;
-            List<ActivityManager.RunningTaskInfo> list = getTasks(maxNum, fl, receiver);
+            List<ActivityManager.RunningTaskInfo> list = getTasks(maxNum, fl);
             reply.writeNoException();
             int N = list != null ? list.size() : -1;
             reply.writeInt(N);
@@ -507,28 +623,14 @@
             return true;
         }
 
-        case GET_TASK_THUMBNAILS_TRANSACTION: {
+        case GET_TASK_THUMBNAIL_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int id = data.readInt();
-            ActivityManager.TaskThumbnails bm = getTaskThumbnails(id);
+            ActivityManager.TaskThumbnail taskThumbnail = getTaskThumbnail(id);
             reply.writeNoException();
-            if (bm != null) {
+            if (taskThumbnail != null) {
                 reply.writeInt(1);
-                bm.writeToParcel(reply, 0);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case GET_TASK_TOP_THUMBNAIL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int id = data.readInt();
-            Bitmap bm = getTaskTopThumbnail(id);
-            reply.writeNoException();
-            if (bm != null) {
-                reply.writeInt(1);
-                bm.writeToParcel(reply, 0);
+                taskThumbnail.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
             } else {
                 reply.writeInt(0);
             }
@@ -654,6 +756,15 @@
             return true;
         }
 
+        case IS_IN_HOME_STACK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int taskId = data.readInt();
+            boolean isInHomeStack = isInHomeStack(taskId);
+            reply.writeNoException();
+            reply.writeInt(isInHomeStack ? 1 : 0);
+            return true;
+        }
+
         case SET_FOCUSED_STACK_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int stackId = data.readInt();
@@ -673,17 +784,6 @@
             return true;
         }
 
-        case REPORT_THUMBNAIL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Bitmap thumbnail = data.readInt() != 0
-                ? Bitmap.CREATOR.createFromParcel(data) : null;
-            CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data);
-            reportThumbnail(token, thumbnail, description);
-            reply.writeNoException();
-            return true;
-        }
-
         case GET_CONTENT_PROVIDER_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
@@ -1091,7 +1191,8 @@
             int pid = data.readInt();
             int uid = data.readInt();
             int mode = data.readInt();
-            int res = checkUriPermission(uri, pid, uid, mode);
+            int userId = data.readInt();
+            int res = checkUriPermission(uri, pid, uid, mode, userId);
             reply.writeNoException();
             reply.writeInt(res);
             return true;
@@ -1116,7 +1217,8 @@
             String targetPkg = data.readString();
             Uri uri = Uri.CREATOR.createFromParcel(data);
             int mode = data.readInt();
-            grantUriPermission(app, targetPkg, uri, mode);
+            int userId = data.readInt();
+            grantUriPermission(app, targetPkg, uri, mode, userId);
             reply.writeNoException();
             return true;
         }
@@ -1127,7 +1229,8 @@
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
             Uri uri = Uri.CREATOR.createFromParcel(data);
             int mode = data.readInt();
-            revokeUriPermission(app, uri, mode);
+            int userId = data.readInt();
+            revokeUriPermission(app, uri, mode, userId);
             reply.writeNoException();
             return true;
         }
@@ -1136,7 +1239,8 @@
             data.enforceInterface(IActivityManager.descriptor);
             Uri uri = Uri.CREATOR.createFromParcel(data);
             int mode = data.readInt();
-            takePersistableUriPermission(uri, mode);
+            int userId = data.readInt();
+            takePersistableUriPermission(uri, mode, userId);
             reply.writeNoException();
             return true;
         }
@@ -1145,7 +1249,8 @@
             data.enforceInterface(IActivityManager.descriptor);
             Uri uri = Uri.CREATOR.createFromParcel(data);
             int mode = data.readInt();
-            releasePersistableUriPermission(uri, mode);
+            int userId = data.readInt();
+            releasePersistableUriPermission(uri, mode, userId);
             reply.writeNoException();
             return true;
         }
@@ -1246,7 +1351,9 @@
             data.enforceInterface(IActivityManager.descriptor);
             IIntentSender is = IIntentSender.Stub.asInterface(
                     data.readStrongBinder());
-            noteWakeupAlarm(is);
+            int sourceUid = data.readInt();
+            String sourcePkg = data.readString();
+            noteWakeupAlarm(is, sourceUid, sourcePkg);
             reply.writeNoException();
             return true;
         }
@@ -1284,8 +1391,9 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder app = data.readStrongBinder();
             String tag = data.readString();
+            boolean system = data.readInt() != 0;
             ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data);
-            boolean res = handleApplicationWtf(app, tag, ci);
+            boolean res = handleApplicationWtf(app, tag, system, ci);
             reply.writeNoException();
             reply.writeInt(res ? 1 : 0);
             return true;
@@ -1351,22 +1459,21 @@
             config.writeToParcel(reply, 0);
             return true;
         }
-        
+
         case PROFILE_CONTROL_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             String process = data.readString();
             int userId = data.readInt();
             boolean start = data.readInt() != 0;
             int profileType = data.readInt();
-            String path = data.readString();
-            ParcelFileDescriptor fd = data.readInt() != 0
-                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
-            boolean res = profileControl(process, userId, start, path, fd, profileType);
+            ProfilerInfo profilerInfo = data.readInt() != 0
+                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
+            boolean res = profileControl(process, userId, start, profilerInfo, profileType);
             reply.writeNoException();
             reply.writeInt(res ? 1 : 0);
             return true;
         }
-        
+
         case SHUTDOWN_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             boolean res = shutdown(data.readInt());
@@ -1425,7 +1532,15 @@
             reply.writeNoException();
             return true;
         }
-        
+
+        case ADD_PACKAGE_DEPENDENCY_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            String packageName = data.readString();
+            addPackageDependency(packageName);
+            reply.writeNoException();
+            return true;
+        }
+
         case KILL_APPLICATION_WITH_APPID_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             String pkg = data.readString();
@@ -1435,7 +1550,7 @@
             reply.writeNoException();
             return true;
         }
-        
+
         case CLOSE_SYSTEM_DIALOGS_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             String reason = data.readString();
@@ -1505,6 +1620,15 @@
             return true;
         }
 
+        case IS_TOP_OF_TASK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            final boolean isTopOfTask = isTopOfTask(token);
+            reply.writeNoException();
+            reply.writeInt(isTopOfTask ? 1 : 0);
+            return true;
+        }
+
         case CONVERT_FROM_TRANSLUCENT_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -1517,12 +1641,28 @@
         case CONVERT_TO_TRANSLUCENT_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
-            boolean converted = convertToTranslucent(token);
+            final Bundle bundle;
+            if (data.readInt() == 0) {
+                bundle = null;
+            } else {
+                bundle = data.readBundle();
+            }
+            final ActivityOptions options = bundle == null ? null : new ActivityOptions(bundle);
+            boolean converted = convertToTranslucent(token, options);
             reply.writeNoException();
             reply.writeInt(converted ? 1 : 0);
             return true;
         }
 
+        case GET_ACTIVITY_OPTIONS_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            final ActivityOptions options = getActivityOptions(token);
+            reply.writeNoException();
+            reply.writeBundle(options == null ? null : options.toBundle());
+            return true;
+        }
+
         case SET_IMMERSIVE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -1577,7 +1717,10 @@
             String targetPkg = data.readString();
             Uri uri = Uri.CREATOR.createFromParcel(data);
             int mode = data.readInt();
-            grantUriPermissionFromOwner(owner, fromUid, targetPkg, uri, mode);
+            int sourceUserId = data.readInt();
+            int targetUserId = data.readInt();
+            grantUriPermissionFromOwner(owner, fromUid, targetPkg, uri, mode, sourceUserId,
+                    targetUserId);
             reply.writeNoException();
             return true;
         }
@@ -1587,10 +1730,11 @@
             IBinder owner = data.readStrongBinder();
             Uri uri = null;
             if (data.readInt() != 0) {
-                Uri.CREATOR.createFromParcel(data);
+                uri = Uri.CREATOR.createFromParcel(data);
             }
             int mode = data.readInt();
-            revokeUriPermissionFromOwner(owner, uri, mode);
+            int userId = data.readInt();
+            revokeUriPermissionFromOwner(owner, uri, mode, userId);
             reply.writeNoException();
             return true;
         }
@@ -1601,7 +1745,8 @@
             String targetPkg = data.readString();
             Uri uri = Uri.CREATOR.createFromParcel(data);
             int modeFlags = data.readInt();
-            int res = checkGrantUriPermission(callingUid, targetPkg, uri, modeFlags);
+            int userId = data.readInt();
+            int res = checkGrantUriPermission(callingUid, targetPkg, uri, modeFlags, userId);
             reply.writeNoException();
             reply.writeInt(res);
             return true;
@@ -1688,6 +1833,15 @@
             return true;
         }
 
+        case START_USER_IN_BACKGROUND_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int userid = data.readInt();
+            boolean result = startUserInBackground(userid);
+            reply.writeNoException();
+            reply.writeInt(result ? 1 : 0);
+            return true;
+        }
+
         case STOP_USER_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int userid = data.readInt();
@@ -1725,17 +1879,6 @@
             return true;
         }
 
-        case REMOVE_SUB_TASK_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            int subTaskIndex = data.readInt();
-            boolean result = removeSubTask(taskId, subTaskIndex);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
         case REMOVE_TASK_TRANSACTION:
         {
             data.enforceInterface(IActivityManager.descriptor);
@@ -1818,6 +1961,17 @@
             return true;
         }
 
+        case GET_TAG_FOR_INTENT_SENDER_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IIntentSender r = IIntentSender.Stub.asInterface(
+                data.readStrongBinder());
+            String prefix = data.readString();
+            String tag = getTagForIntentSender(r, prefix);
+            reply.writeNoException();
+            reply.writeString(tag);
+            return true;
+        }
+
         case UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             Configuration config = Configuration.CREATOR.createFromParcel(data);
@@ -1844,18 +1998,18 @@
             return true;
         }
 
-        case DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION: {
+        case KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            dismissKeyguardOnNextActivity();
+            keyguardWaitingForActivityDrawn();
             reply.writeNoException();
             return true;
         }
 
-        case TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION: {
+        case SHOULD_UP_RECREATE_TASK_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
             String destAffinity = data.readString();
-            boolean res = targetTaskAffinityMatchesActivity(token, destAffinity);
+            boolean res = shouldUpRecreateTask(token, destAffinity);
             reply.writeNoException();
             reply.writeInt(res ? 1 : 0);
             return true;
@@ -2043,6 +2197,125 @@
             reply.writeStrongBinder(homeActivityToken);
             return true;
         }
+
+        case START_LOCK_TASK_BY_TASK_ID_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final int taskId = data.readInt();
+            startLockTaskMode(taskId);
+            reply.writeNoException();
+            return true;
+        }
+
+        case START_LOCK_TASK_BY_TOKEN_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            startLockTaskMode(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case START_LOCK_TASK_BY_CURRENT_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            startLockTaskModeOnCurrent();
+            reply.writeNoException();
+            return true;
+        }
+
+        case STOP_LOCK_TASK_MODE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            stopLockTaskMode();
+            reply.writeNoException();
+            return true;
+        }
+
+        case STOP_LOCK_TASK_BY_CURRENT_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            stopLockTaskModeOnCurrent();
+            reply.writeNoException();
+            return true;
+        }
+
+        case IS_IN_LOCK_TASK_MODE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final boolean isInLockTaskMode = isInLockTaskMode();
+            reply.writeNoException();
+            reply.writeInt(isInLockTaskMode ? 1 : 0);
+            return true;
+        }
+
+        case SET_TASK_DESCRIPTION_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            ActivityManager.TaskDescription values =
+                    ActivityManager.TaskDescription.CREATOR.createFromParcel(data);
+            setTaskDescription(token, values);
+            reply.writeNoException();
+            return true;
+        }
+
+        case GET_TASK_DESCRIPTION_ICON_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            String filename = data.readString();
+            Bitmap icon = getTaskDescriptionIcon(filename);
+            reply.writeNoException();
+            if (icon == null) {
+                reply.writeInt(0);
+            } else {
+                reply.writeInt(1);
+                icon.writeToParcel(reply, 0);
+            }
+            return true;
+        }
+
+        case REQUEST_VISIBLE_BEHIND_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            boolean enable = data.readInt() > 0;
+            boolean success = requestVisibleBehind(token, enable);
+            reply.writeNoException();
+            reply.writeInt(success ? 1 : 0);
+            return true;
+        }
+
+        case IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            final boolean enabled = isBackgroundVisibleBehind(token);
+            reply.writeNoException();
+            reply.writeInt(enabled ? 1 : 0);
+            return true;
+        }
+
+        case BACKGROUND_RESOURCES_RELEASED_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            backgroundResourcesReleased(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            notifyLaunchTaskBehindComplete(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            notifyEnterAnimationComplete(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case BOOT_ANIMATION_COMPLETE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            bootAnimationComplete();
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -2081,8 +2354,7 @@
 
     public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
             String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, String profileFile,
-            ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
+            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -2094,10 +2366,9 @@
         data.writeString(resultWho);
         data.writeInt(requestCode);
         data.writeInt(startFlags);
-        data.writeString(profileFile);
-        if (profileFd != null) {
+        if (profilerInfo != null) {
             data.writeInt(1);
-            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
         } else {
             data.writeInt(0);
         }
@@ -2117,8 +2388,8 @@
 
     public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
             String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, String profileFile,
-            ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException {
+            int startFlags, ProfilerInfo profilerInfo, Bundle options,
+            int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -2130,10 +2401,9 @@
         data.writeString(resultWho);
         data.writeInt(requestCode);
         data.writeInt(startFlags);
-        data.writeString(profileFile);
-        if (profileFd != null) {
+        if (profilerInfo != null) {
             data.writeInt(1);
-            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
         } else {
             data.writeInt(0);
         }
@@ -2151,10 +2421,9 @@
         data.recycle();
         return result;
     }
-    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int startFlags, String profileFile,
-            ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException {
+    public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
+            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -2166,10 +2435,43 @@
         data.writeString(resultWho);
         data.writeInt(requestCode);
         data.writeInt(startFlags);
-        data.writeString(profileFile);
-        if (profileFd != null) {
+        if (profilerInfo != null) {
             data.writeInt(1);
-            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+        } else {
+            data.writeInt(0);
+        }
+        if (options != null) {
+            data.writeInt(1);
+            options.writeToParcel(data, 0);
+        } else {
+            data.writeInt(0);
+        }
+        mRemote.transact(START_ACTIVITY_AS_CALLER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        int result = reply.readInt();
+        reply.recycle();
+        data.recycle();
+        return result;
+    }
+    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
+            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
+            int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options,
+            int userId) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
+        intent.writeToParcel(data, 0);
+        data.writeString(resolvedType);
+        data.writeStrongBinder(resultTo);
+        data.writeString(resultWho);
+        data.writeInt(requestCode);
+        data.writeInt(startFlags);
+        if (profilerInfo != null) {
+            data.writeInt(1);
+            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
         } else {
             data.writeInt(0);
         }
@@ -2251,6 +2553,41 @@
         data.recycle();
         return result;
     }
+    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
+            Intent intent, String resolvedType, IVoiceInteractionSession session,
+            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
+            Bundle options, int userId) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(callingPackage);
+        data.writeInt(callingPid);
+        data.writeInt(callingUid);
+        intent.writeToParcel(data, 0);
+        data.writeString(resolvedType);
+        data.writeStrongBinder(session.asBinder());
+        data.writeStrongBinder(interactor.asBinder());
+        data.writeInt(startFlags);
+        if (profilerInfo != null) {
+            data.writeInt(1);
+            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+        } else {
+            data.writeInt(0);
+        }
+        if (options != null) {
+            data.writeInt(1);
+            options.writeToParcel(data, 0);
+        } else {
+            data.writeInt(0);
+        }
+        data.writeInt(userId);
+        mRemote.transact(START_VOICE_ACTIVITY_TRANSACTION, data, reply, 0);
+        reply.readException();
+        int result = reply.readInt();
+        reply.recycle();
+        data.recycle();
+        return result;
+    }
     public boolean startNextMatchingActivity(IBinder callingActivity,
             Intent intent, Bundle options) throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -2271,7 +2608,25 @@
         data.recycle();
         return result != 0;
     }
-    public boolean finishActivity(IBinder token, int resultCode, Intent resultData)
+    public int startActivityFromRecents(int taskId, Bundle options) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        if (options == null) {
+            data.writeInt(0);
+        } else {
+            data.writeInt(1);
+            options.writeToParcel(data, 0);
+        }
+        mRemote.transact(START_ACTIVITY_FROM_RECENTS_TRANSACTION, data, reply, 0);
+        reply.readException();
+        int result = reply.readInt();
+        reply.recycle();
+        data.recycle();
+        return result;
+    }
+    public boolean finishActivity(IBinder token, int resultCode, Intent resultData, boolean finishTask)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -2284,6 +2639,7 @@
         } else {
             data.writeInt(0);
         }
+        data.writeInt(finishTask ? 1 : 0);
         mRemote.transact(FINISH_ACTIVITY_TRANSACTION, data, reply, 0);
         reply.readException();
         boolean res = reply.readInt() != 0;
@@ -2316,6 +2672,38 @@
         reply.recycle();
         return res;
     }
+    public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(session.asBinder());
+        mRemote.transact(FINISH_VOICE_TASK_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+    public boolean releaseActivityInstance(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(RELEASE_ACTIVITY_INSTANCE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean res = reply.readInt() != 0;
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+    public void releaseSomeActivities(IApplicationThread app) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(app.asBinder());
+        mRemote.transact(RELEASE_SOME_ACTIVITIES_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
     public boolean willActivityBeVisible(IBinder token) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -2473,19 +2861,14 @@
         reply.recycle();
     }
     public void activityStopped(IBinder token, Bundle state,
-            Bitmap thumbnail, CharSequence description) throws RemoteException
+            PersistableBundle persistentState, CharSequence description) throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(token);
         data.writeBundle(state);
-        if (thumbnail != null) {
-            data.writeInt(1);
-            thumbnail.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
+        data.writePersistableBundle(persistentState);
         TextUtils.writeToParcel(description, data, 0);
         mRemote.transact(ACTIVITY_STOPPED_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
         reply.readException();
@@ -2540,14 +2923,60 @@
         reply.recycle();
         return res;
     }
-    public List getTasks(int maxNum, int flags,
-            IThumbnailReceiver receiver) throws RemoteException {
+    public List<IAppTask> getAppTasks(String callingPackage) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(callingPackage);
+        mRemote.transact(GET_APP_TASKS_TRANSACTION, data, reply, 0);
+        reply.readException();
+        ArrayList<IAppTask> list = null;
+        int N = reply.readInt();
+        if (N >= 0) {
+            list = new ArrayList<IAppTask>();
+            while (N > 0) {
+                IAppTask task = IAppTask.Stub.asInterface(reply.readStrongBinder());
+                list.add(task);
+                N--;
+            }
+        }
+        data.recycle();
+        reply.recycle();
+        return list;
+    }
+    public int addAppTask(IBinder activityToken, Intent intent,
+            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(activityToken);
+        intent.writeToParcel(data, 0);
+        description.writeToParcel(data, 0);
+        thumbnail.writeToParcel(data, 0);
+        mRemote.transact(ADD_APP_TASK_TRANSACTION, data, reply, 0);
+        reply.readException();
+        int res = reply.readInt();
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+    public Point getAppTaskThumbnailSize() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        Point size = Point.CREATOR.createFromParcel(reply);
+        data.recycle();
+        reply.recycle();
+        return size;
+    }
+    public List getTasks(int maxNum, int flags) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(maxNum);
         data.writeInt(flags);
-        data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);
         mRemote.transact(GET_TASKS_TRANSACTION, data, reply, 0);
         reply.readException();
         ArrayList list = null;
@@ -2557,7 +2986,7 @@
             while (N > 0) {
                 ActivityManager.RunningTaskInfo info =
                         ActivityManager.RunningTaskInfo.CREATOR
-                        .createFromParcel(reply);
+                                .createFromParcel(reply);
                 list.add(info);
                 N--;
             }
@@ -2582,35 +3011,20 @@
         reply.recycle();
         return list;
     }
-    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) throws RemoteException {
+    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(id);
-        mRemote.transact(GET_TASK_THUMBNAILS_TRANSACTION, data, reply, 0);
+        mRemote.transact(GET_TASK_THUMBNAIL_TRANSACTION, data, reply, 0);
         reply.readException();
-        ActivityManager.TaskThumbnails bm = null;
+        ActivityManager.TaskThumbnail taskThumbnail = null;
         if (reply.readInt() != 0) {
-            bm = ActivityManager.TaskThumbnails.CREATOR.createFromParcel(reply);
+            taskThumbnail = ActivityManager.TaskThumbnail.CREATOR.createFromParcel(reply);
         }
         data.recycle();
         reply.recycle();
-        return bm;
-    }
-    public Bitmap getTaskTopThumbnail(int id) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(id);
-        mRemote.transact(GET_TASK_TOP_THUMBNAIL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Bitmap bm = null;
-        if (reply.readInt() != 0) {
-            bm = Bitmap.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return bm;
+        return taskThumbnail;
     }
     public List getServices(int maxNum, int flags) throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -2788,6 +3202,19 @@
         return info;
     }
     @Override
+    public boolean isInHomeStack(int taskId) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        mRemote.transact(IS_IN_HOME_STACK_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean isInHomeStack = reply.readInt() > 0;
+        data.recycle();
+        reply.recycle();
+        return isInHomeStack;
+    }
+    @Override
     public void setFocusedStack(int stackId) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -2813,25 +3240,6 @@
         reply.recycle();
         return res;
     }
-    public void reportThumbnail(IBinder token,
-                                Bitmap thumbnail, CharSequence description) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        if (thumbnail != null) {
-            data.writeInt(1);
-            thumbnail.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        TextUtils.writeToParcel(description, data, 0);
-        mRemote.transact(REPORT_THUMBNAIL_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
     public ContentProviderHolder getContentProvider(IApplicationThread caller,
             String name, int userId, boolean stable) throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -3431,7 +3839,7 @@
         reply.recycle();
         return res;
     }
-    public int checkUriPermission(Uri uri, int pid, int uid, int mode) 
+    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -3440,6 +3848,7 @@
         data.writeInt(pid);
         data.writeInt(uid);
         data.writeInt(mode);
+        data.writeInt(userId);
         mRemote.transact(CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0);
         reply.readException();
         int res = reply.readInt();
@@ -3448,7 +3857,7 @@
         return res;
     }
     public void grantUriPermission(IApplicationThread caller, String targetPkg,
-            Uri uri, int mode) throws RemoteException {
+            Uri uri, int mode, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -3456,19 +3865,21 @@
         data.writeString(targetPkg);
         uri.writeToParcel(data, 0);
         data.writeInt(mode);
+        data.writeInt(userId);
         mRemote.transact(GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
         reply.recycle();
     }
     public void revokeUriPermission(IApplicationThread caller, Uri uri,
-            int mode) throws RemoteException {
+            int mode, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller.asBinder());
         uri.writeToParcel(data, 0);
         data.writeInt(mode);
+        data.writeInt(userId);
         mRemote.transact(REVOKE_URI_PERMISSION_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -3476,12 +3887,14 @@
     }
 
     @Override
-    public void takePersistableUriPermission(Uri uri, int mode) throws RemoteException {
+    public void takePersistableUriPermission(Uri uri, int mode, int userId)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         uri.writeToParcel(data, 0);
         data.writeInt(mode);
+        data.writeInt(userId);
         mRemote.transact(TAKE_PERSISTABLE_URI_PERMISSION_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -3489,12 +3902,14 @@
     }
 
     @Override
-    public void releasePersistableUriPermission(Uri uri, int mode) throws RemoteException {
+    public void releasePersistableUriPermission(Uri uri, int mode, int userId)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         uri.writeToParcel(data, 0);
         data.writeInt(mode);
+        data.writeInt(userId);
         mRemote.transact(RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -3619,10 +4034,13 @@
         mRemote.transact(ENTER_SAFE_MODE_TRANSACTION, data, null, 0);
         data.recycle();
     }
-    public void noteWakeupAlarm(IIntentSender sender) throws RemoteException {
+    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
-        data.writeStrongBinder(sender.asBinder());
         data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(sender.asBinder());
+        data.writeInt(sourceUid);
+        data.writeString(sourcePkg);
         mRemote.transact(NOTE_WAKEUP_ALARM_TRANSACTION, data, null, 0);
         data.recycle();
     }
@@ -3671,7 +4089,7 @@
         data.recycle();
     }
 
-    public boolean handleApplicationWtf(IBinder app, String tag,
+    public boolean handleApplicationWtf(IBinder app, String tag, boolean system,
             ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -3679,6 +4097,7 @@
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(app);
         data.writeString(tag);
+        data.writeInt(system ? 1 : 0);
         crashInfo.writeToParcel(data, 0);
         mRemote.transact(HANDLE_APPLICATION_WTF_TRANSACTION, data, reply, 0);
         reply.readException();
@@ -3774,9 +4193,9 @@
         data.recycle();
         return res;
     }
-    
+
     public boolean profileControl(String process, int userId, boolean start,
-            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException
+            ProfilerInfo profilerInfo, int profileType) throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -3785,10 +4204,9 @@
         data.writeInt(userId);
         data.writeInt(start ? 1 : 0);
         data.writeInt(profileType);
-        data.writeString(path);
-        if (fd != null) {
+        if (profilerInfo != null) {
             data.writeInt(1);
-            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
         } else {
             data.writeInt(0);
         }
@@ -3799,7 +4217,7 @@
         data.recycle();
         return res;
     }
-    
+
     public boolean shutdown(int timeout) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -3833,7 +4251,18 @@
         reply.recycle();
         data.recycle();
     }
-    
+
+    public void addPackageDependency(String packageName) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(packageName);
+        mRemote.transact(ADD_PACKAGE_DEPENDENCY_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     public void killApplicationWithAppId(String pkg, int appid, String reason)
             throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -3947,12 +4376,18 @@
         return res;
     }
 
-    public boolean convertToTranslucent(IBinder token)
+    public boolean convertToTranslucent(IBinder token, ActivityOptions options)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(token);
+        if (options == null) {
+            data.writeInt(0);
+        } else {
+            data.writeInt(1);
+            data.writeBundle(options.toBundle());
+        }
         mRemote.transact(CONVERT_TO_TRANSLUCENT_TRANSACTION, data, reply, 0);
         reply.readException();
         boolean res = reply.readInt() != 0;
@@ -3961,6 +4396,20 @@
         return res;
     }
 
+    public ActivityOptions getActivityOptions(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(GET_ACTIVITY_OPTIONS_TRANSACTION, data, reply, 0);
+        reply.readException();
+        Bundle bundle = reply.readBundle();
+        ActivityOptions options = bundle == null ? null : new ActivityOptions(bundle);
+        data.recycle();
+        reply.recycle();
+        return options;
+    }
+
     public void setImmersive(IBinder token, boolean immersive)
             throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -3988,6 +4437,19 @@
         return res;
     }
 
+    public boolean isTopOfTask(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(IS_TOP_OF_TASK_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean res = reply.readInt() == 1;
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
     public boolean isTopActivityImmersive()
             throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -4045,7 +4507,7 @@
     }
 
     public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
-            Uri uri, int mode) throws RemoteException {
+            Uri uri, int mode, int sourceUserId, int targetUserId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -4054,6 +4516,8 @@
         data.writeString(targetPkg);
         uri.writeToParcel(data, 0);
         data.writeInt(mode);
+        data.writeInt(sourceUserId);
+        data.writeInt(targetUserId);
         mRemote.transact(GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -4061,7 +4525,7 @@
     }
 
     public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
-            int mode) throws RemoteException {
+            int mode, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -4073,6 +4537,7 @@
             data.writeInt(0);
         }
         data.writeInt(mode);
+        data.writeInt(userId);
         mRemote.transact(REVOKE_URI_PERMISSION_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -4080,7 +4545,7 @@
     }
 
     public int checkGrantUriPermission(int callingUid, String targetPkg,
-            Uri uri, int modeFlags) throws RemoteException {
+            Uri uri, int modeFlags, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -4088,6 +4553,7 @@
         data.writeString(targetPkg);
         uri.writeToParcel(data, 0);
         data.writeInt(modeFlags);
+        data.writeInt(userId);
         mRemote.transact(CHECK_GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
         reply.readException();
         int res = reply.readInt();
@@ -4233,6 +4699,19 @@
         return result;
     }
 
+    public boolean startUserInBackground(int userid) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(userid);
+        mRemote.transact(START_USER_IN_BACKGROUND_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean result = reply.readInt() != 0;
+        reply.recycle();
+        data.recycle();
+        return result;
+    }
+
     public int stopUser(int userid, IStopUserCallback callback) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -4285,20 +4764,6 @@
         return result;
     }
 
-    public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(subTaskIndex);
-        mRemote.transact(REMOVE_SUB_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
     public boolean removeTask(int taskId, int flags) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -4375,6 +4840,21 @@
         return res;
     }
 
+    public String getTagForIntentSender(IIntentSender sender, String prefix)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(sender.asBinder());
+        data.writeString(prefix);
+        mRemote.transact(GET_TAG_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        String res = reply.readString();
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
     public void updatePersistentConfiguration(Configuration values) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -4412,24 +4892,24 @@
         reply.recycle();
     }
 
-    public void dismissKeyguardOnNextActivity() throws RemoteException {
+    public void keyguardWaitingForActivityDrawn() throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION, data, reply, 0);
+        mRemote.transact(KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
         reply.recycle();
     }
 
-    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity)
+    public boolean shouldUpRecreateTask(IBinder token, String destAffinity)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(token);
         data.writeString(destAffinity);
-        mRemote.transact(TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION, data, reply, 0);
+        mRemote.transact(SHOULD_UP_RECREATE_TASK_TRANSACTION, data, reply, 0);
         reply.readException();
         boolean result = reply.readInt() != 0;
         data.recycle();
@@ -4690,5 +5170,182 @@
         return res;
     }
 
+    @Override
+    public void startLockTaskMode(int taskId) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        mRemote.transact(START_LOCK_TASK_BY_TASK_ID_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void startLockTaskMode(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(START_LOCK_TASK_BY_TOKEN_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void startLockTaskModeOnCurrent() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(START_LOCK_TASK_BY_CURRENT_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void stopLockTaskMode() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(STOP_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void stopLockTaskModeOnCurrent() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(STOP_LOCK_TASK_BY_CURRENT_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public boolean isInLockTaskMode() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(IS_IN_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean isInLockTaskMode = reply.readInt() == 1;
+        data.recycle();
+        reply.recycle();
+        return isInLockTaskMode;
+    }
+
+    @Override
+    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        values.writeToParcel(data, 0);
+        mRemote.transact(SET_TASK_DESCRIPTION_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(filename);
+        mRemote.transact(GET_TASK_DESCRIPTION_ICON_TRANSACTION, data, reply, 0);
+        reply.readException();
+        final Bitmap icon = reply.readInt() == 0 ? null : Bitmap.CREATOR.createFromParcel(reply);
+        data.recycle();
+        reply.recycle();
+        return icon;
+    }
+
+    @Override
+    public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        data.writeInt(visible ? 1 : 0);
+        mRemote.transact(REQUEST_VISIBLE_BEHIND_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean success = reply.readInt() > 0;
+        data.recycle();
+        reply.recycle();
+        return success;
+    }
+
+    @Override
+    public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION, data, reply, 0);
+        reply.readException();
+        final boolean visible = reply.readInt() > 0;
+        data.recycle();
+        reply.recycle();
+        return visible;
+    }
+
+    @Override
+    public void backgroundResourcesReleased(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(BACKGROUND_RESOURCES_RELEASED_TRANSACTION, data, reply,
+                IBinder.FLAG_ONEWAY);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void notifyLaunchTaskBehindComplete(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION, data, reply,
+                IBinder.FLAG_ONEWAY);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void notifyEnterAnimationComplete(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION, data, reply,
+                IBinder.FLAG_ONEWAY);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void bootAnimationComplete() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(BOOT_ANIMATION_COMPLETE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 87b1e24..cd6a4f5 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -17,12 +17,18 @@
 package android.app;
 
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.util.Pair;
 import android.view.View;
+import android.view.Window;
+
+import java.util.ArrayList;
 
 /**
  * Helper class for building an options Bundle that can be used with
@@ -30,6 +36,8 @@
  * Context.startActivity(Intent, Bundle)} and related methods.
  */
 public class ActivityOptions {
+    private static final String TAG = "ActivityOptions";
+
     /**
      * The package name that created the options.
      * @hide
@@ -76,13 +84,13 @@
      * Initial width of the animation.
      * @hide
      */
-    public static final String KEY_ANIM_START_WIDTH = "android:animStartWidth";
+    public static final String KEY_ANIM_WIDTH = "android:animWidth";
 
     /**
      * Initial height of the animation.
      * @hide
      */
-    public static final String KEY_ANIM_START_HEIGHT = "android:animStartHeight";
+    public static final String KEY_ANIM_HEIGHT = "android:animHeight";
 
     /**
      * Callback for when animation is started.
@@ -90,6 +98,20 @@
      */
     public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";
 
+    /**
+     * For Activity transitions, the calling Activity's TransitionListener used to
+     * notify the called Activity when the shared element and the exit transitions
+     * complete.
+     */
+    private static final String KEY_TRANSITION_COMPLETE_LISTENER
+            = "android:transitionCompleteListener";
+
+    private static final String KEY_TRANSITION_IS_RETURNING = "android:transitionIsReturning";
+    private static final String KEY_TRANSITION_SHARED_ELEMENTS = "android:sharedElementNames";
+    private static final String KEY_RESULT_DATA = "android:resultData";
+    private static final String KEY_RESULT_CODE = "android:resultCode";
+    private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex";
+
     /** @hide */
     public static final int ANIM_NONE = 0;
     /** @hide */
@@ -100,6 +122,16 @@
     public static final int ANIM_THUMBNAIL_SCALE_UP = 3;
     /** @hide */
     public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4;
+    /** @hide */
+    public static final int ANIM_SCENE_TRANSITION = 5;
+    /** @hide */
+    public static final int ANIM_DEFAULT = 6;
+    /** @hide */
+    public static final int ANIM_LAUNCH_TASK_BEHIND = 7;
+    /** @hide */
+    public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8;
+    /** @hide */
+    public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9;
 
     private String mPackageName;
     private int mAnimationType = ANIM_NONE;
@@ -108,9 +140,15 @@
     private Bitmap mThumbnail;
     private int mStartX;
     private int mStartY;
-    private int mStartWidth;
-    private int mStartHeight;
+    private int mWidth;
+    private int mHeight;
     private IRemoteCallback mAnimationStartedListener;
+    private ResultReceiver mTransitionReceiver;
+    private boolean mIsReturning;
+    private ArrayList<String> mSharedElementNames;
+    private Intent mResultData;
+    private int mResultCode;
+    private int mExitCoordinatorIndex;
 
     /**
      * Create an ActivityOptions specifying a custom animation to run when
@@ -156,11 +194,12 @@
         opts.mAnimationType = ANIM_CUSTOM;
         opts.mCustomEnterResId = enterResId;
         opts.mCustomExitResId = exitResId;
-        opts.setListener(handler, listener);
+        opts.setOnAnimationStartedListener(handler, listener);
         return opts;
     }
 
-    private void setListener(Handler handler, OnAnimationStartedListener listener) {
+    private void setOnAnimationStartedListener(Handler handler,
+            OnAnimationStartedListener listener) {
         if (listener != null) {
             final Handler h = handler;
             final OnAnimationStartedListener finalListener = listener;
@@ -199,13 +238,13 @@
      * defines the coordinate space for <var>startX</var> and <var>startY</var>.
      * @param startX The x starting location of the new activity, relative to <var>source</var>.
      * @param startY The y starting location of the activity, relative to <var>source</var>.
-     * @param startWidth The initial width of the new activity.
-     * @param startHeight The initial height of the new activity.
+     * @param width The initial width of the new activity.
+     * @param height The initial height of the new activity.
      * @return Returns a new ActivityOptions object that you can use to
      * supply these options as the options Bundle when starting an activity.
      */
     public static ActivityOptions makeScaleUpAnimation(View source,
-            int startX, int startY, int startWidth, int startHeight) {
+            int startX, int startY, int width, int height) {
         ActivityOptions opts = new ActivityOptions();
         opts.mPackageName = source.getContext().getPackageName();
         opts.mAnimationType = ANIM_SCALE_UP;
@@ -213,8 +252,8 @@
         source.getLocationOnScreen(pts);
         opts.mStartX = pts[0] + startX;
         opts.mStartY = pts[1] + startY;
-        opts.mStartWidth = startWidth;
-        opts.mStartHeight = startHeight;
+        opts.mWidth = width;
+        opts.mHeight = height;
         return opts;
     }
 
@@ -298,10 +337,194 @@
         source.getLocationOnScreen(pts);
         opts.mStartX = pts[0] + startX;
         opts.mStartY = pts[1] + startY;
-        opts.setListener(source.getHandler(), listener);
+        opts.setOnAnimationStartedListener(source.getHandler(), listener);
         return opts;
     }
 
+    /**
+     * Create an ActivityOptions specifying an animation where the new activity
+     * window and a thumbnail is aspect-scaled to a new location.
+     *
+     * @param source The View that this thumbnail is animating from.  This
+     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
+     * @param thumbnail The bitmap that will be shown as the initial thumbnail
+     * of the animation.
+     * @param startX The x starting location of the bitmap, relative to <var>source</var>.
+     * @param startY The y starting location of the bitmap, relative to <var>source</var>.
+     * @param listener Optional OnAnimationStartedListener to find out when the
+     * requested animation has started running.  If for some reason the animation
+     * is not executed, the callback will happen immediately.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     * @hide
+     */
+    public static ActivityOptions makeThumbnailAspectScaleUpAnimation(View source,
+            Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
+            OnAnimationStartedListener listener) {
+        return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
+                targetWidth, targetHeight, listener, true);
+    }
+
+    /**
+     * Create an ActivityOptions specifying an animation where the new activity
+     * window and a thumbnail is aspect-scaled to a new location.
+     *
+     * @param source The View that this thumbnail is animating to.  This
+     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
+     * @param thumbnail The bitmap that will be shown as the final thumbnail
+     * of the animation.
+     * @param startX The x end location of the bitmap, relative to <var>source</var>.
+     * @param startY The y end location of the bitmap, relative to <var>source</var>.
+     * @param listener Optional OnAnimationStartedListener to find out when the
+     * requested animation has started running.  If for some reason the animation
+     * is not executed, the callback will happen immediately.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     * @hide
+     */
+    public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
+            Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
+            OnAnimationStartedListener listener) {
+        return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
+                targetWidth, targetHeight, listener, false);
+    }
+
+    private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail,
+            int startX, int startY, int targetWidth, int targetHeight,
+            OnAnimationStartedListener listener, boolean scaleUp) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mPackageName = source.getContext().getPackageName();
+        opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP :
+                ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
+        opts.mThumbnail = thumbnail;
+        int[] pts = new int[2];
+        source.getLocationOnScreen(pts);
+        opts.mStartX = pts[0] + startX;
+        opts.mStartY = pts[1] + startY;
+        opts.mWidth = targetWidth;
+        opts.mHeight = targetHeight;
+        opts.setOnAnimationStartedListener(source.getHandler(), listener);
+        return opts;
+    }
+
+    /**
+     * Create an ActivityOptions to transition between Activities using cross-Activity scene
+     * animations. This method carries the position of one shared element to the started Activity.
+     * The position of <code>sharedElement</code> will be used as the epicenter for the
+     * exit Transition. The position of the shared element in the launched Activity will be the
+     * epicenter of its entering Transition.
+     *
+     * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
+     * enabled on the calling Activity to cause an exit transition. The same must be in
+     * the called Activity to get an entering transition.</p>
+     * @param activity The Activity whose window contains the shared elements.
+     * @param sharedElement The View to transition to the started Activity.
+     * @param sharedElementName The shared element name as used in the target Activity. This
+     *                          must not be null.
+     * @return Returns a new ActivityOptions object that you can use to
+     *         supply these options as the options Bundle when starting an activity.
+     * @see android.transition.Transition#setEpicenterCallback(
+     *          android.transition.Transition.EpicenterCallback)
+     */
+    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
+            View sharedElement, String sharedElementName) {
+        return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName));
+    }
+
+    /**
+     * Create an ActivityOptions to transition between Activities using cross-Activity scene
+     * animations. This method carries the position of multiple shared elements to the started
+     * Activity. The position of the first element in sharedElements
+     * will be used as the epicenter for the exit Transition. The position of the associated
+     * shared element in the launched Activity will be the epicenter of its entering Transition.
+     *
+     * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
+     * enabled on the calling Activity to cause an exit transition. The same must be in
+     * the called Activity to get an entering transition.</p>
+     * @param activity The Activity whose window contains the shared elements.
+     * @param sharedElements The names of the shared elements to transfer to the called
+     *                       Activity and their associated Views. The Views must each have
+     *                       a unique shared element name.
+     * @return Returns a new ActivityOptions object that you can use to
+     *         supply these options as the options Bundle when starting an activity.
+     * @see android.transition.Transition#setEpicenterCallback(
+     *          android.transition.Transition.EpicenterCallback)
+     */
+    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
+            Pair<View, String>... sharedElements) {
+        ActivityOptions opts = new ActivityOptions();
+        if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
+            opts.mAnimationType = ANIM_DEFAULT;
+            return opts;
+        }
+        opts.mAnimationType = ANIM_SCENE_TRANSITION;
+
+        ArrayList<String> names = new ArrayList<String>();
+        ArrayList<View> views = new ArrayList<View>();
+
+        if (sharedElements != null) {
+            for (int i = 0; i < sharedElements.length; i++) {
+                Pair<View, String> sharedElement = sharedElements[i];
+                String sharedElementName = sharedElement.second;
+                if (sharedElementName == null) {
+                    throw new IllegalArgumentException("Shared element name must not be null");
+                }
+                names.add(sharedElementName);
+                View view = sharedElement.first;
+                if (view == null) {
+                    throw new IllegalArgumentException("Shared element must not be null");
+                }
+                views.add(sharedElement.first);
+            }
+        }
+
+        ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, names, names,
+                views, false);
+        opts.mTransitionReceiver = exit;
+        opts.mSharedElementNames = names;
+        opts.mIsReturning = false;
+        opts.mExitCoordinatorIndex =
+                activity.mActivityTransitionState.addExitTransitionCoordinator(exit);
+        return opts;
+    }
+
+    /** @hide */
+    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
+            ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames,
+            int resultCode, Intent resultData) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mAnimationType = ANIM_SCENE_TRANSITION;
+        opts.mSharedElementNames = sharedElementNames;
+        opts.mTransitionReceiver = exitCoordinator;
+        opts.mIsReturning = true;
+        opts.mResultCode = resultCode;
+        opts.mResultData = resultData;
+        opts.mExitCoordinatorIndex =
+                activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator);
+        return opts;
+    }
+
+    /**
+     * If set along with Intent.FLAG_ACTIVITY_NEW_DOCUMENT then the task being launched will not be
+     * presented to the user but will instead be only available through the recents task list.
+     * In addition, the new task wil be affiliated with the launching activity's task.
+     * Affiliated tasks are grouped together in the recents task list.
+     *
+     * <p>This behavior is not supported for activities with {@link
+     * android.R.styleable#AndroidManifestActivity_launchMode launchMode} values of
+     * <code>singleInstance</code> or <code>singleTask</code>.
+     */
+    public static ActivityOptions makeTaskLaunchBehind() {
+        final ActivityOptions opts = new ActivityOptions();
+        opts.mAnimationType = ANIM_LAUNCH_TASK_BEHIND;
+        return opts;
+    }
+
+    /** @hide */
+    public boolean getLaunchTaskBehind() {
+        return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
+    }
+
     private ActivityOptions() {
     }
 
@@ -309,23 +532,42 @@
     public ActivityOptions(Bundle opts) {
         mPackageName = opts.getString(KEY_PACKAGE_NAME);
         mAnimationType = opts.getInt(KEY_ANIM_TYPE);
-        if (mAnimationType == ANIM_CUSTOM) {
-            mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
-            mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
-            mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
-                    opts.getIBinder(KEY_ANIM_START_LISTENER));
-        } else if (mAnimationType == ANIM_SCALE_UP) {
-            mStartX = opts.getInt(KEY_ANIM_START_X, 0);
-            mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
-            mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0);
-            mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0);
-        } else if (mAnimationType == ANIM_THUMBNAIL_SCALE_UP ||
-                mAnimationType == ANIM_THUMBNAIL_SCALE_DOWN) {
-            mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL);
-            mStartX = opts.getInt(KEY_ANIM_START_X, 0);
-            mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
-            mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
-                    opts.getIBinder(KEY_ANIM_START_LISTENER));
+        switch (mAnimationType) {
+            case ANIM_CUSTOM:
+                mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
+                mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
+                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_ANIM_START_LISTENER));
+                break;
+
+            case ANIM_SCALE_UP:
+                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
+                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
+                mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
+                mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
+                break;
+
+            case ANIM_THUMBNAIL_SCALE_UP:
+            case ANIM_THUMBNAIL_SCALE_DOWN:
+            case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
+            case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
+                mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL);
+                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
+                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
+                mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
+                mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
+                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_ANIM_START_LISTENER));
+                break;
+
+            case ANIM_SCENE_TRANSITION:
+                mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER);
+                mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false);
+                mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS);
+                mResultData = opts.getParcelable(KEY_RESULT_DATA);
+                mResultCode = opts.getInt(KEY_RESULT_CODE);
+                mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
+                break;
         }
     }
 
@@ -365,13 +607,13 @@
     }
 
     /** @hide */
-    public int getStartWidth() {
-        return mStartWidth;
+    public int getWidth() {
+        return mWidth;
     }
 
     /** @hide */
-    public int getStartHeight() {
-        return mStartHeight;
+    public int getHeight() {
+        return mHeight;
     }
 
     /** @hide */
@@ -380,6 +622,9 @@
     }
 
     /** @hide */
+    public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
+
+    /** @hide */
     public void abort() {
         if (mAnimationStartedListener != null) {
             try {
@@ -390,6 +635,25 @@
     }
 
     /** @hide */
+    public boolean isReturning() {
+        return mIsReturning;
+    }
+
+    /** @hide */
+    public ArrayList<String> getSharedElementNames() {
+        return mSharedElementNames;
+    }
+
+    /** @hide */
+    public ResultReceiver getResultReceiver() { return mTransitionReceiver; }
+
+    /** @hide */
+    public int getResultCode() { return mResultCode; }
+
+    /** @hide */
+    public Intent getResultData() { return mResultData; }
+
+    /** @hide */
     public static void abort(Bundle options) {
         if (options != null) {
             (new ActivityOptions(options)).abort();
@@ -405,29 +669,34 @@
         if (otherOptions.mPackageName != null) {
             mPackageName = otherOptions.mPackageName;
         }
+        mTransitionReceiver = null;
+        mSharedElementNames = null;
+        mIsReturning = false;
+        mResultData = null;
+        mResultCode = 0;
+        mExitCoordinatorIndex = 0;
+        mAnimationType = otherOptions.mAnimationType;
         switch (otherOptions.mAnimationType) {
             case ANIM_CUSTOM:
-                mAnimationType = otherOptions.mAnimationType;
                 mCustomEnterResId = otherOptions.mCustomEnterResId;
                 mCustomExitResId = otherOptions.mCustomExitResId;
                 mThumbnail = null;
-                if (otherOptions.mAnimationStartedListener != null) {
+                if (mAnimationStartedListener != null) {
                     try {
-                        otherOptions.mAnimationStartedListener.sendResult(null);
+                        mAnimationStartedListener.sendResult(null);
                     } catch (RemoteException e) {
                     }
                 }
                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
                 break;
             case ANIM_SCALE_UP:
-                mAnimationType = otherOptions.mAnimationType;
                 mStartX = otherOptions.mStartX;
                 mStartY = otherOptions.mStartY;
-                mStartWidth = otherOptions.mStartWidth;
-                mStartHeight = otherOptions.mStartHeight;
-                if (otherOptions.mAnimationStartedListener != null) {
+                mWidth = otherOptions.mWidth;
+                mHeight = otherOptions.mHeight;
+                if (mAnimationStartedListener != null) {
                     try {
-                        otherOptions.mAnimationStartedListener.sendResult(null);
+                        mAnimationStartedListener.sendResult(null);
                     } catch (RemoteException e) {
                     }
                 }
@@ -435,18 +704,31 @@
                 break;
             case ANIM_THUMBNAIL_SCALE_UP:
             case ANIM_THUMBNAIL_SCALE_DOWN:
-                mAnimationType = otherOptions.mAnimationType;
+            case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
+            case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
                 mThumbnail = otherOptions.mThumbnail;
                 mStartX = otherOptions.mStartX;
                 mStartY = otherOptions.mStartY;
-                if (otherOptions.mAnimationStartedListener != null) {
+                mWidth = otherOptions.mWidth;
+                mHeight = otherOptions.mHeight;
+                if (mAnimationStartedListener != null) {
                     try {
-                        otherOptions.mAnimationStartedListener.sendResult(null);
+                        mAnimationStartedListener.sendResult(null);
                     } catch (RemoteException e) {
                     }
                 }
                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
                 break;
+            case ANIM_SCENE_TRANSITION:
+                mTransitionReceiver = otherOptions.mTransitionReceiver;
+                mSharedElementNames = otherOptions.mSharedElementNames;
+                mIsReturning = otherOptions.mIsReturning;
+                mThumbnail = null;
+                mAnimationStartedListener = null;
+                mResultData = otherOptions.mResultData;
+                mResultCode = otherOptions.mResultCode;
+                mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex;
+                break;
         }
     }
 
@@ -459,35 +741,66 @@
      * methods that take an options Bundle.
      */
     public Bundle toBundle() {
+        if (mAnimationType == ANIM_DEFAULT) {
+            return null;
+        }
         Bundle b = new Bundle();
         if (mPackageName != null) {
             b.putString(KEY_PACKAGE_NAME, mPackageName);
         }
+        b.putInt(KEY_ANIM_TYPE, mAnimationType);
         switch (mAnimationType) {
             case ANIM_CUSTOM:
-                b.putInt(KEY_ANIM_TYPE, mAnimationType);
                 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
                 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
-                b.putIBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
+                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
                         != null ? mAnimationStartedListener.asBinder() : null);
                 break;
             case ANIM_SCALE_UP:
-                b.putInt(KEY_ANIM_TYPE, mAnimationType);
                 b.putInt(KEY_ANIM_START_X, mStartX);
                 b.putInt(KEY_ANIM_START_Y, mStartY);
-                b.putInt(KEY_ANIM_START_WIDTH, mStartWidth);
-                b.putInt(KEY_ANIM_START_HEIGHT, mStartHeight);
+                b.putInt(KEY_ANIM_WIDTH, mWidth);
+                b.putInt(KEY_ANIM_HEIGHT, mHeight);
                 break;
             case ANIM_THUMBNAIL_SCALE_UP:
             case ANIM_THUMBNAIL_SCALE_DOWN:
-                b.putInt(KEY_ANIM_TYPE, mAnimationType);
+            case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
+            case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
                 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
                 b.putInt(KEY_ANIM_START_X, mStartX);
                 b.putInt(KEY_ANIM_START_Y, mStartY);
-                b.putIBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
+                b.putInt(KEY_ANIM_WIDTH, mWidth);
+                b.putInt(KEY_ANIM_HEIGHT, mHeight);
+                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
                         != null ? mAnimationStartedListener.asBinder() : null);
                 break;
+            case ANIM_SCENE_TRANSITION:
+                if (mTransitionReceiver != null) {
+                    b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver);
+                }
+                b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning);
+                b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames);
+                b.putParcelable(KEY_RESULT_DATA, mResultData);
+                b.putInt(KEY_RESULT_CODE, mResultCode);
+                b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
+                break;
         }
+
         return b;
     }
+
+    /**
+     * Return the filtered options only meant to be seen by the target activity itself
+     * @hide
+     */
+    public ActivityOptions forTargetActivity() {
+        if (mAnimationType == ANIM_SCENE_TRANSITION) {
+            final ActivityOptions result = new ActivityOptions();
+            result.update(this);
+            return result;
+        }
+
+        return null;
+    }
+
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 156eadb..dd49009 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -46,7 +46,8 @@
 import android.hardware.display.DisplayManagerGlobal;
 import android.net.IConnectivityManager;
 import android.net.Proxy;
-import android.net.ProxyProperties;
+import android.net.ProxyInfo;
+import android.net.Uri;
 import android.opengl.GLUtils;
 import android.os.AsyncTask;
 import android.os.Binder;
@@ -60,6 +61,7 @@
 import android.os.Message;
 import android.os.MessageQueue;
 import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -75,6 +77,7 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.LogPrinter;
+import android.util.Pair;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.SuperNotCalledException;
@@ -90,6 +93,7 @@
 import android.renderscript.RenderScript;
 import android.security.AndroidKeyStoreProvider;
 
+import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.RuntimeInit;
 import com.android.internal.os.SamplingProfilerIntegration;
@@ -98,8 +102,6 @@
 import com.android.org.conscrypt.TrustedCertificateStore;
 import com.google.android.collect.Lists;
 
-import dalvik.system.VMRuntime;
-
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
@@ -120,8 +122,9 @@
 import libcore.io.DropBox;
 import libcore.io.EventLogger;
 import libcore.io.IoUtils;
-
+import libcore.net.event.NetworkEventDispatcher;
 import dalvik.system.CloseGuard;
+import dalvik.system.VMDebug;
 import dalvik.system.VMRuntime;
 
 final class RemoteServiceException extends AndroidRuntimeException {
@@ -188,13 +191,16 @@
     /** Reference to singleton {@link ActivityThread} */
     private static ActivityThread sCurrentActivityThread;
     Instrumentation mInstrumentation;
+    String mInstrumentationPackageName = null;
     String mInstrumentationAppDir = null;
-    String mInstrumentationAppLibraryDir = null;
-    String mInstrumentationAppPackage = null;
+    String[] mInstrumentationSplitAppDirs = null;
+    String mInstrumentationLibDir = null;
     String mInstrumentedAppDir = null;
-    String mInstrumentedAppLibraryDir = null;
+    String[] mInstrumentedSplitAppDirs = null;
+    String mInstrumentedLibDir = null;
     boolean mSystemThread = false;
     boolean mJitEnabled = false;
+    boolean mSomeActivitiesChanged = false;
 
     // These can be accessed by multiple threads; mPackages is the lock.
     // XXX For now we keep around information about all packages we have
@@ -262,7 +268,9 @@
         IBinder token;
         int ident;
         Intent intent;
+        IVoiceInteractor voiceInteractor;
         Bundle state;
+        PersistableBundle persistentState;
         Activity activity;
         Window window;
         Activity parent;
@@ -275,9 +283,7 @@
         Configuration createdConfig;
         ActivityClientRecord nextIdle;
 
-        String profileFile;
-        ParcelFileDescriptor profileFd;
-        boolean autoStopProfiler;
+        ProfilerInfo profilerInfo;
 
         ActivityInfo activityInfo;
         CompatibilityInfo compatInfo;
@@ -311,6 +317,10 @@
             return false;
         }
 
+        public boolean isPersistable() {
+            return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS;
+        }
+
         public String toString() {
             ComponentName componentName = intent != null ? intent.getComponent() : null;
             return "ActivityRecord{"
@@ -425,9 +435,7 @@
         CompatibilityInfo compatInfo;
 
         /** Initial values for {@link Profiler}. */
-        String initProfileFile;
-        ParcelFileDescriptor initProfileFd;
-        boolean initAutoStopProfiler;
+        ProfilerInfo initProfilerInfo;
 
         public String toString() {
             return "AppBindData{appInfo=" + appInfo + "}";
@@ -437,10 +445,12 @@
     static final class Profiler {
         String profileFile;
         ParcelFileDescriptor profileFd;
+        int samplingInterval;
         boolean autoStopProfiler;
         boolean profiling;
         boolean handlingProfiling;
-        public void setProfiler(String file, ParcelFileDescriptor fd) {
+        public void setProfiler(ProfilerInfo profilerInfo) {
+            ParcelFileDescriptor fd = profilerInfo.profileFd;
             if (profiling) {
                 if (fd != null) {
                     try {
@@ -458,16 +468,18 @@
                     // Ignore
                 }
             }
-            profileFile = file;
+            profileFile = profilerInfo.profileFile;
             profileFd = fd;
+            samplingInterval = profilerInfo.samplingInterval;
+            autoStopProfiler = profilerInfo.autoStopProfiler;
         }
         public void startProfiling() {
             if (profileFd == null || profiling) {
                 return;
             }
             try {
-                Debug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
-                        8 * 1024 * 1024, 0);
+                VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
+                        8 * 1024 * 1024, 0, samplingInterval != 0, samplingInterval);
                 profiling = true;
             } catch (RuntimeException e) {
                 Slog.w(TAG, "Profiling failed on path " + profileFile);
@@ -516,11 +528,6 @@
         String who;
     }
 
-    static final class ProfilerControlData {
-        String path;
-        ParcelFileDescriptor fd;
-    }
-
     static final class DumpHeapData {
         String path;
         ParcelFileDescriptor fd;
@@ -556,11 +563,11 @@
         }
 
         public final void schedulePauseActivity(IBinder token, boolean finished,
-                boolean userLeaving, int configChanges) {
+                boolean userLeaving, int configChanges, boolean dontReport) {
             sendMessage(
                     finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                     token,
-                    (userLeaving ? 1 : 0),
+                    (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
                     configChanges);
         }
 
@@ -582,7 +589,7 @@
         }
 
         public final void scheduleResumeActivity(IBinder token, int processState,
-                boolean isForward) {
+                boolean isForward, Bundle resumeArgs) {
             updateProcessState(processState, false);
             sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
         }
@@ -598,9 +605,10 @@
         // activity itself back to the activity manager. (matters more with ipc)
         public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
-                int procState, Bundle state, List<ResultInfo> pendingResults,
+                IVoiceInteractor voiceInteractor, int procState, Bundle state,
+                PersistableBundle persistentState, List<ResultInfo> pendingResults,
                 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-                String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
+                ProfilerInfo profilerInfo) {
 
             updateProcessState(procState, false);
 
@@ -609,9 +617,11 @@
             r.token = token;
             r.ident = ident;
             r.intent = intent;
+            r.voiceInteractor = voiceInteractor;
             r.activityInfo = info;
             r.compatInfo = compatInfo;
             r.state = state;
+            r.persistentState = persistentState;
 
             r.pendingResults = pendingResults;
             r.pendingIntents = pendingNewIntents;
@@ -619,9 +629,7 @@
             r.startsNotResumed = notResumed;
             r.isForward = isForward;
 
-            r.profileFile = profileName;
-            r.profileFd = profileFd;
-            r.autoStopProfiler = autoStopProfiler;
+            r.profilerInfo = profilerInfo;
 
             updatePendingConfiguration(curConfig);
 
@@ -728,11 +736,10 @@
             sendMessage(H.STOP_SERVICE, token);
         }
 
-        public final void bindApplication(String processName,
-                ApplicationInfo appInfo, List<ProviderInfo> providers,
-                ComponentName instrumentationName, String profileFile,
-                ParcelFileDescriptor profileFd, boolean autoStopProfiler,
-                Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
+        public final void bindApplication(String processName, ApplicationInfo appInfo,
+                List<ProviderInfo> providers, ComponentName instrumentationName,
+                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
+                IInstrumentationWatcher instrumentationWatcher,
                 IUiAutomationConnection instrumentationUiConnection, int debugMode,
                 boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
                 Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
@@ -796,9 +803,7 @@
             data.persistent = persistent;
             data.config = config;
             data.compatInfo = compatInfo;
-            data.initProfileFile = profileFile;
-            data.initProfileFd = profileFd;
-            data.initAutoStopProfiler = false;
+            data.initProfilerInfo = profilerInfo;
             sendMessage(H.BIND_APPLICATION, data);
         }
 
@@ -810,10 +815,6 @@
             sendMessage(H.SUICIDE, null);
         }
 
-        public void requestThumbnail(IBinder token) {
-            sendMessage(H.REQUEST_THUMBNAIL, token);
-        }
-
         public void scheduleConfigurationChanged(Configuration config) {
             updatePendingConfiguration(config);
             sendMessage(H.CONFIGURATION_CHANGED, config);
@@ -826,9 +827,12 @@
         public void clearDnsCache() {
             // a non-standard API to get this to libcore
             InetAddress.clearDnsCache();
+            // Allow libcore to perform the necessary actions as it sees fit upon a network
+            // configuration change.
+            NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
         }
 
-        public void setHttpProxy(String host, String port, String exclList, String pacFileUrl) {
+        public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) {
             Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
         }
 
@@ -868,12 +872,8 @@
             sendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
         }
 
-        public void profilerControl(boolean start, String path, ParcelFileDescriptor fd,
-                int profileType) {
-            ProfilerControlData pcd = new ProfilerControlData();
-            pcd.path = path;
-            pcd.fd = fd;
-            sendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType);
+        public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
+            sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType);
         }
 
         public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
@@ -1103,6 +1103,11 @@
             sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
         }
 
+        public void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options) {
+            sendMessage(H.ON_NEW_ACTIVITY_OPTIONS,
+                    new Pair<IBinder, ActivityOptions>(token, options));
+        }
+
         public void setProcessState(int state) {
             updateProcessState(state, true);
         }
@@ -1137,6 +1142,20 @@
         public final void updateTimePrefs(boolean is24Hour) {
             DateFormat.set24HourTimePref(is24Hour);
         }
+
+        @Override
+        public void scheduleCancelVisibleBehind(IBinder token) {
+            sendMessage(H.CANCEL_VISIBLE_BEHIND, token);
+        }
+
+        @Override
+        public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
+            sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0);
+        }
+
+        public void scheduleEnterAnimationComplete(IBinder token) {
+            sendMessage(H.ENTER_ANIMATION_COMPLETE, token);
+        }
     }
 
     private class H extends Handler {
@@ -1157,7 +1176,7 @@
         public static final int CREATE_SERVICE          = 114;
         public static final int SERVICE_ARGS            = 115;
         public static final int STOP_SERVICE            = 116;
-        public static final int REQUEST_THUMBNAIL       = 117;
+
         public static final int CONFIGURATION_CHANGED   = 118;
         public static final int CLEAN_UP_CONTEXT        = 119;
         public static final int GC_WHEN_IDLE            = 120;
@@ -1186,6 +1205,10 @@
         public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
         public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
         public static final int INSTALL_PROVIDER        = 145;
+        public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
+        public static final int CANCEL_VISIBLE_BEHIND = 147;
+        public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148;
+        public static final int ENTER_ANIMATION_COMPLETE = 149;
 
         String codeToString(int code) {
             if (DEBUG_MESSAGES) {
@@ -1207,7 +1230,6 @@
                     case CREATE_SERVICE: return "CREATE_SERVICE";
                     case SERVICE_ARGS: return "SERVICE_ARGS";
                     case STOP_SERVICE: return "STOP_SERVICE";
-                    case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL";
                     case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
                     case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
                     case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
@@ -1236,6 +1258,10 @@
                     case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
                     case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
                     case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
+                    case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
+                    case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND";
+                    case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED";
+                    case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
                 }
             }
             return Integer.toString(code);
@@ -1245,7 +1271,7 @@
             switch (msg.what) {
                 case LAUNCH_ACTIVITY: {
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
-                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
+                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
 
                     r.packageInfo = getPackageInfoNoCheck(
                             r.activityInfo.applicationInfo, r.compatInfo);
@@ -1260,13 +1286,15 @@
                 } break;
                 case PAUSE_ACTIVITY:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
-                    handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
+                    handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
+                            (msg.arg1&2) != 0);
                     maybeSnapshot();
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case PAUSE_ACTIVITY_FINISHING:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
-                    handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
+                    handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
+                            (msg.arg1&1) != 0);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case STOP_ACTIVITY_SHOW:
@@ -1291,8 +1319,7 @@
                     break;
                 case RESUME_ACTIVITY:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
-                    handleResumeActivity((IBinder)msg.obj, true,
-                            msg.arg1 != 0, true);
+                    handleResumeActivity((IBinder) msg.obj, true, msg.arg1 != 0, true);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case SEND_RESULT:
@@ -1355,11 +1382,6 @@
                     maybeSnapshot();
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
-                case REQUEST_THUMBNAIL:
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail");
-                    handleRequestThumbnail((IBinder)msg.obj);
-                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-                    break;
                 case CONFIGURATION_CHANGED:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
                     mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
@@ -1387,7 +1409,7 @@
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case PROFILER_CONTROL:
-                    handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
+                    handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
                     break;
                 case CREATE_BACKUP_AGENT:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
@@ -1456,6 +1478,19 @@
                 case INSTALL_PROVIDER:
                     handleInstallProvider((ProviderInfo) msg.obj);
                     break;
+                case ON_NEW_ACTIVITY_OPTIONS:
+                    Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
+                    onNewActivityOptions(pair.first, pair.second);
+                    break;
+                case CANCEL_VISIBLE_BEHIND:
+                    handleCancelVisibleBehind((IBinder) msg.obj);
+                    break;
+                case BACKGROUND_VISIBLE_BEHIND_CHANGED:
+                    handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
+                    break;
+                case ENTER_ANIMATION_COMPLETE:
+                    handleEnterAnimationComplete((IBinder) msg.obj);
+                    break;
             }
             if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
         }
@@ -1584,11 +1619,11 @@
     /**
      * Creates the top level resources for the given package.
      */
-    Resources getTopLevelResources(String resDir, String[] overlayDirs,
-            int displayId, Configuration overrideConfiguration,
+    Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
+            String[] libDirs, int displayId, Configuration overrideConfiguration,
             LoadedApk pkgInfo) {
-        return mResourcesManager.getTopLevelResources(resDir, overlayDirs, displayId,
-                overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);
+        return mResourcesManager.getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs,
+                displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);
     }
 
     final Handler getHandler() {
@@ -1649,6 +1684,7 @@
                 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
                         ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
                         : true);
+        boolean registerPackage = includeCode && (flags&Context.CONTEXT_REGISTER_PACKAGE) != 0;
         if ((flags&(Context.CONTEXT_INCLUDE_CODE
                 |Context.CONTEXT_IGNORE_SECURITY))
                 == Context.CONTEXT_INCLUDE_CODE) {
@@ -1663,12 +1699,13 @@
                 throw new SecurityException(msg);
             }
         }
-        return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode);
+        return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode,
+                registerPackage);
     }
 
     public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
             CompatibilityInfo compatInfo) {
-        return getPackageInfo(ai, compatInfo, null, false, true);
+        return getPackageInfo(ai, compatInfo, null, false, true, false);
     }
 
     public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
@@ -1684,7 +1721,8 @@
     }
 
     private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
-            ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
+            ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
+            boolean registerPackage) {
         synchronized (mResourcesManager) {
             WeakReference<LoadedApk> ref;
             if (includeCode) {
@@ -1703,7 +1741,7 @@
                 packageInfo =
                     new LoadedApk(this, aInfo, compatInfo, baseLoader,
                             securityViolation, includeCode &&
-                            (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
+                            (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
                 if (includeCode) {
                     mPackages.put(aInfo.packageName,
                             new WeakReference<LoadedApk>(packageInfo));
@@ -1760,9 +1798,13 @@
         }
     }
 
-    public void installSystemApplicationInfo(ApplicationInfo info) {
+    public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
         synchronized (this) {
-            getSystemContext().installSystemApplicationInfo(info);
+            getSystemContext().installSystemApplicationInfo(info, classLoader);
+
+            // The code package for "android" in the system server needs
+            // to be the system context's package.
+            mPackages.put("android", new WeakReference<LoadedApk>(getSystemContext().mPackageInfo));
 
             // give ourselves a default profiler
             mProfiler = new Profiler();
@@ -1901,7 +1943,7 @@
         if (dumpFullInfo) {
             printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
                     "Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
-            printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
+            printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "",
                     "Clean", "Clean", "Dirty", "Size", "Alloc", "Free");
             printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
                     "------", "------", "------", "------", "------", "------");
@@ -2158,6 +2200,7 @@
                     cl, component.getClassName(), r.intent);
             StrictMode.incrementExpectedActivityCount(activity.getClass());
             r.intent.setExtrasClassLoader(cl);
+            r.intent.prepareToEnterProcess();
             if (r.state != null) {
                 r.state.setClassLoader(cl);
             }
@@ -2188,7 +2231,8 @@
                         + r.activityInfo.name + " with config " + config);
                 activity.attach(appContext, this, getInstrumentation(), r.token,
                         r.ident, app, r.intent, r.activityInfo, title, r.parent,
-                        r.embeddedID, r.lastNonConfigurationInstances, config);
+                        r.embeddedID, r.lastNonConfigurationInstances, config,
+                        r.voiceInteractor);
 
                 if (customIntent != null) {
                     activity.mIntent = customIntent;
@@ -2201,7 +2245,11 @@
                 }
 
                 activity.mCalled = false;
-                mInstrumentation.callActivityOnCreate(activity, r.state);
+                if (r.isPersistable()) {
+                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
+                } else {
+                    mInstrumentation.callActivityOnCreate(activity, r.state);
+                }
                 if (!activity.mCalled) {
                     throw new SuperNotCalledException(
                         "Activity " + r.intent.getComponent().toShortString() +
@@ -2214,13 +2262,23 @@
                     r.stopped = false;
                 }
                 if (!r.activity.mFinished) {
-                    if (r.state != null) {
+                    if (r.isPersistable()) {
+                        if (r.state != null || r.persistentState != null) {
+                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
+                                    r.persistentState);
+                        }
+                    } else if (r.state != null) {
                         mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                     }
                 }
                 if (!r.activity.mFinished) {
                     activity.mCalled = false;
-                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
+                    if (r.isPersistable()) {
+                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
+                                r.persistentState);
+                    } else {
+                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
+                    }
                     if (!activity.mCalled) {
                         throw new SuperNotCalledException(
                             "Activity " + r.intent.getComponent().toShortString() +
@@ -2286,11 +2344,11 @@
         // If we are getting ready to gc after going to the background, well
         // we are back active so skip it.
         unscheduleGcIdler();
+        mSomeActivitiesChanged = true;
 
-        if (r.profileFd != null) {
-            mProfiler.setProfiler(r.profileFile, r.profileFd);
+        if (r.profilerInfo != null) {
+            mProfiler.setProfiler(r.profilerInfo);
             mProfiler.startProfiling();
-            mProfiler.autoStopProfiler = r.autoStopProfiler;
         }
 
         // Make sure we are running with the most recent config.
@@ -2298,6 +2356,7 @@
 
         if (localLOGV) Slog.v(
             TAG, "Handling launch of " + r);
+
         Activity a = performLaunchActivity(r, customIntent);
 
         if (a != null) {
@@ -2353,7 +2412,7 @@
             // manager to stop us.
             try {
                 ActivityManagerNative.getDefault()
-                    .finishActivity(r.token, Activity.RESULT_CANCELED, null);
+                    .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
             } catch (RemoteException ex) {
                 // Ignore
             }
@@ -2366,6 +2425,7 @@
         for (int i=0; i<N; i++) {
             Intent intent = intents.get(i);
             intent.setExtrasClassLoader(r.activity.getClassLoader());
+            intent.prepareToEnterProcess();
             r.activity.mFragments.noteStateNotSaved();
             mInstrumentation.callActivityOnNewIntent(r.activity, intent);
         }
@@ -2416,10 +2476,53 @@
         }
     }
 
+    public void onNewActivityOptions(IBinder token, ActivityOptions options) {
+        ActivityClientRecord r = mActivities.get(token);
+        if (r != null) {
+            r.activity.onNewActivityOptions(options);
+        }
+    }
+
+    public void handleCancelVisibleBehind(IBinder token) {
+        ActivityClientRecord r = mActivities.get(token);
+        if (r != null) {
+            mSomeActivitiesChanged = true;
+            final Activity activity = r.activity;
+            if (activity.mVisibleBehind) {
+                activity.mCalled = false;
+                activity.onVisibleBehindCanceled();
+                // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed.
+                if (!activity.mCalled) {
+                    throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
+                            " did not call through to super.onVisibleBehindCanceled()");
+                }
+                activity.mVisibleBehind = false;
+            }
+        }
+        try {
+            ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
+        } catch (RemoteException e) {
+        }
+    }
+
+    public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
+        ActivityClientRecord r = mActivities.get(token);
+        if (r != null) {
+            r.activity.onBackgroundVisibleBehindChanged(visible);
+        }
+    }
+
     public void handleInstallProvider(ProviderInfo info) {
         installContentProviders(mInitialApplication, Lists.newArrayList(info));
     }
 
+    private void handleEnterAnimationComplete(IBinder token) {
+        ActivityClientRecord r = mActivities.get(token);
+        if (r != null) {
+            r.activity.onEnterAnimationComplete();
+        }
+    }
+
     private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
 
     /**
@@ -2447,6 +2550,7 @@
         try {
             java.lang.ClassLoader cl = packageInfo.getClassLoader();
             data.intent.setExtrasClassLoader(cl);
+            data.intent.prepareToEnterProcess();
             data.setExtrasClassLoader(cl);
             receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
         } catch (Exception e) {
@@ -2521,15 +2625,7 @@
             return;
         }
 
-        if (mBackupAgents.get(packageName) != null) {
-            Slog.d(TAG, "BackupAgent " + "  for " + packageName
-                    + " already exists");
-            return;
-        }
-
-        BackupAgent agent = null;
         String classname = data.appInfo.backupAgentName;
-
         // full backup operation but no app-supplied agent?  use the default implementation
         if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
                 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
@@ -2538,29 +2634,38 @@
 
         try {
             IBinder binder = null;
-            try {
-                if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
-
-                java.lang.ClassLoader cl = packageInfo.getClassLoader();
-                agent = (BackupAgent) cl.loadClass(classname).newInstance();
-
-                // set up the agent's context
-                ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
-                context.setOuterContext(agent);
-                agent.attach(context);
-
-                agent.onCreate();
-                binder = agent.onBind();
-                mBackupAgents.put(packageName, agent);
-            } catch (Exception e) {
-                // If this is during restore, fail silently; otherwise go
-                // ahead and let the user see the crash.
-                Slog.e(TAG, "Agent threw during creation: " + e);
-                if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
-                        && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
-                    throw e;
+            BackupAgent agent = mBackupAgents.get(packageName);
+            if (agent != null) {
+                // reusing the existing instance
+                if (DEBUG_BACKUP) {
+                    Slog.v(TAG, "Reusing existing agent instance");
                 }
-                // falling through with 'binder' still null
+                binder = agent.onBind();
+            } else {
+                try {
+                    if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
+
+                    java.lang.ClassLoader cl = packageInfo.getClassLoader();
+                    agent = (BackupAgent) cl.loadClass(classname).newInstance();
+
+                    // set up the agent's context
+                    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
+                    context.setOuterContext(agent);
+                    agent.attach(context);
+
+                    agent.onCreate();
+                    binder = agent.onBind();
+                    mBackupAgents.put(packageName, agent);
+                } catch (Exception e) {
+                    // If this is during restore, fail silently; otherwise go
+                    // ahead and let the user see the crash.
+                    Slog.e(TAG, "Agent threw during creation: " + e);
+                    if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
+                            && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
+                        throw e;
+                    }
+                    // falling through with 'binder' still null
+                }
             }
 
             // tell the OS that we're live now
@@ -2647,6 +2752,7 @@
         if (s != null) {
             try {
                 data.intent.setExtrasClassLoader(s.getClassLoader());
+                data.intent.prepareToEnterProcess();
                 try {
                     if (!data.rebind) {
                         IBinder binder = s.onBind(data.intent);
@@ -2675,6 +2781,7 @@
         if (s != null) {
             try {
                 data.intent.setExtrasClassLoader(s.getClassLoader());
+                data.intent.prepareToEnterProcess();
                 boolean doRebind = s.onUnbind(data.intent);
                 try {
                     if (doRebind) {
@@ -2750,6 +2857,7 @@
             try {
                 if (data.args != null) {
                     data.args.setExtrasClassLoader(s.getClassLoader());
+                    data.args.prepareToEnterProcess();
                 }
                 int res;
                 if (!data.taskRemoved) {
@@ -2837,6 +2945,7 @@
                 r.paused = false;
                 r.stopped = false;
                 r.state = null;
+                r.persistentState = null;
             } catch (Exception e) {
                 if (!mInstrumentation.onException(r.activity, e)) {
                     throw new RuntimeException(
@@ -2862,12 +2971,14 @@
         r.mPendingRemoveWindowManager = null;
     }
 
-    final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
-            boolean reallyResume) {
+    final void handleResumeActivity(IBinder token,
+            boolean clearHide, boolean isForward, boolean reallyResume) {
         // If we are getting ready to gc after going to the background, well
         // we are back active so skip it.
         unscheduleGcIdler();
+        mSomeActivitiesChanged = true;
 
+        // TODO Push resumeArgs into the activity for consideration
         ActivityClientRecord r = performResumeActivity(token, clearHide);
 
         if (r != null) {
@@ -2973,7 +3084,7 @@
             // just end this activity.
             try {
                 ActivityManagerNative.getDefault()
-                    .finishActivity(token, Activity.RESULT_CANCELED, null);
+                    .finishActivity(token, Activity.RESULT_CANCELED, null, false);
             } catch (RemoteException ex) {
             }
         }
@@ -2992,11 +3103,10 @@
                 int h;
                 if (w < 0) {
                     Resources res = r.activity.getResources();
-                    mThumbnailHeight = h =
-                        res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
-
-                    mThumbnailWidth = w =
-                        res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
+                    int wId = com.android.internal.R.dimen.thumbnail_width;
+                    int hId = com.android.internal.R.dimen.thumbnail_height;
+                    mThumbnailWidth = w = res.getDimensionPixelSize(wId);
+                    mThumbnailHeight = h = res.getDimensionPixelSize(hId);
                 } else {
                     h = mThumbnailHeight;
                 }
@@ -3037,7 +3147,7 @@
     }
 
     private void handlePauseActivity(IBinder token, boolean finished,
-            boolean userLeaving, int configChanges) {
+            boolean userLeaving, int configChanges, boolean dontReport) {
         ActivityClientRecord r = mActivities.get(token);
         if (r != null) {
             //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
@@ -3054,10 +3164,13 @@
             }
 
             // Tell the activity manager we have paused.
-            try {
-                ActivityManagerNative.getDefault().activityPaused(token);
-            } catch (RemoteException ex) {
+            if (!dontReport) {
+                try {
+                    ActivityManagerNative.getDefault().activityPaused(token);
+                } catch (RemoteException ex) {
+                }
             }
+            mSomeActivitiesChanged = true;
         }
     }
 
@@ -3085,17 +3198,13 @@
                     + r.intent.getComponent().toShortString());
             Slog.e(TAG, e.getMessage(), e);
         }
-        Bundle state = null;
         if (finished) {
             r.activity.mFinished = true;
         }
         try {
             // Next have the activity save its current state and managed dialogs...
             if (!r.activity.mFinished && saveState) {
-                state = new Bundle();
-                state.setAllowFds(false);
-                mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
-                r.state = state;
+                callCallActivityOnSaveInstanceState(r);
             }
             // Now we are idle.
             r.activity.mCalled = false;
@@ -3131,7 +3240,7 @@
             listeners.get(i).onPaused(r.activity);
         }
 
-        return state;
+        return !r.activity.mFinished && saveState ? r.state : null;
     }
 
     final void performStopActivity(IBinder token, boolean saveState) {
@@ -3142,7 +3251,7 @@
     private static class StopInfo implements Runnable {
         ActivityClientRecord activity;
         Bundle state;
-        Bitmap thumbnail;
+        PersistableBundle persistentState;
         CharSequence description;
 
         @Override public void run() {
@@ -3150,7 +3259,7 @@
             try {
                 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
                 ActivityManagerNative.getDefault().activityStopped(
-                    activity.token, state, thumbnail, description);
+                    activity.token, state, persistentState, description);
             } catch (RemoteException ex) {
             }
         }
@@ -3189,7 +3298,6 @@
     private void performStopActivityInner(ActivityClientRecord r,
             StopInfo info, boolean keepShown, boolean saveState) {
         if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
-        Bundle state = null;
         if (r != null) {
             if (!keepShown && r.stopped) {
                 if (r.activity.mFinished) {
@@ -3209,7 +3317,6 @@
                     // First create a thumbnail for the activity...
                     // For now, don't create the thumbnail here; we are
                     // doing that by doing a screen snapshot.
-                    info.thumbnail = null; //createThumbnailBitmap(r);
                     info.description = r.activity.onCreateDescription();
                 } catch (Exception e) {
                     if (!mInstrumentation.onException(r.activity, e)) {
@@ -3224,12 +3331,7 @@
             // Next have the activity save its current state and managed dialogs...
             if (!r.activity.mFinished && saveState) {
                 if (r.state == null) {
-                    state = new Bundle();
-                    state.setAllowFds(false);
-                    mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
-                    r.state = state;
-                } else {
-                    state = r.state;
+                    callCallActivityOnSaveInstanceState(r);
                 }
             }
 
@@ -3305,7 +3407,9 @@
         // manager to proceed and allow us to go fully into the background.
         info.activity = r;
         info.state = r.state;
+        info.persistentState = r.persistentState;
         mH.post(info);
+        mSomeActivitiesChanged = true;
     }
 
     final void performRestartActivity(IBinder token) {
@@ -3339,6 +3443,7 @@
                 TAG, "Handle window " + r + " visibility: " + show);
             updateVisibility(r, show);
         }
+        mSomeActivitiesChanged = true;
     }
 
     private void handleSleeping(IBinder token, boolean sleeping) {
@@ -3387,6 +3492,20 @@
         synchronized (mResourcesManager) {
             mCoreSettings = coreSettings;
         }
+        onCoreSettingsChange();
+    }
+
+    private void onCoreSettingsChange() {
+        boolean debugViewAttributes =
+                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
+        if (debugViewAttributes != View.mDebugViewAttributes) {
+            View.mDebugViewAttributes = debugViewAttributes;
+
+            // request all activities to relaunch for the changes to take place
+            for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
+                requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, false);
+            }
+        }
     }
 
     private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
@@ -3409,6 +3528,7 @@
             try {
                 if (ri.mData != null) {
                     ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
+                    ri.mData.prepareToEnterProcess();
                 }
                 if (DEBUG_RESULTS) Slog.v(TAG,
                         "Delivering result to activity " + r + " : " + ri);
@@ -3621,6 +3741,7 @@
                 // If the system process has died, it's game over for everyone.
             }
         }
+        mSomeActivitiesChanged = true;
     }
 
     public final void requestRelaunchActivity(IBinder token,
@@ -3683,6 +3804,7 @@
         // If we are getting ready to gc after going to the background, well
         // we are back active so skip it.
         unscheduleGcIdler();
+        mSomeActivitiesChanged = true;
 
         Configuration changedConfig = null;
         int configChanges = 0;
@@ -3761,9 +3883,7 @@
             performPauseActivity(r.token, false, r.isPreHoneycomb());
         }
         if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
-            r.state = new Bundle();
-            r.state.setAllowFds(false);
-            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
+            callCallActivityOnSaveInstanceState(r);
         }
 
         handleDestroyActivity(r.token, false, configChanges, true);
@@ -3792,25 +3912,15 @@
         handleLaunchActivity(r, currentIntent);
     }
 
-    private void handleRequestThumbnail(IBinder token) {
-        ActivityClientRecord r = mActivities.get(token);
-        Bitmap thumbnail = createThumbnailBitmap(r);
-        CharSequence description = null;
-        try {
-            description = r.activity.onCreateDescription();
-        } catch (Exception e) {
-            if (!mInstrumentation.onException(r.activity, e)) {
-                throw new RuntimeException(
-                        "Unable to create description of activity "
-                        + r.intent.getComponent().toShortString()
-                        + ": " + e.toString(), e);
-            }
-        }
-        //System.out.println("Reporting top thumbnail " + thumbnail);
-        try {
-            ActivityManagerNative.getDefault().reportThumbnail(
-                token, thumbnail, description);
-        } catch (RemoteException ex) {
+    private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
+        r.state = new Bundle();
+        r.state.setAllowFds(false);
+        if (r.isPersistable()) {
+            r.persistentState = new PersistableBundle();
+            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
+                    r.persistentState);
+        } else {
+            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
         }
     }
 
@@ -3964,9 +4074,6 @@
 
         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
 
-        // Cleanup hardware accelerated stuff
-        WindowManagerGlobal.getInstance().trimLocalMemory();
-
         freeTextLayoutCachesIfNeeded(configDiff);
 
         if (callbacks != null) {
@@ -4000,24 +4107,25 @@
         performConfigurationChanged(r.activity, mCompatConfiguration);
 
         freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
+
+        mSomeActivitiesChanged = true;
     }
 
-    final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
+    final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
         if (start) {
             try {
                 switch (profileType) {
-                    default:                        
-                        mProfiler.setProfiler(pcd.path, pcd.fd);
-                        mProfiler.autoStopProfiler = false;
+                    default:
+                        mProfiler.setProfiler(profilerInfo);
                         mProfiler.startProfiling();
                         break;
                 }
             } catch (RuntimeException e) {
-                Slog.w(TAG, "Profiling failed on path " + pcd.path
+                Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
                         + " -- can the process access this path?");
             } finally {
                 try {
-                    pcd.fd.close();
+                    profilerInfo.profileFd.close();
                 } catch (IOException e) {
                     Slog.w(TAG, "Failure closing profile fd", e);
                 }
@@ -4101,9 +4209,6 @@
     final void handleTrimMemory(int level) {
         if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
 
-        final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance();
-        windowManager.startTrimMemory(level);
-
         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
 
         final int N = callbacks.size();
@@ -4111,7 +4216,7 @@
             callbacks.get(i).onTrimMemory(level);
         }
 
-        windowManager.endTrimMemory();
+        WindowManagerGlobal.getInstance().trimMemory(level);
     }
 
     private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
@@ -4152,9 +4257,12 @@
         mCompatConfiguration = new Configuration(data.config);
 
         mProfiler = new Profiler();
-        mProfiler.profileFile = data.initProfileFile;
-        mProfiler.profileFd = data.initProfileFd;
-        mProfiler.autoStopProfiler = data.initAutoStopProfiler;
+        if (data.initProfilerInfo != null) {
+            mProfiler.profileFile = data.initProfilerInfo.profileFile;
+            mProfiler.profileFd = data.initProfilerInfo.profileFd;
+            mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
+            mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
+        }
 
         // send up app name; do this *before* waiting for debugger
         Process.setArgV0(data.processName);
@@ -4169,7 +4277,7 @@
                 HardwareRenderer.disable(false);
             }
         }
-        
+
         if (mProfiler.profileFd != null) {
             mProfiler.startProfiling();
         }
@@ -4182,6 +4290,8 @@
             AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
         }
 
+        Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
+
         /*
          * Before spawning a new process, reset the time zone to be the system time zone.
          * This needs to be done because the system time zone could have changed after the
@@ -4234,6 +4344,9 @@
         final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
         DateFormat.set24HourTimePref(is24Hr);
 
+        View.mDebugViewAttributes =
+                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
+
         /**
          * For system applications on userdebug/eng builds, log stack
          * traces of disk and network access to dropbox for analysis.
@@ -4300,8 +4413,8 @@
             // crash if we can't get it.
             IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
             try {
-                ProxyProperties proxyProperties = service.getProxy();
-                Proxy.setHttpProxySystemProperty(proxyProperties);
+                ProxyInfo proxyInfo = service.getProxy();
+                Proxy.setHttpProxySystemProperty(proxyInfo);
             } catch (RemoteException e) {}
         }
 
@@ -4318,20 +4431,24 @@
                     + data.instrumentationName);
             }
 
+            mInstrumentationPackageName = ii.packageName;
             mInstrumentationAppDir = ii.sourceDir;
-            mInstrumentationAppLibraryDir = ii.nativeLibraryDir;
-            mInstrumentationAppPackage = ii.packageName;
+            mInstrumentationSplitAppDirs = ii.splitSourceDirs;
+            mInstrumentationLibDir = ii.nativeLibraryDir;
             mInstrumentedAppDir = data.info.getAppDir();
-            mInstrumentedAppLibraryDir = data.info.getLibDir();
+            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
+            mInstrumentedLibDir = data.info.getLibDir();
 
             ApplicationInfo instrApp = new ApplicationInfo();
             instrApp.packageName = ii.packageName;
             instrApp.sourceDir = ii.sourceDir;
             instrApp.publicSourceDir = ii.publicSourceDir;
+            instrApp.splitSourceDirs = ii.splitSourceDirs;
+            instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
             instrApp.dataDir = ii.dataDir;
             instrApp.nativeLibraryDir = ii.nativeLibraryDir;
             LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
-                    appContext.getClassLoader(), false, true);
+                    appContext.getClassLoader(), false, true, false);
             ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
 
             try {
@@ -4934,25 +5051,44 @@
             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                     UserHandle.myUserId());
             RuntimeInit.setApplicationObject(mAppThread.asBinder());
-            IActivityManager mgr = ActivityManagerNative.getDefault();
+            final IActivityManager mgr = ActivityManagerNative.getDefault();
             try {
                 mgr.attachApplication(mAppThread);
             } catch (RemoteException ex) {
                 // Ignore
             }
+            // Watch for getting close to heap limit.
+            BinderInternal.addGcWatcher(new Runnable() {
+                @Override public void run() {
+                    if (!mSomeActivitiesChanged) {
+                        return;
+                    }
+                    Runtime runtime = Runtime.getRuntime();
+                    long dalvikMax = runtime.maxMemory();
+                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
+                    if (dalvikUsed > ((3*dalvikMax)/4)) {
+                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+                                + " total=" + (runtime.totalMemory()/1024)
+                                + " used=" + (dalvikUsed/1024));
+                        mSomeActivitiesChanged = false;
+                        try {
+                            mgr.releaseSomeActivities(mAppThread);
+                        } catch (RemoteException e) {
+                        }
+                    }
+                }
+            });
         } else {
             // Don't set application object here -- if the system crashes,
             // we can't display an alert, we just want to die die die.
             android.ddm.DdmHandleAppName.setAppName("system_process",
-                                                    UserHandle.myUserId());
+                    UserHandle.myUserId());
             try {
                 mInstrumentation = new Instrumentation();
                 ContextImpl context = ContextImpl.createAppContext(
                         this, getSystemContext().mPackageInfo);
-                Application app = Instrumentation.newApplication(Application.class, context);
-                mAllApplications.add(app);
-                mInitialApplication = app;
-                app.onCreate();
+                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
+                mInitialApplication.onCreate();
             } catch (Exception e) {
                 throw new RuntimeException(
                         "Unable to instantiate Application():" + e.toString(), e);
@@ -4991,7 +5127,14 @@
     }
 
     public static ActivityThread systemMain() {
-        HardwareRenderer.disable(true);
+        // The system process on low-memory devices do not get to use hardware
+        // accelerated drawing, since this can add too much overhead to the
+        // process.
+        if (!ActivityManager.isHighEndGfx()) {
+            HardwareRenderer.disable(true);
+        } else {
+            HardwareRenderer.enableForegroundTrimming();
+        }
         ActivityThread thread = new ActivityThread();
         thread.attach(true);
         return thread;
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
new file mode 100644
index 0000000..540376e
--- /dev/null
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -0,0 +1,864 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcelable;
+import android.os.ResultReceiver;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.util.ArrayMap;
+import android.view.GhostView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroupOverlay;
+import android.view.ViewParent;
+import android.view.ViewTreeObserver;
+import android.view.Window;
+import android.widget.ImageView;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Base class for ExitTransitionCoordinator and EnterTransitionCoordinator, classes
+ * that manage activity transitions and the communications coordinating them between
+ * Activities. The ExitTransitionCoordinator is created in the
+ * ActivityOptions#makeSceneTransitionAnimation. The EnterTransitionCoordinator
+ * is created by ActivityOptions#createEnterActivityTransition by Activity when the window is
+ * attached.
+ *
+ * Typical startActivity goes like this:
+ * 1) ExitTransitionCoordinator created with ActivityOptions#makeSceneTransitionAnimation
+ * 2) Activity#startActivity called and that calls startExit() through
+ *    ActivityOptions#dispatchStartExit
+ *    - Exit transition starts by setting transitioning Views to INVISIBLE
+ * 3) Launched Activity starts, creating an EnterTransitionCoordinator.
+ *    - The Window is made translucent
+ *    - The Window background alpha is set to 0
+ *    - The transitioning views are made INVISIBLE
+ *    - MSG_SET_LISTENER is sent back to the ExitTransitionCoordinator.
+ * 4) The shared element transition completes.
+ *    - MSG_TAKE_SHARED_ELEMENTS is sent to the EnterTransitionCoordinator
+ * 5) The MSG_TAKE_SHARED_ELEMENTS is received by the EnterTransitionCoordinator.
+ *    - Shared elements are made VISIBLE
+ *    - Shared elements positions and size are set to match the end state of the calling
+ *      Activity.
+ *    - The shared element transition is started
+ *    - If the window allows overlapping transitions, the views transition is started by setting
+ *      the entering Views to VISIBLE and the background alpha is animated to opaque.
+ *    - MSG_HIDE_SHARED_ELEMENTS is sent to the ExitTransitionCoordinator
+ * 6) MSG_HIDE_SHARED_ELEMENTS is received by the ExitTransitionCoordinator
+ *    - The shared elements are made INVISIBLE
+ * 7) The exit transition completes in the calling Activity.
+ *    - MSG_EXIT_TRANSITION_COMPLETE is sent to the EnterTransitionCoordinator.
+ * 8) The MSG_EXIT_TRANSITION_COMPLETE is received by the EnterTransitionCoordinator.
+ *    - If the window doesn't allow overlapping enter transitions, the enter transition is started
+ *      by setting entering views to VISIBLE and the background is animated to opaque.
+ * 9) The background opacity animation completes.
+ *    - The window is made opaque
+ * 10) The calling Activity gets an onStop() call
+ *    - onActivityStopped() is called and all exited Views are made VISIBLE.
+ *
+ * Typical finishAfterTransition goes like this:
+ * 1) finishAfterTransition() creates an ExitTransitionCoordinator and calls startExit()
+ *    - The Window start transitioning to Translucent with a new ActivityOptions.
+ *    - If no background exists, a black background is substituted
+ *    - The shared elements in the scene are matched against those shared elements
+ *      that were sent by comparing the names.
+ *    - The exit transition is started by setting Views to INVISIBLE.
+ * 2) The ActivityOptions is received by the Activity and an EnterTransitionCoordinator is created.
+ *    - All transitioning views are made VISIBLE to reverse what was done when onActivityStopped()
+ *      was called
+ * 3) The Window is made translucent and a callback is received
+ *    - The background alpha is animated to 0
+ * 4) The background alpha animation completes
+ * 5) The shared element transition completes
+ *    - After both 4 & 5 complete, MSG_TAKE_SHARED_ELEMENTS is sent to the
+ *      EnterTransitionCoordinator
+ * 6) MSG_TAKE_SHARED_ELEMENTS is received by EnterTransitionCoordinator
+ *    - Shared elements are made VISIBLE
+ *    - Shared elements positions and size are set to match the end state of the calling
+ *      Activity.
+ *    - The shared element transition is started
+ *    - If the window allows overlapping transitions, the views transition is started by setting
+ *      the entering Views to VISIBLE.
+ *    - MSG_HIDE_SHARED_ELEMENTS is sent to the ExitTransitionCoordinator
+ * 7) MSG_HIDE_SHARED_ELEMENTS is received by the ExitTransitionCoordinator
+ *    - The shared elements are made INVISIBLE
+ * 8) The exit transition completes in the finishing Activity.
+ *    - MSG_EXIT_TRANSITION_COMPLETE is sent to the EnterTransitionCoordinator.
+ *    - finish() is called on the exiting Activity
+ * 9) The MSG_EXIT_TRANSITION_COMPLETE is received by the EnterTransitionCoordinator.
+ *    - If the window doesn't allow overlapping enter transitions, the enter transition is started
+ *      by setting entering views to VISIBLE.
+ */
+abstract class ActivityTransitionCoordinator extends ResultReceiver {
+    private static final String TAG = "ActivityTransitionCoordinator";
+
+    /**
+     * For Activity transitions, the called Activity's listener to receive calls
+     * when transitions complete.
+     */
+    static final String KEY_REMOTE_RECEIVER = "android:remoteReceiver";
+
+    protected static final String KEY_SCREEN_LEFT = "shared_element:screenLeft";
+    protected static final String KEY_SCREEN_TOP = "shared_element:screenTop";
+    protected static final String KEY_SCREEN_RIGHT = "shared_element:screenRight";
+    protected static final String KEY_SCREEN_BOTTOM= "shared_element:screenBottom";
+    protected static final String KEY_TRANSLATION_Z = "shared_element:translationZ";
+    protected static final String KEY_SNAPSHOT = "shared_element:bitmap";
+    protected static final String KEY_SCALE_TYPE = "shared_element:scaleType";
+    protected static final String KEY_IMAGE_MATRIX = "shared_element:imageMatrix";
+    protected static final String KEY_ELEVATION = "shared_element:elevation";
+
+    protected static final ImageView.ScaleType[] SCALE_TYPE_VALUES = ImageView.ScaleType.values();
+
+    /**
+     * Sent by the exiting coordinator (either EnterTransitionCoordinator
+     * or ExitTransitionCoordinator) after the shared elements have
+     * become stationary (shared element transition completes). This tells
+     * the remote coordinator to take control of the shared elements and
+     * that animations may begin. The remote Activity won't start entering
+     * until this message is received, but may wait for
+     * MSG_EXIT_TRANSITION_COMPLETE if allowOverlappingTransitions() is true.
+     */
+    public static final int MSG_SET_REMOTE_RECEIVER = 100;
+
+    /**
+     * Sent by the entering coordinator to tell the exiting coordinator
+     * to hide its shared elements after it has started its shared
+     * element transition. This is temporary until the
+     * interlock of shared elements is figured out.
+     */
+    public static final int MSG_HIDE_SHARED_ELEMENTS = 101;
+
+    /**
+     * Sent by the exiting coordinator (either EnterTransitionCoordinator
+     * or ExitTransitionCoordinator) after the shared elements have
+     * become stationary (shared element transition completes). This tells
+     * the remote coordinator to take control of the shared elements and
+     * that animations may begin. The remote Activity won't start entering
+     * until this message is received, but may wait for
+     * MSG_EXIT_TRANSITION_COMPLETE if allowOverlappingTransitions() is true.
+     */
+    public static final int MSG_TAKE_SHARED_ELEMENTS = 103;
+
+    /**
+     * Sent by the exiting coordinator (either
+     * EnterTransitionCoordinator or ExitTransitionCoordinator) after
+     * the exiting Views have finished leaving the scene. This will
+     * be ignored if allowOverlappingTransitions() is true on the
+     * remote coordinator. If it is false, it will trigger the enter
+     * transition to start.
+     */
+    public static final int MSG_EXIT_TRANSITION_COMPLETE = 104;
+
+    /**
+     * Sent by Activity#startActivity to begin the exit transition.
+     */
+    public static final int MSG_START_EXIT_TRANSITION = 105;
+
+    /**
+     * It took too long for a message from the entering Activity, so we canceled the transition.
+     */
+    public static final int MSG_CANCEL = 106;
+
+    /**
+     * When returning, this is the destination location for the shared element.
+     */
+    public static final int MSG_SHARED_ELEMENT_DESTINATION = 107;
+
+    /**
+     * Send the shared element positions.
+     */
+    public static final int MSG_SEND_SHARED_ELEMENT_DESTINATION = 108;
+
+    private Window mWindow;
+    final protected ArrayList<String> mAllSharedElementNames;
+    final protected ArrayList<View> mSharedElements = new ArrayList<View>();
+    final protected ArrayList<String> mSharedElementNames = new ArrayList<String>();
+    protected ArrayList<View> mTransitioningViews = new ArrayList<View>();
+    protected SharedElementCallback mListener;
+    protected ResultReceiver mResultReceiver;
+    final private FixedEpicenterCallback mEpicenterCallback = new FixedEpicenterCallback();
+    final protected boolean mIsReturning;
+    private Runnable mPendingTransition;
+    private boolean mIsStartingTransition;
+    private ArrayList<GhostViewListeners> mGhostViewListeners =
+            new ArrayList<GhostViewListeners>();
+    private ArrayMap<View, Float> mOriginalAlphas = new ArrayMap<View, Float>();
+
+    public ActivityTransitionCoordinator(Window window,
+            ArrayList<String> allSharedElementNames,
+            SharedElementCallback listener, boolean isReturning) {
+        super(new Handler());
+        mWindow = window;
+        mListener = listener;
+        mAllSharedElementNames = allSharedElementNames;
+        mIsReturning = isReturning;
+    }
+
+    protected void viewsReady(ArrayMap<String, View> sharedElements) {
+        sharedElements.retainAll(mAllSharedElementNames);
+        if (mListener != null) {
+            mListener.onMapSharedElements(mAllSharedElementNames, sharedElements);
+        }
+        mSharedElementNames.addAll(sharedElements.keySet());
+        mSharedElements.addAll(sharedElements.values());
+        if (getViewsTransition() != null && mTransitioningViews != null) {
+            ViewGroup decorView = getDecor();
+            if (decorView != null) {
+                decorView.captureTransitioningViews(mTransitioningViews);
+            }
+            mTransitioningViews.removeAll(mSharedElements);
+        }
+        setEpicenter();
+    }
+
+    protected void stripOffscreenViews() {
+        if (mTransitioningViews == null) {
+            return;
+        }
+        Rect r = new Rect();
+        for (int i = mTransitioningViews.size() - 1; i >= 0; i--) {
+            View view = mTransitioningViews.get(i);
+            if (!view.getGlobalVisibleRect(r)) {
+                mTransitioningViews.remove(i);
+                showView(view, true);
+            }
+        }
+    }
+
+    protected Window getWindow() {
+        return mWindow;
+    }
+
+    public ViewGroup getDecor() {
+        return (mWindow == null) ? null : (ViewGroup) mWindow.getDecorView();
+    }
+
+    /**
+     * Sets the transition epicenter to the position of the first shared element.
+     */
+    protected void setEpicenter() {
+        View epicenter = null;
+        if (!mAllSharedElementNames.isEmpty() && !mSharedElementNames.isEmpty()) {
+            int index = mSharedElementNames.indexOf(mAllSharedElementNames.get(0));
+            if (index >= 0) {
+                epicenter = mSharedElements.get(index);
+            }
+        }
+        setEpicenter(epicenter);
+    }
+
+    private void setEpicenter(View view) {
+        if (view == null) {
+            mEpicenterCallback.setEpicenter(null);
+        } else {
+            Rect epicenter = new Rect();
+            view.getBoundsOnScreen(epicenter);
+            mEpicenterCallback.setEpicenter(epicenter);
+        }
+    }
+
+    public ArrayList<String> getAcceptedNames() {
+        return mSharedElementNames;
+    }
+
+    public ArrayList<String> getMappedNames() {
+        ArrayList<String> names = new ArrayList<String>(mSharedElements.size());
+        for (int i = 0; i < mSharedElements.size(); i++) {
+            names.add(mSharedElements.get(i).getTransitionName());
+        }
+        return names;
+    }
+
+    public ArrayList<View> copyMappedViews() {
+        return new ArrayList<View>(mSharedElements);
+    }
+
+    public ArrayList<String> getAllSharedElementNames() { return mAllSharedElementNames; }
+
+    protected Transition setTargets(Transition transition, boolean add) {
+        if (transition == null || (add &&
+                (mTransitioningViews == null || mTransitioningViews.isEmpty()))) {
+            return null;
+        }
+        // Add the targets to a set containing transition so that transition
+        // remains unaffected. We don't want to modify the targets of transition itself.
+        TransitionSet set = new TransitionSet();
+        if (mTransitioningViews != null) {
+            for (int i = mTransitioningViews.size() - 1; i >= 0; i--) {
+                View view = mTransitioningViews.get(i);
+                if (add) {
+                    set.addTarget(view);
+                } else {
+                    set.excludeTarget(view, true);
+                }
+            }
+        }
+        // By adding the transition after addTarget, we prevent addTarget from
+        // affecting transition.
+        set.addTransition(transition);
+
+        if (!add && mTransitioningViews != null && !mTransitioningViews.isEmpty()) {
+            // Allow children of excluded transitioning views, but not the views themselves
+            set = new TransitionSet().addTransition(set);
+        }
+
+        return set;
+    }
+
+    protected Transition configureTransition(Transition transition,
+            boolean includeTransitioningViews) {
+        if (transition != null) {
+            transition = transition.clone();
+            transition.setEpicenterCallback(mEpicenterCallback);
+            transition = setTargets(transition, includeTransitioningViews);
+        }
+        return transition;
+    }
+
+    protected static Transition mergeTransitions(Transition transition1, Transition transition2) {
+        if (transition1 == null) {
+            return transition2;
+        } else if (transition2 == null) {
+            return transition1;
+        } else {
+            TransitionSet transitionSet = new TransitionSet();
+            transitionSet.addTransition(transition1);
+            transitionSet.addTransition(transition2);
+            return transitionSet;
+        }
+    }
+
+    protected ArrayMap<String, View> mapSharedElements(ArrayList<String> accepted,
+            ArrayList<View> localViews) {
+        ArrayMap<String, View> sharedElements = new ArrayMap<String, View>();
+        if (accepted != null) {
+            for (int i = 0; i < accepted.size(); i++) {
+                sharedElements.put(accepted.get(i), localViews.get(i));
+            }
+        } else {
+            ViewGroup decorView = getDecor();
+            if (decorView != null) {
+                decorView.findNamedViews(sharedElements);
+            }
+        }
+        return sharedElements;
+    }
+
+    protected void setResultReceiver(ResultReceiver resultReceiver) {
+        mResultReceiver = resultReceiver;
+    }
+
+    protected abstract Transition getViewsTransition();
+
+    private void setSharedElementState(View view, String name, Bundle transitionArgs,
+            Matrix tempMatrix, RectF tempRect, int[] decorLoc) {
+        Bundle sharedElementBundle = transitionArgs.getBundle(name);
+        if (sharedElementBundle == null) {
+            return;
+        }
+
+        if (view instanceof ImageView) {
+            int scaleTypeInt = sharedElementBundle.getInt(KEY_SCALE_TYPE, -1);
+            if (scaleTypeInt >= 0) {
+                ImageView imageView = (ImageView) view;
+                ImageView.ScaleType scaleType = SCALE_TYPE_VALUES[scaleTypeInt];
+                imageView.setScaleType(scaleType);
+                if (scaleType == ImageView.ScaleType.MATRIX) {
+                    float[] matrixValues = sharedElementBundle.getFloatArray(KEY_IMAGE_MATRIX);
+                    tempMatrix.setValues(matrixValues);
+                    imageView.setImageMatrix(tempMatrix);
+                }
+            }
+        }
+
+        float z = sharedElementBundle.getFloat(KEY_TRANSLATION_Z);
+        view.setTranslationZ(z);
+        float elevation = sharedElementBundle.getFloat(KEY_ELEVATION);
+        view.setElevation(elevation);
+
+        float left = sharedElementBundle.getFloat(KEY_SCREEN_LEFT);
+        float top = sharedElementBundle.getFloat(KEY_SCREEN_TOP);
+        float right = sharedElementBundle.getFloat(KEY_SCREEN_RIGHT);
+        float bottom = sharedElementBundle.getFloat(KEY_SCREEN_BOTTOM);
+
+        if (decorLoc != null) {
+            left -= decorLoc[0];
+            top -= decorLoc[1];
+            right -= decorLoc[0];
+            bottom -= decorLoc[1];
+        } else {
+            // Find the location in the view's parent
+            getSharedElementParentMatrix(view, tempMatrix);
+            tempRect.set(left, top, right, bottom);
+            tempMatrix.mapRect(tempRect);
+
+            float leftInParent = tempRect.left;
+            float topInParent = tempRect.top;
+
+            // Find the size of the view
+            view.getInverseMatrix().mapRect(tempRect);
+            float width = tempRect.width();
+            float height = tempRect.height();
+
+            // Now determine the offset due to view transform:
+            view.setLeft(0);
+            view.setTop(0);
+            view.setRight(Math.round(width));
+            view.setBottom(Math.round(height));
+            tempRect.set(0, 0, width, height);
+            view.getMatrix().mapRect(tempRect);
+
+            ViewGroup parent = (ViewGroup) view.getParent();
+            left = leftInParent - tempRect.left + parent.getScrollX();
+            top = topInParent - tempRect.top + parent.getScrollY();
+            right = left + width;
+            bottom = top + height;
+        }
+
+        int x = Math.round(left);
+        int y = Math.round(top);
+        int width = Math.round(right) - x;
+        int height = Math.round(bottom) - y;
+        int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
+        int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
+        view.measure(widthSpec, heightSpec);
+
+        view.layout(x, y, x + width, y + height);
+    }
+
+    protected void getSharedElementParentMatrix(View view, Matrix matrix) {
+        // Find the location in the view's parent
+        ViewGroup parent = (ViewGroup) view.getParent();
+        matrix.reset();
+        parent.transformMatrixToLocal(matrix);
+    }
+
+    protected ArrayList<SharedElementOriginalState> setSharedElementState(
+            Bundle sharedElementState, final ArrayList<View> snapshots) {
+        ArrayList<SharedElementOriginalState> originalImageState =
+                new ArrayList<SharedElementOriginalState>();
+        if (sharedElementState != null) {
+            Matrix tempMatrix = new Matrix();
+            RectF tempRect = new RectF();
+            final int numSharedElements = mSharedElements.size();
+            for (int i = 0; i < numSharedElements; i++) {
+                View sharedElement = mSharedElements.get(i);
+                String name = mSharedElementNames.get(i);
+                SharedElementOriginalState originalState = getOldSharedElementState(sharedElement,
+                        name, sharedElementState);
+                originalImageState.add(originalState);
+                setSharedElementState(sharedElement, name, sharedElementState,
+                        tempMatrix, tempRect, null);
+            }
+        }
+        if (mListener != null) {
+            mListener.onSharedElementStart(mSharedElementNames, mSharedElements, snapshots);
+        }
+        return originalImageState;
+    }
+
+    protected void notifySharedElementEnd(ArrayList<View> snapshots) {
+        if (mListener != null) {
+            mListener.onSharedElementEnd(mSharedElementNames, mSharedElements, snapshots);
+        }
+    }
+
+    protected void scheduleSetSharedElementEnd(final ArrayList<View> snapshots) {
+        final View decorView = getDecor();
+        if (decorView != null) {
+            decorView.getViewTreeObserver().addOnPreDrawListener(
+                    new ViewTreeObserver.OnPreDrawListener() {
+                        @Override
+                        public boolean onPreDraw() {
+                            decorView.getViewTreeObserver().removeOnPreDrawListener(this);
+                            notifySharedElementEnd(snapshots);
+                            return true;
+                        }
+                    }
+            );
+        }
+    }
+
+    private static SharedElementOriginalState getOldSharedElementState(View view, String name,
+            Bundle transitionArgs) {
+
+        SharedElementOriginalState state = new SharedElementOriginalState();
+        state.mLeft = view.getLeft();
+        state.mTop = view.getTop();
+        state.mRight = view.getRight();
+        state.mBottom = view.getBottom();
+        state.mMeasuredWidth = view.getMeasuredWidth();
+        state.mMeasuredHeight = view.getMeasuredHeight();
+        state.mTranslationZ = view.getTranslationZ();
+        state.mElevation = view.getElevation();
+        if (!(view instanceof ImageView)) {
+            return state;
+        }
+        Bundle bundle = transitionArgs.getBundle(name);
+        if (bundle == null) {
+            return state;
+        }
+        int scaleTypeInt = bundle.getInt(KEY_SCALE_TYPE, -1);
+        if (scaleTypeInt < 0) {
+            return state;
+        }
+
+        ImageView imageView = (ImageView) view;
+        state.mScaleType = imageView.getScaleType();
+        if (state.mScaleType == ImageView.ScaleType.MATRIX) {
+            state.mMatrix = new Matrix(imageView.getImageMatrix());
+        }
+        return state;
+    }
+
+    protected ArrayList<View> createSnapshots(Bundle state, Collection<String> names) {
+        int numSharedElements = names.size();
+        if (numSharedElements == 0) {
+            return null;
+        }
+        ArrayList<View> snapshots = new ArrayList<View>(numSharedElements);
+        Context context = getWindow().getContext();
+        int[] decorLoc = new int[2];
+        ViewGroup decorView = getDecor();
+        if (decorView != null) {
+            decorView.getLocationOnScreen(decorLoc);
+        }
+        for (String name: names) {
+            Bundle sharedElementBundle = state.getBundle(name);
+            if (sharedElementBundle != null) {
+                Parcelable parcelable = sharedElementBundle.getParcelable(KEY_SNAPSHOT);
+                View snapshot = null;
+                if (parcelable != null && mListener != null) {
+                    snapshot = mListener.onCreateSnapshotView(context, parcelable);
+                }
+                if (snapshot != null) {
+                    setSharedElementState(snapshot, name, state, null, null, decorLoc);
+                }
+                snapshots.add(snapshot);
+            }
+        }
+        return snapshots;
+    }
+
+    protected static void setOriginalSharedElementState(ArrayList<View> sharedElements,
+            ArrayList<SharedElementOriginalState> originalState) {
+        for (int i = 0; i < originalState.size(); i++) {
+            View view = sharedElements.get(i);
+            SharedElementOriginalState state = originalState.get(i);
+            if (view instanceof ImageView && state.mScaleType != null) {
+                ImageView imageView = (ImageView) view;
+                imageView.setScaleType(state.mScaleType);
+                if (state.mScaleType == ImageView.ScaleType.MATRIX) {
+                  imageView.setImageMatrix(state.mMatrix);
+                }
+            }
+            view.setElevation(state.mElevation);
+            view.setTranslationZ(state.mTranslationZ);
+            int widthSpec = View.MeasureSpec.makeMeasureSpec(state.mMeasuredWidth,
+                    View.MeasureSpec.EXACTLY);
+            int heightSpec = View.MeasureSpec.makeMeasureSpec(state.mMeasuredHeight,
+                    View.MeasureSpec.EXACTLY);
+            view.measure(widthSpec, heightSpec);
+            view.layout(state.mLeft, state.mTop, state.mRight, state.mBottom);
+        }
+    }
+
+    protected Bundle captureSharedElementState() {
+        Bundle bundle = new Bundle();
+        RectF tempBounds = new RectF();
+        Matrix tempMatrix = new Matrix();
+        for (int i = 0; i < mSharedElements.size(); i++) {
+            View sharedElement = mSharedElements.get(i);
+            String name = mSharedElementNames.get(i);
+            captureSharedElementState(sharedElement, name, bundle, tempMatrix, tempBounds);
+        }
+        return bundle;
+    }
+
+    protected void clearState() {
+        // Clear the state so that we can't hold any references accidentally and leak memory.
+        mWindow = null;
+        mSharedElements.clear();
+        mTransitioningViews = null;
+        mOriginalAlphas.clear();
+        mResultReceiver = null;
+        mPendingTransition = null;
+        mListener = null;
+    }
+
+    protected long getFadeDuration() {
+        return getWindow().getTransitionBackgroundFadeDuration();
+    }
+
+    protected void hideViews(ArrayList<View> views) {
+        int count = views.size();
+        for (int i = 0; i < count; i++) {
+            View view = views.get(i);
+            if (!mOriginalAlphas.containsKey(view)) {
+                mOriginalAlphas.put(view, view.getAlpha());
+            }
+            view.setAlpha(0f);
+        }
+    }
+
+    protected void showViews(ArrayList<View> views, boolean setTransitionAlpha) {
+        int count = views.size();
+        for (int i = 0; i < count; i++) {
+            showView(views.get(i), setTransitionAlpha);
+        }
+    }
+
+    private void showView(View view, boolean setTransitionAlpha) {
+        Float alpha = mOriginalAlphas.remove(view);
+        if (alpha != null) {
+            view.setAlpha(alpha);
+        }
+        if (setTransitionAlpha) {
+            view.setTransitionAlpha(1f);
+        }
+    }
+
+    /**
+     * Captures placement information for Views with a shared element name for
+     * Activity Transitions.
+     *
+     * @param view           The View to capture the placement information for.
+     * @param name           The shared element name in the target Activity to apply the placement
+     *                       information for.
+     * @param transitionArgs Bundle to store shared element placement information.
+     * @param tempBounds     A temporary Rect for capturing the current location of views.
+     */
+    protected void captureSharedElementState(View view, String name, Bundle transitionArgs,
+            Matrix tempMatrix, RectF tempBounds) {
+        Bundle sharedElementBundle = new Bundle();
+        tempMatrix.reset();
+        view.transformMatrixToGlobal(tempMatrix);
+        tempBounds.set(0, 0, view.getWidth(), view.getHeight());
+        tempMatrix.mapRect(tempBounds);
+
+        sharedElementBundle.putFloat(KEY_SCREEN_LEFT, tempBounds.left);
+        sharedElementBundle.putFloat(KEY_SCREEN_RIGHT, tempBounds.right);
+        sharedElementBundle.putFloat(KEY_SCREEN_TOP, tempBounds.top);
+        sharedElementBundle.putFloat(KEY_SCREEN_BOTTOM, tempBounds.bottom);
+        sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ());
+        sharedElementBundle.putFloat(KEY_ELEVATION, view.getElevation());
+
+        Parcelable bitmap = null;
+        if (mListener != null) {
+            bitmap = mListener.onCaptureSharedElementSnapshot(view, tempMatrix, tempBounds);
+        }
+
+        if (bitmap != null) {
+            sharedElementBundle.putParcelable(KEY_SNAPSHOT, bitmap);
+        }
+
+        if (view instanceof ImageView) {
+            ImageView imageView = (ImageView) view;
+            int scaleTypeInt = scaleTypeToInt(imageView.getScaleType());
+            sharedElementBundle.putInt(KEY_SCALE_TYPE, scaleTypeInt);
+            if (imageView.getScaleType() == ImageView.ScaleType.MATRIX) {
+                float[] matrix = new float[9];
+                imageView.getImageMatrix().getValues(matrix);
+                sharedElementBundle.putFloatArray(KEY_IMAGE_MATRIX, matrix);
+            }
+        }
+
+        transitionArgs.putBundle(name, sharedElementBundle);
+    }
+
+
+    protected void startTransition(Runnable runnable) {
+        if (mIsStartingTransition) {
+            mPendingTransition = runnable;
+        } else {
+            mIsStartingTransition = true;
+            runnable.run();
+        }
+    }
+
+    protected void transitionStarted() {
+        mIsStartingTransition = false;
+    }
+
+    protected void moveSharedElementsToOverlay() {
+        if (!mWindow.getSharedElementsUseOverlay()) {
+            return;
+        }
+        int numSharedElements = mSharedElements.size();
+        ViewGroup decor = getDecor();
+        if (decor != null) {
+            boolean moveWithParent = moveSharedElementWithParent();
+            for (int i = 0; i < numSharedElements; i++) {
+                View view = mSharedElements.get(i);
+                GhostView.addGhost(view, decor);
+                ViewGroup parent = (ViewGroup) view.getParent();
+                if (moveWithParent && !isInTransitionGroup(parent, decor)) {
+                    GhostViewListeners listener = new GhostViewListeners(view, parent, decor);
+                    parent.getViewTreeObserver().addOnPreDrawListener(listener);
+                    mGhostViewListeners.add(listener);
+                }
+            }
+        }
+    }
+
+    protected boolean moveSharedElementWithParent() {
+        return true;
+    }
+
+    public static boolean isInTransitionGroup(ViewParent viewParent, ViewGroup decor) {
+        if (viewParent == decor || !(viewParent instanceof ViewGroup)) {
+            return false;
+        }
+        ViewGroup parent = (ViewGroup) viewParent;
+        if (parent.isTransitionGroup()) {
+            return true;
+        } else {
+            return isInTransitionGroup(parent.getParent(), decor);
+        }
+    }
+
+    protected void moveSharedElementsFromOverlay() {
+        int numListeners = mGhostViewListeners.size();
+        for (int i = 0; i < numListeners; i++) {
+            GhostViewListeners listener = mGhostViewListeners.get(i);
+            ViewGroup parent = (ViewGroup) listener.getView().getParent();
+            parent.getViewTreeObserver().removeOnPreDrawListener(listener);
+        }
+        mGhostViewListeners.clear();
+
+        if (mWindow == null || !mWindow.getSharedElementsUseOverlay()) {
+            return;
+        }
+        ViewGroup decor = getDecor();
+        if (decor != null) {
+            ViewGroupOverlay overlay = decor.getOverlay();
+            int count = mSharedElements.size();
+            for (int i = 0; i < count; i++) {
+                View sharedElement = mSharedElements.get(i);
+                GhostView.removeGhost(sharedElement);
+            }
+        }
+    }
+
+    protected void setGhostVisibility(int visibility) {
+        int numSharedElements = mSharedElements.size();
+        for (int i = 0; i < numSharedElements; i++) {
+            GhostView ghostView = GhostView.getGhost(mSharedElements.get(i));
+            if (ghostView != null) {
+                ghostView.setVisibility(visibility);
+            }
+        }
+    }
+
+    protected void scheduleGhostVisibilityChange(final int visibility) {
+        final View decorView = getDecor();
+        if (decorView != null) {
+            decorView.getViewTreeObserver()
+                    .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+                        @Override
+                        public boolean onPreDraw() {
+                            decorView.getViewTreeObserver().removeOnPreDrawListener(this);
+                            setGhostVisibility(visibility);
+                            return true;
+                        }
+                    });
+        }
+    }
+
+    protected class ContinueTransitionListener extends Transition.TransitionListenerAdapter {
+        @Override
+        public void onTransitionStart(Transition transition) {
+            mIsStartingTransition = false;
+            Runnable pending = mPendingTransition;
+            mPendingTransition = null;
+            if (pending != null) {
+                startTransition(pending);
+            }
+        }
+    }
+
+    private static int scaleTypeToInt(ImageView.ScaleType scaleType) {
+        for (int i = 0; i < SCALE_TYPE_VALUES.length; i++) {
+            if (scaleType == SCALE_TYPE_VALUES[i]) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private static class FixedEpicenterCallback extends Transition.EpicenterCallback {
+        private Rect mEpicenter;
+
+        public void setEpicenter(Rect epicenter) { mEpicenter = epicenter; }
+
+        @Override
+        public Rect onGetEpicenter(Transition transition) {
+            return mEpicenter;
+        }
+    }
+
+    private static class GhostViewListeners implements ViewTreeObserver.OnPreDrawListener {
+        private View mView;
+        private ViewGroup mDecor;
+        private View mParent;
+        private Matrix mMatrix = new Matrix();
+
+        public GhostViewListeners(View view, View parent, ViewGroup decor) {
+            mView = view;
+            mParent = parent;
+            mDecor = decor;
+        }
+
+        public View getView() {
+            return mView;
+        }
+
+        @Override
+        public boolean onPreDraw() {
+            GhostView ghostView = GhostView.getGhost(mView);
+            if (ghostView == null) {
+                mParent.getViewTreeObserver().removeOnPreDrawListener(this);
+            } else {
+                GhostView.calculateMatrix(mView, mDecor, mMatrix);
+                ghostView.setMatrix(mMatrix);
+            }
+            return true;
+        }
+    }
+
+    static class SharedElementOriginalState {
+        int mLeft;
+        int mTop;
+        int mRight;
+        int mBottom;
+        int mMeasuredWidth;
+        int mMeasuredHeight;
+        ImageView.ScaleType mScaleType;
+        Matrix mMatrix;
+        float mTranslationZ;
+        float mElevation;
+    }
+}
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
new file mode 100644
index 0000000..555d20b
--- /dev/null
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app;
+
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.transition.Transition;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * This class contains all persistence-related functionality for Activity Transitions.
+ * Activities start exit and enter Activity Transitions through this class.
+ */
+class ActivityTransitionState {
+
+    private static final String ENTERING_SHARED_ELEMENTS = "android:enteringSharedElements";
+
+    private static final String EXITING_MAPPED_FROM = "android:exitingMappedFrom";
+
+    private static final String EXITING_MAPPED_TO = "android:exitingMappedTo";
+
+    /**
+     * The shared elements that the calling Activity has said that they transferred to this
+     * Activity.
+     */
+    private ArrayList<String> mEnteringNames;
+
+    /**
+     * The names of shared elements that were shared to the called Activity.
+     */
+    private ArrayList<String> mExitingFrom;
+
+    /**
+     * The names of local Views that were shared out, mapped to those elements in mExitingFrom.
+     */
+    private ArrayList<String> mExitingTo;
+
+    /**
+     * The local Views that were shared out, mapped to those elements in mExitingFrom.
+     */
+    private ArrayList<View> mExitingToView;
+
+    /**
+     * The ExitTransitionCoordinator used to start an Activity. Used to make the elements restore
+     * Visibility of exited Views.
+     */
+    private ExitTransitionCoordinator mCalledExitCoordinator;
+
+    /**
+     * The ExitTransitionCoordinator used to return to a previous Activity when called with
+     * {@link android.app.Activity#finishAfterTransition()}.
+     */
+    private ExitTransitionCoordinator mReturnExitCoordinator;
+
+    /**
+     * We must be able to cancel entering transitions to stop changing the Window to
+     * opaque when we exit before making the Window opaque.
+     */
+    private EnterTransitionCoordinator mEnterTransitionCoordinator;
+
+    /**
+     * ActivityOptions used on entering this Activity.
+     */
+    private ActivityOptions mEnterActivityOptions;
+
+    /**
+     * Has an exit transition been started? If so, we don't want to double-exit.
+     */
+    private boolean mHasExited;
+
+    /**
+     * Postpone painting and starting the enter transition until this is false.
+     */
+    private boolean mIsEnterPostponed;
+
+    /**
+     * Potential exit transition coordinators.
+     */
+    private SparseArray<WeakReference<ExitTransitionCoordinator>> mExitTransitionCoordinators;
+
+    /**
+     * Next key for mExitTransitionCoordinator.
+     */
+    private int mExitTransitionCoordinatorsKey = 1;
+
+    private boolean mIsEnterTriggered;
+
+    public ActivityTransitionState() {
+    }
+
+    public int addExitTransitionCoordinator(ExitTransitionCoordinator exitTransitionCoordinator) {
+        if (mExitTransitionCoordinators == null) {
+            mExitTransitionCoordinators =
+                    new SparseArray<WeakReference<ExitTransitionCoordinator>>();
+        }
+        WeakReference<ExitTransitionCoordinator> ref = new WeakReference(exitTransitionCoordinator);
+        // clean up old references:
+        for (int i = mExitTransitionCoordinators.size() - 1; i >= 0; i--) {
+            WeakReference<ExitTransitionCoordinator> oldRef
+                    = mExitTransitionCoordinators.valueAt(i);
+            if (oldRef.get() == null) {
+                mExitTransitionCoordinators.removeAt(i);
+            }
+        }
+        int newKey = mExitTransitionCoordinatorsKey++;
+        mExitTransitionCoordinators.append(newKey, ref);
+        return newKey;
+    }
+
+    public void readState(Bundle bundle) {
+        if (bundle != null) {
+            if (mEnterTransitionCoordinator == null || mEnterTransitionCoordinator.isReturning()) {
+                mEnteringNames = bundle.getStringArrayList(ENTERING_SHARED_ELEMENTS);
+            }
+            if (mEnterTransitionCoordinator == null) {
+                mExitingFrom = bundle.getStringArrayList(EXITING_MAPPED_FROM);
+                mExitingTo = bundle.getStringArrayList(EXITING_MAPPED_TO);
+            }
+        }
+    }
+
+    public void saveState(Bundle bundle) {
+        if (mEnteringNames != null) {
+            bundle.putStringArrayList(ENTERING_SHARED_ELEMENTS, mEnteringNames);
+        }
+        if (mExitingFrom != null) {
+            bundle.putStringArrayList(EXITING_MAPPED_FROM, mExitingFrom);
+            bundle.putStringArrayList(EXITING_MAPPED_TO, mExitingTo);
+        }
+    }
+
+    public void setEnterActivityOptions(Activity activity, ActivityOptions options) {
+        if (activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
+                && options != null && mEnterActivityOptions == null
+                && mEnterTransitionCoordinator == null
+                && options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
+            mEnterActivityOptions = options;
+            mIsEnterTriggered = false;
+            if (mEnterActivityOptions.isReturning()) {
+                restoreExitedViews();
+                int result = mEnterActivityOptions.getResultCode();
+                if (result != 0) {
+                    activity.onActivityReenter(result, mEnterActivityOptions.getResultData());
+                }
+            }
+        }
+    }
+
+    public void enterReady(Activity activity) {
+        if (mEnterActivityOptions == null || mIsEnterTriggered) {
+            return;
+        }
+        mIsEnterTriggered = true;
+        mHasExited = false;
+        ArrayList<String> sharedElementNames = mEnterActivityOptions.getSharedElementNames();
+        ResultReceiver resultReceiver = mEnterActivityOptions.getResultReceiver();
+        if (mEnterActivityOptions.isReturning()) {
+            restoreExitedViews();
+            activity.getWindow().getDecorView().setVisibility(View.VISIBLE);
+        }
+        mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
+                resultReceiver, sharedElementNames, mEnterActivityOptions.isReturning());
+
+        if (!mIsEnterPostponed) {
+            startEnter();
+        }
+    }
+
+    public void postponeEnterTransition() {
+        mIsEnterPostponed = true;
+    }
+
+    public void startPostponedEnterTransition() {
+        if (mIsEnterPostponed) {
+            mIsEnterPostponed = false;
+            if (mEnterTransitionCoordinator != null) {
+                startEnter();
+            }
+        }
+    }
+
+    private void startEnter() {
+        if (mEnterActivityOptions.isReturning()) {
+            if (mExitingToView != null) {
+                mEnterTransitionCoordinator.viewInstancesReady(mExitingFrom, mExitingTo,
+                        mExitingToView);
+            } else {
+                mEnterTransitionCoordinator.namedViewsReady(mExitingFrom, mExitingTo);
+            }
+        } else {
+            mEnterTransitionCoordinator.namedViewsReady(null, null);
+            mEnteringNames = mEnterTransitionCoordinator.getAllSharedElementNames();
+        }
+
+        mExitingFrom = null;
+        mExitingTo = null;
+        mExitingToView = null;
+        mEnterActivityOptions = null;
+    }
+
+    public void onStop() {
+        restoreExitedViews();
+        if (mEnterTransitionCoordinator != null) {
+            mEnterTransitionCoordinator.stop();
+            mEnterTransitionCoordinator = null;
+        }
+        if (mReturnExitCoordinator != null) {
+            mReturnExitCoordinator.stop();
+            mReturnExitCoordinator = null;
+        }
+    }
+
+    public void onResume() {
+        restoreExitedViews();
+    }
+
+    public void clear() {
+        mEnteringNames = null;
+        mExitingFrom = null;
+        mExitingTo = null;
+        mExitingToView = null;
+        mCalledExitCoordinator = null;
+        mEnterTransitionCoordinator = null;
+        mEnterActivityOptions = null;
+        mExitTransitionCoordinators = null;
+    }
+
+    private void restoreExitedViews() {
+        if (mCalledExitCoordinator != null) {
+            mCalledExitCoordinator.resetViews();
+            mCalledExitCoordinator = null;
+        }
+    }
+
+    public boolean startExitBackTransition(Activity activity) {
+        if (mEnteringNames == null) {
+            return false;
+        } else {
+            if (!mHasExited) {
+                mHasExited = true;
+                Transition enterViewsTransition = null;
+                ViewGroup decor = null;
+                if (mEnterTransitionCoordinator != null) {
+                    enterViewsTransition = mEnterTransitionCoordinator.getEnterViewsTransition();
+                    decor = mEnterTransitionCoordinator.getDecor();
+                    mEnterTransitionCoordinator.cancelEnter();
+                    mEnterTransitionCoordinator = null;
+                    if (enterViewsTransition != null && decor != null) {
+                        enterViewsTransition.pause(decor);
+                    }
+                }
+
+                mReturnExitCoordinator =
+                        new ExitTransitionCoordinator(activity, mEnteringNames, null, null, true);
+                if (enterViewsTransition != null && decor != null) {
+                    enterViewsTransition.resume(decor);
+                }
+                mReturnExitCoordinator.startExit(activity.mResultCode, activity.mResultData);
+            }
+            return true;
+        }
+    }
+
+    public void startExitOutTransition(Activity activity, Bundle options) {
+        if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
+            return;
+        }
+        ActivityOptions activityOptions = new ActivityOptions(options);
+        mEnterTransitionCoordinator = null;
+        if (activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
+            int key = activityOptions.getExitCoordinatorKey();
+            int index = mExitTransitionCoordinators.indexOfKey(key);
+            if (index >= 0) {
+                mCalledExitCoordinator = mExitTransitionCoordinators.valueAt(index).get();
+                mExitTransitionCoordinators.removeAt(index);
+                if (mCalledExitCoordinator != null) {
+                    mExitingFrom = mCalledExitCoordinator.getAcceptedNames();
+                    mExitingTo = mCalledExitCoordinator.getMappedNames();
+                    mExitingToView = mCalledExitCoordinator.copyMappedViews();
+                    mCalledExitCoordinator.startExit();
+                }
+            }
+        }
+    }
+}
diff --git a/core/java/android/app/AlarmManager.aidl b/core/java/android/app/AlarmManager.aidl
new file mode 100644
index 0000000..c9547b2
--- /dev/null
+++ b/core/java/android/app/AlarmManager.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+parcelable AlarmManager.AlarmClockInfo;
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 0cf7ad0..2c596e5 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -16,11 +16,17 @@
 
 package android.app;
 
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.os.WorkSource;
+import android.os.Parcelable.Creator;
 
 /**
  * This class provides access to the system alarm services.  These allow you
@@ -94,6 +100,17 @@
      */
     public static final int ELAPSED_REALTIME = 3;
 
+    /**
+     * Broadcast Action: Sent after the value returned by
+     * {@link #getNextAlarmClock()} has changed.
+     *
+     * <p class="note">This is a protected intent that can only be sent by the system.
+     * It is only sent to registered receivers.</p>
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_NEXT_ALARM_CLOCK_CHANGED =
+            "android.app.action.NEXT_ALARM_CLOCK_CHANGED";
+
     /** @hide */
     public static final long WINDOW_EXACT = 0;
     /** @hide */
@@ -188,7 +205,7 @@
      * @see #RTC_WAKEUP
      */
     public void set(int type, long triggerAtMillis, PendingIntent operation) {
-        setImpl(type, triggerAtMillis, legacyExactLength(), 0, operation, null);
+        setImpl(type, triggerAtMillis, legacyExactLength(), 0, operation, null, null);
     }
 
     /**
@@ -249,7 +266,7 @@
      */
     public void setRepeating(int type, long triggerAtMillis,
             long intervalMillis, PendingIntent operation) {
-        setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, operation, null);
+        setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, operation, null, null);
     }
 
     /**
@@ -299,7 +316,7 @@
      */
     public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
             PendingIntent operation) {
-        setImpl(type, windowStartMillis, windowLengthMillis, 0, operation, null);
+        setImpl(type, windowStartMillis, windowLengthMillis, 0, operation, null, null);
     }
 
     /**
@@ -337,17 +354,46 @@
      * @see #RTC_WAKEUP
      */
     public void setExact(int type, long triggerAtMillis, PendingIntent operation) {
-        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, operation, null);
+        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, operation, null, null);
+    }
+
+    /**
+     * Schedule an alarm that represents an alarm clock.
+     *
+     * The system may choose to display information about this alarm to the user.
+     *
+     * <p>
+     * This method is like {@link #setExact(int, long, PendingIntent)}, but implies
+     * {@link #RTC_WAKEUP}.
+     *
+     * @param info
+     * @param operation Action to perform when the alarm goes off;
+     *        typically comes from {@link PendingIntent#getBroadcast
+     *        IntentSender.getBroadcast()}.
+     *
+     * @see #set
+     * @see #setRepeating
+     * @see #setWindow
+     * @see #setExact
+     * @see #cancel
+     * @see #getNextAlarmClock()
+     * @see android.content.Context#sendBroadcast
+     * @see android.content.Context#registerReceiver
+     * @see android.content.Intent#filterEquals
+     */
+    public void setAlarmClock(AlarmClockInfo info, PendingIntent operation) {
+        setImpl(RTC_WAKEUP, info.getTriggerTime(), WINDOW_EXACT, 0, operation, null, info);
     }
 
     /** @hide */
+    @SystemApi
     public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
             PendingIntent operation, WorkSource workSource) {
-        setImpl(type, triggerAtMillis, windowMillis, intervalMillis, operation, workSource);
+        setImpl(type, triggerAtMillis, windowMillis, intervalMillis, operation, workSource, null);
     }
 
     private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
-            PendingIntent operation, WorkSource workSource) {
+            PendingIntent operation, WorkSource workSource, AlarmClockInfo alarmClock) {
         if (triggerAtMillis < 0) {
             /* NOTYET
             if (mAlwaysExact) {
@@ -361,7 +407,7 @@
 
         try {
             mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation,
-                    workSource);
+                    workSource, alarmClock);
         } catch (RemoteException ex) {
         }
     }
@@ -461,7 +507,7 @@
      */
     public void setInexactRepeating(int type, long triggerAtMillis,
             long intervalMillis, PendingIntent operation) {
-        setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, operation, null);
+        setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, operation, null, null);
     }
     
     /**
@@ -506,4 +552,117 @@
         } catch (RemoteException ex) {
         }
     }
+
+    /**
+     * Gets information about the next alarm clock currently scheduled.
+     *
+     * The alarm clocks considered are those scheduled by {@link #setAlarmClock}
+     * from any package of the calling user.
+     *
+     * @see #setAlarmClock
+     * @see AlarmClockInfo
+     */
+    public AlarmClockInfo getNextAlarmClock() {
+        return getNextAlarmClock(UserHandle.myUserId());
+    }
+
+    /**
+     * Gets information about the next alarm clock currently scheduled.
+     *
+     * The alarm clocks considered are those scheduled by {@link #setAlarmClock}
+     * from any package of the given {@parm userId}.
+     *
+     * @see #setAlarmClock
+     * @see AlarmClockInfo
+     *
+     * @hide
+     */
+    public AlarmClockInfo getNextAlarmClock(int userId) {
+        try {
+            return mService.getNextAlarmClock(userId);
+        } catch (RemoteException ex) {
+            return null;
+        }
+    }
+
+    /**
+     * An immutable description of an alarm clock.
+     *
+     * @see AlarmManager#setAlarmClock
+     * @see AlarmManager#getNextAlarmClock
+     */
+    public static final class AlarmClockInfo implements Parcelable {
+
+        private final long mTriggerTime;
+        private final PendingIntent mShowIntent;
+
+        /**
+         * Creates a new alarm clock description.
+         *
+         * @param triggerTime time at which the underlying alarm is triggered in wall time 
+         *                    milliseconds since the epoch
+         * @param showIntent an intent that can be used to show or edit details of
+         *                        the alarm clock.
+         */
+        public AlarmClockInfo(long triggerTime, PendingIntent showIntent) {
+            mTriggerTime = triggerTime;
+            mShowIntent = showIntent;
+        }
+
+        /**
+         * Use the {@link #CREATOR}
+         * @hide
+         */
+        AlarmClockInfo(Parcel in) {
+            mTriggerTime = in.readLong();
+            mShowIntent = in.readParcelable(PendingIntent.class.getClassLoader());
+        }
+
+        /**
+         * Returns the time at which the alarm is going to trigger.
+         *
+         * This value is UTC wall clock time in milliseconds, as returned by
+         * {@link System#currentTimeMillis()} for example.
+         */
+        public long getTriggerTime() {
+            return mTriggerTime;
+        }
+
+        /**
+         * Returns an intent intent that can be used to show or edit details of the alarm clock in
+         * the application that scheduled it.
+         *
+         * <p class="note">Beware that any application can retrieve and send this intent, 
+         * potentially with additional fields filled in. See
+         * {@link PendingIntent#send(android.content.Context, int, android.content.Intent)
+         * PendingIntent.send()} and {@link android.content.Intent#fillIn Intent.fillIn()}
+         * for details.
+         */
+        public PendingIntent getShowIntent() {
+            return mShowIntent;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeLong(mTriggerTime);
+            dest.writeParcelable(mShowIntent, flags);
+        }
+
+        public static final Creator<AlarmClockInfo> CREATOR = new Creator<AlarmClockInfo>() {
+            @Override
+            public AlarmClockInfo createFromParcel(Parcel in) {
+                return new AlarmClockInfo(in);
+            }
+
+            @Override
+            public AlarmClockInfo[] newArray(int size) {
+                return new AlarmClockInfo[size];
+            }
+        };
+    }
 }
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 10d5e25..4ce7835 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -27,7 +27,6 @@
 import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 import android.view.KeyEvent;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.AdapterView;
@@ -93,6 +92,18 @@
      * the device's default alert theme with a light background.
      */
     public static final int THEME_DEVICE_DEFAULT_LIGHT = 5;
+
+    /**
+     * No layout hint.
+     * @hide
+     */
+    public static final int LAYOUT_HINT_NONE = 0;
+
+    /**
+     * Hint layout to the side.
+     * @hide
+     */
+    public static final int LAYOUT_HINT_SIDE = 1;
     
     protected AlertDialog(Context context) {
         this(context, resolveDialogTheme(context, 0), true);
@@ -147,10 +158,10 @@
     }
 
     /**
-     * Gets one of the buttons used in the dialog.
-     * <p>
-     * If a button does not exist in the dialog, null will be returned.
-     * 
+     * Gets one of the buttons used in the dialog. Returns null if the specified
+     * button does not exist or the dialog has not yet been fully created (for
+     * example, via {@link #show()} or {@link #create()}).
+     *
      * @param whichButton The identifier of the button that should be returned.
      *            For example, this can be
      *            {@link DialogInterface#BUTTON_POSITIVE}.
@@ -159,7 +170,7 @@
     public Button getButton(int whichButton) {
         return mAlert.getButton(whichButton);
     }
-    
+
     /**
      * Gets the list view used in the dialog.
      *  
@@ -209,6 +220,14 @@
     }
 
     /**
+     * Internal api to allow hinting for the best button panel layout.
+     * @hide
+     */
+    void setButtonPanelLayoutHint(int layoutHint) {
+        mAlert.setButtonPanelLayoutHint(layoutHint);
+    }
+
+    /**
      * Set a message to be sent when a button is pressed.
      * 
      * @param whichButton Which button to set the message for, can be one of
@@ -853,6 +872,21 @@
         }
         
         /**
+         * Set a custom view resource to be the contents of the Dialog. The
+         * resource will be inflated, adding all top-level views to the screen.
+         *
+         * @param layoutResId Resource ID to be inflated.
+         * @return This Builder object to allow for chaining of calls to set
+         *         methods
+         */
+        public Builder setView(int layoutResId) {
+            P.mView = null;
+            P.mViewLayoutResId = layoutResId;
+            P.mViewSpacingSpecified = false;
+            return this;
+        }
+
+        /**
          * Set a custom view to be the contents of the Dialog. If the supplied view is an instance
          * of a {@link ListView} the light background will be used.
          *
@@ -862,6 +896,7 @@
          */
         public Builder setView(View view) {
             P.mView = view;
+            P.mViewLayoutResId = 0;
             P.mViewSpacingSpecified = false;
             return this;
         }
@@ -891,6 +926,7 @@
         public Builder setView(View view, int viewSpacingLeft, int viewSpacingTop,
                 int viewSpacingRight, int viewSpacingBottom) {
             P.mView = view;
+            P.mViewLayoutResId = 0;
             P.mViewSpacingSpecified = true;
             P.mViewSpacingLeft = viewSpacingLeft;
             P.mViewSpacingTop = viewSpacingTop;
diff --git a/core/java/android/app/AppImportanceMonitor.java b/core/java/android/app/AppImportanceMonitor.java
new file mode 100644
index 0000000..c760e1e
--- /dev/null
+++ b/core/java/android/app/AppImportanceMonitor.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+
+import java.util.List;
+
+/**
+ * Helper for monitoring the current importance of applications.
+ * @hide
+ */
+public class AppImportanceMonitor {
+    final Context mContext;
+
+    final SparseArray<AppEntry> mApps = new SparseArray<>();
+
+    static class AppEntry {
+        final int uid;
+        final SparseArray<Integer> procs = new SparseArray<>(1);
+        int importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
+
+        AppEntry(int _uid) {
+            uid = _uid;
+        }
+    }
+
+    final IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
+        @Override
+        public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
+        }
+
+        @Override
+        public void onProcessStateChanged(int pid, int uid, int procState) {
+            synchronized (mApps) {
+                updateImportanceLocked(pid, uid,
+                        ActivityManager.RunningAppProcessInfo.procStateToImportance(procState),
+                        true);
+            }
+        }
+
+        @Override
+        public void onProcessDied(int pid, int uid) {
+            synchronized (mApps) {
+                updateImportanceLocked(pid, uid,
+                        ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE, true);
+            }
+        }
+    };
+
+    static final int MSG_UPDATE = 1;
+
+    final Handler mHandler;
+
+    public AppImportanceMonitor(Context context, Looper looper) {
+        mContext = context;
+        mHandler = new Handler(looper) {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_UPDATE:
+                        onImportanceChanged(msg.arg1, msg.arg2&0xffff, msg.arg2>>16);
+                        break;
+                    default:
+                        super.handleMessage(msg);
+                }
+            }
+        };
+        ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
+        try {
+            ActivityManagerNative.getDefault().registerProcessObserver(mProcessObserver);
+        } catch (RemoteException e) {
+        }
+        List<ActivityManager.RunningAppProcessInfo> apps = am.getRunningAppProcesses();
+        if (apps != null) {
+            for (int i=0; i<apps.size(); i++) {
+                ActivityManager.RunningAppProcessInfo app = apps.get(i);
+                updateImportanceLocked(app.uid, app.pid, app.importance, false);
+            }
+        }
+    }
+
+    public int getImportance(int uid) {
+        AppEntry ent = mApps.get(uid);
+        if (ent == null) {
+            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
+        }
+        return ent.importance;
+    }
+
+    /**
+     * Report when an app's importance changed. Called on looper given to constructor.
+     */
+    public void onImportanceChanged(int uid, int importance, int oldImportance) {
+    }
+
+    void updateImportanceLocked(int uid, int pid, int importance, boolean repChange) {
+        AppEntry ent = mApps.get(uid);
+        if (ent == null) {
+            ent = new AppEntry(uid);
+            mApps.put(uid, ent);
+        }
+        if (importance >= ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE) {
+            ent.procs.remove(pid);
+        } else {
+            ent.procs.put(pid, importance);
+        }
+        updateImportanceLocked(ent, repChange);
+    }
+
+    void updateImportanceLocked(AppEntry ent, boolean repChange) {
+        int appImp = ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
+        for (int i=0; i<ent.procs.size(); i++) {
+            int procImp = ent.procs.valueAt(i);
+            if (procImp < appImp) {
+                appImp = procImp;
+            }
+        }
+        if (appImp != ent.importance) {
+            int impCode = appImp | (ent.importance<<16);
+            ent.importance = appImp;
+            if (appImp >= ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE) {
+                mApps.remove(ent.uid);
+            }
+            if (repChange) {
+                mHandler.obtainMessage(MSG_UPDATE, ent.uid, impCode).sendToTarget();
+            }
+        }
+    }
+}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 079cf7a..ba9c9d6 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -16,21 +16,25 @@
 
 package android.app;
 
+import android.annotation.SystemApi;
+import android.app.usage.UsageStatsManager;
+import android.content.Context;
+import android.media.AudioAttributes.AttributeUsage;
 import android.os.Binder;
 import android.os.IBinder;
-import android.util.ArrayMap;
-import com.android.internal.app.IAppOpsService;
-import com.android.internal.app.IAppOpsCallback;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import android.content.Context;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.UserManager;
+import android.util.ArrayMap;
+
+import com.android.internal.app.IAppOpsCallback;
+import com.android.internal.app.IAppOpsService;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 
 /**
  * API for interacting with "application operation" tracking.
@@ -90,6 +94,13 @@
      */
     public static final int MODE_ERRORED = 2;
 
+    /**
+     * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
+     * use its default security check.  This mode is not normally used; it should only be used
+     * with appop permissions, and callers must explicitly check for it and deal with it.
+     */
+    public static final int MODE_DEFAULT = 3;
+
     // when adding one of these:
     //  - increment _NUM_OP
     //  - add rows to sOpToSwitch, sOpToString, sOpNames, sOpPerms, sOpDefaultMode
@@ -184,8 +195,18 @@
     public static final int OP_MONITOR_LOCATION = 41;
     /** @hide Continually monitoring location data with a relatively high power request. */
     public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
+    /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
+    public static final int OP_GET_USAGE_STATS = 43;
     /** @hide */
-    public static final int _NUM_OP = 43;
+    public static final int OP_MUTE_MICROPHONE = 44;
+    /** @hide */
+    public static final int OP_TOAST_WINDOW = 45;
+    /** @hide Capture the device's display contents and/or audio */
+    public static final int OP_PROJECT_MEDIA = 46;
+    /** @hide Activate a VPN connection without user intervention. */
+    public static final int OP_ACTIVATE_VPN = 47;
+    /** @hide */
+    public static final int _NUM_OP = 48;
 
     /** Access to coarse location information. */
     public static final String OPSTR_COARSE_LOCATION =
@@ -199,6 +220,12 @@
     /** Continually monitoring location data with a relatively high power request. */
     public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
             = "android:monitor_location_high_power";
+    /** Access to {@link android.app.usage.UsageStatsManager}. */
+    public static final String OPSTR_GET_USAGE_STATS
+            = "android:get_usage_stats";
+    /** Activate a VPN connection without user intervention. @hide */
+    @SystemApi
+    public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
 
     /**
      * This maps each operation to the operation that serves as the
@@ -252,6 +279,11 @@
             OP_WAKE_LOCK,
             OP_COARSE_LOCATION,
             OP_COARSE_LOCATION,
+            OP_GET_USAGE_STATS,
+            OP_MUTE_MICROPHONE,
+            OP_TOAST_WINDOW,
+            OP_PROJECT_MEDIA,
+            OP_ACTIVATE_VPN,
     };
 
     /**
@@ -302,6 +334,11 @@
             null,
             OPSTR_MONITOR_LOCATION,
             OPSTR_MONITOR_HIGH_POWER_LOCATION,
+            OPSTR_GET_USAGE_STATS,
+            null,
+            null,
+            null,
+            OPSTR_ACTIVATE_VPN,
     };
 
     /**
@@ -352,6 +389,11 @@
             "WAKE_LOCK",
             "MONITOR_LOCATION",
             "MONITOR_HIGH_POWER_LOCATION",
+            "GET_USAGE_STATS",
+            "MUTE_MICROPHONE",
+            "TOAST_WINDOW",
+            "PROJECT_MEDIA",
+            "ACTIVATE_VPN",
     };
 
     /**
@@ -402,6 +444,122 @@
             android.Manifest.permission.WAKE_LOCK,
             null, // no permission for generic location monitoring
             null, // no permission for high power location monitoring
+            android.Manifest.permission.PACKAGE_USAGE_STATS,
+            null, // no permission for muting/unmuting microphone
+            null, // no permission for displaying toasts
+            null, // no permission for projecting media
+            null, // no permission for activating vpn
+    };
+
+    /**
+     * Specifies whether an Op should be restricted by a user restriction.
+     * Each Op should be filled with a restriction string from UserManager or
+     * null to specify it is not affected by any user restriction.
+     */
+    private static String[] sOpRestrictions = new String[] {
+            UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
+            UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
+            UserManager.DISALLOW_SHARE_LOCATION, //GPS
+            null, //VIBRATE
+            null, //READ_CONTACTS
+            null, //WRITE_CONTACTS
+            UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
+            UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
+            null, //READ_CALENDAR
+            null, //WRITE_CALENDAR
+            UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
+            null, //POST_NOTIFICATION
+            null, //NEIGHBORING_CELLS
+            null, //CALL_PHONE
+            UserManager.DISALLOW_SMS, //READ_SMS
+            UserManager.DISALLOW_SMS, //WRITE_SMS
+            UserManager.DISALLOW_SMS, //RECEIVE_SMS
+            null, //RECEIVE_EMERGENCY_SMS
+            UserManager.DISALLOW_SMS, //RECEIVE_MMS
+            null, //RECEIVE_WAP_PUSH
+            UserManager.DISALLOW_SMS, //SEND_SMS
+            UserManager.DISALLOW_SMS, //READ_ICC_SMS
+            UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
+            null, //WRITE_SETTINGS
+            UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
+            null, //ACCESS_NOTIFICATIONS
+            null, //CAMERA
+            null, //RECORD_AUDIO
+            null, //PLAY_AUDIO
+            null, //READ_CLIPBOARD
+            null, //WRITE_CLIPBOARD
+            null, //TAKE_MEDIA_BUTTONS
+            null, //TAKE_AUDIO_FOCUS
+            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
+            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
+            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
+            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
+            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
+            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
+            UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
+            null, //WAKE_LOCK
+            UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
+            UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
+            null, //GET_USAGE_STATS
+            UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
+            UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
+            null, //PROJECT_MEDIA
+            UserManager.DISALLOW_CONFIG_VPN, // ACTIVATE_VPN
+    };
+
+    /**
+     * This specifies whether each option should allow the system
+     * (and system ui) to bypass the user restriction when active.
+     */
+    private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
+            false, //COARSE_LOCATION
+            false, //FINE_LOCATION
+            false, //GPS
+            false, //VIBRATE
+            false, //READ_CONTACTS
+            false, //WRITE_CONTACTS
+            false, //READ_CALL_LOG
+            false, //WRITE_CALL_LOG
+            false, //READ_CALENDAR
+            false, //WRITE_CALENDAR
+            true, //WIFI_SCAN
+            false, //POST_NOTIFICATION
+            false, //NEIGHBORING_CELLS
+            false, //CALL_PHONE
+            false, //READ_SMS
+            false, //WRITE_SMS
+            false, //RECEIVE_SMS
+            false, //RECEIVE_EMERGECY_SMS
+            false, //RECEIVE_MMS
+            false, //RECEIVE_WAP_PUSH
+            false, //SEND_SMS
+            false, //READ_ICC_SMS
+            false, //WRITE_ICC_SMS
+            false, //WRITE_SETTINGS
+            true, //SYSTEM_ALERT_WINDOW
+            false, //ACCESS_NOTIFICATIONS
+            false, //CAMERA
+            false, //RECORD_AUDIO
+            false, //PLAY_AUDIO
+            false, //READ_CLIPBOARD
+            false, //WRITE_CLIPBOARD
+            false, //TAKE_MEDIA_BUTTONS
+            false, //TAKE_AUDIO_FOCUS
+            false, //AUDIO_MASTER_VOLUME
+            false, //AUDIO_VOICE_VOLUME
+            false, //AUDIO_RING_VOLUME
+            false, //AUDIO_MEDIA_VOLUME
+            false, //AUDIO_ALARM_VOLUME
+            false, //AUDIO_NOTIFICATION_VOLUME
+            false, //AUDIO_BLUETOOTH_VOLUME
+            false, //WAKE_LOCK
+            false, //MONITOR_LOCATION
+            false, //MONITOR_HIGH_POWER_LOCATION
+            false, //GET_USAGE_STATS
+            false, //MUTE_MICROPHONE
+            true, //TOAST_WINDOW
+            false, //PROJECT_MEDIA
+            false, //ACTIVATE_VPN
     };
 
     /**
@@ -451,6 +609,11 @@
             AppOpsManager.MODE_ALLOWED,
             AppOpsManager.MODE_ALLOWED,
             AppOpsManager.MODE_ALLOWED,
+            AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
+            AppOpsManager.MODE_ALLOWED,
+            AppOpsManager.MODE_ALLOWED,
+            AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
+            AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN
     };
 
     /**
@@ -504,6 +667,11 @@
             false,
             false,
             false,
+            false,
+            false,
+            false,
+            false,
+            false,
     };
 
     private static HashMap<String, Integer> sOpStrToOp = new HashMap<String, Integer>();
@@ -533,6 +701,14 @@
             throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
                     + " should be " + _NUM_OP);
         }
+        if (sOpRestrictions.length != _NUM_OP) {
+            throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
+                    + " should be " + _NUM_OP);
+        }
+        if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
+            throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
+                    + sOpRestrictions.length + " should be " + _NUM_OP);
+        }
         for (int i=0; i<_NUM_OP; i++) {
             if (sOpToString[i] != null) {
                 sOpStrToOp.put(sOpToString[i], i);
@@ -566,6 +742,23 @@
     }
 
     /**
+     * Retrieve the user restriction associated with an operation, or null if there is not one.
+     * @hide
+     */
+    public static String opToRestriction(int op) {
+        return sOpRestrictions[op];
+    }
+
+    /**
+     * Retrieve whether the op allows the system (and system ui) to
+     * bypass the user restriction.
+     * @hide
+     */
+    public static boolean opAllowSystemBypassRestriction(int op) {
+        return sOpAllowSystemRestrictionBypass[op];
+    }
+
+    /**
      * Retrieve the default mode for the operation.
      * @hide
      */
@@ -780,6 +973,26 @@
         }
     }
 
+    /**
+     * Set a non-persisted restriction on an audio operation at a stream-level.
+     * Restrictions are temporary additional constraints imposed on top of the persisted rules
+     * defined by {@link #setMode}.
+     *
+     * @param code The operation to restrict.
+     * @param usage The {@link android.media.AudioAttributes} usage value.
+     * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
+     * @param exceptionPackages Optional list of packages to exclude from the restriction.
+     * @hide
+     */
+    public void setRestriction(int code, @AttributeUsage int usage, int mode,
+            String[] exceptionPackages) {
+        try {
+            final int uid = Binder.getCallingUid();
+            mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
+        } catch (RemoteException e) {
+        }
+    }
+
     /** @hide */
     public void resetAllModes() {
         try {
@@ -849,7 +1062,10 @@
         return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
     }
 
-    private int strOpToOp(String op) {
+    /**
+     * {@hide}
+     */
+    public static int strOpToOp(String op) {
         Integer val = sOpStrToOp.get(op);
         if (val == null) {
             throw new IllegalArgumentException("Unknown operation string: " + op);
@@ -1009,6 +1225,35 @@
     }
 
     /**
+     * Like {@link #checkOp} but at a stream-level for audio operations.
+     * @hide
+     */
+    public int checkAudioOp(int op, int stream, int uid, String packageName) {
+        try {
+            final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
+            if (mode == MODE_ERRORED) {
+                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
+            }
+            return mode;
+        } catch (RemoteException e) {
+        }
+        return MODE_IGNORED;
+    }
+
+    /**
+     * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
+     * returns {@link #MODE_ERRORED}.
+     * @hide
+     */
+    public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
+        try {
+            return mService.checkAudioOperation(op, stream, uid, packageName);
+        } catch (RemoteException e) {
+        }
+        return MODE_IGNORED;
+    }
+
+    /**
      * Make note of an application performing an operation.  Note that you must pass
      * in both the uid and name of the application to be checked; this function will verify
      * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index c117486..841bd16 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -24,10 +24,10 @@
 import android.content.pm.ResolveInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.util.Printer;
+import android.util.Slog;
 import com.android.internal.util.FastPrintWriter;
 
 import java.io.PrintWriter;
@@ -379,6 +379,7 @@
          * Save a CrashInfo instance to a parcel.
          */
         public void writeToParcel(Parcel dest, int flags) {
+            int start = dest.dataPosition();
             dest.writeString(exceptionClassName);
             dest.writeString(exceptionMessage);
             dest.writeString(throwFileName);
@@ -386,6 +387,16 @@
             dest.writeString(throwMethodName);
             dest.writeInt(throwLineNumber);
             dest.writeString(stackTrace);
+            int total = dest.dataPosition()-start;
+            if (total > 10*1024) {
+                Slog.d("Error", "ERR: exClass=" + exceptionClassName);
+                Slog.d("Error", "ERR: exMsg=" + exceptionMessage);
+                Slog.d("Error", "ERR: file=" + throwFileName);
+                Slog.d("Error", "ERR: class=" + throwClassName);
+                Slog.d("Error", "ERR: method=" + throwMethodName + " line=" + throwLineNumber);
+                Slog.d("Error", "ERR: stack=" + stackTrace);
+                Slog.d("Error", "ERR: TOTAL BYTES WRITTEN: " + (dest.dataPosition()-start));
+            }
         }
 
         /**
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 02192eb..68606836 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -33,7 +33,11 @@
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.IPackageStatsObserver;
 import android.content.pm.InstrumentationInfo;
+import android.content.pm.KeySet;
+import android.content.pm.ManifestDigest;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionGroupInfo;
@@ -41,24 +45,33 @@
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.ManifestDigest;
+import android.content.pm.UserInfo;
 import android.content.pm.VerificationParams;
 import android.content.pm.VerifierDeviceIdentity;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.Display;
 
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+import com.android.internal.util.UserIcons;
+
+import dalvik.system.VMRuntime;
+
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 
 /*package*/
@@ -67,6 +80,22 @@
     private final static boolean DEBUG = false;
     private final static boolean DEBUG_ICONS = false;
 
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private UserManager mUserManager;
+    @GuardedBy("mLock")
+    private PackageInstaller mInstaller;
+
+    UserManager getUserManager() {
+        synchronized (mLock) {
+            if (mUserManager == null) {
+                mUserManager = UserManager.get(mContext);
+            }
+            return mUserManager;
+        }
+    }
+
     @Override
     public PackageInfo getPackageInfo(String packageName, int flags)
             throws NameNotFoundException {
@@ -128,7 +157,6 @@
         return intent;
     }
 
-    /** @hide */
     @Override
     public Intent getLeanbackLaunchIntentForPackage(String packageName) {
         // Try to find a main leanback_launcher activity.
@@ -237,6 +265,10 @@
         try {
             ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, mContext.getUserId());
             if (ai != null) {
+                // This is a temporary hack. Callers must use
+                // createPackageContext(packageName).getApplicationInfo() to
+                // get the right paths.
+                maybeAdjustApplicationInfo(ai);
                 return ai;
             }
         } catch (RemoteException e) {
@@ -246,6 +278,24 @@
         throw new NameNotFoundException(packageName);
     }
 
+    private static void maybeAdjustApplicationInfo(ApplicationInfo info) {
+        // If we're dealing with a multi-arch application that has both
+        // 32 and 64 bit shared libraries, we might need to choose the secondary
+        // depending on what the current runtime's instruction set is.
+        if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
+            final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
+            final String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
+
+            // If the runtimeIsa is the same as the primary isa, then we do nothing.
+            // Everything will be set up correctly because info.nativeLibraryDir will
+            // correspond to the right ISA.
+            if (runtimeIsa.equals(secondaryIsa)) {
+                info.nativeLibraryDir = info.secondaryNativeLibraryDir;
+            }
+        }
+    }
+
+
     @Override
     public ActivityInfo getActivityInfo(ComponentName className, int flags)
             throws NameNotFoundException {
@@ -620,10 +670,15 @@
     }
 
     @Override
-    public ProviderInfo resolveContentProvider(String name,
-                                               int flags) {
+    public ProviderInfo resolveContentProvider(String name, int flags) {
+        return resolveContentProviderAsUser(name, flags, mContext.getUserId());
+    }
+
+    /** @hide **/
+    @Override
+    public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
         try {
-            return mPM.resolveContentProvider(name, flags, mContext.getUserId());
+            return mPM.resolveContentProvider(name, flags, userId);
         } catch (RemoteException e) {
             throw new RuntimeException("Package manager has died", e);
         }
@@ -698,10 +753,10 @@
             putCachedIcon(name, dr);
             return dr;
         } catch (NameNotFoundException e) {
-            Log.w("PackageManager", "Failure retrieving resources for"
+            Log.w("PackageManager", "Failure retrieving resources for "
                   + appInfo.packageName);
         } catch (Resources.NotFoundException e) {
-            Log.w("PackageManager", "Failure retrieving resources for"
+            Log.w("PackageManager", "Failure retrieving resources for "
                   + appInfo.packageName + ": " + e.getMessage());
         } catch (RuntimeException e) {
             // If an exception was thrown, fall through to return
@@ -813,6 +868,49 @@
         return getApplicationLogo(getApplicationInfo(packageName, 0));
     }
 
+    @Override
+    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
+        final int badgeResId = getBadgeResIdForUser(user.getIdentifier());
+        if (badgeResId == 0) {
+            return icon;
+        }
+        Drawable badgeIcon = getDrawable("system", badgeResId, null);
+        return getBadgedDrawable(icon, badgeIcon, null, true);
+    }
+
+    @Override
+    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
+            Rect badgeLocation, int badgeDensity) {
+        Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity);
+        if (badgeDrawable == null) {
+            return drawable;
+        }
+        return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
+    }
+
+    @Override
+    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
+        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
+        if (userInfo != null && userInfo.isManagedProfile()) {
+            if (density <= 0) {
+                density = mContext.getResources().getDisplayMetrics().densityDpi;
+            }
+            return Resources.getSystem().getDrawableForDensity(
+                    com.android.internal.R.drawable.ic_corp_badge, density);
+        }
+        return null;
+    }
+
+    @Override
+    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
+        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
+        if (userInfo != null && userInfo.isManagedProfile()) {
+            return Resources.getSystem().getString(
+                    com.android.internal.R.string.managed_profile_label_badge, label);
+        }
+        return label;
+    }
+
     @Override public Resources getResourcesForActivity(
         ComponentName activityName) throws NameNotFoundException {
         return getResourcesForApplication(
@@ -824,9 +922,11 @@
         if (app.packageName.equals("system")) {
             return mContext.mMainThread.getSystemContext().getResources();
         }
+        final boolean sameUid = (app.uid == Process.myUid());
         Resources r = mContext.mMainThread.getTopLevelResources(
-                app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
-                app.resourceDirs, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
+                sameUid ? app.sourceDir : app.publicSourceDir,
+                sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
+                app.resourceDirs, null, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
         if (r != null) {
             return r;
         }
@@ -1047,7 +1147,7 @@
             putCachedString(name, text);
             return text;
         } catch (NameNotFoundException e) {
-            Log.w("PackageManager", "Failure retrieving resources for"
+            Log.w("PackageManager", "Failure retrieving resources for "
                   + appInfo.packageName);
         } catch (RuntimeException e) {
             // If an exception was thrown, fall through to return
@@ -1093,34 +1193,72 @@
     @Override
     public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
                                String installerPackageName) {
-        try {
-            mPM.installPackage(packageURI, observer, flags, installerPackageName);
-        } catch (RemoteException e) {
-            // Should never happen!
-        }
+        final VerificationParams verificationParams = new VerificationParams(null, null,
+                null, VerificationParams.NO_UID, null);
+        installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
+                installerPackageName, verificationParams, null);
     }
 
     @Override
     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
             int flags, String installerPackageName, Uri verificationURI,
             ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
-        try {
-            mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
-                    verificationURI, manifestDigest, encryptionParams);
-        } catch (RemoteException e) {
-            // Should never happen!
-        }
+        final VerificationParams verificationParams = new VerificationParams(verificationURI, null,
+                null, VerificationParams.NO_UID, manifestDigest);
+        installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
+                installerPackageName, verificationParams, encryptionParams);
     }
 
     @Override
-	  public void installPackageWithVerificationAndEncryption(Uri packageURI,
+    public void installPackageWithVerificationAndEncryption(Uri packageURI,
             IPackageInstallObserver observer, int flags, String installerPackageName,
             VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+        installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
+                installerPackageName, verificationParams, encryptionParams);
+    }
+
+    @Override
+    public void installPackage(Uri packageURI, PackageInstallObserver observer,
+            int flags, String installerPackageName) {
+        final VerificationParams verificationParams = new VerificationParams(null, null,
+                null, VerificationParams.NO_UID, null);
+        installCommon(packageURI, observer, flags, installerPackageName, verificationParams, null);
+    }
+
+    @Override
+    public void installPackageWithVerification(Uri packageURI,
+            PackageInstallObserver observer, int flags, String installerPackageName,
+            Uri verificationURI, ManifestDigest manifestDigest,
+            ContainerEncryptionParams encryptionParams) {
+        final VerificationParams verificationParams = new VerificationParams(verificationURI, null,
+                null, VerificationParams.NO_UID, manifestDigest);
+        installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
+                encryptionParams);
+    }
+
+    @Override
+    public void installPackageWithVerificationAndEncryption(Uri packageURI,
+            PackageInstallObserver observer, int flags, String installerPackageName,
+            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+        installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
+                encryptionParams);
+    }
+
+    private void installCommon(Uri packageURI,
+            PackageInstallObserver observer, int flags, String installerPackageName,
+            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+        if (!"file".equals(packageURI.getScheme())) {
+            throw new UnsupportedOperationException("Only file:// URIs are supported");
+        }
+        if (encryptionParams != null) {
+            throw new UnsupportedOperationException("ContainerEncryptionParams not supported");
+        }
+
+        final String originPath = packageURI.getPath();
         try {
-            mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags,
-                    installerPackageName, verificationParams, encryptionParams);
-        } catch (RemoteException e) {
-            // Should never happen!
+            mPM.installPackage(originPath, observer.getBinder(), flags, installerPackageName,
+                    verificationParams, null);
+        } catch (RemoteException ignored) {
         }
     }
 
@@ -1195,6 +1333,7 @@
             // Should never happen!
         }
     }
+
     @Override
     public void clearApplicationUserData(String packageName,
                                          IPackageDataObserver observer) {
@@ -1292,7 +1431,18 @@
     public void replacePreferredActivity(IntentFilter filter,
                                          int match, ComponentName[] set, ComponentName activity) {
         try {
-            mPM.replacePreferredActivity(filter, match, set, activity);
+            mPM.replacePreferredActivity(filter, match, set, activity, UserHandle.myUserId());
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+    }
+
+    @Override
+    public void replacePreferredActivityAsUser(IntentFilter filter,
+                                         int match, ComponentName[] set, ComponentName activity,
+                                         int userId) {
+        try {
+            mPM.replacePreferredActivity(filter, match, set, activity, userId);
         } catch (RemoteException e) {
             // Should never happen!
         }
@@ -1370,10 +1520,10 @@
     }
 
     @Override
-    public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
+    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
             UserHandle user) {
         try {
-            return mPM.setApplicationBlockedSettingAsUser(packageName, blocked,
+            return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
                     user.getIdentifier());
         } catch (RemoteException re) {
             // Should never happen!
@@ -1382,15 +1532,66 @@
     }
 
     @Override
-    public boolean getApplicationBlockedSettingAsUser(String packageName, UserHandle user) {
+    public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
         try {
-            return mPM.getApplicationBlockedSettingAsUser(packageName, user.getIdentifier());
+            return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
         } catch (RemoteException re) {
             // Should never happen!
         }
         return false;
     }
 
+    /** @hide */
+    @Override
+    public KeySet getKeySetByAlias(String packageName, String alias) {
+        Preconditions.checkNotNull(packageName);
+        Preconditions.checkNotNull(alias);
+        KeySet ks;
+        try {
+            ks = mPM.getKeySetByAlias(packageName, alias);
+        } catch (RemoteException e) {
+            return null;
+        }
+        return ks;
+    }
+
+    /** @hide */
+    @Override
+    public KeySet getSigningKeySet(String packageName) {
+        Preconditions.checkNotNull(packageName);
+        KeySet ks;
+        try {
+            ks = mPM.getSigningKeySet(packageName);
+        } catch (RemoteException e) {
+            return null;
+        }
+        return ks;
+    }
+
+    /** @hide */
+    @Override
+    public boolean isSignedBy(String packageName, KeySet ks) {
+        Preconditions.checkNotNull(packageName);
+        Preconditions.checkNotNull(ks);
+        try {
+            return mPM.isPackageSignedByKeySet(packageName, ks);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /** @hide */
+    @Override
+    public boolean isSignedByExactly(String packageName, KeySet ks) {
+        Preconditions.checkNotNull(packageName);
+        Preconditions.checkNotNull(ks);
+        try {
+            return mPM.isPackageSignedByKeySetExactly(packageName, ks);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
     /**
      * @hide
      */
@@ -1404,6 +1605,150 @@
         return null;
     }
 
+    @Override
+    public PackageInstaller getPackageInstaller() {
+        synchronized (mLock) {
+            if (mInstaller == null) {
+                try {
+                    mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(),
+                            mContext.getPackageName(), mContext.getUserId());
+                } catch (RemoteException e) {
+                    throw e.rethrowAsRuntimeException();
+                }
+            }
+            return mInstaller;
+        }
+    }
+
+    @Override
+    public boolean isPackageAvailable(String packageName) {
+        try {
+            return mPM.isPackageAvailable(packageName, mContext.getUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
+            int flags) {
+        try {
+            mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
+                    mContext.getUserId(), sourceUserId, targetUserId, flags);
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void clearCrossProfileIntentFilters(int sourceUserId) {
+        try {
+            mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName(),
+                    mContext.getUserId());
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
+        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
+            Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
+            if (bitmap == null) {
+                return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false);
+            }
+            return new BitmapDrawable(bitmap);
+        }
+        Drawable dr = null;
+        if (itemInfo.packageName != null) {
+            dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
+        }
+        if (dr == null) {
+            dr = itemInfo.loadDefaultIcon(this);
+        }
+        return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
+    }
+
+    private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
+            Rect badgeLocation, boolean tryBadgeInPlace) {
+        final int badgedWidth = drawable.getIntrinsicWidth();
+        final int badgedHeight = drawable.getIntrinsicHeight();
+        final boolean canBadgeInPlace = tryBadgeInPlace
+                && (drawable instanceof BitmapDrawable)
+                && ((BitmapDrawable) drawable).getBitmap().isMutable();
+
+        final Bitmap bitmap;
+        if (canBadgeInPlace) {
+            bitmap = ((BitmapDrawable) drawable).getBitmap();
+        } else {
+            bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
+        }
+        Canvas canvas = new Canvas(bitmap);
+
+        if (!canBadgeInPlace) {
+            drawable.setBounds(0, 0, badgedWidth, badgedHeight);
+            drawable.draw(canvas);
+        }
+
+        if (badgeLocation != null) {
+            if (badgeLocation.left < 0 || badgeLocation.top < 0
+                    || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
+                throw new IllegalArgumentException("Badge location " + badgeLocation
+                        + " not in badged drawable bounds "
+                        + new Rect(0, 0, badgedWidth, badgedHeight));
+            }
+            badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
+
+            canvas.save();
+            canvas.translate(badgeLocation.left, badgeLocation.top);
+            badgeDrawable.draw(canvas);
+            canvas.restore();
+        } else {
+            badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
+            badgeDrawable.draw(canvas);
+        }
+
+        if (!canBadgeInPlace) {
+            BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
+
+            if (drawable instanceof BitmapDrawable) {
+                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
+                mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
+            }
+
+            return mergedDrawable;
+        }
+
+        return drawable;
+    }
+
+    private int getBadgeResIdForUser(int userHandle) {
+        // Return the framework-provided badge.
+        UserInfo userInfo = getUserIfProfile(userHandle);
+        if (userInfo != null && userInfo.isManagedProfile()) {
+            return com.android.internal.R.drawable.ic_corp_icon_badge;
+        }
+        return 0;
+    }
+
+    private UserInfo getUserIfProfile(int userHandle) {
+        List<UserInfo> userProfiles = getUserManager().getProfiles(UserHandle.myUserId());
+        for (UserInfo user : userProfiles) {
+            if (user.id == userHandle) {
+                return user;
+            }
+        }
+        return null;
+    }
+
     private final ContextImpl mContext;
     private final IPackageManager mPM;
 
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index badaec3..0123e167 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -25,14 +25,17 @@
 import android.content.pm.ServiceInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
+import com.android.internal.app.IVoiceInteractor;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -75,7 +78,8 @@
             boolean finished = data.readInt() != 0;
             boolean userLeaving = data.readInt() != 0;
             int configChanges = data.readInt();
-            schedulePauseActivity(b, finished, userLeaving, configChanges);
+            boolean dontReport = data.readInt() != 0;
+            schedulePauseActivity(b, finished, userLeaving, configChanges, dontReport);
             return true;
         }
 
@@ -113,7 +117,8 @@
             IBinder b = data.readStrongBinder();
             int procState = data.readInt();
             boolean isForward = data.readInt() != 0;
-            scheduleResumeActivity(b, procState, isForward);
+            Bundle resumeArgs = data.readBundle();
+            scheduleResumeActivity(b, procState, isForward, resumeArgs);
             return true;
         }
         
@@ -125,7 +130,7 @@
             scheduleSendResult(b, ri);
             return true;
         }
-        
+
         case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
@@ -135,21 +140,22 @@
             ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
             Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
             CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
+            IVoiceInteractor voiceInteractor = IVoiceInteractor.Stub.asInterface(
+                    data.readStrongBinder());
             int procState = data.readInt();
             Bundle state = data.readBundle();
+            PersistableBundle persistentState = data.readPersistableBundle();
             List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
             List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
             boolean notResumed = data.readInt() != 0;
             boolean isForward = data.readInt() != 0;
-            String profileName = data.readString();
-            ParcelFileDescriptor profileFd = data.readInt() != 0
-                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
-            boolean autoStopProfiler = data.readInt() != 0;
-            scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, procState, state,
-                    ri, pi, notResumed, isForward, profileName, profileFd, autoStopProfiler);
+            ProfilerInfo profilerInfo = data.readInt() != 0
+                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
+            scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, voiceInteractor,
+                    procState, state, persistentState, ri, pi, notResumed, isForward, profilerInfo);
             return true;
         }
-        
+
         case SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
@@ -265,10 +271,8 @@
                 data.createTypedArrayList(ProviderInfo.CREATOR);
             ComponentName testName = (data.readInt() != 0)
                 ? new ComponentName(data) : null;
-            String profileName = data.readString();
-            ParcelFileDescriptor profileFd = data.readInt() != 0
-                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
-            boolean autoStopProfiler = data.readInt() != 0;
+            ProfilerInfo profilerInfo = data.readInt() != 0
+                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
             Bundle testArgs = data.readBundle();
             IBinder binder = data.readStrongBinder();
             IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);
@@ -283,11 +287,9 @@
             CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
             HashMap<String, IBinder> services = data.readHashMap(null);
             Bundle coreSettings = data.readBundle();
-            bindApplication(packageName, info,
-                            providers, testName, profileName, profileFd, autoStopProfiler,
-                            testArgs, testWatcher, uiAutomationConnection, testMode,
-                            openGlTrace, restrictedBackupMode, persistent, config, compatInfo,
-                            services, coreSettings);
+            bindApplication(packageName, info, providers, testName, profilerInfo, testArgs,
+                    testWatcher, uiAutomationConnection, testMode, openGlTrace,
+                    restrictedBackupMode, persistent, config, compatInfo, services, coreSettings);
             return true;
         }
 
@@ -305,14 +307,6 @@
             return true;
         }
 
-        case REQUEST_THUMBNAIL_TRANSACTION:
-        {
-            data.enforceInterface(IApplicationThread.descriptor);
-            IBinder b = data.readStrongBinder();
-            requestThumbnail(b);
-            return true;
-        }
-
         case SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
@@ -338,7 +332,7 @@
             final String proxy = data.readString();
             final String port = data.readString();
             final String exclList = data.readString();
-            final String pacFileUrl = data.readString();
+            final Uri pacFileUrl = Uri.CREATOR.createFromParcel(data);
             setHttpProxy(proxy, port, exclList, pacFileUrl);
             return true;
         }
@@ -402,7 +396,7 @@
             scheduleLowMemory();
             return true;
         }
-        
+
         case SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
@@ -410,19 +404,18 @@
             scheduleActivityConfigurationChanged(b);
             return true;
         }
-        
+
         case PROFILER_CONTROL_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
             boolean start = data.readInt() != 0;
             int profileType = data.readInt();
-            String path = data.readString();
-            ParcelFileDescriptor fd = data.readInt() != 0
-                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
-            profilerControl(start, path, fd, profileType);
+            ProfilerInfo profilerInfo = data.readInt() != 0
+                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
+            profilerControl(start, profilerInfo, profileType);
             return true;
         }
-        
+
         case SET_SCHEDULING_GROUP_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
@@ -610,6 +603,16 @@
             return true;
         }
 
+        case SCHEDULE_ON_NEW_ACTIVITY_OPTIONS_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            IBinder token = data.readStrongBinder();
+            ActivityOptions options = new ActivityOptions(data.readBundle());
+            scheduleOnNewActivityOptions(token, options);
+            reply.writeNoException();
+            return true;
+        }
+
         case SET_PROCESS_STATE_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
@@ -636,6 +639,34 @@
             reply.writeNoException();
             return true;
         }
+
+        case CANCEL_VISIBLE_BEHIND_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            IBinder token = data.readStrongBinder();
+            scheduleCancelVisibleBehind(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            IBinder token = data.readStrongBinder();
+            boolean enabled = data.readInt() > 0;
+            scheduleBackgroundVisibleBehindChanged(token, enabled);
+            reply.writeNoException();
+            return true;
+        }
+
+        case ENTER_ANIMATION_COMPLETE_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            IBinder token = data.readStrongBinder();
+            scheduleEnterAnimationComplete(token);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -659,13 +690,14 @@
     }
     
     public final void schedulePauseActivity(IBinder token, boolean finished,
-            boolean userLeaving, int configChanges) throws RemoteException {
+            boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         data.writeInt(finished ? 1 : 0);
         data.writeInt(userLeaving ? 1 :0);
         data.writeInt(configChanges);
+        data.writeInt(dontReport ? 1 : 0);
         mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
@@ -705,20 +737,22 @@
         data.recycle();
     }
 
-    public final void scheduleResumeActivity(IBinder token, int procState, boolean isForward)
+    public final void scheduleResumeActivity(IBinder token, int procState, boolean isForward,
+            Bundle resumeArgs)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         data.writeInt(procState);
         data.writeInt(isForward ? 1 : 0);
+        data.writeBundle(resumeArgs);
         mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
 
     public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
-    		throws RemoteException {
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
@@ -730,10 +764,10 @@
 
     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
             ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
-            int procState, Bundle state, List<ResultInfo> pendingResults,
-    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-    		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
-    		throws RemoteException {
+            IVoiceInteractor voiceInteractor, int procState, Bundle state,
+            PersistableBundle persistentState, List<ResultInfo> pendingResults,
+            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+            ProfilerInfo profilerInfo) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         intent.writeToParcel(data, 0);
@@ -742,20 +776,20 @@
         info.writeToParcel(data, 0);
         curConfig.writeToParcel(data, 0);
         compatInfo.writeToParcel(data, 0);
+        data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null);
         data.writeInt(procState);
         data.writeBundle(state);
+        data.writePersistableBundle(persistentState);
         data.writeTypedList(pendingResults);
         data.writeTypedList(pendingNewIntents);
         data.writeInt(notResumed ? 1 : 0);
         data.writeInt(isForward ? 1 : 0);
-        data.writeString(profileName);
-        if (profileFd != null) {
+        if (profilerInfo != null) {
             data.writeInt(1);
-            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
         } else {
             data.writeInt(0);
         }
-        data.writeInt(autoStopProfiler ? 1 : 0);
         mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
@@ -886,7 +920,7 @@
     }
 
     public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
-	    int flags, Intent args) throws RemoteException {
+            int flags, Intent args) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
@@ -915,9 +949,8 @@
     }
 
     public final void bindApplication(String packageName, ApplicationInfo info,
-            List<ProviderInfo> providers, ComponentName testName, String profileName,
-            ParcelFileDescriptor profileFd, boolean autoStopProfiler, Bundle testArgs,
-            IInstrumentationWatcher testWatcher,
+            List<ProviderInfo> providers, ComponentName testName, ProfilerInfo profilerInfo,
+            Bundle testArgs, IInstrumentationWatcher testWatcher,
             IUiAutomationConnection uiAutomationConnection, int debugMode,
             boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
             Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
@@ -933,14 +966,12 @@
             data.writeInt(1);
             testName.writeToParcel(data, 0);
         }
-        data.writeString(profileName);
-        if (profileFd != null) {
+        if (profilerInfo != null) {
             data.writeInt(1);
-            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
         } else {
             data.writeInt(0);
         }
-        data.writeInt(autoStopProfiler ? 1 : 0);
         data.writeBundle(testArgs);
         data.writeStrongInterface(testWatcher);
         data.writeStrongInterface(uiAutomationConnection);
@@ -973,16 +1004,6 @@
         data.recycle();
     }
 
-    public final void requestThumbnail(IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        data.writeInterfaceToken(IApplicationThread.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(REQUEST_THUMBNAIL_TRANSACTION, data, null,
-                IBinder.FLAG_ONEWAY);
-        data.recycle();
-    }
-
     public final void scheduleConfigurationChanged(Configuration config)
             throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -1010,13 +1031,13 @@
     }
 
     public void setHttpProxy(String proxy, String port, String exclList,
-            String pacFileUrl) throws RemoteException {
+            Uri pacFileUrl) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeString(proxy);
         data.writeString(port);
         data.writeString(exclList);
-        data.writeString(pacFileUrl);
+        pacFileUrl.writeToParcel(data, 0);
         mRemote.transact(SET_HTTP_PROXY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
         data.recycle();
     }
@@ -1077,7 +1098,7 @@
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
-    
+
     public final void scheduleActivityConfigurationChanged(
             IBinder token) throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -1087,17 +1108,16 @@
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
-    
-    public void profilerControl(boolean start, String path,
-            ParcelFileDescriptor fd, int profileType) throws RemoteException {
+
+    public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeInt(start ? 1 : 0);
         data.writeInt(profileType);
-        data.writeString(path);
-        if (fd != null) {
+        if (profilerInfo != null) {
             data.writeInt(1);
-            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
         } else {
             data.writeInt(0);
         }
@@ -1105,7 +1125,7 @@
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
-    
+
     public void setSchedulingGroup(int group) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -1114,7 +1134,7 @@
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
-    
+
     public void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -1123,9 +1143,8 @@
         mRemote.transact(DISPATCH_PACKAGE_BROADCAST_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
-        
     }
-    
+
     public void scheduleCrash(String msg) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -1133,7 +1152,6 @@
         mRemote.transact(SCHEDULE_CRASH_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
-        
     }
 
     public void dumpHeap(boolean managed, String path,
@@ -1255,7 +1273,20 @@
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         data.writeInt(timeout ? 1 : 0);
-        mRemote.transact(SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+        mRemote.transact(SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION, data, null,
+                IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
+
+    @Override
+    public void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeStrongBinder(token);
+        data.writeBundle(options == null ? null : options.toBundle());
+        mRemote.transact(SCHEDULE_ON_NEW_ACTIVITY_OPTIONS_TRANSACTION, data, null,
+                IBinder.FLAG_ONEWAY);
         data.recycle();
     }
 
@@ -1285,4 +1316,34 @@
         mRemote.transact(UPDATE_TIME_PREFS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
         data.recycle();
     }
+
+    @Override
+    public void scheduleCancelVisibleBehind(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(CANCEL_VISIBLE_BEHIND_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
+
+    @Override
+    public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeStrongBinder(token);
+        data.writeInt(enabled ? 1 : 0);
+        mRemote.transact(BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION, data, null,
+                IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
+
+    @Override
+    public void scheduleEnterAnimationComplete(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(ENTER_ANIMATION_COMPLETE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
 }
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 89ee145..0092ee7 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -16,12 +16,24 @@
 
 package android.app;
 
+import com.android.internal.util.FastPrintWriter;
+
+import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+import android.transition.TransitionSet;
+import android.transition.TransitionUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.LogWriter;
-import com.android.internal.util.FastPrintWriter;
+import android.util.Pair;
+import android.util.SparseArray;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -37,15 +49,19 @@
     final CharSequence mBreadCrumbTitleText;
     final int mBreadCrumbShortTitleRes;
     final CharSequence mBreadCrumbShortTitleText;
+    final ArrayList<String> mSharedElementSourceNames;
+    final ArrayList<String> mSharedElementTargetNames;
 
     public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
         int numRemoved = 0;
         BackStackRecord.Op op = bse.mHead;
         while (op != null) {
-            if (op.removed != null) numRemoved += op.removed.size();
+            if (op.removed != null) {
+                numRemoved += op.removed.size();
+            }
             op = op.next;
         }
-        mOps = new int[bse.mNumOp*7 + numRemoved];
+        mOps = new int[bse.mNumOp * 7 + numRemoved];
 
         if (!bse.mAddToBackStack) {
             throw new IllegalStateException("Not on back stack");
@@ -63,7 +79,7 @@
             if (op.removed != null) {
                 final int N = op.removed.size();
                 mOps[pos++] = N;
-                for (int i=0; i<N; i++) {
+                for (int i = 0; i < N; i++) {
                     mOps[pos++] = op.removed.get(i).mIndex;
                 }
             } else {
@@ -79,6 +95,8 @@
         mBreadCrumbTitleText = bse.mBreadCrumbTitleText;
         mBreadCrumbShortTitleRes = bse.mBreadCrumbShortTitleRes;
         mBreadCrumbShortTitleText = bse.mBreadCrumbShortTitleText;
+        mSharedElementSourceNames = bse.mSharedElementSourceNames;
+        mSharedElementTargetNames = bse.mSharedElementTargetNames;
     }
 
     public BackStackState(Parcel in) {
@@ -91,6 +109,8 @@
         mBreadCrumbTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mBreadCrumbShortTitleRes = in.readInt();
         mBreadCrumbShortTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mSharedElementSourceNames = in.createStringArrayList();
+        mSharedElementTargetNames = in.createStringArrayList();
     }
 
     public BackStackRecord instantiate(FragmentManagerImpl fm) {
@@ -100,8 +120,10 @@
         while (pos < mOps.length) {
             BackStackRecord.Op op = new BackStackRecord.Op();
             op.cmd = mOps[pos++];
-            if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
-                    "Instantiate " + bse + " op #" + num + " base fragment #" + mOps[pos]);
+            if (FragmentManagerImpl.DEBUG) {
+                Log.v(FragmentManagerImpl.TAG,
+                        "Instantiate " + bse + " op #" + num + " base fragment #" + mOps[pos]);
+            }
             int findex = mOps[pos++];
             if (findex >= 0) {
                 Fragment f = fm.mActive.get(findex);
@@ -116,9 +138,11 @@
             final int N = mOps[pos++];
             if (N > 0) {
                 op.removed = new ArrayList<Fragment>(N);
-                for (int i=0; i<N; i++) {
-                    if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
-                            "Instantiate " + bse + " set remove fragment #" + mOps[pos]);
+                for (int i = 0; i < N; i++) {
+                    if (FragmentManagerImpl.DEBUG) {
+                        Log.v(FragmentManagerImpl.TAG,
+                                "Instantiate " + bse + " set remove fragment #" + mOps[pos]);
+                    }
                     Fragment r = fm.mActive.get(mOps[pos++]);
                     op.removed.add(r);
                 }
@@ -135,6 +159,8 @@
         bse.mBreadCrumbTitleText = mBreadCrumbTitleText;
         bse.mBreadCrumbShortTitleRes = mBreadCrumbShortTitleRes;
         bse.mBreadCrumbShortTitleText = mBreadCrumbShortTitleText;
+        bse.mSharedElementSourceNames = mSharedElementSourceNames;
+        bse.mSharedElementTargetNames = mSharedElementTargetNames;
         bse.bumpBackStackNesting(1);
         return bse;
     }
@@ -153,6 +179,8 @@
         TextUtils.writeToParcel(mBreadCrumbTitleText, dest, 0);
         dest.writeInt(mBreadCrumbShortTitleRes);
         TextUtils.writeToParcel(mBreadCrumbShortTitleText, dest, 0);
+        dest.writeStringList(mSharedElementSourceNames);
+        dest.writeStringList(mSharedElementTargetNames);
     }
 
     public static final Parcelable.Creator<BackStackState> CREATOR
@@ -217,6 +245,9 @@
     int mBreadCrumbShortTitleRes;
     CharSequence mBreadCrumbShortTitleText;
 
+    ArrayList<String> mSharedElementSourceNames;
+    ArrayList<String> mSharedElementTargetNames;
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(128);
@@ -240,78 +271,112 @@
 
     void dump(String prefix, PrintWriter writer, boolean full) {
         if (full) {
-            writer.print(prefix); writer.print("mName="); writer.print(mName);
-                    writer.print(" mIndex="); writer.print(mIndex);
-                    writer.print(" mCommitted="); writer.println(mCommitted);
+            writer.print(prefix);
+            writer.print("mName=");
+            writer.print(mName);
+            writer.print(" mIndex=");
+            writer.print(mIndex);
+            writer.print(" mCommitted=");
+            writer.println(mCommitted);
             if (mTransition != FragmentTransaction.TRANSIT_NONE) {
-                writer.print(prefix); writer.print("mTransition=#");
-                        writer.print(Integer.toHexString(mTransition));
-                        writer.print(" mTransitionStyle=#");
-                        writer.println(Integer.toHexString(mTransitionStyle));
+                writer.print(prefix);
+                writer.print("mTransition=#");
+                writer.print(Integer.toHexString(mTransition));
+                writer.print(" mTransitionStyle=#");
+                writer.println(Integer.toHexString(mTransitionStyle));
             }
-            if (mEnterAnim != 0 || mExitAnim !=0) {
-                writer.print(prefix); writer.print("mEnterAnim=#");
-                        writer.print(Integer.toHexString(mEnterAnim));
-                        writer.print(" mExitAnim=#");
-                        writer.println(Integer.toHexString(mExitAnim));
+            if (mEnterAnim != 0 || mExitAnim != 0) {
+                writer.print(prefix);
+                writer.print("mEnterAnim=#");
+                writer.print(Integer.toHexString(mEnterAnim));
+                writer.print(" mExitAnim=#");
+                writer.println(Integer.toHexString(mExitAnim));
             }
-            if (mPopEnterAnim != 0 || mPopExitAnim !=0) {
-                writer.print(prefix); writer.print("mPopEnterAnim=#");
-                        writer.print(Integer.toHexString(mPopEnterAnim));
-                        writer.print(" mPopExitAnim=#");
-                        writer.println(Integer.toHexString(mPopExitAnim));
+            if (mPopEnterAnim != 0 || mPopExitAnim != 0) {
+                writer.print(prefix);
+                writer.print("mPopEnterAnim=#");
+                writer.print(Integer.toHexString(mPopEnterAnim));
+                writer.print(" mPopExitAnim=#");
+                writer.println(Integer.toHexString(mPopExitAnim));
             }
             if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
-                writer.print(prefix); writer.print("mBreadCrumbTitleRes=#");
-                        writer.print(Integer.toHexString(mBreadCrumbTitleRes));
-                        writer.print(" mBreadCrumbTitleText=");
-                        writer.println(mBreadCrumbTitleText);
+                writer.print(prefix);
+                writer.print("mBreadCrumbTitleRes=#");
+                writer.print(Integer.toHexString(mBreadCrumbTitleRes));
+                writer.print(" mBreadCrumbTitleText=");
+                writer.println(mBreadCrumbTitleText);
             }
             if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
-                writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#");
-                        writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
-                        writer.print(" mBreadCrumbShortTitleText=");
-                        writer.println(mBreadCrumbShortTitleText);
+                writer.print(prefix);
+                writer.print("mBreadCrumbShortTitleRes=#");
+                writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
+                writer.print(" mBreadCrumbShortTitleText=");
+                writer.println(mBreadCrumbShortTitleText);
             }
         }
 
         if (mHead != null) {
-            writer.print(prefix); writer.println("Operations:");
+            writer.print(prefix);
+            writer.println("Operations:");
             String innerPrefix = prefix + "    ";
             Op op = mHead;
             int num = 0;
             while (op != null) {
                 String cmdStr;
                 switch (op.cmd) {
-                    case OP_NULL: cmdStr="NULL"; break;
-                    case OP_ADD: cmdStr="ADD"; break;
-                    case OP_REPLACE: cmdStr="REPLACE"; break;
-                    case OP_REMOVE: cmdStr="REMOVE"; break;
-                    case OP_HIDE: cmdStr="HIDE"; break;
-                    case OP_SHOW: cmdStr="SHOW"; break;
-                    case OP_DETACH: cmdStr="DETACH"; break;
-                    case OP_ATTACH: cmdStr="ATTACH"; break;
-                    default: cmdStr="cmd=" + op.cmd; break;
+                    case OP_NULL:
+                        cmdStr = "NULL";
+                        break;
+                    case OP_ADD:
+                        cmdStr = "ADD";
+                        break;
+                    case OP_REPLACE:
+                        cmdStr = "REPLACE";
+                        break;
+                    case OP_REMOVE:
+                        cmdStr = "REMOVE";
+                        break;
+                    case OP_HIDE:
+                        cmdStr = "HIDE";
+                        break;
+                    case OP_SHOW:
+                        cmdStr = "SHOW";
+                        break;
+                    case OP_DETACH:
+                        cmdStr = "DETACH";
+                        break;
+                    case OP_ATTACH:
+                        cmdStr = "ATTACH";
+                        break;
+                    default:
+                        cmdStr = "cmd=" + op.cmd;
+                        break;
                 }
-                writer.print(prefix); writer.print("  Op #"); writer.print(num);
-                        writer.print(": "); writer.print(cmdStr);
-                        writer.print(" "); writer.println(op.fragment);
+                writer.print(prefix);
+                writer.print("  Op #");
+                writer.print(num);
+                writer.print(": ");
+                writer.print(cmdStr);
+                writer.print(" ");
+                writer.println(op.fragment);
                 if (full) {
                     if (op.enterAnim != 0 || op.exitAnim != 0) {
-                        writer.print(innerPrefix); writer.print("enterAnim=#");
-                                writer.print(Integer.toHexString(op.enterAnim));
-                                writer.print(" exitAnim=#");
-                                writer.println(Integer.toHexString(op.exitAnim));
+                        writer.print(innerPrefix);
+                        writer.print("enterAnim=#");
+                        writer.print(Integer.toHexString(op.enterAnim));
+                        writer.print(" exitAnim=#");
+                        writer.println(Integer.toHexString(op.exitAnim));
                     }
                     if (op.popEnterAnim != 0 || op.popExitAnim != 0) {
-                        writer.print(innerPrefix); writer.print("popEnterAnim=#");
-                                writer.print(Integer.toHexString(op.popEnterAnim));
-                                writer.print(" popExitAnim=#");
-                                writer.println(Integer.toHexString(op.popExitAnim));
+                        writer.print(innerPrefix);
+                        writer.print("popEnterAnim=#");
+                        writer.print(Integer.toHexString(op.popEnterAnim));
+                        writer.print(" popExitAnim=#");
+                        writer.println(Integer.toHexString(op.popExitAnim));
                     }
                 }
                 if (op.removed != null && op.removed.size() > 0) {
-                    for (int i=0; i<op.removed.size(); i++) {
+                    for (int i = 0; i < op.removed.size(); i++) {
                         writer.print(innerPrefix);
                         if (op.removed.size() == 1) {
                             writer.print("Removed: ");
@@ -319,8 +384,10 @@
                             if (i == 0) {
                                 writer.println("Removed:");
                             }
-                            writer.print(innerPrefix); writer.print("  #"); writer.print(i);
-                                    writer.print(": "); 
+                            writer.print(innerPrefix);
+                            writer.print("  #");
+                            writer.print(i);
+                            writer.print(": ");
                         }
                         writer.println(op.removed.get(i));
                     }
@@ -494,6 +561,62 @@
         return this;
     }
 
+    @Override
+    public FragmentTransaction addSharedElement(View sharedElement, String name) {
+        String transitionName = sharedElement.getTransitionName();
+        if (transitionName == null) {
+            throw new IllegalArgumentException("Unique transitionNames are required for all" +
+                    " sharedElements");
+        }
+        if (mSharedElementSourceNames == null) {
+            mSharedElementSourceNames = new ArrayList<String>();
+            mSharedElementTargetNames = new ArrayList<String>();
+        }
+        mSharedElementSourceNames.add(transitionName);
+        mSharedElementTargetNames.add(name);
+        return this;
+    }
+
+    /** TODO: remove this */
+    @Override
+    public FragmentTransaction setSharedElement(View sharedElement, String name) {
+        String transitionName = sharedElement.getTransitionName();
+        if (transitionName == null) {
+            throw new IllegalArgumentException("Unique transitionNames are required for all" +
+                    " sharedElements");
+        }
+        mSharedElementSourceNames = new ArrayList<String>(1);
+        mSharedElementSourceNames.add(transitionName);
+
+        mSharedElementTargetNames = new ArrayList<String>(1);
+        mSharedElementTargetNames.add(name);
+        return this;
+    }
+
+    /** TODO: remove this */
+    @Override
+    public FragmentTransaction setSharedElements(Pair<View, String>... sharedElements) {
+        if (sharedElements == null || sharedElements.length == 0) {
+            mSharedElementSourceNames = null;
+            mSharedElementTargetNames = null;
+        } else {
+            ArrayList<String> sourceNames = new ArrayList<String>(sharedElements.length);
+            ArrayList<String> targetNames = new ArrayList<String>(sharedElements.length);
+            for (int i = 0; i < sharedElements.length; i++) {
+                String transitionName = sharedElements[i].first.getTransitionName();
+                if (transitionName == null) {
+                    throw new IllegalArgumentException("Unique transitionNames are required for all"
+                            + " sharedElements");
+                }
+                sourceNames.add(transitionName);
+                targetNames.add(sharedElements[i].second);
+            }
+            mSharedElementSourceNames = sourceNames;
+            mSharedElementTargetNames = targetNames;
+        }
+        return this;
+    }
+
     public FragmentTransaction setTransitionStyle(int styleRes) {
         mTransitionStyle = styleRes;
         return this;
@@ -550,21 +673,27 @@
         if (!mAddToBackStack) {
             return;
         }
-        if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting in " + this
-                + " by " + amt);
+        if (FragmentManagerImpl.DEBUG) {
+            Log.v(TAG, "Bump nesting in " + this
+                    + " by " + amt);
+        }
         Op op = mHead;
         while (op != null) {
             if (op.fragment != null) {
                 op.fragment.mBackStackNesting += amt;
-                if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
-                        + op.fragment + " to " + op.fragment.mBackStackNesting);
+                if (FragmentManagerImpl.DEBUG) {
+                    Log.v(TAG, "Bump nesting of "
+                            + op.fragment + " to " + op.fragment.mBackStackNesting);
+                }
             }
             if (op.removed != null) {
-                for (int i=op.removed.size()-1; i>=0; i--) {
+                for (int i = op.removed.size() - 1; i >= 0; i--) {
                     Fragment r = op.removed.get(i);
                     r.mBackStackNesting += amt;
-                    if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
-                            + r + " to " + r.mBackStackNesting);
+                    if (FragmentManagerImpl.DEBUG) {
+                        Log.v(TAG, "Bump nesting of "
+                                + r + " to " + r.mBackStackNesting);
+                    }
                 }
             }
             op = op.next;
@@ -578,9 +707,11 @@
     public int commitAllowingStateLoss() {
         return commitInternal(true);
     }
-    
+
     int commitInternal(boolean allowStateLoss) {
-        if (mCommitted) throw new IllegalStateException("commit already called");
+        if (mCommitted) {
+            throw new IllegalStateException("commit already called");
+        }
         if (FragmentManagerImpl.DEBUG) {
             Log.v(TAG, "Commit: " + this);
             LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
@@ -597,9 +728,11 @@
         mManager.enqueueAction(this, allowStateLoss);
         return mIndex;
     }
-    
+
     public void run() {
-        if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Run: " + this);
+        if (FragmentManagerImpl.DEBUG) {
+            Log.v(TAG, "Run: " + this);
+        }
 
         if (mAddToBackStack) {
             if (mIndex < 0) {
@@ -609,6 +742,11 @@
 
         bumpBackStackNesting(1);
 
+        SparseArray<Fragment> firstOutFragments = new SparseArray<Fragment>();
+        SparseArray<Fragment> lastInFragments = new SparseArray<Fragment>();
+        calculateFragments(firstOutFragments, lastInFragments);
+        beginTransition(firstOutFragments, lastInFragments, false);
+
         Op op = mHead;
         while (op != null) {
             switch (op.cmd) {
@@ -616,14 +754,17 @@
                     Fragment f = op.fragment;
                     f.mNextAnim = op.enterAnim;
                     mManager.addFragment(f, false);
-                } break;
+                }
+                break;
                 case OP_REPLACE: {
                     Fragment f = op.fragment;
                     if (mManager.mAdded != null) {
-                        for (int i=0; i<mManager.mAdded.size(); i++) {
+                        for (int i = 0; i < mManager.mAdded.size(); i++) {
                             Fragment old = mManager.mAdded.get(i);
-                            if (FragmentManagerImpl.DEBUG) Log.v(TAG,
-                                    "OP_REPLACE: adding=" + f + " old=" + old);
+                            if (FragmentManagerImpl.DEBUG) {
+                                Log.v(TAG,
+                                        "OP_REPLACE: adding=" + f + " old=" + old);
+                            }
                             if (f == null || old.mContainerId == f.mContainerId) {
                                 if (old == f) {
                                     op.fragment = f = null;
@@ -635,8 +776,10 @@
                                     old.mNextAnim = op.exitAnim;
                                     if (mAddToBackStack) {
                                         old.mBackStackNesting += 1;
-                                        if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
-                                                + old + " to " + old.mBackStackNesting);
+                                        if (FragmentManagerImpl.DEBUG) {
+                                            Log.v(TAG, "Bump nesting of "
+                                                    + old + " to " + old.mBackStackNesting);
+                                        }
                                     }
                                     mManager.removeFragment(old, mTransition, mTransitionStyle);
                                 }
@@ -647,32 +790,38 @@
                         f.mNextAnim = op.enterAnim;
                         mManager.addFragment(f, false);
                     }
-                } break;
+                }
+                break;
                 case OP_REMOVE: {
                     Fragment f = op.fragment;
                     f.mNextAnim = op.exitAnim;
                     mManager.removeFragment(f, mTransition, mTransitionStyle);
-                } break;
+                }
+                break;
                 case OP_HIDE: {
                     Fragment f = op.fragment;
                     f.mNextAnim = op.exitAnim;
                     mManager.hideFragment(f, mTransition, mTransitionStyle);
-                } break;
+                }
+                break;
                 case OP_SHOW: {
                     Fragment f = op.fragment;
                     f.mNextAnim = op.enterAnim;
                     mManager.showFragment(f, mTransition, mTransitionStyle);
-                } break;
+                }
+                break;
                 case OP_DETACH: {
                     Fragment f = op.fragment;
                     f.mNextAnim = op.exitAnim;
                     mManager.detachFragment(f, mTransition, mTransitionStyle);
-                } break;
+                }
+                break;
                 case OP_ATTACH: {
                     Fragment f = op.fragment;
                     f.mNextAnim = op.enterAnim;
                     mManager.attachFragment(f, mTransition, mTransitionStyle);
-                } break;
+                }
+                break;
                 default: {
                     throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
                 }
@@ -689,7 +838,671 @@
         }
     }
 
-    public void popFromBackStack(boolean doStateMove) {
+    private static void setFirstOut(SparseArray<Fragment> fragments, Fragment fragment) {
+        if (fragment != null) {
+            int containerId = fragment.mContainerId;
+            if (containerId != 0 && !fragment.isHidden() && fragment.isAdded() &&
+                    fragment.getView() != null && fragments.get(containerId) == null) {
+                fragments.put(containerId, fragment);
+            }
+        }
+    }
+
+    private void setLastIn(SparseArray<Fragment> fragments, Fragment fragment) {
+        if (fragment != null) {
+            int containerId = fragment.mContainerId;
+            if (containerId != 0) {
+                fragments.put(containerId, fragment);
+            }
+        }
+    }
+
+    /**
+     * Finds the first removed fragment and last added fragments when going forward.
+     * If none of the fragments have transitions, then both lists will be empty.
+     *
+     * @param firstOutFragments The list of first fragments to be removed, keyed on the
+     *                          container ID. This list will be modified by the method.
+     * @param lastInFragments The list of last fragments to be added, keyed on the
+     *                        container ID. This list will be modified by the method.
+     */
+    private void calculateFragments(SparseArray<Fragment> firstOutFragments,
+            SparseArray<Fragment> lastInFragments) {
+        if (!mManager.mContainer.hasView()) {
+            return; // nothing to see, so no transitions
+        }
+        Op op = mHead;
+        while (op != null) {
+            switch (op.cmd) {
+                case OP_ADD:
+                    setLastIn(lastInFragments, op.fragment);
+                    break;
+                case OP_REPLACE: {
+                    Fragment f = op.fragment;
+                    if (mManager.mAdded != null) {
+                        for (int i = 0; i < mManager.mAdded.size(); i++) {
+                            Fragment old = mManager.mAdded.get(i);
+                            if (f == null || old.mContainerId == f.mContainerId) {
+                                if (old == f) {
+                                    f = null;
+                                } else {
+                                    setFirstOut(firstOutFragments, old);
+                                }
+                            }
+                        }
+                    }
+                    setLastIn(lastInFragments, f);
+                    break;
+                }
+                case OP_REMOVE:
+                    setFirstOut(firstOutFragments, op.fragment);
+                    break;
+                case OP_HIDE:
+                    setFirstOut(firstOutFragments, op.fragment);
+                    break;
+                case OP_SHOW:
+                    setLastIn(lastInFragments, op.fragment);
+                    break;
+                case OP_DETACH:
+                    setFirstOut(firstOutFragments, op.fragment);
+                    break;
+                case OP_ATTACH:
+                    setLastIn(lastInFragments, op.fragment);
+                    break;
+            }
+
+            op = op.next;
+        }
+    }
+
+    /**
+     * Finds the first removed fragment and last added fragments when popping the back stack.
+     * If none of the fragments have transitions, then both lists will be empty.
+     *
+     * @param firstOutFragments The list of first fragments to be removed, keyed on the
+     *                          container ID. This list will be modified by the method.
+     * @param lastInFragments The list of last fragments to be added, keyed on the
+     *                        container ID. This list will be modified by the method.
+     */
+    public void calculateBackFragments(SparseArray<Fragment> firstOutFragments,
+            SparseArray<Fragment> lastInFragments) {
+        if (!mManager.mContainer.hasView()) {
+            return; // nothing to see, so no transitions
+        }
+        Op op = mHead;
+        while (op != null) {
+            switch (op.cmd) {
+                case OP_ADD:
+                    setFirstOut(firstOutFragments, op.fragment);
+                    break;
+                case OP_REPLACE:
+                    if (op.removed != null) {
+                        for (int i = op.removed.size() - 1; i >= 0; i--) {
+                            setLastIn(lastInFragments, op.removed.get(i));
+                        }
+                    }
+                    setFirstOut(firstOutFragments, op.fragment);
+                    break;
+                case OP_REMOVE:
+                    setLastIn(lastInFragments, op.fragment);
+                    break;
+                case OP_HIDE:
+                    setLastIn(lastInFragments, op.fragment);
+                    break;
+                case OP_SHOW:
+                    setFirstOut(firstOutFragments, op.fragment);
+                    break;
+                case OP_DETACH:
+                    setLastIn(lastInFragments, op.fragment);
+                    break;
+                case OP_ATTACH:
+                    setFirstOut(firstOutFragments, op.fragment);
+                    break;
+            }
+
+            op = op.next;
+        }
+    }
+
+    /**
+     * When custom fragment transitions are used, this sets up the state for each transition
+     * and begins the transition. A different transition is started for each fragment container
+     * and consists of up to 3 different transitions: the exit transition, a shared element
+     * transition and an enter transition.
+     *
+     * <p>The exit transition operates against the leaf nodes of the first fragment
+     * with a view that was removed. If no such fragment was removed, then no exit
+     * transition is executed. The exit transition comes from the outgoing fragment.</p>
+     *
+     * <p>The enter transition operates against the last fragment that was added. If
+     * that fragment does not have a view or no fragment was added, then no enter
+     * transition is executed. The enter transition comes from the incoming fragment.</p>
+     *
+     * <p>The shared element transition operates against all views and comes either
+     * from the outgoing fragment or the incoming fragment, depending on whether this
+     * is going forward or popping the back stack. When going forward, the incoming
+     * fragment's enter shared element transition is used, but when going back, the
+     * outgoing fragment's return shared element transition is used. Shared element
+     * transitions only operate if there is both an incoming and outgoing fragment.</p>
+     *
+     * @param firstOutFragments The list of first fragments to be removed, keyed on the
+     *                          container ID.
+     * @param lastInFragments The list of last fragments to be added, keyed on the
+     *                        container ID.
+     * @param isBack true if this is popping the back stack or false if this is a
+     *               forward operation.
+     * @return The TransitionState used to complete the operation of the transition
+     * in {@link #setNameOverrides(android.app.BackStackRecord.TransitionState, java.util.ArrayList,
+     * java.util.ArrayList)}.
+     */
+    private TransitionState beginTransition(SparseArray<Fragment> firstOutFragments,
+            SparseArray<Fragment> lastInFragments, boolean isBack) {
+        TransitionState state = new TransitionState();
+
+        // Adding a non-existent target view makes sure that the transitions don't target
+        // any views by default. They'll only target the views we tell add. If we don't
+        // add any, then no views will be targeted.
+        state.nonExistentView = new View(mManager.mActivity);
+
+        // Go over all leaving fragments.
+        for (int i = 0; i < firstOutFragments.size(); i++) {
+            int containerId = firstOutFragments.keyAt(i);
+            configureTransitions(containerId, state, isBack, firstOutFragments,
+                    lastInFragments);
+        }
+
+        // Now go over all entering fragments that didn't have a leaving fragment.
+        for (int i = 0; i < lastInFragments.size(); i++) {
+            int containerId = lastInFragments.keyAt(i);
+            if (firstOutFragments.get(containerId) == null) {
+                configureTransitions(containerId, state, isBack, firstOutFragments,
+                        lastInFragments);
+            }
+        }
+        return state;
+    }
+
+    private static Transition cloneTransition(Transition transition) {
+        if (transition != null) {
+            transition = transition.clone();
+        }
+        return transition;
+    }
+
+    private static Transition getEnterTransition(Fragment inFragment, boolean isBack) {
+        if (inFragment == null) {
+            return null;
+        }
+        return cloneTransition(isBack ? inFragment.getReenterTransition() :
+                inFragment.getEnterTransition());
+    }
+
+    private static Transition getExitTransition(Fragment outFragment, boolean isBack) {
+        if (outFragment == null) {
+            return null;
+        }
+        return cloneTransition(isBack ? outFragment.getReturnTransition() :
+                outFragment.getExitTransition());
+    }
+
+    private static Transition getSharedElementTransition(Fragment inFragment, Fragment outFragment,
+            boolean isBack) {
+        if (inFragment == null || outFragment == null) {
+            return null;
+        }
+        return cloneTransition(isBack ? outFragment.getSharedElementReturnTransition() :
+                inFragment.getSharedElementEnterTransition());
+    }
+
+    private static ArrayList<View> captureExitingViews(Transition exitTransition,
+            Fragment outFragment, ArrayMap<String, View> namedViews) {
+        ArrayList<View> viewList = null;
+        if (exitTransition != null) {
+            viewList = new ArrayList<View>();
+            View root = outFragment.getView();
+            root.captureTransitioningViews(viewList);
+            if (namedViews != null) {
+                viewList.removeAll(namedViews.values());
+            }
+            addTargets(exitTransition, viewList);
+        }
+        return viewList;
+    }
+
+    private ArrayMap<String, View> remapSharedElements(TransitionState state, Fragment outFragment,
+            boolean isBack) {
+        ArrayMap<String, View> namedViews = new ArrayMap<String, View>();
+        if (mSharedElementSourceNames != null) {
+            outFragment.getView().findNamedViews(namedViews);
+            if (isBack) {
+                namedViews.retainAll(mSharedElementTargetNames);
+            } else {
+                namedViews = remapNames(mSharedElementSourceNames, mSharedElementTargetNames,
+                        namedViews);
+            }
+        }
+
+        if (isBack) {
+            outFragment.mEnterTransitionCallback.onMapSharedElements(
+                    mSharedElementTargetNames, namedViews);
+            setBackNameOverrides(state, namedViews, false);
+        } else {
+            outFragment.mExitTransitionCallback.onMapSharedElements(
+                    mSharedElementTargetNames, namedViews);
+            setNameOverrides(state, namedViews, false);
+        }
+
+        return namedViews;
+    }
+
+    /**
+     * Prepares the enter transition by adding a non-existent view to the transition's target list
+     * and setting it epicenter callback. By adding a non-existent view to the target list,
+     * we can prevent any view from being targeted at the beginning of the transition.
+     * We will add to the views before the end state of the transition is captured so that the
+     * views will appear. At the start of the transition, we clear the list of targets so that
+     * we can restore the state of the transition and use it again.
+     *
+     * <p>The shared element transition maps its shared elements immediately prior to
+     * capturing the final state of the Transition.</p>
+     */
+    private ArrayList<View> addTransitionTargets(final TransitionState state,
+            final Transition enterTransition, final Transition sharedElementTransition,
+            final Transition overallTransition, final View container,
+            final Fragment inFragment, final Fragment outFragment,
+            final ArrayList<View> hiddenFragmentViews, final boolean isBack,
+            final ArrayList<View> sharedElementTargets) {
+        if (enterTransition == null && sharedElementTransition == null &&
+                overallTransition == null) {
+            return null;
+        }
+        final ArrayList<View> enteringViews = new ArrayList<View>();
+        container.getViewTreeObserver().addOnPreDrawListener(
+                new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        container.getViewTreeObserver().removeOnPreDrawListener(this);
+
+                        // Don't include any newly-hidden fragments in the transition.
+                        excludeHiddenFragments(hiddenFragmentViews, inFragment.mContainerId,
+                                overallTransition);
+
+                        ArrayMap<String, View> namedViews = null;
+                        if (sharedElementTransition != null) {
+                            namedViews = mapSharedElementsIn(state, isBack, inFragment);
+                            removeTargets(sharedElementTransition, sharedElementTargets);
+                            sharedElementTargets.clear();
+                            if (namedViews.isEmpty()) {
+                                sharedElementTargets.add(state.nonExistentView);
+                            } else {
+                                sharedElementTargets.addAll(namedViews.values());
+                            }
+
+                            addTargets(sharedElementTransition, sharedElementTargets);
+
+                            setEpicenterIn(namedViews, state);
+
+                            callSharedElementEnd(state, inFragment, outFragment, isBack,
+                                    namedViews);
+                        }
+
+                        if (enterTransition != null) {
+                            View view = inFragment.getView();
+                            if (view != null) {
+                                view.captureTransitioningViews(enteringViews);
+                                if (namedViews != null) {
+                                    enteringViews.removeAll(namedViews.values());
+                                }
+                                addTargets(enterTransition, enteringViews);
+                            }
+                            setSharedElementEpicenter(enterTransition, state);
+                        }
+                        return true;
+                    }
+                });
+        return enteringViews;
+    }
+
+    private void callSharedElementEnd(TransitionState state, Fragment inFragment,
+            Fragment outFragment, boolean isBack, ArrayMap<String, View> namedViews) {
+        SharedElementCallback sharedElementCallback = isBack ?
+                outFragment.mEnterTransitionCallback :
+                inFragment.mEnterTransitionCallback;
+        ArrayList<String> names = new ArrayList<String>(namedViews.keySet());
+        ArrayList<View> views = new ArrayList<View>(namedViews.values());
+        sharedElementCallback.onSharedElementEnd(names, views, null);
+    }
+
+    private void setEpicenterIn(ArrayMap<String, View> namedViews, TransitionState state) {
+        if (mSharedElementTargetNames != null && !namedViews.isEmpty()) {
+            // now we know the epicenter of the entering transition.
+            View epicenter = namedViews
+                    .get(mSharedElementTargetNames.get(0));
+            if (epicenter != null) {
+                state.enteringEpicenterView = epicenter;
+            }
+        }
+    }
+
+    private ArrayMap<String, View> mapSharedElementsIn(TransitionState state,
+            boolean isBack, Fragment inFragment) {
+        // Now map the shared elements in the incoming fragment
+        ArrayMap<String, View> namedViews = mapEnteringSharedElements(state, inFragment, isBack);
+
+        // remap shared elements and set the name mapping used
+        // in the shared element transition.
+        if (isBack) {
+            inFragment.mExitTransitionCallback.onMapSharedElements(
+                    mSharedElementTargetNames, namedViews);
+            setBackNameOverrides(state, namedViews, true);
+        } else {
+            inFragment.mEnterTransitionCallback.onMapSharedElements(
+                    mSharedElementTargetNames, namedViews);
+            setNameOverrides(state, namedViews, true);
+        }
+        return namedViews;
+    }
+
+    private static Transition mergeTransitions(Transition enterTransition,
+            Transition exitTransition, Transition sharedElementTransition, Fragment inFragment,
+            boolean isBack) {
+        boolean overlap = true;
+        if (enterTransition != null && exitTransition != null) {
+            overlap = isBack ? inFragment.getAllowReturnTransitionOverlap() :
+                    inFragment.getAllowEnterTransitionOverlap();
+        }
+
+        // Wrap the transitions. Explicit targets like in enter and exit will cause the
+        // views to be targeted regardless of excluded views. If that happens, then the
+        // excluded fragments views (hidden fragments) will still be in the transition.
+
+        Transition transition;
+        if (overlap) {
+            // Regular transition -- do it all together
+            TransitionSet transitionSet = new TransitionSet();
+            if (enterTransition != null) {
+                transitionSet.addTransition(enterTransition);
+            }
+            if (exitTransition != null) {
+                transitionSet.addTransition(exitTransition);
+            }
+            if (sharedElementTransition != null) {
+                transitionSet.addTransition(sharedElementTransition);
+            }
+            transition = transitionSet;
+        } else {
+            // First do exit, then enter, but allow shared element transition to happen
+            // during both.
+            Transition staggered = null;
+            if (exitTransition != null && enterTransition != null) {
+                staggered = new TransitionSet()
+                        .addTransition(exitTransition)
+                        .addTransition(enterTransition)
+                        .setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+            } else if (exitTransition != null) {
+                staggered = exitTransition;
+            } else if (enterTransition != null) {
+                staggered = enterTransition;
+            }
+            if (sharedElementTransition != null) {
+                TransitionSet together = new TransitionSet();
+                if (staggered != null) {
+                    together.addTransition(staggered);
+                }
+                together.addTransition(sharedElementTransition);
+                transition = together;
+            } else {
+                transition = staggered;
+            }
+        }
+        return transition;
+    }
+
+    /**
+     * Configures custom transitions for a specific fragment container.
+     *
+     * @param containerId The container ID of the fragments to configure the transition for.
+     * @param state The Transition State keeping track of the executing transitions.
+     * @param firstOutFragments The list of first fragments to be removed, keyed on the
+     *                          container ID.
+     * @param lastInFragments The list of last fragments to be added, keyed on the
+     *                        container ID.
+     * @param isBack true if this is popping the back stack or false if this is a
+     *               forward operation.
+     */
+    private void configureTransitions(int containerId, TransitionState state, boolean isBack,
+            SparseArray<Fragment> firstOutFragments, SparseArray<Fragment> lastInFragments) {
+        ViewGroup sceneRoot = (ViewGroup) mManager.mContainer.findViewById(containerId);
+        if (sceneRoot != null) {
+            Fragment inFragment = lastInFragments.get(containerId);
+            Fragment outFragment = firstOutFragments.get(containerId);
+
+            Transition enterTransition = getEnterTransition(inFragment, isBack);
+            Transition sharedElementTransition = getSharedElementTransition(inFragment, outFragment,
+                    isBack);
+            Transition exitTransition = getExitTransition(outFragment, isBack);
+
+            if (enterTransition == null && sharedElementTransition == null &&
+                    exitTransition == null) {
+                return; // no transitions!
+            }
+            if (enterTransition != null) {
+                enterTransition.addTarget(state.nonExistentView);
+            }
+            ArrayMap<String, View> namedViews = null;
+            ArrayList<View> sharedElementTargets = new ArrayList<View>();
+            if (sharedElementTransition != null) {
+                namedViews = remapSharedElements(state, outFragment, isBack);
+                if (namedViews.isEmpty()) {
+                    sharedElementTargets.add(state.nonExistentView);
+                } else {
+                    sharedElementTargets.addAll(namedViews.values());
+                }
+                addTargets(sharedElementTransition, sharedElementTargets);
+
+                // Notify the start of the transition.
+                SharedElementCallback callback = isBack ?
+                        outFragment.mEnterTransitionCallback :
+                        inFragment.mEnterTransitionCallback;
+                ArrayList<String> names = new ArrayList<String>(namedViews.keySet());
+                ArrayList<View> views = new ArrayList<View>(namedViews.values());
+                callback.onSharedElementStart(names, views, null);
+            }
+
+            ArrayList<View> exitingViews = captureExitingViews(exitTransition, outFragment,
+                    namedViews);
+            if (exitingViews == null || exitingViews.isEmpty()) {
+                exitTransition = null;
+            }
+
+            // Set the epicenter of the exit transition
+            if (mSharedElementTargetNames != null && namedViews != null) {
+                View epicenterView = namedViews.get(mSharedElementTargetNames.get(0));
+                if (epicenterView != null) {
+                    if (exitTransition != null) {
+                        setEpicenter(exitTransition, epicenterView);
+                    }
+                    if (sharedElementTransition != null) {
+                        setEpicenter(sharedElementTransition, epicenterView);
+                    }
+                }
+            }
+
+            Transition transition = mergeTransitions(enterTransition, exitTransition,
+                    sharedElementTransition, inFragment, isBack);
+
+            if (transition != null) {
+                ArrayList<View> hiddenFragments = new ArrayList<View>();
+                ArrayList<View> enteringViews = addTransitionTargets(state, enterTransition,
+                        sharedElementTransition, transition, sceneRoot, inFragment, outFragment,
+                        hiddenFragments, isBack, sharedElementTargets);
+
+                transition.setNameOverrides(state.nameOverrides);
+                // We want to exclude hidden views later, so we need a non-null list in the
+                // transition now.
+                transition.excludeTarget(state.nonExistentView, true);
+                // Now exclude all currently hidden fragments.
+                excludeHiddenFragments(hiddenFragments, containerId, transition);
+                TransitionManager.beginDelayedTransition(sceneRoot, transition);
+                // Remove the view targeting after the transition starts
+                removeTargetedViewsFromTransitions(sceneRoot, state.nonExistentView,
+                        enterTransition, enteringViews, exitTransition, exitingViews,
+                        sharedElementTransition, sharedElementTargets, transition, hiddenFragments);
+            }
+        }
+    }
+
+    /**
+     * After the transition has started, remove all targets that we added to the transitions
+     * so that the transitions are left in a clean state.
+     */
+    private void removeTargetedViewsFromTransitions(
+            final ViewGroup sceneRoot, final View nonExistingView,
+            final Transition enterTransition, final ArrayList<View> enteringViews,
+            final Transition exitTransition, final ArrayList<View> exitingViews,
+            final Transition sharedElementTransition, final ArrayList<View> sharedElementTargets,
+            final Transition overallTransition, final ArrayList<View> hiddenViews) {
+        if (overallTransition != null) {
+            sceneRoot.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+                @Override
+                public boolean onPreDraw() {
+                    sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+                    if (enterTransition != null) {
+                        enterTransition.removeTarget(nonExistingView);
+                        removeTargets(enterTransition, enteringViews);
+                    }
+                    if (exitTransition != null) {
+                        removeTargets(exitTransition, exitingViews);
+                    }
+                    if (sharedElementTransition != null) {
+                        removeTargets(sharedElementTransition, sharedElementTargets);
+                    }
+                    int numViews = hiddenViews.size();
+                    for (int i = 0; i < numViews; i++) {
+                        overallTransition.excludeTarget(hiddenViews.get(i), false);
+                    }
+                    overallTransition.excludeTarget(nonExistingView, false);
+                    return true;
+                }
+            });
+        }
+    }
+
+    private static void removeTargets(Transition transition, ArrayList<View> views) {
+        int numViews = views.size();
+        for (int i = 0; i < numViews; i++) {
+            transition.removeTarget(views.get(i));
+        }
+    }
+
+    private static void addTargets(Transition transition, ArrayList<View> views) {
+        int numViews = views.size();
+        for (int i = 0; i < numViews; i++) {
+            transition.addTarget(views.get(i));
+        }
+    }
+
+    /**
+     * Remaps a name-to-View map, substituting different names for keys.
+     *
+     * @param inMap A list of keys found in the map, in the order in toGoInMap
+     * @param toGoInMap A list of keys to use for the new map, in the order of inMap
+     * @param namedViews The current mapping
+     * @return a new Map after it has been mapped with the new names as keys.
+     */
+    private static ArrayMap<String, View> remapNames(ArrayList<String> inMap,
+            ArrayList<String> toGoInMap, ArrayMap<String, View> namedViews) {
+        ArrayMap<String, View> remappedViews = new ArrayMap<String, View>();
+        if (!namedViews.isEmpty()) {
+            int numKeys = inMap.size();
+            for (int i = 0; i < numKeys; i++) {
+                View view = namedViews.get(inMap.get(i));
+
+                if (view != null) {
+                    remappedViews.put(toGoInMap.get(i), view);
+                }
+            }
+        }
+        return remappedViews;
+    }
+
+    /**
+     * Maps shared elements to views in the entering fragment.
+     *
+     * @param state The transition State as returned from {@link #beginTransition(
+     * android.util.SparseArray, android.util.SparseArray, boolean)}.
+     * @param inFragment The last fragment to be added.
+     * @param isBack true if this is popping the back stack or false if this is a
+     *               forward operation.
+     */
+    private ArrayMap<String, View> mapEnteringSharedElements(TransitionState state,
+            Fragment inFragment, boolean isBack) {
+        ArrayMap<String, View> namedViews = new ArrayMap<String, View>();
+        View root = inFragment.getView();
+        if (root != null) {
+            if (mSharedElementSourceNames != null) {
+                root.findNamedViews(namedViews);
+                if (isBack) {
+                    namedViews = remapNames(mSharedElementSourceNames,
+                            mSharedElementTargetNames, namedViews);
+                } else {
+                    namedViews.retainAll(mSharedElementTargetNames);
+                }
+            }
+        }
+        return namedViews;
+    }
+
+    private void excludeHiddenFragments(final ArrayList<View> hiddenFragmentViews, int containerId,
+            Transition transition) {
+        if (mManager.mAdded != null) {
+            for (int i = 0; i < mManager.mAdded.size(); i++) {
+                Fragment fragment = mManager.mAdded.get(i);
+                if (fragment.mView != null && fragment.mContainer != null &&
+                        fragment.mContainerId == containerId) {
+                    if (fragment.mHidden) {
+                        if (!hiddenFragmentViews.contains(fragment.mView)) {
+                            transition.excludeTarget(fragment.mView, true);
+                            hiddenFragmentViews.add(fragment.mView);
+                        }
+                    } else {
+                        transition.excludeTarget(fragment.mView, false);
+                        hiddenFragmentViews.remove(fragment.mView);
+                    }
+                }
+            }
+        }
+    }
+
+    private static void setEpicenter(Transition transition, View view) {
+        final Rect epicenter = new Rect();
+        view.getBoundsOnScreen(epicenter);
+
+        transition.setEpicenterCallback(new Transition.EpicenterCallback() {
+            @Override
+            public Rect onGetEpicenter(Transition transition) {
+                return epicenter;
+            }
+        });
+    }
+
+    private void setSharedElementEpicenter(Transition transition, final TransitionState state) {
+        transition.setEpicenterCallback(new Transition.EpicenterCallback() {
+            private Rect mEpicenter;
+
+            @Override
+            public Rect onGetEpicenter(Transition transition) {
+                if (mEpicenter == null && state.enteringEpicenterView != null) {
+                    mEpicenter = new Rect();
+                    state.enteringEpicenterView.getBoundsOnScreen(mEpicenter);
+                }
+                return mEpicenter;
+            }
+        });
+    }
+
+    public TransitionState popFromBackStack(boolean doStateMove, TransitionState state,
+            SparseArray<Fragment> firstOutFragments, SparseArray<Fragment> lastInFragments) {
         if (FragmentManagerImpl.DEBUG) {
             Log.v(TAG, "popFromBackStack: " + this);
             LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
@@ -698,6 +1511,14 @@
             pw.flush();
         }
 
+        if (state == null) {
+            if (firstOutFragments.size() != 0 || lastInFragments.size() != 0) {
+                state = beginTransition(firstOutFragments, lastInFragments, true);
+            }
+        } else if (!doStateMove) {
+            setNameOverrides(state, mSharedElementTargetNames, mSharedElementSourceNames);
+        }
+
         bumpBackStackNesting(-1);
 
         Op op = mTail;
@@ -709,7 +1530,8 @@
                     mManager.removeFragment(f,
                             FragmentManagerImpl.reverseTransit(mTransition),
                             mTransitionStyle);
-                } break;
+                }
+                break;
                 case OP_REPLACE: {
                     Fragment f = op.fragment;
                     if (f != null) {
@@ -719,42 +1541,48 @@
                                 mTransitionStyle);
                     }
                     if (op.removed != null) {
-                        for (int i=0; i<op.removed.size(); i++) {
+                        for (int i = 0; i < op.removed.size(); i++) {
                             Fragment old = op.removed.get(i);
                             old.mNextAnim = op.popEnterAnim;
                             mManager.addFragment(old, false);
                         }
                     }
-                } break;
+                }
+                break;
                 case OP_REMOVE: {
                     Fragment f = op.fragment;
                     f.mNextAnim = op.popEnterAnim;
                     mManager.addFragment(f, false);
-                } break;
+                }
+                break;
                 case OP_HIDE: {
                     Fragment f = op.fragment;
                     f.mNextAnim = op.popEnterAnim;
                     mManager.showFragment(f,
                             FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
-                } break;
+                }
+                break;
                 case OP_SHOW: {
                     Fragment f = op.fragment;
                     f.mNextAnim = op.popExitAnim;
                     mManager.hideFragment(f,
                             FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
-                } break;
+                }
+                break;
                 case OP_DETACH: {
                     Fragment f = op.fragment;
                     f.mNextAnim = op.popEnterAnim;
                     mManager.attachFragment(f,
                             FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
-                } break;
+                }
+                break;
                 case OP_ATTACH: {
                     Fragment f = op.fragment;
                     f.mNextAnim = op.popExitAnim;
                     mManager.detachFragment(f,
                             FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
-                } break;
+                }
+                break;
                 default: {
                     throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
                 }
@@ -766,12 +1594,70 @@
         if (doStateMove) {
             mManager.moveToState(mManager.mCurState,
                     FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle, true);
+            state = null;
         }
 
         if (mIndex >= 0) {
             mManager.freeBackStackIndex(mIndex);
             mIndex = -1;
         }
+        return state;
+    }
+
+    private static void setNameOverride(ArrayMap<String, String> overrides,
+            String source, String target) {
+        if (source != null && target != null && !source.equals(target)) {
+            for (int index = 0; index < overrides.size(); index++) {
+                if (source.equals(overrides.valueAt(index))) {
+                    overrides.setValueAt(index, target);
+                    return;
+                }
+            }
+            overrides.put(source, target);
+        }
+    }
+
+    private static void setNameOverrides(TransitionState state, ArrayList<String> sourceNames,
+            ArrayList<String> targetNames) {
+        if (sourceNames != null) {
+            for (int i = 0; i < sourceNames.size(); i++) {
+                String source = sourceNames.get(i);
+                String target = targetNames.get(i);
+                setNameOverride(state.nameOverrides, source, target);
+            }
+        }
+    }
+
+    private void setBackNameOverrides(TransitionState state, ArrayMap<String, View> namedViews,
+            boolean isEnd) {
+        int count = mSharedElementTargetNames.size();
+        for (int i = 0; i < count; i++) {
+            String source = mSharedElementSourceNames.get(i);
+            String originalTarget = mSharedElementTargetNames.get(i);
+            View view = namedViews.get(originalTarget);
+            if (view != null) {
+                String target = view.getTransitionName();
+                if (isEnd) {
+                    setNameOverride(state.nameOverrides, source, target);
+                } else {
+                    setNameOverride(state.nameOverrides, target, source);
+                }
+            }
+        }
+    }
+
+    private void setNameOverrides(TransitionState state, ArrayMap<String, View> namedViews,
+            boolean isEnd) {
+        int count = namedViews.size();
+        for (int i = 0; i < count; i++) {
+            String source = namedViews.keyAt(i);
+            String target = namedViews.valueAt(i).getTransitionName();
+            if (isEnd) {
+                setNameOverride(state.nameOverrides, source, target);
+            } else {
+                setNameOverride(state.nameOverrides, target, source);
+            }
+        }
     }
 
     public String getName() {
@@ -789,4 +1675,10 @@
     public boolean isEmpty() {
         return mNumOp == 0;
     }
+
+    public class TransitionState {
+        public ArrayMap<String, String> nameOverrides = new ArrayMap<String, String>();
+        public View enteringEpicenterView;
+        public View nonExistentView;
+    }
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index e49fd67..e9340eb 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -16,13 +16,21 @@
 
 package android.app;
 
+import android.app.usage.IUsageStatsManager;
+import android.app.usage.UsageStatsManager;
+import android.appwidget.AppWidgetManager;
 import android.os.Build;
+
+import android.service.persistentdata.IPersistentDataBlockService;
+import android.service.persistentdata.PersistentDataBlockManager;
+import com.android.internal.appwidget.IAppWidgetService;
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.util.Preconditions;
 
 import android.bluetooth.BluetoothManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ContextWrapper;
@@ -31,11 +39,15 @@
 import android.content.IntentFilter;
 import android.content.IIntentReceiver;
 import android.content.IntentSender;
+import android.content.IRestrictionsManager;
 import android.content.ReceiverCallNotAllowedException;
+import android.content.RestrictionsManager;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ILauncherApps;
 import android.content.pm.IPackageManager;
+import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.AssetManager;
@@ -51,8 +63,8 @@
 import android.hardware.ISerialManager;
 import android.hardware.SerialManager;
 import android.hardware.SystemSensorManager;
-import android.hardware.hdmi.HdmiCecManager;
-import android.hardware.hdmi.IHdmiCecService;
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.IHdmiControlService;
 import android.hardware.camera2.CameraManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.input.InputManager;
@@ -64,10 +76,17 @@
 import android.location.LocationManager;
 import android.media.AudioManager;
 import android.media.MediaRouter;
+import android.media.projection.MediaProjectionManager;
+import android.media.session.MediaSessionManager;
+import android.media.tv.ITvInputManager;
+import android.media.tv.TvInputManager;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
+import android.net.EthernetManager;
+import android.net.IEthernetManager;
 import android.net.INetworkPolicyManager;
 import android.net.NetworkPolicyManager;
+import android.net.NetworkScoreManager;
 import android.net.Uri;
 import android.net.nsd.INsdManager;
 import android.net.nsd.NsdManager;
@@ -75,7 +94,12 @@
 import android.net.wifi.WifiManager;
 import android.net.wifi.p2p.IWifiP2pManager;
 import android.net.wifi.p2p.WifiP2pManager;
+import android.net.wifi.IWifiScanner;
+import android.net.wifi.WifiScanner;
+import android.net.wifi.IRttManager;
+import android.net.wifi.RttManager;
 import android.nfc.NfcManager;
+import android.os.BatteryManager;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Debug;
@@ -98,6 +122,9 @@
 import android.os.storage.StorageManager;
 import android.print.IPrintManager;
 import android.print.PrintManager;
+import android.service.fingerprint.IFingerprintService;
+import android.service.fingerprint.FingerprintManager;
+import android.telecom.TelecomManager;
 import android.telephony.TelephonyManager;
 import android.content.ClipboardManager;
 import android.util.AndroidRuntimeException;
@@ -115,10 +142,13 @@
 import android.accounts.AccountManager;
 import android.accounts.IAccountManager;
 import android.app.admin.DevicePolicyManager;
+import android.app.job.IJobScheduler;
+import android.app.trust.TrustManager;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.os.IDropBoxManagerService;
+import com.android.internal.telecom.ITelecomService;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -220,7 +250,11 @@
     @GuardedBy("mSync")
     private File mFilesDir;
     @GuardedBy("mSync")
+    private File mNoBackupFilesDir;
+    @GuardedBy("mSync")
     private File mCacheDir;
+    @GuardedBy("mSync")
+    private File mCodeCacheDir;
 
     @GuardedBy("mSync")
     private File[] mExternalObbDirs;
@@ -228,6 +262,8 @@
     private File[] mExternalFilesDirs;
     @GuardedBy("mSync")
     private File[] mExternalCacheDirs;
+    @GuardedBy("mSync")
+    private File[] mExternalMediaDirs;
 
     private static final String[] EMPTY_FILE_LIST = {};
 
@@ -359,13 +395,12 @@
                     return new BluetoothManager(ctx);
                 }});
 
-        registerService(HDMI_CEC_SERVICE, new StaticServiceFetcher() {
+        registerService(HDMI_CONTROL_SERVICE, new StaticServiceFetcher() {
                 public Object createStaticService() {
-                    IBinder b = ServiceManager.getService(HDMI_CEC_SERVICE);
-                    return new HdmiCecManager(IHdmiCecService.Stub.asInterface(b));
+                    IBinder b = ServiceManager.getService(HDMI_CONTROL_SERVICE);
+                    return new HdmiControlManager(IHdmiControlService.Stub.asInterface(b));
                 }});
 
-
         registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
                     return new ClipboardManager(ctx.getOuterContext(),
@@ -375,8 +410,7 @@
         registerService(CONNECTIVITY_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
                     IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
-                    return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b),
-                        ctx.getPackageName());
+                    return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
                 }});
 
         registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
@@ -395,6 +429,11 @@
                     return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
                 }});
 
+        registerService(BATTERY_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
+                    return new BatteryManager();
+                }});
+
         registerService(NFC_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
                     return new NfcManager(ctx);
@@ -463,7 +502,8 @@
                                         outerContext.getApplicationInfo().targetSdkVersion,
                                         com.android.internal.R.style.Theme_Dialog,
                                         com.android.internal.R.style.Theme_Holo_Dialog,
-                                        com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
+                                        com.android.internal.R.style.Theme_DeviceDefault_Dialog,
+                                        com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog)),
                         ctx.mMainThread.getHandler());
                 }});
 
@@ -482,6 +522,9 @@
                 public Object createService(ContextImpl ctx) {
                     IBinder b = ServiceManager.getService(POWER_SERVICE);
                     IPowerManager service = IPowerManager.Stub.asInterface(b);
+                    if (service == null) {
+                        Log.wtf(TAG, "Failed to get power manager service.");
+                    }
                     return new PowerManager(ctx.getOuterContext(),
                             service, ctx.mMainThread.getHandler());
                 }});
@@ -519,6 +562,11 @@
                     return new TelephonyManager(ctx.getOuterContext());
                 }});
 
+        registerService(TELECOM_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
+                    return new TelecomManager(ctx.getOuterContext());
+                }});
+
         registerService(UI_MODE_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
                     return new UiModeManager();
@@ -557,6 +605,27 @@
                     return new WifiP2pManager(service);
                 }});
 
+        registerService(WIFI_SCANNING_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder b = ServiceManager.getService(WIFI_SCANNING_SERVICE);
+                IWifiScanner service = IWifiScanner.Stub.asInterface(b);
+                return new WifiScanner(ctx.getOuterContext(), service);
+            }});
+
+        registerService(WIFI_RTT_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder b = ServiceManager.getService(WIFI_RTT_SERVICE);
+                IRttManager service = IRttManager.Stub.asInterface(b);
+                return new RttManager(ctx.getOuterContext(), service);
+            }});
+
+        registerService(ETHERNET_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
+                    IBinder b = ServiceManager.getService(ETHERNET_SERVICE);
+                    IEthernetManager service = IEthernetManager.Stub.asInterface(b);
+                    return new EthernetManager(ctx.getOuterContext(), service);
+                }});
+
         registerService(WINDOW_SERVICE, new ServiceFetcher() {
                 Display mDefaultDisplay;
                 public Object getService(ContextImpl ctx) {
@@ -592,6 +661,21 @@
             }
         });
 
+        registerService(LAUNCHER_APPS_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder b = ServiceManager.getService(LAUNCHER_APPS_SERVICE);
+                ILauncherApps service = ILauncherApps.Stub.asInterface(b);
+                return new LauncherApps(ctx, service);
+            }
+        });
+
+        registerService(RESTRICTIONS_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder b = ServiceManager.getService(RESTRICTIONS_SERVICE);
+                IRestrictionsManager service = IRestrictionsManager.Stub.asInterface(b);
+                return new RestrictionsManager(ctx, service);
+            }
+        });
         registerService(PRINT_SERVICE, new ServiceFetcher() {
             public Object createService(ContextImpl ctx) {
                 IBinder iBinder = ServiceManager.getService(Context.PRINT_SERVICE);
@@ -604,6 +688,81 @@
             public Object createService(ContextImpl ctx) {
                 return new ConsumerIrManager(ctx);
             }});
+
+        registerService(MEDIA_SESSION_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                return new MediaSessionManager(ctx);
+            }
+        });
+
+        registerService(TRUST_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder b = ServiceManager.getService(TRUST_SERVICE);
+                return new TrustManager(b);
+            }
+        });
+
+        registerService(FINGERPRINT_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder binder = ServiceManager.getService(FINGERPRINT_SERVICE);
+                IFingerprintService service = IFingerprintService.Stub.asInterface(binder);
+                return new FingerprintManager(ctx.getOuterContext(), service);
+            }
+        });
+
+        registerService(TV_INPUT_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder iBinder = ServiceManager.getService(TV_INPUT_SERVICE);
+                ITvInputManager service = ITvInputManager.Stub.asInterface(iBinder);
+                return new TvInputManager(service, UserHandle.myUserId());
+            }
+        });
+
+        registerService(NETWORK_SCORE_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                return new NetworkScoreManager(ctx);
+            }
+        });
+
+        registerService(USAGE_STATS_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder iBinder = ServiceManager.getService(USAGE_STATS_SERVICE);
+                IUsageStatsManager service = IUsageStatsManager.Stub.asInterface(iBinder);
+                return new UsageStatsManager(ctx.getOuterContext(), service);
+            }
+        });
+
+        registerService(JOB_SCHEDULER_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder b = ServiceManager.getService(JOB_SCHEDULER_SERVICE);
+                return new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b));
+        }});
+
+        registerService(PERSISTENT_DATA_BLOCK_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder b = ServiceManager.getService(PERSISTENT_DATA_BLOCK_SERVICE);
+                IPersistentDataBlockService persistentDataBlockService =
+                        IPersistentDataBlockService.Stub.asInterface(b);
+                if (persistentDataBlockService != null) {
+                    return new PersistentDataBlockManager(persistentDataBlockService);
+                } else {
+                    // not supported
+                    return null;
+                }
+            }
+        });
+
+        registerService(MEDIA_PROJECTION_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
+                    return new MediaProjectionManager(ctx);
+                }
+        });
+
+        registerService(APPWIDGET_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder b = ServiceManager.getService(APPWIDGET_SERVICE);
+                return new AppWidgetManager(ctx, IAppWidgetService.Stub.asInterface(b));
+            }});
     }
 
     static ContextImpl getImpl(Context context) {
@@ -826,27 +985,42 @@
         return f.delete();
     }
 
+    // Common-path handling of app data dir creation
+    private static File createFilesDirLocked(File file) {
+        if (!file.exists()) {
+            if (!file.mkdirs()) {
+                if (file.exists()) {
+                    // spurious failure; probably racing with another process for this app
+                    return file;
+                }
+                Log.w(TAG, "Unable to create files subdir " + file.getPath());
+                return null;
+            }
+            FileUtils.setPermissions(
+                    file.getPath(),
+                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
+                    -1, -1);
+        }
+        return file;
+    }
+
     @Override
     public File getFilesDir() {
         synchronized (mSync) {
             if (mFilesDir == null) {
                 mFilesDir = new File(getDataDirFile(), "files");
             }
-            if (!mFilesDir.exists()) {
-                if(!mFilesDir.mkdirs()) {
-                    if (mFilesDir.exists()) {
-                        // spurious failure; probably racing with another process for this app
-                        return mFilesDir;
-                    }
-                    Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
-                    return null;
-                }
-                FileUtils.setPermissions(
-                        mFilesDir.getPath(),
-                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
-                        -1, -1);
+            return createFilesDirLocked(mFilesDir);
+        }
+    }
+
+    @Override
+    public File getNoBackupFilesDir() {
+        synchronized (mSync) {
+            if (mNoBackupFilesDir == null) {
+                mNoBackupFilesDir = new File(getDataDirFile(), "no_backup");
             }
-            return mFilesDir;
+            return createFilesDirLocked(mNoBackupFilesDir);
         }
     }
 
@@ -898,22 +1072,18 @@
             if (mCacheDir == null) {
                 mCacheDir = new File(getDataDirFile(), "cache");
             }
-            if (!mCacheDir.exists()) {
-                if(!mCacheDir.mkdirs()) {
-                    if (mCacheDir.exists()) {
-                        // spurious failure; probably racing with another process for this app
-                        return mCacheDir;
-                    }
-                    Log.w(TAG, "Unable to create cache directory " + mCacheDir.getAbsolutePath());
-                    return null;
-                }
-                FileUtils.setPermissions(
-                        mCacheDir.getPath(),
-                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
-                        -1, -1);
-            }
+            return createFilesDirLocked(mCacheDir);
         }
-        return mCacheDir;
+    }
+
+    @Override
+    public File getCodeCacheDir() {
+        synchronized (mSync) {
+            if (mCodeCacheDir == null) {
+                mCodeCacheDir = new File(getDataDirFile(), "code_cache");
+            }
+            return createFilesDirLocked(mCodeCacheDir);
+        }
     }
 
     @Override
@@ -935,6 +1105,18 @@
     }
 
     @Override
+    public File[] getExternalMediaDirs() {
+        synchronized (mSync) {
+            if (mExternalMediaDirs == null) {
+                mExternalMediaDirs = Environment.buildExternalStorageAppMediaDirs(getPackageName());
+            }
+
+            // Create dirs if needed
+            return ensureDirsExistOrFilter(mExternalMediaDirs);
+        }
+    }
+
+    @Override
     public File getFileStreamPath(String name) {
         return makeFilename(getFilesDir(), name);
     }
@@ -1065,7 +1247,7 @@
             ActivityManagerNative.getDefault().startActivityAsUser(
                 mMainThread.getApplicationThread(), getBasePackageName(), intent,
                 intent.resolveTypeIfNeeded(getContentResolver()),
-                null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, options,
+                null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options,
                 user.getIdentifier());
         } catch (RemoteException re) {
         }
@@ -1265,6 +1447,15 @@
     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
             String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
             int initialCode, String initialData, Bundle initialExtras) {
+        sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE,
+                resultReceiver, scheduler, initialCode, initialData, initialExtras);
+    }
+
+    @Override
+    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
+            Handler scheduler,
+            int initialCode, String initialData, Bundle initialExtras) {
         IIntentReceiver rd = null;
         if (resultReceiver != null) {
             if (mPackageInfo != null) {
@@ -1288,7 +1479,7 @@
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, receiverPermission,
-                    AppOpsManager.OP_NONE, true, false, user.getIdentifier());
+                    appOp, true, false, user.getIdentifier());
         } catch (RemoteException e) {
         }
     }
@@ -1480,13 +1671,13 @@
 
     private void validateServiceIntent(Intent service) {
         if (service.getComponent() == null && service.getPackage() == null) {
-            if (true || getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
+            if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
+                IllegalArgumentException ex = new IllegalArgumentException(
+                        "Service Intent must be explicit: " + service);
+                throw ex;
+            } else {
                 Log.w(TAG, "Implicit intents with startService are not safe: " + service
                         + " " + Debug.getCallers(2, 3));
-                //IllegalArgumentException ex = new IllegalArgumentException(
-                //        "Service Intent must be explicit: " + service);
-                //Log.e(TAG, "This will become an error", ex);
-                //throw ex;
             }
         }
     }
@@ -1740,8 +1931,8 @@
     public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
          try {
             ActivityManagerNative.getDefault().grantUriPermission(
-                    mMainThread.getApplicationThread(), toPackage, uri,
-                    modeFlags);
+                    mMainThread.getApplicationThread(), toPackage,
+                    ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
         } catch (RemoteException e) {
         }
     }
@@ -1750,8 +1941,8 @@
     public void revokeUriPermission(Uri uri, int modeFlags) {
          try {
             ActivityManagerNative.getDefault().revokeUriPermission(
-                    mMainThread.getApplicationThread(), uri,
-                    modeFlags);
+                    mMainThread.getApplicationThread(),
+                    ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
         } catch (RemoteException e) {
         }
     }
@@ -1760,12 +1951,17 @@
     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
         try {
             return ActivityManagerNative.getDefault().checkUriPermission(
-                    uri, pid, uid, modeFlags);
+                    ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
+                    resolveUserId(uri));
         } catch (RemoteException e) {
             return PackageManager.PERMISSION_DENIED;
         }
     }
 
+    private int resolveUserId(Uri uri) {
+        return ContentProvider.getUserIdFromUri(uri, getUserId());
+    }
+
     @Override
     public int checkCallingUriPermission(Uri uri, int modeFlags) {
         int pid = Binder.getCallingPid();
@@ -1809,17 +2005,26 @@
     }
 
     private String uriModeFlagToString(int uriModeFlags) {
-        switch (uriModeFlags) {
-            case Intent.FLAG_GRANT_READ_URI_PERMISSION |
-                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
-                return "read and write";
-            case Intent.FLAG_GRANT_READ_URI_PERMISSION:
-                return "read";
-            case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
-                return "write";
+        StringBuilder builder = new StringBuilder();
+        if ((uriModeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+            builder.append("read and ");
         }
-        throw new IllegalArgumentException(
-                "Unknown permission mode flags: " + uriModeFlags);
+        if ((uriModeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+            builder.append("write and ");
+        }
+        if ((uriModeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
+            builder.append("persistable and ");
+        }
+        if ((uriModeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
+            builder.append("prefix and ");
+        }
+
+        if (builder.length() > 5) {
+            builder.setLength(builder.length() - 5);
+            return builder.toString();
+        } else {
+            throw new IllegalArgumentException("Unknown permission mode flags: " + uriModeFlags);
+        }
     }
 
     private void enforceForUri(
@@ -1887,6 +2092,25 @@
     }
 
     @Override
+    public Context createApplicationContext(ApplicationInfo application, int flags)
+            throws NameNotFoundException {
+        LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
+                flags | CONTEXT_REGISTER_PACKAGE);
+        if (pi != null) {
+            final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
+            ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
+                    new UserHandle(UserHandle.getUserId(application.uid)), restricted,
+                    mDisplay, mOverrideConfiguration);
+            if (c.mResources != null) {
+                return c;
+            }
+        }
+
+        throw new PackageManager.NameNotFoundException(
+                "Application package " + application.packageName + " not found");
+    }
+
+    @Override
     public Context createPackageContext(String packageName, int flags)
             throws NameNotFoundException {
         return createPackageContextAsUser(packageName, flags,
@@ -1903,7 +2127,7 @@
         }
 
         LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
-                flags, user.getIdentifier());
+                flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
         if (pi != null) {
             ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
                     user, restricted, mDisplay, mOverrideConfiguration);
@@ -2013,7 +2237,6 @@
         mUser = user;
 
         mPackageInfo = packageInfo;
-        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
         mResourcesManager = ResourcesManager.getInstance();
         mDisplay = display;
         mOverrideConfiguration = overrideConfiguration;
@@ -2036,8 +2259,9 @@
                     || overrideConfiguration != null
                     || (compatInfo != null && compatInfo.applicationScale
                             != resources.getCompatibilityInfo().applicationScale)) {
-                resources = mResourcesManager.getTopLevelResources(
-                        packageInfo.getResDir(), packageInfo.getOverlayDirs(), displayId,
+                resources = mResourcesManager.getTopLevelResources(packageInfo.getResDir(),
+                        packageInfo.getSplitResDirs(), packageInfo.getOverlayDirs(),
+                        packageInfo.getApplicationInfo().sharedLibraryFiles, displayId,
                         overrideConfiguration, compatInfo, activityToken);
             }
         }
@@ -2059,10 +2283,12 @@
                 mOpPackageName = mBasePackageName;
             }
         }
+
+        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
     }
 
-    void installSystemApplicationInfo(ApplicationInfo info) {
-        mPackageInfo.installSystemApplicationInfo(info);
+    void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
+        mPackageInfo.installSystemApplicationInfo(info, classLoader);
     }
 
     final void scheduleFinalCleanup(String who, String what) {
@@ -2192,12 +2418,16 @@
 
         @Override
         protected IContentProvider acquireProvider(Context context, String auth) {
-            return mMainThread.acquireProvider(context, auth, mUser.getIdentifier(), true);
+            return mMainThread.acquireProvider(context,
+                    ContentProvider.getAuthorityWithoutUserId(auth),
+                    resolveUserIdFromAuthority(auth), true);
         }
 
         @Override
         protected IContentProvider acquireExistingProvider(Context context, String auth) {
-            return mMainThread.acquireExistingProvider(context, auth, mUser.getIdentifier(), true);
+            return mMainThread.acquireExistingProvider(context,
+                    ContentProvider.getAuthorityWithoutUserId(auth),
+                    resolveUserIdFromAuthority(auth), true);
         }
 
         @Override
@@ -2207,7 +2437,9 @@
 
         @Override
         protected IContentProvider acquireUnstableProvider(Context c, String auth) {
-            return mMainThread.acquireProvider(c, auth, mUser.getIdentifier(), false);
+            return mMainThread.acquireProvider(c,
+                    ContentProvider.getAuthorityWithoutUserId(auth),
+                    resolveUserIdFromAuthority(auth), false);
         }
 
         @Override
@@ -2224,5 +2456,10 @@
         public void appNotRespondingViaProvider(IContentProvider icp) {
             mMainThread.appNotRespondingViaProvider(icp.asBinder());
         }
+
+        /** @hide */
+        protected int resolveUserIdFromAuthority(String auth) {
+            return ContentProvider.getUserIdFromAuthority(auth, mUser.getIdentifier());
+        }
     }
 }
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index d168800..f79d32b 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -21,10 +21,13 @@
 import android.content.DialogInterface.OnClickListener;
 import android.os.Bundle;
 import android.text.format.DateUtils;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.Button;
 import android.widget.DatePicker;
 import android.widget.DatePicker.OnDateChangedListener;
+import android.widget.DatePicker.ValidationCallback;
 
 import com.android.internal.R;
 
@@ -44,7 +47,7 @@
     private static final String DAY = "day";
 
     private final DatePicker mDatePicker;
-    private final OnDateSetListener mCallBack;
+    private final OnDateSetListener mDateSetListener;
     private final Calendar mCalendar;
 
     private boolean mTitleNeedsUpdate = true;
@@ -79,49 +82,65 @@
         this(context, 0, callBack, year, monthOfYear, dayOfMonth);
     }
 
+    static int resolveDialogTheme(Context context, int resid) {
+        if (resid == 0) {
+            final TypedValue outValue = new TypedValue();
+            context.getTheme().resolveAttribute(R.attr.datePickerDialogTheme, outValue, true);
+            return outValue.resourceId;
+        } else {
+            return resid;
+        }
+    }
+
     /**
      * @param context The context the dialog is to run in.
      * @param theme the theme to apply to this dialog
-     * @param callBack How the parent is notified that the date is set.
+     * @param listener How the parent is notified that the date is set.
      * @param year The initial year of the dialog.
      * @param monthOfYear The initial month of the dialog.
      * @param dayOfMonth The initial day of the dialog.
      */
-    public DatePickerDialog(Context context,
-            int theme,
-            OnDateSetListener callBack,
-            int year,
-            int monthOfYear,
-            int dayOfMonth) {
-        super(context, theme);
+    public DatePickerDialog(Context context, int theme, OnDateSetListener listener, int year,
+            int monthOfYear, int dayOfMonth) {
+        super(context, resolveDialogTheme(context, theme));
 
-        mCallBack = callBack;
-
+        mDateSetListener = listener;
         mCalendar = Calendar.getInstance();
 
-        Context themeContext = getContext();
-        setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this);
-        setIcon(0);
-
-        LayoutInflater inflater =
-                (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        View view = inflater.inflate(R.layout.date_picker_dialog, null);
+        final Context themeContext = getContext();
+        final LayoutInflater inflater = LayoutInflater.from(themeContext);
+        final View view = inflater.inflate(R.layout.date_picker_dialog, null);
         setView(view);
+        setButton(BUTTON_POSITIVE, themeContext.getString(R.string.ok), this);
+        setButton(BUTTON_NEGATIVE, themeContext.getString(R.string.cancel), this);
+        setButtonPanelLayoutHint(LAYOUT_HINT_SIDE);
+
         mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
         mDatePicker.init(year, monthOfYear, dayOfMonth, this);
-        updateTitle(year, monthOfYear, dayOfMonth);
+        mDatePicker.setValidationCallback(mValidationCallback);
     }
 
-    public void onClick(DialogInterface dialog, int which) {
-        tryNotifyDateSet();
-    }
-
-    public void onDateChanged(DatePicker view, int year,
-            int month, int day) {
+    @Override
+    public void onDateChanged(DatePicker view, int year, int month, int day) {
         mDatePicker.init(year, month, day, this);
         updateTitle(year, month, day);
     }
 
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        switch (which) {
+            case BUTTON_POSITIVE:
+                if (mDateSetListener != null) {
+                    mDateSetListener.onDateSet(mDatePicker, mDatePicker.getYear(),
+                            mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
+                }
+                break;
+            case BUTTON_NEGATIVE:
+                cancel();
+                break;
+        }
+    }
+
     /**
      * Gets the {@link DatePicker} contained in this dialog.
      *
@@ -142,20 +161,6 @@
         mDatePicker.updateDate(year, monthOfYear, dayOfMonth);
     }
 
-    private void tryNotifyDateSet() {
-        if (mCallBack != null) {
-            mDatePicker.clearFocus();
-            mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
-                    mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
-        }
-    }
-
-    @Override
-    protected void onStop() {
-        tryNotifyDateSet();
-        super.onStop();
-    }
-
     private void updateTitle(int year, int month, int day) {
         if (!mDatePicker.getCalendarViewShown()) {
             mCalendar.set(Calendar.YEAR, year);
@@ -180,7 +185,7 @@
 
     @Override
     public Bundle onSaveInstanceState() {
-        Bundle state = super.onSaveInstanceState();
+        final Bundle state = super.onSaveInstanceState();
         state.putInt(YEAR, mDatePicker.getYear());
         state.putInt(MONTH, mDatePicker.getMonth());
         state.putInt(DAY, mDatePicker.getDayOfMonth());
@@ -190,9 +195,19 @@
     @Override
     public void onRestoreInstanceState(Bundle savedInstanceState) {
         super.onRestoreInstanceState(savedInstanceState);
-        int year = savedInstanceState.getInt(YEAR);
-        int month = savedInstanceState.getInt(MONTH);
-        int day = savedInstanceState.getInt(DAY);
+        final int year = savedInstanceState.getInt(YEAR);
+        final int month = savedInstanceState.getInt(MONTH);
+        final int day = savedInstanceState.getInt(DAY);
         mDatePicker.init(year, month, day, this);
     }
+
+    private final ValidationCallback mValidationCallback = new ValidationCallback() {
+        @Override
+        public void onValidationChanged(boolean valid) {
+            final Button positive = getButton(BUTTON_POSITIVE);
+            if (positive != null) {
+                positive.setEnabled(valid);
+            }
+        }
+    };
 }
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 7a362df..12d4513 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -17,8 +17,7 @@
 package android.app;
 
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import com.android.internal.app.ActionBarImpl;
+import com.android.internal.app.WindowDecorActionBar;
 import com.android.internal.policy.PolicyManager;
 
 import android.content.ComponentName;
@@ -88,7 +87,7 @@
     final WindowManager mWindowManager;
     Window mWindow;
     View mDecor;
-    private ActionBarImpl mActionBar;
+    private ActionBar mActionBar;
     /**
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
@@ -241,6 +240,18 @@
     }
 
     /**
+     * Forces immediate creation of the dialog.
+     * <p>
+     * Note that you should not override this method to perform dialog creation.
+     * Rather, override {@link #onCreate(Bundle)}.
+     */
+    public void create() {
+        if (!mCreated) {
+            dispatchOnCreate(null);
+        }
+    }
+
+    /**
      * Start the dialog and display it on screen.  The window is placed in the
      * application layer and opaque.  Note that you should not override this
      * method to do initialization when the dialog is shown, instead implement
@@ -270,7 +281,7 @@
             final ApplicationInfo info = mContext.getApplicationInfo();
             mWindow.setDefaultIcon(info.icon);
             mWindow.setDefaultLogo(info.logo);
-            mActionBar = new ActionBarImpl(this);
+            mActionBar = new WindowDecorActionBar(this);
         }
 
         WindowManager.LayoutParams l = mWindow.getAttributes();
@@ -458,11 +469,12 @@
     }
 
     /**
-     * Finds a view that was identified by the id attribute from the XML that
-     * was processed in {@link #onStart}.
+     * Finds a child view with the given identifier. Returns null if the
+     * specified child view does not exist or the dialog has not yet been fully
+     * created (for example, via {@link #show()} or {@link #create()}).
      *
      * @param id the identifier of the view to find
-     * @return The view if found or null otherwise.
+     * @return The view with the given id or null.
      */
     public View findViewById(int id) {
         return mWindow.findViewById(id);
@@ -481,7 +493,7 @@
     /**
      * Set the screen content to an explicit view.  This view is placed
      * directly into the screen's view hierarchy.  It can itself be a complex
-     * view hierarhcy.
+     * view hierarchy.
      * 
      * @param view The desired content to display.
      */
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
new file mode 100644
index 0000000..add67f2
--- /dev/null
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -0,0 +1,663 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.graphics.Matrix;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.text.TextUtils;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+import android.util.ArrayMap;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroupOverlay;
+import android.view.ViewTreeObserver;
+import android.view.Window;
+
+import java.util.ArrayList;
+
+/**
+ * This ActivityTransitionCoordinator is created by the Activity to manage
+ * the enter scene and shared element transfer into the Scene, either during
+ * launch of an Activity or returning from a launched Activity.
+ */
+class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
+    private static final String TAG = "EnterTransitionCoordinator";
+
+    private static final int MIN_ANIMATION_FRAMES = 2;
+
+    private boolean mSharedElementTransitionStarted;
+    private Activity mActivity;
+    private boolean mHasStopped;
+    private boolean mIsCanceled;
+    private ObjectAnimator mBackgroundAnimator;
+    private boolean mIsExitTransitionComplete;
+    private boolean mIsReadyForTransition;
+    private Bundle mSharedElementsBundle;
+    private boolean mWasOpaque;
+    private boolean mAreViewsReady;
+    private boolean mIsViewsTransitionStarted;
+    private boolean mIsViewsTransitionComplete;
+    private boolean mIsSharedElementTransitionComplete;
+    private ArrayList<Matrix> mSharedElementParentMatrices;
+    private Transition mEnterViewsTransition;
+
+    public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
+            ArrayList<String> sharedElementNames, boolean isReturning) {
+        super(activity.getWindow(), sharedElementNames,
+                getListener(activity, isReturning), isReturning);
+        mActivity = activity;
+        setResultReceiver(resultReceiver);
+        prepareEnter();
+        Bundle resultReceiverBundle = new Bundle();
+        resultReceiverBundle.putParcelable(KEY_REMOTE_RECEIVER, this);
+        mResultReceiver.send(MSG_SET_REMOTE_RECEIVER, resultReceiverBundle);
+        final View decorView = getDecor();
+        if (decorView != null) {
+            decorView.getViewTreeObserver().addOnPreDrawListener(
+                    new ViewTreeObserver.OnPreDrawListener() {
+                        @Override
+                        public boolean onPreDraw() {
+                            if (mIsReadyForTransition) {
+                                decorView.getViewTreeObserver().removeOnPreDrawListener(this);
+                            }
+                            return mIsReadyForTransition;
+                        }
+                    });
+        }
+    }
+
+    public void viewInstancesReady(ArrayList<String> accepted, ArrayList<String> localNames,
+            ArrayList<View> localViews) {
+        boolean remap = false;
+        for (int i = 0; i < localViews.size(); i++) {
+            View view = localViews.get(i);
+            if (!TextUtils.equals(view.getTransitionName(), localNames.get(i))
+                    || !view.isAttachedToWindow()) {
+                remap = true;
+                break;
+            }
+        }
+        if (remap) {
+            triggerViewsReady(mapNamedElements(accepted, localNames));
+        } else {
+            triggerViewsReady(mapSharedElements(accepted, localViews));
+        }
+    }
+
+    public void namedViewsReady(ArrayList<String> accepted, ArrayList<String> localNames) {
+        triggerViewsReady(mapNamedElements(accepted, localNames));
+    }
+
+    public Transition getEnterViewsTransition() {
+        return mEnterViewsTransition;
+    }
+
+    @Override
+    protected void viewsReady(ArrayMap<String, View> sharedElements) {
+        super.viewsReady(sharedElements);
+        mIsReadyForTransition = true;
+        hideViews(mSharedElements);
+        if (getViewsTransition() != null && mTransitioningViews != null) {
+            hideViews(mTransitioningViews);
+        }
+        if (mIsReturning) {
+            sendSharedElementDestination();
+        } else {
+            setSharedElementMatrices();
+            moveSharedElementsToOverlay();
+        }
+        if (mSharedElementsBundle != null) {
+            onTakeSharedElements();
+        }
+    }
+
+    private void triggerViewsReady(final ArrayMap<String, View> sharedElements) {
+        if (mAreViewsReady) {
+            return;
+        }
+        mAreViewsReady = true;
+        // Ensure the views have been laid out before capturing the views -- we need the epicenter.
+        if (sharedElements.isEmpty() || !sharedElements.valueAt(0).isLayoutRequested()) {
+            viewsReady(sharedElements);
+        } else {
+            final View sharedElement = sharedElements.valueAt(0);
+            sharedElement.getViewTreeObserver()
+                    .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+                @Override
+                public boolean onPreDraw() {
+                    sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
+                    viewsReady(sharedElements);
+                    return true;
+                }
+            });
+        }
+    }
+
+    private ArrayMap<String, View> mapNamedElements(ArrayList<String> accepted,
+            ArrayList<String> localNames) {
+        ArrayMap<String, View> sharedElements = new ArrayMap<String, View>();
+        ViewGroup decorView = getDecor();
+        if (decorView != null) {
+            decorView.findNamedViews(sharedElements);
+        }
+        if (accepted != null) {
+            for (int i = 0; i < localNames.size(); i++) {
+                String localName = localNames.get(i);
+                String acceptedName = accepted.get(i);
+                if (localName != null && !localName.equals(acceptedName)) {
+                    View view = sharedElements.remove(localName);
+                    if (view != null) {
+                        sharedElements.put(acceptedName, view);
+                    }
+                }
+            }
+        }
+        return sharedElements;
+    }
+
+    private void sendSharedElementDestination() {
+        boolean allReady;
+        final View decorView = getDecor();
+        if (allowOverlappingTransitions() && getEnterViewsTransition() != null) {
+            allReady = false;
+        } else if (decorView == null) {
+            allReady = true;
+        } else {
+            allReady = !decorView.isLayoutRequested();
+            if (allReady) {
+                for (int i = 0; i < mSharedElements.size(); i++) {
+                    if (mSharedElements.get(i).isLayoutRequested()) {
+                        allReady = false;
+                        break;
+                    }
+                }
+            }
+        }
+        if (allReady) {
+            Bundle state = captureSharedElementState();
+            setSharedElementMatrices();
+            moveSharedElementsToOverlay();
+            mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
+        } else if (decorView != null) {
+            decorView.getViewTreeObserver()
+                    .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+                        @Override
+                        public boolean onPreDraw() {
+                            decorView.getViewTreeObserver().removeOnPreDrawListener(this);
+                            if (mResultReceiver != null) {
+                                Bundle state = captureSharedElementState();
+                                setSharedElementMatrices();
+                                moveSharedElementsToOverlay();
+                                mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
+                            }
+                            return true;
+                        }
+                    });
+        }
+        if (allowOverlappingTransitions()) {
+            startEnterTransitionOnly();
+        }
+    }
+
+    private static SharedElementCallback getListener(Activity activity, boolean isReturning) {
+        return isReturning ? activity.mExitTransitionListener : activity.mEnterTransitionListener;
+    }
+
+    @Override
+    protected void onReceiveResult(int resultCode, Bundle resultData) {
+        switch (resultCode) {
+            case MSG_TAKE_SHARED_ELEMENTS:
+                if (!mIsCanceled) {
+                    mSharedElementsBundle = resultData;
+                    onTakeSharedElements();
+                }
+                break;
+            case MSG_EXIT_TRANSITION_COMPLETE:
+                if (!mIsCanceled) {
+                    mIsExitTransitionComplete = true;
+                    if (mSharedElementTransitionStarted) {
+                        onRemoteExitTransitionComplete();
+                    }
+                }
+                break;
+            case MSG_CANCEL:
+                cancel();
+                break;
+        }
+    }
+
+    private void cancel() {
+        if (!mIsCanceled) {
+            mIsCanceled = true;
+            if (getViewsTransition() == null || mIsViewsTransitionStarted) {
+                showViews(mSharedElements, true);
+            } else if (mTransitioningViews != null) {
+                mTransitioningViews.addAll(mSharedElements);
+            }
+            mSharedElementNames.clear();
+            mSharedElements.clear();
+            mAllSharedElementNames.clear();
+            startSharedElementTransition(null);
+            onRemoteExitTransitionComplete();
+        }
+    }
+
+    public boolean isReturning() {
+        return mIsReturning;
+    }
+
+    protected void prepareEnter() {
+        ViewGroup decorView = getDecor();
+        if (mActivity == null || decorView == null) {
+            return;
+        }
+        mActivity.overridePendingTransition(0, 0);
+        if (!mIsReturning) {
+            mWasOpaque = mActivity.convertToTranslucent(null, null);
+            Drawable background = decorView.getBackground();
+            if (background != null) {
+                getWindow().setBackgroundDrawable(null);
+                background = background.mutate();
+                background.setAlpha(0);
+                getWindow().setBackgroundDrawable(background);
+            }
+        } else {
+            mActivity = null; // all done with it now.
+        }
+    }
+
+    @Override
+    protected Transition getViewsTransition() {
+        Window window = getWindow();
+        if (window == null) {
+            return null;
+        }
+        if (mIsReturning) {
+            return window.getReenterTransition();
+        } else {
+            return window.getEnterTransition();
+        }
+    }
+
+    protected Transition getSharedElementTransition() {
+        Window window = getWindow();
+        if (window == null) {
+            return null;
+        }
+        if (mIsReturning) {
+            return window.getSharedElementReenterTransition();
+        } else {
+            return window.getSharedElementEnterTransition();
+        }
+    }
+
+    private void startSharedElementTransition(Bundle sharedElementState) {
+        ViewGroup decorView = getDecor();
+        if (decorView == null) {
+            return;
+        }
+        // Remove rejected shared elements
+        ArrayList<String> rejectedNames = new ArrayList<String>(mAllSharedElementNames);
+        rejectedNames.removeAll(mSharedElementNames);
+        ArrayList<View> rejectedSnapshots = createSnapshots(sharedElementState, rejectedNames);
+        if (mListener != null) {
+            mListener.onRejectSharedElements(rejectedSnapshots);
+        }
+        startRejectedAnimations(rejectedSnapshots);
+
+        // Now start shared element transition
+        ArrayList<View> sharedElementSnapshots = createSnapshots(sharedElementState,
+                mSharedElementNames);
+        showViews(mSharedElements, true);
+        scheduleSetSharedElementEnd(sharedElementSnapshots);
+        ArrayList<SharedElementOriginalState> originalImageViewState =
+                setSharedElementState(sharedElementState, sharedElementSnapshots);
+        requestLayoutForSharedElements();
+
+        boolean startEnterTransition = allowOverlappingTransitions() && !mIsReturning;
+        boolean startSharedElementTransition = true;
+        setGhostVisibility(View.INVISIBLE);
+        scheduleGhostVisibilityChange(View.INVISIBLE);
+        Transition transition = beginTransition(decorView, startEnterTransition,
+                startSharedElementTransition);
+        scheduleGhostVisibilityChange(View.VISIBLE);
+        setGhostVisibility(View.VISIBLE);
+
+        if (startEnterTransition) {
+            startEnterTransition(transition);
+        }
+
+        setOriginalSharedElementState(mSharedElements, originalImageViewState);
+
+        if (mResultReceiver != null) {
+            // We can't trust that the view will disappear on the same frame that the shared
+            // element appears here. Assure that we get at least 2 frames for double-buffering.
+            decorView.postOnAnimation(new Runnable() {
+                int mAnimations;
+
+                @Override
+                public void run() {
+                    if (mAnimations++ < MIN_ANIMATION_FRAMES) {
+                        View decorView = getDecor();
+                        if (decorView != null) {
+                            decorView.postOnAnimation(this);
+                        }
+                    } else if (mResultReceiver != null) {
+                        mResultReceiver.send(MSG_HIDE_SHARED_ELEMENTS, null);
+                        mResultReceiver = null; // all done sending messages.
+                    }
+                }
+            });
+        }
+    }
+
+    private void onTakeSharedElements() {
+        if (!mIsReadyForTransition || mSharedElementsBundle == null) {
+            return;
+        }
+        final Bundle sharedElementState = mSharedElementsBundle;
+        mSharedElementsBundle = null;
+        final View decorView = getDecor();
+        if (decorView != null) {
+            decorView.getViewTreeObserver()
+                    .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+                        @Override
+                        public boolean onPreDraw() {
+                            decorView.getViewTreeObserver().removeOnPreDrawListener(this);
+                            startTransition(new Runnable() {
+                                @Override
+                                public void run() {
+                                    startSharedElementTransition(sharedElementState);
+                                }
+                            });
+                            return false;
+                        }
+                    });
+            decorView.invalidate();
+        }
+    }
+
+    private void requestLayoutForSharedElements() {
+        int numSharedElements = mSharedElements.size();
+        for (int i = 0; i < numSharedElements; i++) {
+            mSharedElements.get(i).requestLayout();
+        }
+    }
+
+    private Transition beginTransition(ViewGroup decorView, boolean startEnterTransition,
+            boolean startSharedElementTransition) {
+        Transition sharedElementTransition = null;
+        if (startSharedElementTransition) {
+            if (!mSharedElementNames.isEmpty()) {
+                sharedElementTransition = configureTransition(getSharedElementTransition(), false);
+            }
+            if (sharedElementTransition == null) {
+                sharedElementTransitionStarted();
+                sharedElementTransitionComplete();
+            } else {
+                sharedElementTransition.addListener(new Transition.TransitionListenerAdapter() {
+                    @Override
+                    public void onTransitionStart(Transition transition) {
+                        sharedElementTransitionStarted();
+                    }
+
+                    @Override
+                    public void onTransitionEnd(Transition transition) {
+                        transition.removeListener(this);
+                        sharedElementTransitionComplete();
+                    }
+                });
+            }
+        }
+        Transition viewsTransition = null;
+        if (startEnterTransition) {
+            mIsViewsTransitionStarted = true;
+            if (mTransitioningViews != null && !mTransitioningViews.isEmpty()) {
+                viewsTransition = configureTransition(getViewsTransition(), true);
+                if (viewsTransition != null && !mIsReturning) {
+                    stripOffscreenViews();
+                }
+            }
+            if (viewsTransition == null) {
+                viewTransitionComplete();
+            } else {
+                viewsTransition.forceVisibility(View.INVISIBLE, true);
+                final ArrayList<View> transitioningViews = mTransitioningViews;
+                viewsTransition.addListener(new ContinueTransitionListener() {
+                    @Override
+                    public void onTransitionStart(Transition transition) {
+                        mEnterViewsTransition = transition;
+                        if (transitioningViews != null) {
+                            showViews(transitioningViews, false);
+                        }
+                        super.onTransitionStart(transition);
+                    }
+
+                    @Override
+                    public void onTransitionEnd(Transition transition) {
+                        mEnterViewsTransition = null;
+                        transition.removeListener(this);
+                        viewTransitionComplete();
+                        super.onTransitionEnd(transition);
+                    }
+                });
+            }
+        }
+
+        Transition transition = mergeTransitions(sharedElementTransition, viewsTransition);
+        if (transition != null) {
+            transition.addListener(new ContinueTransitionListener());
+            TransitionManager.beginDelayedTransition(decorView, transition);
+            if (startSharedElementTransition && !mSharedElementNames.isEmpty()) {
+                mSharedElements.get(0).invalidate();
+            } else if (startEnterTransition && mTransitioningViews != null &&
+                    !mTransitioningViews.isEmpty()) {
+                mTransitioningViews.get(0).invalidate();
+            }
+        } else {
+            transitionStarted();
+        }
+        return transition;
+    }
+
+    private void viewTransitionComplete() {
+        mIsViewsTransitionComplete = true;
+        if (mIsSharedElementTransitionComplete) {
+            moveSharedElementsFromOverlay();
+        }
+    }
+
+    private void sharedElementTransitionComplete() {
+        mIsSharedElementTransitionComplete = true;
+        if (mIsViewsTransitionComplete) {
+            moveSharedElementsFromOverlay();
+        }
+    }
+
+    private void sharedElementTransitionStarted() {
+        mSharedElementTransitionStarted = true;
+        if (mIsExitTransitionComplete) {
+            send(MSG_EXIT_TRANSITION_COMPLETE, null);
+        }
+    }
+
+    private void startEnterTransition(Transition transition) {
+        ViewGroup decorView = getDecor();
+        if (!mIsReturning && decorView != null) {
+            Drawable background = decorView.getBackground();
+            if (background != null) {
+                background = background.mutate();
+                getWindow().setBackgroundDrawable(background);
+                mBackgroundAnimator = ObjectAnimator.ofInt(background, "alpha", 255);
+                mBackgroundAnimator.setDuration(getFadeDuration());
+                mBackgroundAnimator.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        makeOpaque();
+                    }
+                });
+                mBackgroundAnimator.start();
+            } else if (transition != null) {
+                transition.addListener(new Transition.TransitionListenerAdapter() {
+                    @Override
+                    public void onTransitionEnd(Transition transition) {
+                        transition.removeListener(this);
+                        makeOpaque();
+                    }
+                });
+            } else {
+                makeOpaque();
+            }
+        }
+    }
+
+    public void stop() {
+        // Restore the background to its previous state since the
+        // Activity is stopping.
+        if (mBackgroundAnimator != null) {
+            mBackgroundAnimator.end();
+            mBackgroundAnimator = null;
+        } else if (mWasOpaque) {
+            ViewGroup decorView = getDecor();
+            if (decorView != null) {
+                Drawable drawable = decorView.getBackground();
+                if (drawable != null) {
+                    drawable.setAlpha(1);
+                }
+            }
+        }
+        makeOpaque();
+        mIsCanceled = true;
+        mResultReceiver = null;
+        mActivity = null;
+        moveSharedElementsFromOverlay();
+        if (mTransitioningViews != null) {
+            showViews(mTransitioningViews, true);
+        }
+        showViews(mSharedElements, true);
+        clearState();
+    }
+
+    public void cancelEnter() {
+        setGhostVisibility(View.INVISIBLE);
+        mHasStopped = true;
+        mIsCanceled = true;
+        mResultReceiver = null;
+        if (mBackgroundAnimator != null) {
+            mBackgroundAnimator.cancel();
+            mBackgroundAnimator = null;
+        }
+        mActivity = null;
+        clearState();
+    }
+
+    private void makeOpaque() {
+        if (!mHasStopped && mActivity != null) {
+            if (mWasOpaque) {
+                mActivity.convertFromTranslucent();
+            }
+            mActivity = null;
+        }
+    }
+
+    private boolean allowOverlappingTransitions() {
+        return mIsReturning ? getWindow().getAllowExitTransitionOverlap()
+                : getWindow().getAllowEnterTransitionOverlap();
+    }
+
+    private void startRejectedAnimations(final ArrayList<View> rejectedSnapshots) {
+        if (rejectedSnapshots == null || rejectedSnapshots.isEmpty()) {
+            return;
+        }
+        final ViewGroup decorView = getDecor();
+        if (decorView != null) {
+            ViewGroupOverlay overlay = decorView.getOverlay();
+            ObjectAnimator animator = null;
+            int numRejected = rejectedSnapshots.size();
+            for (int i = 0; i < numRejected; i++) {
+                View snapshot = rejectedSnapshots.get(i);
+                overlay.add(snapshot);
+                animator = ObjectAnimator.ofFloat(snapshot, View.ALPHA, 1, 0);
+                animator.start();
+            }
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    ViewGroupOverlay overlay = decorView.getOverlay();
+                    int numRejected = rejectedSnapshots.size();
+                    for (int i = 0; i < numRejected; i++) {
+                        overlay.remove(rejectedSnapshots.get(i));
+                    }
+                }
+            });
+        }
+    }
+
+    protected void onRemoteExitTransitionComplete() {
+        if (!allowOverlappingTransitions()) {
+            startEnterTransitionOnly();
+        }
+    }
+
+    private void startEnterTransitionOnly() {
+        startTransition(new Runnable() {
+            @Override
+            public void run() {
+                boolean startEnterTransition = true;
+                boolean startSharedElementTransition = false;
+                ViewGroup decorView = getDecor();
+                if (decorView != null) {
+                    Transition transition = beginTransition(decorView, startEnterTransition,
+                            startSharedElementTransition);
+                    startEnterTransition(transition);
+                }
+            }
+        });
+    }
+
+    private void setSharedElementMatrices() {
+        int numSharedElements = mSharedElements.size();
+        if (numSharedElements > 0) {
+            mSharedElementParentMatrices = new ArrayList<Matrix>(numSharedElements);
+        }
+        for (int i = 0; i < numSharedElements; i++) {
+            View view = mSharedElements.get(i);
+
+            // Find the location in the view's parent
+            ViewGroup parent = (ViewGroup) view.getParent();
+            Matrix matrix = new Matrix();
+            parent.transformMatrixToLocal(matrix);
+
+            mSharedElementParentMatrices.add(matrix);
+        }
+    }
+
+    @Override
+    protected void getSharedElementParentMatrix(View view, Matrix matrix) {
+        int index = mSharedElementParentMatrices == null ? -1 : mSharedElements.indexOf(view);
+        if (index < 0) {
+            super.getSharedElementParentMatrix(view, matrix);
+        } else {
+            matrix.set(mSharedElementParentMatrices.get(index));
+        }
+    }
+}
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
new file mode 100644
index 0000000..dd3df47
--- /dev/null
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.RectF;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+
+import java.util.ArrayList;
+
+/**
+ * This ActivityTransitionCoordinator is created in ActivityOptions#makeSceneTransitionAnimation
+ * to govern the exit of the Scene and the shared elements when calling an Activity as well as
+ * the reentry of the Scene when coming back from the called Activity.
+ */
+class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
+    private static final String TAG = "ExitTransitionCoordinator";
+    private static final long MAX_WAIT_MS = 1000;
+
+    private boolean mExitComplete;
+
+    private Bundle mSharedElementBundle;
+
+    private boolean mExitNotified;
+
+    private boolean mSharedElementNotified;
+
+    private Activity mActivity;
+
+    private boolean mIsBackgroundReady;
+
+    private boolean mIsCanceled;
+
+    private Handler mHandler;
+
+    private ObjectAnimator mBackgroundAnimator;
+
+    private boolean mIsHidden;
+
+    private Bundle mExitSharedElementBundle;
+
+    private boolean mIsExitStarted;
+
+    private boolean mSharedElementsHidden;
+
+    public ExitTransitionCoordinator(Activity activity, ArrayList<String> names,
+            ArrayList<String> accepted, ArrayList<View> mapped, boolean isReturning) {
+        super(activity.getWindow(), names, getListener(activity, isReturning), isReturning);
+        viewsReady(mapSharedElements(accepted, mapped));
+        stripOffscreenViews();
+        mIsBackgroundReady = !isReturning;
+        mActivity = activity;
+    }
+
+    private static SharedElementCallback getListener(Activity activity, boolean isReturning) {
+        return isReturning ? activity.mEnterTransitionListener : activity.mExitTransitionListener;
+    }
+
+    @Override
+    protected void onReceiveResult(int resultCode, Bundle resultData) {
+        switch (resultCode) {
+            case MSG_SET_REMOTE_RECEIVER:
+                stopCancel();
+                mResultReceiver = resultData.getParcelable(KEY_REMOTE_RECEIVER);
+                if (mIsCanceled) {
+                    mResultReceiver.send(MSG_CANCEL, null);
+                    mResultReceiver = null;
+                } else {
+                    notifyComplete();
+                }
+                break;
+            case MSG_HIDE_SHARED_ELEMENTS:
+                stopCancel();
+                if (!mIsCanceled) {
+                    hideSharedElements();
+                }
+                break;
+            case MSG_START_EXIT_TRANSITION:
+                mHandler.removeMessages(MSG_CANCEL);
+                startExit();
+                break;
+            case MSG_SHARED_ELEMENT_DESTINATION:
+                mExitSharedElementBundle = resultData;
+                sharedElementExitBack();
+                break;
+        }
+    }
+
+    private void stopCancel() {
+        if (mHandler != null) {
+            mHandler.removeMessages(MSG_CANCEL);
+        }
+    }
+
+    private void delayCancel() {
+        if (mHandler != null) {
+            mHandler.sendEmptyMessageDelayed(MSG_CANCEL, MAX_WAIT_MS);
+        }
+    }
+
+    public void resetViews() {
+        if (mTransitioningViews != null) {
+            showViews(mTransitioningViews, true);
+        }
+        showViews(mSharedElements, true);
+        mIsHidden = true;
+        ViewGroup decorView = getDecor();
+        if (!mIsReturning && decorView != null) {
+            decorView.suppressLayout(false);
+        }
+        moveSharedElementsFromOverlay();
+        clearState();
+    }
+
+    private void sharedElementExitBack() {
+        final ViewGroup decorView = getDecor();
+        if (decorView != null) {
+            decorView.suppressLayout(true);
+        }
+        if (decorView != null && mExitSharedElementBundle != null &&
+                !mExitSharedElementBundle.isEmpty() &&
+                !mSharedElements.isEmpty() && getSharedElementTransition() != null) {
+            startTransition(new Runnable() {
+                public void run() {
+                    startSharedElementExit(decorView);
+                }
+            });
+        } else {
+            sharedElementTransitionComplete();
+        }
+    }
+
+    private void startSharedElementExit(final ViewGroup decorView) {
+        Transition transition = getSharedElementExitTransition();
+        transition.addListener(new Transition.TransitionListenerAdapter() {
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                transition.removeListener(this);
+                if (mExitComplete) {
+                    delayCancel();
+                }
+            }
+        });
+        final ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle,
+                mSharedElementNames);
+        decorView.getViewTreeObserver()
+                .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        decorView.getViewTreeObserver().removeOnPreDrawListener(this);
+                        setSharedElementState(mExitSharedElementBundle, sharedElementSnapshots);
+                        return true;
+                    }
+                });
+        setGhostVisibility(View.INVISIBLE);
+        scheduleGhostVisibilityChange(View.INVISIBLE);
+        if (mListener != null) {
+            mListener.onSharedElementEnd(mSharedElementNames, mSharedElements,
+                    sharedElementSnapshots);
+        }
+        TransitionManager.beginDelayedTransition(decorView, transition);
+        scheduleGhostVisibilityChange(View.VISIBLE);
+        setGhostVisibility(View.VISIBLE);
+        decorView.invalidate();
+    }
+
+    private void hideSharedElements() {
+        moveSharedElementsFromOverlay();
+        if (!mIsHidden) {
+            hideViews(mSharedElements);
+        }
+        mSharedElementsHidden = true;
+        finishIfNecessary();
+    }
+
+    public void startExit() {
+        if (!mIsExitStarted) {
+            mIsExitStarted = true;
+            ViewGroup decorView = getDecor();
+            if (decorView != null) {
+                decorView.suppressLayout(true);
+            }
+            moveSharedElementsToOverlay();
+            startTransition(new Runnable() {
+                @Override
+                public void run() {
+                    beginTransitions();
+                }
+            });
+        }
+    }
+
+    public void startExit(int resultCode, Intent data) {
+        if (!mIsExitStarted) {
+            mIsExitStarted = true;
+            ViewGroup decorView = getDecor();
+            if (decorView != null) {
+                decorView.suppressLayout(true);
+            }
+            mHandler = new Handler() {
+                @Override
+                public void handleMessage(Message msg) {
+                    mIsCanceled = true;
+                    finish();
+                }
+            };
+            delayCancel();
+            moveSharedElementsToOverlay();
+            if (decorView != null && decorView.getBackground() == null) {
+                getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
+            }
+            ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this,
+                    mAllSharedElementNames, resultCode, data);
+            mActivity.convertToTranslucent(new Activity.TranslucentConversionListener() {
+                @Override
+                public void onTranslucentConversionComplete(boolean drawComplete) {
+                    if (!mIsCanceled) {
+                        fadeOutBackground();
+                    }
+                }
+            }, options);
+            startTransition(new Runnable() {
+                @Override
+                public void run() {
+                    startExitTransition();
+                }
+            });
+        }
+    }
+
+    public void stop() {
+        if (mIsReturning && mActivity != null) {
+            // Override the previous ActivityOptions. We don't want the
+            // activity to have options since we're essentially canceling the
+            // transition and finishing right now.
+            mActivity.convertToTranslucent(null, null);
+            finish();
+        }
+    }
+
+    private void startExitTransition() {
+        Transition transition = getExitTransition();
+        ViewGroup decorView = getDecor();
+        if (transition != null && decorView != null && mTransitioningViews != null) {
+            TransitionManager.beginDelayedTransition(decorView, transition);
+            mTransitioningViews.get(0).invalidate();
+        } else {
+            transitionStarted();
+        }
+    }
+
+    private void fadeOutBackground() {
+        if (mBackgroundAnimator == null) {
+            ViewGroup decor = getDecor();
+            Drawable background;
+            if (decor != null && (background = decor.getBackground()) != null) {
+                background = background.mutate();
+                getWindow().setBackgroundDrawable(background);
+                mBackgroundAnimator = ObjectAnimator.ofInt(background, "alpha", 0);
+                mBackgroundAnimator.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        mBackgroundAnimator = null;
+                        if (!mIsCanceled) {
+                            mIsBackgroundReady = true;
+                            notifyComplete();
+                        }
+                    }
+                });
+                mBackgroundAnimator.setDuration(getFadeDuration());
+                mBackgroundAnimator.start();
+            } else {
+                mIsBackgroundReady = true;
+            }
+        }
+    }
+
+    private Transition getExitTransition() {
+        Transition viewsTransition = null;
+        if (mTransitioningViews != null && !mTransitioningViews.isEmpty()) {
+            viewsTransition = configureTransition(getViewsTransition(), true);
+        }
+        if (viewsTransition == null) {
+            exitTransitionComplete();
+        } else {
+            final ArrayList<View> transitioningViews = mTransitioningViews;
+            viewsTransition.addListener(new ContinueTransitionListener() {
+                @Override
+                public void onTransitionEnd(Transition transition) {
+                    transition.removeListener(this);
+                    exitTransitionComplete();
+                    if (mIsHidden && transitioningViews != null) {
+                        showViews(transitioningViews, true);
+                    }
+                    if (mSharedElementBundle != null) {
+                        delayCancel();
+                    }
+                    super.onTransitionEnd(transition);
+                }
+            });
+            viewsTransition.forceVisibility(View.INVISIBLE, false);
+        }
+        return viewsTransition;
+    }
+
+    private Transition getSharedElementExitTransition() {
+        Transition sharedElementTransition = null;
+        if (!mSharedElements.isEmpty()) {
+            sharedElementTransition = configureTransition(getSharedElementTransition(), false);
+        }
+        if (sharedElementTransition == null) {
+            sharedElementTransitionComplete();
+        } else {
+            sharedElementTransition.addListener(new ContinueTransitionListener() {
+                @Override
+                public void onTransitionEnd(Transition transition) {
+                    transition.removeListener(this);
+                    sharedElementTransitionComplete();
+                    if (mIsHidden) {
+                        showViews(mSharedElements, true);
+                    }
+                }
+            });
+            mSharedElements.get(0).invalidate();
+        }
+        return sharedElementTransition;
+    }
+
+    private void beginTransitions() {
+        Transition sharedElementTransition = getSharedElementExitTransition();
+        Transition viewsTransition = getExitTransition();
+
+        Transition transition = mergeTransitions(sharedElementTransition, viewsTransition);
+        ViewGroup decorView = getDecor();
+        if (transition != null && decorView != null) {
+            setGhostVisibility(View.INVISIBLE);
+            scheduleGhostVisibilityChange(View.INVISIBLE);
+            TransitionManager.beginDelayedTransition(decorView, transition);
+            scheduleGhostVisibilityChange(View.VISIBLE);
+            setGhostVisibility(View.VISIBLE);
+            decorView.invalidate();
+        } else {
+            transitionStarted();
+        }
+    }
+
+    private void exitTransitionComplete() {
+        mExitComplete = true;
+        notifyComplete();
+    }
+
+    protected boolean isReadyToNotify() {
+        return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady;
+    }
+
+    private void sharedElementTransitionComplete() {
+        mSharedElementBundle = mExitSharedElementBundle == null
+                ? captureSharedElementState() : captureExitSharedElementsState();
+        notifyComplete();
+    }
+
+    private Bundle captureExitSharedElementsState() {
+        Bundle bundle = new Bundle();
+        RectF bounds = new RectF();
+        Matrix matrix = new Matrix();
+        for (int i = 0; i < mSharedElements.size(); i++) {
+            String name = mSharedElementNames.get(i);
+            Bundle sharedElementState = mExitSharedElementBundle.getBundle(name);
+            if (sharedElementState != null) {
+                bundle.putBundle(name, sharedElementState);
+            } else {
+                View view = mSharedElements.get(i);
+                captureSharedElementState(view, name, bundle, matrix, bounds);
+            }
+        }
+        return bundle;
+    }
+
+    protected void notifyComplete() {
+        if (isReadyToNotify()) {
+            if (!mSharedElementNotified) {
+                mSharedElementNotified = true;
+                delayCancel();
+                mResultReceiver.send(MSG_TAKE_SHARED_ELEMENTS, mSharedElementBundle);
+            }
+            if (!mExitNotified && mExitComplete) {
+                mExitNotified = true;
+                mResultReceiver.send(MSG_EXIT_TRANSITION_COMPLETE, null);
+                mResultReceiver = null; // done talking
+                ViewGroup decorView = getDecor();
+                if (!mIsReturning && decorView != null) {
+                    decorView.suppressLayout(false);
+                }
+                finishIfNecessary();
+            }
+        }
+    }
+
+    private void finishIfNecessary() {
+        if (mIsReturning && mExitNotified && mActivity != null && (mSharedElements.isEmpty() ||
+                mSharedElementsHidden)) {
+            finish();
+        }
+        if (!mIsReturning && mExitNotified) {
+            mActivity = null; // don't need it anymore
+        }
+    }
+
+    private void finish() {
+        stopCancel();
+        if (mActivity != null) {
+            mActivity.mActivityTransitionState.clear();
+            mActivity.finish();
+            mActivity.overridePendingTransition(0, 0);
+            mActivity = null;
+        }
+        // Clear the state so that we can't hold any references accidentally and leak memory.
+        mHandler = null;
+        mSharedElementBundle = null;
+        if (mBackgroundAnimator != null) {
+            mBackgroundAnimator.cancel();
+            mBackgroundAnimator = null;
+        }
+        mExitSharedElementBundle = null;
+        clearState();
+    }
+
+    @Override
+    protected boolean moveSharedElementWithParent() {
+        return !mIsReturning;
+    }
+
+    @Override
+    protected Transition getViewsTransition() {
+        if (mIsReturning) {
+            return getWindow().getReturnTransition();
+        } else {
+            return getWindow().getExitTransition();
+        }
+    }
+
+    protected Transition getSharedElementTransition() {
+        if (mIsReturning) {
+            return getWindow().getSharedElementReturnTransition();
+        } else {
+            return getWindow().getSharedElementExitTransition();
+        }
+    }
+}
diff --git a/core/java/android/app/ExpandableListActivity.java b/core/java/android/app/ExpandableListActivity.java
index 9651078..e08f25a 100644
--- a/core/java/android/app/ExpandableListActivity.java
+++ b/core/java/android/app/ExpandableListActivity.java
@@ -27,7 +27,6 @@
 import android.widget.ExpandableListView;
 import android.widget.SimpleCursorTreeAdapter;
 import android.widget.SimpleExpandableListAdapter;
-import android.widget.AdapterView.AdapterContextMenuInfo;
 
 import java.util.Map;
 
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index af8f177..5196834 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -17,14 +17,20 @@
 package android.app;
 
 import android.animation.Animator;
+import android.annotation.Nullable;
 import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.transition.Transition;
+import android.transition.TransitionInflater;
+import android.transition.TransitionSet;
 import android.util.AndroidRuntimeException;
 import android.util.ArrayMap;
 import android.util.AttributeSet;
@@ -56,11 +62,11 @@
     final boolean mRetainInstance;
     final boolean mDetached;
     final Bundle mArguments;
-    
+
     Bundle mSavedFragmentState;
-    
+
     Fragment mInstance;
-    
+
     public FragmentState(Fragment frag) {
         mClassName = frag.getClass().getName();
         mIndex = frag.mIndex;
@@ -72,7 +78,7 @@
         mDetached = frag.mDetached;
         mArguments = frag.mArguments;
     }
-    
+
     public FragmentState(Parcel in) {
         mClassName = in.readString();
         mIndex = in.readInt();
@@ -85,18 +91,18 @@
         mArguments = in.readBundle();
         mSavedFragmentState = in.readBundle();
     }
-    
+
     public Fragment instantiate(Activity activity, Fragment parent) {
         if (mInstance != null) {
             return mInstance;
         }
-        
+
         if (mArguments != null) {
             mArguments.setClassLoader(activity.getClassLoader());
         }
-        
+
         mInstance = Fragment.instantiate(activity, mClassName, mArguments);
-        
+
         if (mSavedFragmentState != null) {
             mSavedFragmentState.setClassLoader(activity.getClassLoader());
             mInstance.mSavedFragmentState = mSavedFragmentState;
@@ -115,7 +121,7 @@
 
         return mInstance;
     }
-    
+
     public int describeContents() {
         return 0;
     }
@@ -132,13 +138,13 @@
         dest.writeBundle(mArguments);
         dest.writeBundle(mSavedFragmentState);
     }
-    
+
     public static final Parcelable.Creator<FragmentState> CREATOR
             = new Parcelable.Creator<FragmentState>() {
         public FragmentState createFromParcel(Parcel in) {
             return new FragmentState(in);
         }
-        
+
         public FragmentState[] newArray(int size) {
             return new FragmentState[size];
         }
@@ -160,11 +166,12 @@
  * activity: if the activity is stopped, no fragments inside of it can be
  * started; when the activity is destroyed, all fragments will be destroyed.
  *
- * <p>All subclasses of Fragment must include a public empty constructor.
+ * <p>All subclasses of Fragment must include a public no-argument constructor.
  * The framework will often re-instantiate a fragment class when needed,
  * in particular during state restore, and needs to be able to find this
- * constructor to instantiate it.  If the empty constructor is not available,
- * a runtime exception will occur in some cases during state restore.
+ * constructor to instantiate it.  If the no-argument constructor is not
+ * available, a runtime exception will occur in some cases during state
+ * restore.
  *
  * <p>Topics covered here:
  * <ol>
@@ -297,17 +304,17 @@
  * how you can determine if a fragment placed in a container is no longer
  * running in a layout with that container and avoid creating its view hierarchy
  * in that case.)
- * 
+ *
  * <p>The attributes of the &lt;fragment&gt; tag are used to control the
  * LayoutParams provided when attaching the fragment's view to the parent
  * container.  They can also be parsed by the fragment in {@link #onInflate}
  * as parameters.
- * 
+ *
  * <p>The fragment being instantiated must have some kind of unique identifier
  * so that it can be re-associated with a previous instance if the parent
  * activity needs to be destroyed and recreated.  This can be provided these
  * ways:
- * 
+ *
  * <ul>
  * <li>If nothing is explicitly supplied, the view ID of the container will
  * be used.
@@ -316,7 +323,7 @@
  * <li><code>android:id</code> can be used in &lt;fragment&gt; to provide
  * a specific identifier for the fragment.
  * </ul>
- * 
+ *
  * <a name="BackStack"></a>
  * <h3>Back Stack</h3>
  *
@@ -345,7 +352,7 @@
 public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListener {
     private static final ArrayMap<String, Class<?>> sClassMap =
             new ArrayMap<String, Class<?>>();
-    
+
     static final int INVALID_STATE = -1;   // Invalid state used as a null value.
     static final int INITIALIZING = 0;     // Not yet created.
     static final int CREATED = 1;          // Created.
@@ -353,9 +360,11 @@
     static final int STOPPED = 3;          // Fully created, not started.
     static final int STARTED = 4;          // Created and started, not resumed.
     static final int RESUMED = 5;          // Created started and resumed.
-    
+
+    private static final Transition USE_DEFAULT_TRANSITION = new TransitionSet();
+
     int mState = INITIALIZING;
-    
+
     // Non-null if the fragment's view hierarchy is currently animating away,
     // meaning we need to wait a bit on completely destroying it.  This is the
     // animation that is running.
@@ -368,13 +377,13 @@
     // When instantiated from saved state, this is the saved state.
     Bundle mSavedFragmentState;
     SparseArray<Parcelable> mSavedViewState;
-    
+
     // Index into active fragment array.
     int mIndex = -1;
-    
+
     // Internal unique name for this fragment;
     String mWho;
-    
+
     // Construction arguments;
     Bundle mArguments;
 
@@ -389,25 +398,25 @@
 
     // True if the fragment is in the list of added fragments.
     boolean mAdded;
-    
+
     // If set this fragment is being removed from its activity.
     boolean mRemoving;
 
     // True if the fragment is in the resumed state.
     boolean mResumed;
-    
+
     // Set to true if this fragment was instantiated from a layout file.
     boolean mFromLayout;
-    
+
     // Set to true when the view has actually been inflated in its layout.
     boolean mInLayout;
 
     // True if this fragment has been restored from previously saved state.
     boolean mRestored;
-    
+
     // Number of active back stack entries this fragment is in.
     int mBackStackNesting;
-    
+
     // The fragment manager we are associated with.  Set as soon as the
     // fragment is used in a transaction; cleared after it has been removed
     // from all transactions.
@@ -426,29 +435,29 @@
     // was dynamically added to the view hierarchy, or the ID supplied in
     // layout.
     int mFragmentId;
-    
+
     // When a fragment is being dynamically added to the view hierarchy, this
     // is the identifier of the parent container it is being added to.
     int mContainerId;
-    
+
     // The optional named tag for this fragment -- usually used to find
     // fragments that are not part of the layout.
     String mTag;
-    
+
     // Set to true when the app has requested that this fragment be hidden
     // from the user.
     boolean mHidden;
-    
+
     // Set to true when the app has requested that this fragment be detached.
     boolean mDetached;
 
     // If set this fragment would like its instance retained across
     // configuration changes.
     boolean mRetainInstance;
-    
+
     // If set this fragment is being retained across the current config change.
     boolean mRetaining;
-    
+
     // If set this fragment has menu items to contribute.
     boolean mHasMenu;
 
@@ -457,16 +466,16 @@
 
     // Used to verify that subclasses call through to super class.
     boolean mCalled;
-    
+
     // If app has requested a specific animation, this is the one to use.
     int mNextAnim;
-    
+
     // The parent container of the fragment after dynamically added to UI.
     ViewGroup mContainer;
-    
+
     // The View generated for this fragment.
     View mView;
-    
+
     // Whether this fragment should defer starting until after other fragments
     // have been started and their loaders are finished.
     boolean mDeferStart;
@@ -477,7 +486,19 @@
     LoaderManagerImpl mLoaderManager;
     boolean mLoadersStarted;
     boolean mCheckedForLoaderManager;
-    
+
+    private Transition mEnterTransition = null;
+    private Transition mReturnTransition = USE_DEFAULT_TRANSITION;
+    private Transition mExitTransition = null;
+    private Transition mReenterTransition = USE_DEFAULT_TRANSITION;
+    private Transition mSharedElementEnterTransition = null;
+    private Transition mSharedElementReturnTransition = USE_DEFAULT_TRANSITION;
+    private Boolean mAllowReturnTransitionOverlap;
+    private Boolean mAllowEnterTransitionOverlap;
+
+    SharedElementCallback mEnterTransitionCallback = SharedElementCallback.NULL_CALLBACK;
+    SharedElementCallback mExitTransitionCallback = SharedElementCallback.NULL_CALLBACK;
+
     /**
      * State information that has been retrieved from a fragment instance
      * through {@link FragmentManager#saveFragmentInstanceState(Fragment)
@@ -541,7 +562,7 @@
      * will not be called when the fragment is re-instantiated; instead,
      * arguments can be supplied by the caller with {@link #setArguments}
      * and later retrieved by the Fragment with {@link #getArguments}.
-     * 
+     *
      * <p>Applications should generally not implement a constructor.  The
      * first place application code an run where the fragment is ready to
      * be used is in {@link #onAttach(Activity)}, the point where the fragment
@@ -575,7 +596,7 @@
      * the given fragment class.  This is a runtime exception; it is not
      * normally expected to happen.
      */
-    public static Fragment instantiate(Context context, String fname, Bundle args) {
+    public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) {
         try {
             Class<?> clazz = sClassMap.get(fname);
             if (clazz == null) {
@@ -607,7 +628,7 @@
                     + " empty constructor that is public", e);
         }
     }
-    
+
     final void restoreViewState(Bundle savedInstanceState) {
         if (mSavedViewState != null) {
             mView.restoreHierarchyState(mSavedViewState);
@@ -647,7 +668,7 @@
     @Override final public int hashCode() {
         return super.hashCode();
     }
-    
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(128);
@@ -667,7 +688,7 @@
         sb.append('}');
         return sb.toString();
     }
-    
+
     /**
      * Return the identifier this fragment is known by.  This is either
      * the android:id value supplied in a layout or the container view ID
@@ -676,14 +697,14 @@
     final public int getId() {
         return mFragmentId;
     }
-    
+
     /**
      * Get the tag name of the fragment, if specified.
      */
     final public String getTag() {
         return mTag;
     }
-    
+
     /**
      * Supply the construction arguments for this fragment.  This can only
      * be called before the fragment has been attached to its activity; that
@@ -758,7 +779,7 @@
     final public Activity getActivity() {
         return mActivity;
     }
-    
+
     /**
      * Return <code>getActivity().getResources()</code>.
      */
@@ -768,7 +789,7 @@
         }
         return mActivity.getResources();
     }
-    
+
     /**
      * Return a localized, styled CharSequence from the application's package's
      * default string table.
@@ -868,7 +889,7 @@
     final public boolean isRemoving() {
         return mRemoving;
     }
-    
+
     /**
      * Return true if the layout is included as part of an activity view
      * hierarchy via the &lt;fragment&gt; tag.  This will always be true when
@@ -887,7 +908,7 @@
     final public boolean isResumed() {
         return mResumed;
     }
-    
+
     /**
      * Return true if the fragment is currently visible to the user.  This means
      * it: (1) has been added, (2) has its view attached to the window, and 
@@ -897,7 +918,7 @@
         return isAdded() && !isHidden() && mView != null
                 && mView.getWindowToken() != null && mView.getVisibility() == View.VISIBLE;
     }
-    
+
     /**
      * Return true if the fragment has been hidden.  By default fragments
      * are shown.  You can find out about changes to this state with
@@ -908,7 +929,7 @@
     final public boolean isHidden() {
         return mHidden;
     }
-    
+
     /**
      * Called when the hidden state (as returned by {@link #isHidden()} of
      * the fragment has changed.  Fragments start out not hidden; this will
@@ -918,7 +939,7 @@
      */
     public void onHiddenChanged(boolean hidden) {
     }
-    
+
     /**
      * Control whether a fragment instance is retained across Activity
      * re-creation (such as from a configuration change).  This can only
@@ -940,16 +961,16 @@
         }
         mRetainInstance = retain;
     }
-    
+
     final public boolean getRetainInstance() {
         return mRetainInstance;
     }
-    
+
     /**
      * Report that this fragment would like to participate in populating
      * the options menu by receiving a call to {@link #onCreateOptionsMenu}
      * and related methods.
-     * 
+     *
      * @param hasMenu If true, the fragment has menu items to contribute.
      */
     public void setHasOptionsMenu(boolean hasMenu) {
@@ -1032,7 +1053,7 @@
     public void startActivity(Intent intent) {
         startActivity(intent, null);
     }
-    
+
     /**
      * Call {@link Activity#startActivity(Intent, Bundle)} from the fragment's
      * containing Activity.
@@ -1079,13 +1100,13 @@
             mActivity.startActivityFromFragment(this, intent, requestCode, options);
         }
     }
-    
+
     /**
      * Receive the result from a previous call to
      * {@link #startActivityForResult(Intent, int)}.  This follows the
      * related Activity API as described there in
      * {@link Activity#onActivityResult(int, int, Intent)}.
-     * 
+     *
      * @param requestCode The integer request code originally supplied to
      *                    startActivityForResult(), allowing you to identify who this
      *                    result came from.
@@ -1096,16 +1117,24 @@
      */
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
     }
-    
+
     /**
      * @hide Hack so that DialogFragment can make its Dialog before creating
      * its views, and the view construction can use the dialog's context for
      * inflation.  Maybe this should become a public API. Note sure.
      */
     public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
-        return mActivity.getLayoutInflater();
+        // Newer platform versions use the child fragment manager's LayoutInflaterFactory.
+        if (mActivity.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
+            LayoutInflater result = mActivity.getLayoutInflater().cloneInContext(mActivity);
+            getChildFragmentManager(); // Init if needed; use raw implementation below.
+            result.setPrivateFactory(mChildFragmentManager.getLayoutInflaterFactory());
+            return result;
+        } else {
+            return mActivity.getLayoutInflater();
+        }
     }
-    
+
     /**
      * @deprecated Use {@link #onInflate(Activity, AttributeSet, Bundle)} instead.
      */
@@ -1121,7 +1150,7 @@
      * tag in a layout file.  Note this is <em>before</em> the fragment's
      * {@link #onAttach(Activity)} has been called; all you should do here is
      * parse the attributes and save them away.
-     * 
+     *
      * <p>This is called every time the fragment is inflated, even if it is
      * being inflated into a new instance with saved state.  It typically makes
      * sense to re-parse the parameters each time, to allow them to change with
@@ -1159,8 +1188,33 @@
     public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
         onInflate(attrs, savedInstanceState);
         mCalled = true;
+
+        TypedArray a = activity.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.Fragment);
+        mEnterTransition = loadTransition(activity, a, mEnterTransition, null,
+                com.android.internal.R.styleable.Fragment_fragmentEnterTransition);
+        mReturnTransition = loadTransition(activity, a, mReturnTransition, USE_DEFAULT_TRANSITION,
+                com.android.internal.R.styleable.Fragment_fragmentReturnTransition);
+        mExitTransition = loadTransition(activity, a, mExitTransition, null,
+                com.android.internal.R.styleable.Fragment_fragmentExitTransition);
+        mReenterTransition = loadTransition(activity, a, mReenterTransition, USE_DEFAULT_TRANSITION,
+                com.android.internal.R.styleable.Fragment_fragmentReenterTransition);
+        mSharedElementEnterTransition = loadTransition(activity, a, mSharedElementEnterTransition,
+                null, com.android.internal.R.styleable.Fragment_fragmentSharedElementEnterTransition);
+        mSharedElementReturnTransition = loadTransition(activity, a, mSharedElementReturnTransition,
+                USE_DEFAULT_TRANSITION,
+                com.android.internal.R.styleable.Fragment_fragmentSharedElementReturnTransition);
+        if (mAllowEnterTransitionOverlap == null) {
+            mAllowEnterTransitionOverlap = a.getBoolean(
+                    com.android.internal.R.styleable.Fragment_fragmentAllowEnterTransitionOverlap, true);
+        }
+        if (mAllowReturnTransitionOverlap == null) {
+            mAllowReturnTransitionOverlap = a.getBoolean(
+                    com.android.internal.R.styleable.Fragment_fragmentAllowReturnTransitionOverlap, true);
+        }
+        a.recycle();
     }
-    
+
     /**
      * Called when a fragment is first attached to its activity.
      * {@link #onCreate(Bundle)} will be called after this.
@@ -1168,25 +1222,25 @@
     public void onAttach(Activity activity) {
         mCalled = true;
     }
-    
+
     /**
      * Called when a fragment loads an animation.
      */
     public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
         return null;
     }
-    
+
     /**
      * Called to do initial creation of a fragment.  This is called after
      * {@link #onAttach(Activity)} and before
      * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
-     * 
+     *
      * <p>Note that this can be called while the fragment's activity is
      * still in the process of being created.  As such, you can not rely
      * on things like the activity's content view hierarchy being initialized
      * at this point.  If you want to do work once the activity itself is
      * created, see {@link #onActivityCreated(Bundle)}.
-     * 
+     *
      * @param savedInstanceState If the fragment is being re-created from
      * a previous saved state, this is the state.
      */
@@ -1199,10 +1253,10 @@
      * This is optional, and non-graphical fragments can return null (which
      * is the default implementation).  This will be called between
      * {@link #onCreate(Bundle)} and {@link #onActivityCreated(Bundle)}.
-     * 
+     *
      * <p>If you return a View from here, you will later be called in
      * {@link #onDestroyView} when the view is being released.
-     * 
+     *
      * @param inflater The LayoutInflater object that can be used to inflate
      * any views in the fragment,
      * @param container If non-null, this is the parent view that the fragment's
@@ -1210,10 +1264,11 @@
      * but this can be used to generate the LayoutParams of the view.
      * @param savedInstanceState If non-null, this fragment is being re-constructed
      * from a previous saved state as given here.
-     * 
+     *
      * @return Return the View for the fragment's UI, or null.
      */
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+    @Nullable
+    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
             Bundle savedInstanceState) {
         return null;
     }
@@ -1228,19 +1283,20 @@
      * @param savedInstanceState If non-null, this fragment is being re-constructed
      * from a previous saved state as given here.
      */
-    public void onViewCreated(View view, Bundle savedInstanceState) {
+    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
     }
-    
+
     /**
      * Get the root view for the fragment's layout (the one returned by {@link #onCreateView}),
      * if provided.
-     * 
+     *
      * @return The fragment's root view, or null if it has no layout.
      */
+    @Nullable
     public View getView() {
         return mView;
     }
-    
+
     /**
      * Called when the fragment's activity has been created and this
      * fragment's view hierarchy instantiated.  It can be used to do final
@@ -1280,7 +1336,7 @@
      */
     public void onStart() {
         mCalled = true;
-        
+
         if (!mLoadersStarted) {
             mLoadersStarted = true;
             if (!mCheckedForLoaderManager) {
@@ -1292,7 +1348,7 @@
             }
         }
     }
-    
+
     /**
      * Called when the fragment is visible to the user and actively running.
      * This is generally
@@ -1302,7 +1358,7 @@
     public void onResume() {
         mCalled = true;
     }
-    
+
     /**
      * Called to ask the fragment to save its current dynamic state, so it
      * can later be reconstructed in a new instance of its process is
@@ -1324,11 +1380,11 @@
      */
     public void onSaveInstanceState(Bundle outState) {
     }
-    
+
     public void onConfigurationChanged(Configuration newConfig) {
         mCalled = true;
     }
-    
+
     /**
      * Called when the Fragment is no longer resumed.  This is generally
      * tied to {@link Activity#onPause() Activity.onPause} of the containing
@@ -1337,7 +1393,7 @@
     public void onPause() {
         mCalled = true;
     }
-    
+
     /**
      * Called when the Fragment is no longer started.  This is generally
      * tied to {@link Activity#onStop() Activity.onStop} of the containing
@@ -1346,11 +1402,11 @@
     public void onStop() {
         mCalled = true;
     }
-    
+
     public void onLowMemory() {
         mCalled = true;
     }
-    
+
     public void onTrimMemory(int level) {
         mCalled = true;
     }
@@ -1367,7 +1423,7 @@
     public void onDestroyView() {
         mCalled = true;
     }
-    
+
     /**
      * Called when the fragment is no longer in use.  This is called
      * after {@link #onStop()} and before {@link #onDetach()}.
@@ -1422,16 +1478,16 @@
     public void onDetach() {
         mCalled = true;
     }
-    
+
     /**
      * Initialize the contents of the Activity's standard options menu.  You
      * should place your menu items in to <var>menu</var>.  For this method
      * to be called, you must have first called {@link #setHasOptionsMenu}.  See
      * {@link Activity#onCreateOptionsMenu(Menu) Activity.onCreateOptionsMenu}
      * for more information.
-     * 
+     *
      * @param menu The options menu in which you place your items.
-     * 
+     *
      * @see #setHasOptionsMenu
      * @see #onPrepareOptionsMenu
      * @see #onOptionsItemSelected
@@ -1446,10 +1502,10 @@
      * dynamically modify the contents.  See
      * {@link Activity#onPrepareOptionsMenu(Menu) Activity.onPrepareOptionsMenu}
      * for more information.
-     * 
+     *
      * @param menu The options menu as last shown or first initialized by
      *             onCreateOptionsMenu().
-     * 
+     *
      * @see #setHasOptionsMenu
      * @see #onCreateOptionsMenu
      */
@@ -1465,7 +1521,7 @@
      */
     public void onDestroyOptionsMenu() {
     }
-    
+
     /**
      * This hook is called whenever an item in your options menu is selected.
      * The default implementation simply returns false to have the normal
@@ -1473,15 +1529,15 @@
      * its Handler as appropriate).  You can use this method for any items
      * for which you would like to do processing without those other
      * facilities.
-     * 
+     *
      * <p>Derived classes should call through to the base class for it to
      * perform the default menu handling.
-     * 
+     *
      * @param item The menu item that was selected.
-     * 
+     *
      * @return boolean Return false to allow normal menu processing to
      *         proceed, true to consume it here.
-     * 
+     *
      * @see #onCreateOptionsMenu
      */
     public boolean onOptionsItemSelected(MenuItem item) {
@@ -1491,13 +1547,13 @@
     /**
      * This hook is called whenever the options menu is being closed (either by the user canceling
      * the menu with the back/menu button, or when an item is selected).
-     *  
+     *
      * @param menu The options menu as last shown or first initialized by
      *             onCreateOptionsMenu().
      */
     public void onOptionsMenuClosed(Menu menu) {
     }
-    
+
     /**
      * Called when a context menu for the {@code view} is about to be shown.
      * Unlike {@link #onCreateOptionsMenu}, this will be called every
@@ -1525,25 +1581,25 @@
      * {@link OnCreateContextMenuListener} on the view to this fragment, so
      * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be
      * called when it is time to show the context menu.
-     * 
+     *
      * @see #unregisterForContextMenu(View)
      * @param view The view that should show a context menu.
      */
     public void registerForContextMenu(View view) {
         view.setOnCreateContextMenuListener(this);
     }
-    
+
     /**
      * Prevents a context menu to be shown for the given view. This method will
      * remove the {@link OnCreateContextMenuListener} on the view.
-     * 
+     *
      * @see #registerForContextMenu(View)
      * @param view The view that should stop showing a context menu.
      */
     public void unregisterForContextMenu(View view) {
         view.setOnCreateContextMenuListener(null);
     }
-    
+
     /**
      * This hook is called whenever an item in a context menu is selected. The
      * default implementation simply returns false to have the normal processing
@@ -1556,7 +1612,7 @@
      * <p>
      * Derived classes should call through to the base class for it to perform
      * the default menu handling.
-     * 
+     *
      * @param item The context menu item that was selected.
      * @return boolean Return false to allow normal context menu processing to
      *         proceed, true to consume it here.
@@ -1564,7 +1620,298 @@
     public boolean onContextItemSelected(MenuItem item) {
         return false;
     }
-    
+
+    /**
+     * When custom transitions are used with Fragments, the enter transition callback
+     * is called when this Fragment is attached or detached when not popping the back stack.
+     *
+     * @param callback Used to manipulate the shared element transitions on this Fragment
+     *                 when added not as a pop from the back stack.
+     */
+    public void setEnterSharedElementCallback(SharedElementCallback callback) {
+        if (callback == null) {
+            callback = SharedElementCallback.NULL_CALLBACK;
+        }
+        mEnterTransitionCallback = callback;
+    }
+
+    /**
+     * @hide
+     */
+    public void setEnterSharedElementTransitionCallback(SharedElementCallback callback) {
+        setEnterSharedElementCallback(callback);
+    }
+
+    /**
+     * When custom transitions are used with Fragments, the exit transition callback
+     * is called when this Fragment is attached or detached when popping the back stack.
+     *
+     * @param callback Used to manipulate the shared element transitions on this Fragment
+     *                 when added as a pop from the back stack.
+     */
+    public void setExitSharedElementCallback(SharedElementCallback callback) {
+        if (callback == null) {
+            callback = SharedElementCallback.NULL_CALLBACK;
+        }
+        mExitTransitionCallback = callback;
+    }
+
+    /**
+     * @hide
+     */
+    public void setExitSharedElementTransitionCallback(SharedElementCallback callback) {
+        setExitSharedElementCallback(callback);
+    }
+
+    /**
+     * Sets the Transition that will be used to move Views into the initial scene. The entering
+     * Views will be those that are regular Views or ViewGroups that have
+     * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
+     * {@link android.transition.Visibility} as entering is governed by changing visibility from
+     * {@link View#INVISIBLE} to {@link View#VISIBLE}. If <code>transition</code> is null,
+     * entering Views will remain unaffected.
+     *
+     * @param transition The Transition to use to move Views into the initial Scene.
+     * @attr ref android.R.styleable#Fragment_fragmentEnterTransition
+     */
+    public void setEnterTransition(Transition transition) {
+        mEnterTransition = transition;
+    }
+
+    /**
+     * Returns the Transition that will be used to move Views into the initial scene. The entering
+     * Views will be those that are regular Views or ViewGroups that have
+     * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
+     * {@link android.transition.Visibility} as entering is governed by changing visibility from
+     * {@link View#INVISIBLE} to {@link View#VISIBLE}.
+     *
+     * @return the Transition to use to move Views into the initial Scene.
+     * @attr ref android.R.styleable#Fragment_fragmentEnterTransition
+     */
+    public Transition getEnterTransition() {
+        return mEnterTransition;
+    }
+
+    /**
+     * Sets the Transition that will be used to move Views out of the scene when the Fragment is
+     * preparing to be removed, hidden, or detached because of popping the back stack. The exiting
+     * Views will be those that are regular Views or ViewGroups that have
+     * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
+     * {@link android.transition.Visibility} as entering is governed by changing visibility from
+     * {@link View#VISIBLE} to {@link View#INVISIBLE}. If <code>transition</code> is null,
+     * entering Views will remain unaffected. If nothing is set, the default will be to
+     * use the same value as set in {@link #setEnterTransition(android.transition.Transition)}.
+     *
+     * @param transition The Transition to use to move Views out of the Scene when the Fragment
+     *                   is preparing to close.
+     * @attr ref android.R.styleable#Fragment_fragmentExitTransition
+     */
+    public void setReturnTransition(Transition transition) {
+        mReturnTransition = transition;
+    }
+
+    /**
+     * Returns the Transition that will be used to move Views out of the scene when the Fragment is
+     * preparing to be removed, hidden, or detached because of popping the back stack. The exiting
+     * Views will be those that are regular Views or ViewGroups that have
+     * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
+     * {@link android.transition.Visibility} as entering is governed by changing visibility from
+     * {@link View#VISIBLE} to {@link View#INVISIBLE}. If <code>transition</code> is null,
+     * entering Views will remain unaffected.
+     *
+     * @return the Transition to use to move Views out of the Scene when the Fragment
+     *         is preparing to close.
+     * @attr ref android.R.styleable#Fragment_fragmentExitTransition
+     */
+    public Transition getReturnTransition() {
+        return mReturnTransition == USE_DEFAULT_TRANSITION ? getEnterTransition()
+                : mReturnTransition;
+    }
+
+    /**
+     * Sets the Transition that will be used to move Views out of the scene when the
+     * fragment is removed, hidden, or detached when not popping the back stack.
+     * The exiting Views will be those that are regular Views or ViewGroups that
+     * have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
+     * {@link android.transition.Visibility} as exiting is governed by changing visibility
+     * from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will
+     * remain unaffected.
+     *
+     * @param transition The Transition to use to move Views out of the Scene when the Fragment
+     *                   is being closed not due to popping the back stack.
+     * @attr ref android.R.styleable#Fragment_fragmentExitTransition
+     */
+    public void setExitTransition(Transition transition) {
+        mExitTransition = transition;
+    }
+
+    /**
+     * Returns the Transition that will be used to move Views out of the scene when the
+     * fragment is removed, hidden, or detached when not popping the back stack.
+     * The exiting Views will be those that are regular Views or ViewGroups that
+     * have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
+     * {@link android.transition.Visibility} as exiting is governed by changing visibility
+     * from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will
+     * remain unaffected.
+     *
+     * @return the Transition to use to move Views out of the Scene when the Fragment
+     *         is being closed not due to popping the back stack.
+     * @attr ref android.R.styleable#Fragment_fragmentExitTransition
+     */
+    public Transition getExitTransition() {
+        return mExitTransition;
+    }
+
+    /**
+     * Sets the Transition that will be used to move Views in to the scene when returning due
+     * to popping a back stack. The entering Views will be those that are regular Views
+     * or ViewGroups that have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions
+     * will extend {@link android.transition.Visibility} as exiting is governed by changing
+     * visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null,
+     * the views will remain unaffected. If nothing is set, the default will be to use the same
+     * transition as {@link #setExitTransition(android.transition.Transition)}.
+     *
+     * @param transition The Transition to use to move Views into the scene when reentering from a
+     *                   previously-started Activity.
+     * @attr ref android.R.styleable#Fragment_fragmentReenterTransition
+     */
+    public void setReenterTransition(Transition transition) {
+        mReenterTransition = transition;
+    }
+
+    /**
+     * Returns the Transition that will be used to move Views in to the scene when returning due
+     * to popping a back stack. The entering Views will be those that are regular Views
+     * or ViewGroups that have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions
+     * will extend {@link android.transition.Visibility} as exiting is governed by changing
+     * visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null,
+     * the views will remain unaffected. If nothing is set, the default will be to use the same
+     * transition as {@link #setExitTransition(android.transition.Transition)}.
+     *
+     * @return the Transition to use to move Views into the scene when reentering from a
+     *                   previously-started Activity.
+     * @attr ref android.R.styleable#Fragment_fragmentReenterTransition
+     */
+    public Transition getReenterTransition() {
+        return mReenterTransition == USE_DEFAULT_TRANSITION ? getExitTransition()
+                : mReenterTransition;
+    }
+
+    /**
+     * Sets the Transition that will be used for shared elements transferred into the content
+     * Scene. Typical Transitions will affect size and location, such as
+     * {@link android.transition.ChangeBounds}. A null
+     * value will cause transferred shared elements to blink to the final position.
+     *
+     * @param transition The Transition to use for shared elements transferred into the content
+     *                   Scene.
+     * @attr ref android.R.styleable#Fragment_fragmentSharedElementEnterTransition
+     */
+    public void setSharedElementEnterTransition(Transition transition) {
+        mSharedElementEnterTransition = transition;
+    }
+
+    /**
+     * Returns the Transition that will be used for shared elements transferred into the content
+     * Scene. Typical Transitions will affect size and location, such as
+     * {@link android.transition.ChangeBounds}. A null
+     * value will cause transferred shared elements to blink to the final position.
+     *
+     * @return The Transition to use for shared elements transferred into the content
+     *                   Scene.
+     * @attr ref android.R.styleable#Fragment_fragmentSharedElementEnterTransition
+     */
+    public Transition getSharedElementEnterTransition() {
+        return mSharedElementEnterTransition;
+    }
+
+    /**
+     * Sets the Transition that will be used for shared elements transferred back during a
+     * pop of the back stack. This Transition acts in the leaving Fragment.
+     * Typical Transitions will affect size and location, such as
+     * {@link android.transition.ChangeBounds}. A null
+     * value will cause transferred shared elements to blink to the final position.
+     * If no value is set, the default will be to use the same value as
+     * {@link #setSharedElementEnterTransition(android.transition.Transition)}.
+     *
+     * @param transition The Transition to use for shared elements transferred out of the content
+     *                   Scene.
+     * @attr ref android.R.styleable#Fragment_fragmentSharedElementReturnTransition
+     */
+    public void setSharedElementReturnTransition(Transition transition) {
+        mSharedElementReturnTransition = transition;
+    }
+
+    /**
+     * Return the Transition that will be used for shared elements transferred back during a
+     * pop of the back stack. This Transition acts in the leaving Fragment.
+     * Typical Transitions will affect size and location, such as
+     * {@link android.transition.ChangeBounds}. A null
+     * value will cause transferred shared elements to blink to the final position.
+     * If no value is set, the default will be to use the same value as
+     * {@link #setSharedElementEnterTransition(android.transition.Transition)}.
+     *
+     * @return The Transition to use for shared elements transferred out of the content
+     *                   Scene.
+     * @attr ref android.R.styleable#Fragment_fragmentSharedElementReturnTransition
+     */
+    public Transition getSharedElementReturnTransition() {
+        return mSharedElementReturnTransition == USE_DEFAULT_TRANSITION ?
+                getSharedElementEnterTransition() : mSharedElementReturnTransition;
+    }
+
+    /**
+     * Sets whether the the exit transition and enter transition overlap or not.
+     * When true, the enter transition will start as soon as possible. When false, the
+     * enter transition will wait until the exit transition completes before starting.
+     *
+     * @param allow true to start the enter transition when possible or false to
+     *              wait until the exiting transition completes.
+     * @attr ref android.R.styleable#Fragment_fragmentAllowEnterTransitionOverlap
+     */
+    public void setAllowEnterTransitionOverlap(boolean allow) {
+        mAllowEnterTransitionOverlap = allow;
+    }
+
+    /**
+     * Returns whether the the exit transition and enter transition overlap or not.
+     * When true, the enter transition will start as soon as possible. When false, the
+     * enter transition will wait until the exit transition completes before starting.
+     *
+     * @return true when the enter transition should start as soon as possible or false to
+     * when it should wait until the exiting transition completes.
+     * @attr ref android.R.styleable#Fragment_fragmentAllowEnterTransitionOverlap
+     */
+    public boolean getAllowEnterTransitionOverlap() {
+        return (mAllowEnterTransitionOverlap == null) ? true : mAllowEnterTransitionOverlap;
+    }
+
+    /**
+     * Sets whether the the return transition and reenter transition overlap or not.
+     * When true, the reenter transition will start as soon as possible. When false, the
+     * reenter transition will wait until the return transition completes before starting.
+     *
+     * @param allow true to start the reenter transition when possible or false to wait until the
+     *              return transition completes.
+     * @attr ref android.R.styleable#Fragment_fragmentAllowReturnTransitionOverlap
+     */
+    public void setAllowReturnTransitionOverlap(boolean allow) {
+        mAllowReturnTransitionOverlap = allow;
+    }
+
+    /**
+     * Returns whether the the return transition and reenter transition overlap or not.
+     * When true, the reenter transition will start as soon as possible. When false, the
+     * reenter transition will wait until the return transition completes before starting.
+     *
+     * @return true to start the reenter transition when possible or false to wait until the
+     *         return transition completes.
+     * @attr ref android.R.styleable#Fragment_fragmentAllowReturnTransitionOverlap
+     */
+    public boolean getAllowReturnTransitionOverlap() {
+        return (mAllowReturnTransitionOverlap == null) ? true : mAllowReturnTransitionOverlap;
+    }
+
     /**
      * Print the Fragments's state into the given stream.
      *
@@ -1576,53 +1923,53 @@
      */
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
         writer.print(prefix); writer.print("mFragmentId=#");
-                writer.print(Integer.toHexString(mFragmentId));
-                writer.print(" mContainerId=#");
-                writer.print(Integer.toHexString(mContainerId));
-                writer.print(" mTag="); writer.println(mTag);
+        writer.print(Integer.toHexString(mFragmentId));
+        writer.print(" mContainerId=#");
+        writer.print(Integer.toHexString(mContainerId));
+        writer.print(" mTag="); writer.println(mTag);
         writer.print(prefix); writer.print("mState="); writer.print(mState);
-                writer.print(" mIndex="); writer.print(mIndex);
-                writer.print(" mWho="); writer.print(mWho);
-                writer.print(" mBackStackNesting="); writer.println(mBackStackNesting);
+        writer.print(" mIndex="); writer.print(mIndex);
+        writer.print(" mWho="); writer.print(mWho);
+        writer.print(" mBackStackNesting="); writer.println(mBackStackNesting);
         writer.print(prefix); writer.print("mAdded="); writer.print(mAdded);
-                writer.print(" mRemoving="); writer.print(mRemoving);
-                writer.print(" mResumed="); writer.print(mResumed);
-                writer.print(" mFromLayout="); writer.print(mFromLayout);
-                writer.print(" mInLayout="); writer.println(mInLayout);
+        writer.print(" mRemoving="); writer.print(mRemoving);
+        writer.print(" mResumed="); writer.print(mResumed);
+        writer.print(" mFromLayout="); writer.print(mFromLayout);
+        writer.print(" mInLayout="); writer.println(mInLayout);
         writer.print(prefix); writer.print("mHidden="); writer.print(mHidden);
-                writer.print(" mDetached="); writer.print(mDetached);
-                writer.print(" mMenuVisible="); writer.print(mMenuVisible);
-                writer.print(" mHasMenu="); writer.println(mHasMenu);
+        writer.print(" mDetached="); writer.print(mDetached);
+        writer.print(" mMenuVisible="); writer.print(mMenuVisible);
+        writer.print(" mHasMenu="); writer.println(mHasMenu);
         writer.print(prefix); writer.print("mRetainInstance="); writer.print(mRetainInstance);
-                writer.print(" mRetaining="); writer.print(mRetaining);
-                writer.print(" mUserVisibleHint="); writer.println(mUserVisibleHint);
+        writer.print(" mRetaining="); writer.print(mRetaining);
+        writer.print(" mUserVisibleHint="); writer.println(mUserVisibleHint);
         if (mFragmentManager != null) {
             writer.print(prefix); writer.print("mFragmentManager=");
-                    writer.println(mFragmentManager);
+            writer.println(mFragmentManager);
         }
         if (mActivity != null) {
             writer.print(prefix); writer.print("mActivity=");
-                    writer.println(mActivity);
+            writer.println(mActivity);
         }
         if (mParentFragment != null) {
             writer.print(prefix); writer.print("mParentFragment=");
-                    writer.println(mParentFragment);
+            writer.println(mParentFragment);
         }
         if (mArguments != null) {
             writer.print(prefix); writer.print("mArguments="); writer.println(mArguments);
         }
         if (mSavedFragmentState != null) {
             writer.print(prefix); writer.print("mSavedFragmentState=");
-                    writer.println(mSavedFragmentState);
+            writer.println(mSavedFragmentState);
         }
         if (mSavedViewState != null) {
             writer.print(prefix); writer.print("mSavedViewState=");
-                    writer.println(mSavedViewState);
+            writer.println(mSavedViewState);
         }
         if (mTarget != null) {
             writer.print(prefix); writer.print("mTarget="); writer.print(mTarget);
-                    writer.print(" mTargetRequestCode=");
-                    writer.println(mTargetRequestCode);
+            writer.print(" mTargetRequestCode=");
+            writer.println(mTargetRequestCode);
         }
         if (mNextAnim != 0) {
             writer.print(prefix); writer.print("mNextAnim="); writer.println(mNextAnim);
@@ -1636,7 +1983,7 @@
         if (mAnimatingAway != null) {
             writer.print(prefix); writer.print("mAnimatingAway="); writer.println(mAnimatingAway);
             writer.print(prefix); writer.print("mStateAfterAnimating=");
-                    writer.println(mStateAfterAnimating);
+            writer.println(mStateAfterAnimating);
         }
         if (mLoaderManager != null) {
             writer.print(prefix); writer.println("Loader Manager:");
@@ -1668,6 +2015,11 @@
                 }
                 return mView.findViewById(id);
             }
+
+            @Override
+            public boolean hasView() {
+                return (mView != null);
+            }
         }, this);
     }
 
@@ -1874,7 +2226,7 @@
             throw new SuperNotCalledException("Fragment " + this
                     + " did not call through to super.onStop()");
         }
-        
+
         if (mLoadersStarted) {
             mLoadersStarted = false;
             if (!mCheckedForLoaderManager) {
@@ -1917,4 +2269,23 @@
                     + " did not call through to super.onDestroy()");
         }
     }
+
+    private static Transition loadTransition(Context context, TypedArray typedArray,
+            Transition currentValue, Transition defaultValue, int id) {
+        if (currentValue != defaultValue) {
+            return currentValue;
+        }
+        int transitionId = typedArray.getResourceId(id, 0);
+        Transition transition = defaultValue;
+        if (transitionId != 0 && transitionId != com.android.internal.R.transition.no_transition) {
+            TransitionInflater inflater = TransitionInflater.from(context);
+            transition = inflater.inflateTransition(transitionId);
+            if (transition instanceof TransitionSet &&
+                    ((TransitionSet)transition).getTransitionCount() == 0) {
+                transition = null;
+            }
+        }
+        return transition;
+    }
+
 }
diff --git a/core/java/android/app/FragmentBreadCrumbs.java b/core/java/android/app/FragmentBreadCrumbs.java
index b810b89..d0aa0fd 100644
--- a/core/java/android/app/FragmentBreadCrumbs.java
+++ b/core/java/android/app/FragmentBreadCrumbs.java
@@ -37,7 +37,10 @@
  *
  * <p>The default style for this view is
  * {@link android.R.style#Widget_FragmentBreadCrumbs}.
+ *
+ * @deprecated This widget is no longer supported.
  */
+@Deprecated
 public class FragmentBreadCrumbs extends ViewGroup
         implements FragmentManager.OnBackStackChangedListener {
     Activity mActivity;
@@ -55,6 +58,8 @@
     private OnBreadCrumbClickListener mOnBreadCrumbClickListener;
 
     private int mGravity;
+    private int mLayoutResId;
+    private int mTextColor;
 
     private static final int DEFAULT_GRAVITY = Gravity.START | Gravity.CENTER_VERTICAL;
 
@@ -81,17 +86,31 @@
     }
 
     public FragmentBreadCrumbs(Context context, AttributeSet attrs) {
-        this(context, attrs, android.R.style.Widget_FragmentBreadCrumbs);
+        this(context, attrs, com.android.internal.R.attr.fragmentBreadCrumbsStyle);
     }
 
-    public FragmentBreadCrumbs(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public FragmentBreadCrumbs(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.FragmentBreadCrumbs, defStyle, 0);
+    /**
+     * @hide
+     */
+    public FragmentBreadCrumbs(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.FragmentBreadCrumbs, defStyleAttr, defStyleRes);
 
         mGravity = a.getInt(com.android.internal.R.styleable.FragmentBreadCrumbs_gravity,
                 DEFAULT_GRAVITY);
+        mLayoutResId = a.getResourceId(
+                com.android.internal.R.styleable.FragmentBreadCrumbs_itemLayout,
+                com.android.internal.R.layout.fragment_bread_crumb_item);
+        mTextColor = a.getColor(
+                com.android.internal.R.styleable.FragmentBreadCrumbs_itemColor,
+                0);
 
         a.recycle();
     }
@@ -300,12 +319,11 @@
                 }
             }
             if (i >= numViews) {
-                final View item = mInflater.inflate(
-                        com.android.internal.R.layout.fragment_bread_crumb_item,
-                        this, false);
+                final View item = mInflater.inflate(mLayoutResId, this, false);
                 final TextView text = (TextView) item.findViewById(com.android.internal.R.id.title);
                 text.setText(bse.getBreadCrumbTitle());
                 text.setTag(bse);
+                text.setTextColor(mTextColor);
                 if (i == 0) {
                     item.findViewById(com.android.internal.R.id.left_icon).setVisibility(View.GONE);
                 }
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 76f9d97..fc761fe 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
 import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.os.Bundle;
@@ -27,11 +28,13 @@
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.AttributeSet;
 import android.util.DebugUtils;
 import android.util.Log;
 import android.util.LogWriter;
 import android.util.SparseArray;
 import android.util.SuperNotCalledException;
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -392,12 +395,13 @@
  */
 interface FragmentContainer {
     public View findViewById(int id);
+    public boolean hasView();
 }
 
 /**
  * Container for fragments associated with an activity.
  */
-final class FragmentManagerImpl extends FragmentManager {
+final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 {
     static boolean DEBUG = false;
     static final String TAG = "FragmentManager";
     
@@ -432,7 +436,7 @@
     boolean mDestroyed;
     String mNoTransactionsBecause;
     boolean mHavePendingDeferredStart;
-    
+
     // Temporary vars for state save and restore.
     Bundle mStateBundle = null;
     SparseArray<Parcelable> mStateArray = null;
@@ -1494,7 +1498,10 @@
                 return false;
             }
             final BackStackRecord bss = mBackStack.remove(last);
-            bss.popFromBackStack(true);
+            SparseArray<Fragment> firstOutFragments = new SparseArray<Fragment>();
+            SparseArray<Fragment> lastInFragments = new SparseArray<Fragment>();
+            bss.calculateBackFragments(firstOutFragments, lastInFragments);
+            bss.popFromBackStack(true, null, firstOutFragments, lastInFragments);
             reportBackStackChanged();
         } else {
             int index = -1;
@@ -1538,9 +1545,16 @@
                 states.add(mBackStack.remove(i));
             }
             final int LAST = states.size()-1;
+            SparseArray<Fragment> firstOutFragments = new SparseArray<Fragment>();
+            SparseArray<Fragment> lastInFragments = new SparseArray<Fragment>();
+            for (int i=0; i<=LAST; i++) {
+                states.get(i).calculateBackFragments(firstOutFragments, lastInFragments);
+            }
+            BackStackRecord.TransitionState state = null;
             for (int i=0; i<=LAST; i++) {
                 if (DEBUG) Log.v(TAG, "Popping back stack state: " + states.get(i));
-                states.get(i).popFromBackStack(i == LAST);
+                state = states.get(i).popFromBackStack(i == LAST, state,
+                        firstOutFragments, lastInFragments);
             }
             reportBackStackChanged();
         }
@@ -1744,6 +1758,7 @@
                     fs.mSavedFragmentState.setClassLoader(mActivity.getClassLoader());
                     f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray(
                             FragmentManagerImpl.VIEW_STATE_TAG);
+                    f.mSavedFragmentState = fs.mSavedFragmentState;
                 }
             }
         }
@@ -2051,4 +2066,100 @@
         }
         return animAttr;
     }
+
+    @Override
+    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
+        if (!"fragment".equals(name)) {
+            return null;
+        }
+
+        String fname = attrs.getAttributeValue(null, "class");
+        TypedArray a =
+                context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Fragment);
+        if (fname == null) {
+            fname = a.getString(com.android.internal.R.styleable.Fragment_name);
+        }
+        int id = a.getResourceId(com.android.internal.R.styleable.Fragment_id, View.NO_ID);
+        String tag = a.getString(com.android.internal.R.styleable.Fragment_tag);
+        a.recycle();
+
+        int containerId = parent != null ? parent.getId() : 0;
+        if (containerId == View.NO_ID && id == View.NO_ID && tag == null) {
+            throw new IllegalArgumentException(attrs.getPositionDescription()
+                    + ": Must specify unique android:id, android:tag, or have a parent with"
+                    + " an id for " + fname);
+        }
+
+        // If we restored from a previous state, we may already have
+        // instantiated this fragment from the state and should use
+        // that instance instead of making a new one.
+        Fragment fragment = id != View.NO_ID ? findFragmentById(id) : null;
+        if (fragment == null && tag != null) {
+            fragment = findFragmentByTag(tag);
+        }
+        if (fragment == null && containerId != View.NO_ID) {
+            fragment = findFragmentById(containerId);
+        }
+
+        if (FragmentManagerImpl.DEBUG) Log.v(TAG, "onCreateView: id=0x"
+                + Integer.toHexString(id) + " fname=" + fname
+                + " existing=" + fragment);
+        if (fragment == null) {
+            fragment = Fragment.instantiate(context, fname);
+            fragment.mFromLayout = true;
+            fragment.mFragmentId = id != 0 ? id : containerId;
+            fragment.mContainerId = containerId;
+            fragment.mTag = tag;
+            fragment.mInLayout = true;
+            fragment.mFragmentManager = this;
+            fragment.onInflate(mActivity, attrs, fragment.mSavedFragmentState);
+            addFragment(fragment, true);
+        } else if (fragment.mInLayout) {
+            // A fragment already exists and it is not one we restored from
+            // previous state.
+            throw new IllegalArgumentException(attrs.getPositionDescription()
+                    + ": Duplicate id 0x" + Integer.toHexString(id)
+                    + ", tag " + tag + ", or parent id 0x" + Integer.toHexString(containerId)
+                    + " with another fragment for " + fname);
+        } else {
+            // This fragment was retained from a previous instance; get it
+            // going now.
+            fragment.mInLayout = true;
+            // If this fragment is newly instantiated (either right now, or
+            // from last saved state), then give it the attributes to
+            // initialize itself.
+            if (!fragment.mRetaining) {
+                fragment.onInflate(mActivity, attrs, fragment.mSavedFragmentState);
+            }
+        }
+
+        // If we haven't finished entering the CREATED state ourselves yet,
+        // push the inflated child fragment along.
+        if (mCurState < Fragment.CREATED && fragment.mFromLayout) {
+            moveToState(fragment, Fragment.CREATED, 0, 0, false);
+        } else {
+            moveToState(fragment);
+        }
+
+        if (fragment.mView == null) {
+            throw new IllegalStateException("Fragment " + fname
+                    + " did not create a view.");
+        }
+        if (id != 0) {
+            fragment.mView.setId(id);
+        }
+        if (fragment.mView.getTag() == null) {
+            fragment.mView.setTag(tag);
+        }
+        return fragment.mView;
+    }
+
+    @Override
+    public View onCreateView(String name, Context context, AttributeSet attrs) {
+        return null;
+    }
+
+    LayoutInflater.Factory2 getLayoutInflaterFactory() {
+        return this;
+    }
 }
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index 652ad23..25cd3cc 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -1,5 +1,8 @@
 package android.app;
 
+import android.util.Pair;
+import android.view.View;
+
 /**
  * API for performing a set of Fragment operations.
  *
@@ -169,6 +172,36 @@
     public abstract FragmentTransaction setTransition(int transit);
 
     /**
+     * TODO: remove from API
+     * @hide
+     */
+    public FragmentTransaction setCustomTransition(int sceneRootId, int transitionId) {
+        return this;
+    }
+
+    /**
+     * Used with to map a View from a removed or hidden Fragment to a View from a shown
+     * or added Fragment.
+     * @param sharedElement A View in a disappearing Fragment to match with a View in an
+     *                      appearing Fragment.
+     * @param name The transitionName for a View in an appearing Fragment to match to the shared
+     *             element.
+     */
+    public abstract FragmentTransaction addSharedElement(View sharedElement, String name);
+
+    /**
+     * TODO: remove from API
+     * @hide
+     */
+    public abstract FragmentTransaction setSharedElement(View sharedElement, String name);
+
+    /**
+     * TODO: remove from API
+     * @hide
+     */
+    public abstract FragmentTransaction setSharedElements(Pair<View, String>... sharedElements);
+
+    /**
      * Set a custom style resource that will be used for resolving transit
      * animations.
      */
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 27e97d41..aa5fea0 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -36,6 +36,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Bundle;
@@ -45,8 +46,11 @@
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.StrictMode;
+import android.service.voice.IVoiceInteractionSession;
+import com.android.internal.app.IVoiceInteractor;
 
 import java.util.List;
 
@@ -57,18 +61,19 @@
  * {@hide}
  */
 public interface IActivityManager extends IInterface {
-    public int startActivity(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int flags, String profileFile,
-            ParcelFileDescriptor profileFd, Bundle options) throws RemoteException;
-    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int flags, String profileFile,
-            ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
+    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
+            String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
+            ProfilerInfo profilerInfo, Bundle options) throws RemoteException;
+    public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
+            String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
+            ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
+    public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
+            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+            int flags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException;
     public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int flags, String profileFile,
-            ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
+            int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options,
+            int userId) throws RemoteException;
     public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int startFlags, Configuration newConfig,
@@ -77,12 +82,20 @@
             IntentSender intent, Intent fillInIntent, String resolvedType,
             IBinder resultTo, String resultWho, int requestCode,
             int flagsMask, int flagsValues, Bundle options) throws RemoteException;
+    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
+            Intent intent, String resolvedType, IVoiceInteractionSession session,
+            IVoiceInteractor interactor, int flags, ProfilerInfo profilerInfo, Bundle options,
+            int userId) throws RemoteException;
     public boolean startNextMatchingActivity(IBinder callingActivity,
             Intent intent, Bundle options) throws RemoteException;
-    public boolean finishActivity(IBinder token, int code, Intent data)
+    public int startActivityFromRecents(int taskId, Bundle options) throws RemoteException;
+    public boolean finishActivity(IBinder token, int code, Intent data, boolean finishTask)
             throws RemoteException;
     public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
     public boolean finishActivityAffinity(IBinder token) throws RemoteException;
+    public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException;
+    public boolean releaseActivityInstance(IBinder token) throws RemoteException;
+    public void releaseSomeActivities(IApplicationThread app) throws RemoteException;
     public boolean willActivityBeVisible(IBinder token) throws RemoteException;
     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
             IIntentReceiver receiver, IntentFilter filter,
@@ -100,17 +113,19 @@
             boolean stopProfiling) throws RemoteException;
     public void activityPaused(IBinder token) throws RemoteException;
     public void activityStopped(IBinder token, Bundle state,
-            Bitmap thumbnail, CharSequence description) throws RemoteException;
+            PersistableBundle persistentState, CharSequence description) throws RemoteException;
     public void activitySlept(IBinder token) throws RemoteException;
     public void activityDestroyed(IBinder token) throws RemoteException;
     public String getCallingPackage(IBinder token) throws RemoteException;
     public ComponentName getCallingActivity(IBinder token) throws RemoteException;
-    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
-                         IThumbnailReceiver receiver) throws RemoteException;
+    public List<IAppTask> getAppTasks(String callingPackage) throws RemoteException;
+    public int addAppTask(IBinder activityToken, Intent intent,
+            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException;
+    public Point getAppTaskThumbnailSize() throws RemoteException;
+    public List<RunningTaskInfo> getTasks(int maxNum, int flags) throws RemoteException;
     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
             int flags, int userId) throws RemoteException;
-    public ActivityManager.TaskThumbnails getTaskThumbnails(int taskId) throws RemoteException;
-    public Bitmap getTaskTopThumbnail(int taskId) throws RemoteException;
+    public ActivityManager.TaskThumbnail getTaskThumbnail(int taskId) throws RemoteException;
     public List<RunningServiceInfo> getServices(int maxNum, int flags) throws RemoteException;
     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
             throws RemoteException;
@@ -122,11 +137,9 @@
     public void resizeStack(int stackId, Rect bounds) throws RemoteException;
     public List<StackInfo> getAllStackInfos() throws RemoteException;
     public StackInfo getStackInfo(int stackId) throws RemoteException;
+    public boolean isInHomeStack(int taskId) throws RemoteException;
     public void setFocusedStack(int stackId) throws RemoteException;
     public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
-    /* oneway */
-    public void reportThumbnail(IBinder token,
-            Bitmap thumbnail, CharSequence description) throws RemoteException;
     public ContentProviderHolder getContentProvider(IApplicationThread caller,
             String name, int userId, boolean stable) throws RemoteException;
     public ContentProviderHolder getContentProviderExternal(String name, int userId, IBinder token)
@@ -207,14 +220,16 @@
     public int checkPermission(String permission, int pid, int uid)
             throws RemoteException;
 
-    public int checkUriPermission(Uri uri, int pid, int uid, int mode)
+    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId)
             throws RemoteException;
-    public void grantUriPermission(IApplicationThread caller, String targetPkg,
-            Uri uri, int mode) throws RemoteException;
-    public void revokeUriPermission(IApplicationThread caller, Uri uri,
-            int mode) throws RemoteException;
-    public void takePersistableUriPermission(Uri uri, int modeFlags) throws RemoteException;
-    public void releasePersistableUriPermission(Uri uri, int modeFlags) throws RemoteException;
+    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
+            int mode, int userId) throws RemoteException;
+    public void revokeUriPermission(IApplicationThread caller, Uri uri, int mode, int userId)
+            throws RemoteException;
+    public void takePersistableUriPermission(Uri uri, int modeFlags, int userId)
+            throws RemoteException;
+    public void releasePersistableUriPermission(Uri uri, int modeFlags, int userId)
+            throws RemoteException;
     public ParceledListSlice<UriPermission> getPersistedUriPermissions(
             String packageName, boolean incoming) throws RemoteException;
 
@@ -242,7 +257,8 @@
 
     public void enterSafeMode() throws RemoteException;
     
-    public void noteWakeupAlarm(IIntentSender sender) throws RemoteException;
+    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg)
+            throws RemoteException;
 
     public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException;
     public boolean killProcessesBelowForeground(String reason) throws RemoteException;
@@ -250,7 +266,7 @@
     // Special low-level communication with activity manager.
     public void handleApplicationCrash(IBinder app,
             ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;
-    public boolean handleApplicationWtf(IBinder app, String tag,
+    public boolean handleApplicationWtf(IBinder app, String tag, boolean system,
             ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;
 
     // A StrictMode violation to be handled.  The violationMask is a
@@ -277,16 +293,18 @@
             throws RemoteException;
     // Get device configuration
     public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException;
-    
+
     // Turn on/off profiling in a particular process.
     public boolean profileControl(String process, int userId, boolean start,
-            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException;
-    
+            ProfilerInfo profilerInfo, int profileType) throws RemoteException;
+
     public boolean shutdown(int timeout) throws RemoteException;
-    
+
     public void stopAppSwitches() throws RemoteException;
     public void resumeAppSwitches() throws RemoteException;
-    
+
+    public void addPackageDependency(String packageName) throws RemoteException;
+
     public void killApplicationWithAppId(String pkg, int appid, String reason)
             throws RemoteException;
     
@@ -294,10 +312,10 @@
     
     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
             throws RemoteException;
-    
+
     public void overridePendingTransition(IBinder token, String packageName,
             int enterAnim, int exitAnim) throws RemoteException;
-    
+
     public boolean isUserAMonkey() throws RemoteException;
 
     public void setUserIsMonkey(boolean monkey) throws RemoteException;
@@ -305,26 +323,30 @@
     public void finishHeavyWeightApp() throws RemoteException;
 
     public boolean convertFromTranslucent(IBinder token) throws RemoteException;
-    public boolean convertToTranslucent(IBinder token) throws RemoteException;
+    public boolean convertToTranslucent(IBinder token, ActivityOptions options) throws RemoteException;
     public void notifyActivityDrawn(IBinder token) throws RemoteException;
+    public ActivityOptions getActivityOptions(IBinder token) throws RemoteException;
+
+    public void bootAnimationComplete() throws RemoteException;
 
     public void setImmersive(IBinder token, boolean immersive) throws RemoteException;
     public boolean isImmersive(IBinder token) throws RemoteException;
     public boolean isTopActivityImmersive() throws RemoteException;
-    
+    public boolean isTopOfTask(IBinder token) throws RemoteException;
+
     public void crashApplication(int uid, int initialPid, String packageName,
             String message) throws RemoteException;
 
     public String getProviderMimeType(Uri uri, int userId) throws RemoteException;
-    
+
     public IBinder newUriPermissionOwner(String name) throws RemoteException;
     public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
-            Uri uri, int mode) throws RemoteException;
+            Uri uri, int mode, int sourceUserId, int targetUserId) throws RemoteException;
     public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
-            int mode) throws RemoteException;
+            int mode, int userId) throws RemoteException;
 
-    public int checkGrantUriPermission(int callingUid, String targetPkg,
-            Uri uri, int modeFlags) throws RemoteException;
+    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
+            int modeFlags, int userId) throws RemoteException;
 
     // Cause the specified process to dump the specified heap.
     public boolean dumpHeap(String process, int userId, boolean managed, String path,
@@ -345,13 +367,12 @@
 
     // Multi-user APIs
     public boolean switchUser(int userid) throws RemoteException;
+    public boolean startUserInBackground(int userid) throws RemoteException;
     public int stopUser(int userid, IStopUserCallback callback) throws RemoteException;
     public UserInfo getCurrentUser() throws RemoteException;
     public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException;
     public int[] getRunningUserIds() throws RemoteException;
 
-    public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException;
-
     public boolean removeTask(int taskId, int flags) throws RemoteException;
 
     public void registerProcessObserver(IProcessObserver observer) throws RemoteException;
@@ -363,15 +384,17 @@
 
     public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException;
 
+    public String getTagForIntentSender(IIntentSender sender, String prefix) throws RemoteException;
+
     public void updatePersistentConfiguration(Configuration values) throws RemoteException;
 
     public long[] getProcessPss(int[] pids) throws RemoteException;
 
     public void showBootMessage(CharSequence msg, boolean always) throws RemoteException;
 
-    public void dismissKeyguardOnNextActivity() throws RemoteException;
+    public void keyguardWaitingForActivityDrawn() throws RemoteException;
 
-    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity)
+    public boolean shouldUpRecreateTask(IBinder token, String destAffinity)
             throws RemoteException;
 
     public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
@@ -404,11 +427,9 @@
 
     public void performIdleMaintenance() throws RemoteException;
 
-    /** @hide */
     public IActivityContainer createActivityContainer(IBinder parentActivityToken,
             IActivityContainerCallback callback) throws RemoteException;
 
-    /** @hide */
     public void deleteActivityContainer(IActivityContainer container) throws RemoteException;
 
     public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
@@ -416,11 +437,34 @@
 
     public IBinder getHomeActivityToken() throws RemoteException;
 
+    public void startLockTaskModeOnCurrent() throws RemoteException;
+
+    public void startLockTaskMode(int taskId) throws RemoteException;
+
+    public void startLockTaskMode(IBinder token) throws RemoteException;
+
+    public void stopLockTaskMode() throws RemoteException;
+
+    public void stopLockTaskModeOnCurrent() throws RemoteException;
+
+    public boolean isInLockTaskMode() throws RemoteException;
+
+    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
+            throws RemoteException;
+    public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException;
+
+    public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException;
+    public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException;
+    public void backgroundResourcesReleased(IBinder token) throws RemoteException;
+
+    public void notifyLaunchTaskBehindComplete(IBinder token) throws RemoteException;
+    public void notifyEnterAnimationComplete(IBinder token) throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
     /* package */ boolean testIsSystemReady();
-    
+
     /** Information you can retrieve about a particular application. */
     public static class ContentProviderHolder implements Parcelable {
         public final ProviderInfo info;
@@ -545,7 +589,7 @@
     int MOVE_TASK_TO_BACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+24;
     int MOVE_TASK_BACKWARDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+25;
     int GET_TASK_FOR_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+26;
-    int REPORT_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
+
     int GET_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
     int PUBLISH_CONTENT_PROVIDERS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
     int REF_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
@@ -597,7 +641,7 @@
     int FORCE_STOP_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+78;
     int KILL_PIDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+79;
     int GET_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+80;
-    int GET_TASK_THUMBNAILS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+81;
+    int GET_TASK_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+81;
     int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82;
     int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
     int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
@@ -610,7 +654,7 @@
     int UNBIND_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+91;
     int GET_UID_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+92;
     int HANDLE_INCOMING_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+93;
-    int GET_TASK_TOP_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94;
+    int ADD_PACKAGE_DEPENDENCY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94;
     int KILL_APPLICATION_WITH_APPID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95;
     int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96;
     int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97;
@@ -646,7 +690,7 @@
     int GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+127;
     int SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+128;
     int SWITCH_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+129;
-    int REMOVE_SUB_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+130;
+    int ___AVAILABLE_1___ = IBinder.FIRST_CALL_TRANSACTION+130;
     int REMOVE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+131;
     int REGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+132;
     int UNREGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+133;
@@ -654,14 +698,13 @@
     int UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+135;
     int GET_PROCESS_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+136;
     int SHOW_BOOT_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+137;
-    int DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+138;
     int KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+139;
     int GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+140;
     int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141;
     int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142;
     int KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+143;
     int GET_CURRENT_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+144;
-    int TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+145;
+    int SHOULD_UP_RECREATE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+145;
     int NAVIGATE_UP_TO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+146;
     int SET_LOCK_SCREEN_SHOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+147;
     int FINISH_ACTIVITY_AFFINITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+148;
@@ -702,4 +745,36 @@
     int GET_HOME_ACTIVITY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
     int GET_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
     int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
+
+
+    // Start of L transactions
+    int GET_TAG_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+210;
+    int START_USER_IN_BACKGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+211;
+    int IS_IN_HOME_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+212;
+    int START_LOCK_TASK_BY_TASK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+213;
+    int START_LOCK_TASK_BY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+214;
+    int STOP_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+215;
+    int IS_IN_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+216;
+    int SET_TASK_DESCRIPTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+217;
+    int START_VOICE_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+218;
+    int GET_ACTIVITY_OPTIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+219;
+    int GET_APP_TASKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+220;
+    int START_LOCK_TASK_BY_CURRENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+221;
+    int STOP_LOCK_TASK_BY_CURRENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+222;
+    int FINISH_VOICE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+223;
+    int IS_TOP_OF_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+224;
+    int REQUEST_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+225;
+    int IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+226;
+    int BACKGROUND_RESOURCES_RELEASED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+227;
+    int NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+228;
+    int START_ACTIVITY_FROM_RECENTS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 229;
+    int NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+230;
+    int KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+231;
+    int START_ACTIVITY_AS_CALLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+232;
+    int ADD_APP_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+233;
+    int GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+234;
+    int RELEASE_ACTIVITY_INSTANCE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+235;
+    int RELEASE_SOME_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+236;
+    int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
+    int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
 }
diff --git a/core/java/android/app/IAlarmManager.aidl b/core/java/android/app/IAlarmManager.aidl
index ef9f26e..194082e 100644
--- a/core/java/android/app/IAlarmManager.aidl
+++ b/core/java/android/app/IAlarmManager.aidl
@@ -16,6 +16,7 @@
 */
 package android.app;
 
+import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.os.WorkSource;
 
@@ -27,10 +28,12 @@
 interface IAlarmManager {
 	/** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */
     void set(int type, long triggerAtTime, long windowLength,
-            long interval, in PendingIntent operation, in WorkSource workSource);
+            long interval, in PendingIntent operation, in WorkSource workSource,
+            in AlarmManager.AlarmClockInfo alarmClock);
     boolean setTime(long millis);
     void setTimeZone(String zone);
     void remove(in PendingIntent operation);
+    AlarmManager.AlarmClockInfo getNextAlarmClock(int userId);
 }
 
 
diff --git a/core/java/android/app/IAppTask.aidl b/core/java/android/app/IAppTask.aidl
new file mode 100644
index 0000000..37fead9
--- /dev/null
+++ b/core/java/android/app/IAppTask.aidl
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.app.ActivityManager;
+import android.content.Intent;
+import android.os.Bundle;
+
+/** @hide */
+interface IAppTask {
+    void finishAndRemoveTask();
+    ActivityManager.RecentTaskInfo getTaskInfo();
+    void moveToFront();
+    int startActivity(IBinder whoThread, String callingPackage,
+            in Intent intent, String resolvedType, in Bundle options);
+    void setExcludeFromRecents(boolean exclude);
+}
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 3aceff9..f53075c 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -25,12 +25,16 @@
 import android.content.pm.ServiceInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.IBinder;
 import android.os.IInterface;
+import android.service.voice.IVoiceInteractionSession;
+import com.android.internal.app.IVoiceInteractor;
 
 import java.io.FileDescriptor;
 import java.util.List;
@@ -45,20 +49,20 @@
  */
 public interface IApplicationThread extends IInterface {
     void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
-            int configChanges) throws RemoteException;
+            int configChanges, boolean dontReport) throws RemoteException;
     void scheduleStopActivity(IBinder token, boolean showWindow,
             int configChanges) throws RemoteException;
     void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
     void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
-    void scheduleResumeActivity(IBinder token, int procState, boolean isForward)
+    void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)
             throws RemoteException;
     void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
     void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
             ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
-            int procState, Bundle state, List<ResultInfo> pendingResults,
-    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-    		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
-    		throws RemoteException;
+            IVoiceInteractor voiceInteractor, int procState, Bundle state,
+            PersistableBundle persistentState, List<ResultInfo> pendingResults,
+            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+            ProfilerInfo profilerInfo) throws RemoteException;
     void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
             List<Intent> pendingNewIntents, int configChanges,
             boolean notResumed, Configuration config) throws RemoteException;
@@ -89,20 +93,18 @@
     static final int DEBUG_ON = 1;
     static final int DEBUG_WAIT = 2;
     void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers,
-            ComponentName testName, String profileName, ParcelFileDescriptor profileFd,
-            boolean autoStopProfiler, Bundle testArguments, IInstrumentationWatcher testWatcher,
-            IUiAutomationConnection uiAutomationConnection, int debugMode,
-            boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
+            ComponentName testName, ProfilerInfo profilerInfo, Bundle testArguments,
+            IInstrumentationWatcher testWatcher, IUiAutomationConnection uiAutomationConnection,
+            int debugMode, boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
             Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
             Bundle coreSettings) throws RemoteException;
     void scheduleExit() throws RemoteException;
     void scheduleSuicide() throws RemoteException;
-    void requestThumbnail(IBinder token) throws RemoteException;
     void scheduleConfigurationChanged(Configuration config) throws RemoteException;
     void updateTimeZone() throws RemoteException;
     void clearDnsCache() throws RemoteException;
     void setHttpProxy(String proxy, String port, String exclList,
-            String pacFileUrl) throws RemoteException;
+            Uri pacFileUrl) throws RemoteException;
     void processInBackground() throws RemoteException;
     void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args)
             throws RemoteException;
@@ -113,7 +115,7 @@
             boolean sticky, int sendingUser, int processState) throws RemoteException;
     void scheduleLowMemory() throws RemoteException;
     void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
-    void profilerControl(boolean start, String path, ParcelFileDescriptor fd, int profileType)
+    void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType)
             throws RemoteException;
     void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd)
             throws RemoteException;
@@ -136,9 +138,14 @@
             throws RemoteException;
     void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
             throws RemoteException;
+    void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options)
+            throws RemoteException;
     void setProcessState(int state) throws RemoteException;
     void scheduleInstallProvider(ProviderInfo provider) throws RemoteException;
     void updateTimePrefs(boolean is24Hour) throws RemoteException;
+    void scheduleCancelVisibleBehind(IBinder token) throws RemoteException;
+    void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) throws RemoteException;
+    void scheduleEnterAnimationComplete(IBinder token) throws RemoteException;
 
     String descriptor = "android.app.IApplicationThread";
 
@@ -155,7 +162,7 @@
     int SCHEDULE_STOP_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+11;
     int BIND_APPLICATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+12;
     int SCHEDULE_EXIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+13;
-    int REQUEST_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+14;
+
     int SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+15;
     int SCHEDULE_SERVICE_ARGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+16;
     int UPDATE_TIME_ZONE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+17;
@@ -172,7 +179,7 @@
     int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
     int SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
     int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
-
+    int SCHEDULE_ON_NEW_ACTIVITY_OPTIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
     int SCHEDULE_SUICIDE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
     int DISPATCH_PACKAGE_BROADCAST_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
     int SCHEDULE_CRASH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+34;
@@ -193,4 +200,7 @@
     int SET_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49;
     int SCHEDULE_INSTALL_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+50;
     int UPDATE_TIME_PREFS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+51;
+    int CANCEL_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+52;
+    int BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+53;
+    int ENTER_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+54;
 }
diff --git a/core/java/android/app/IBackupAgent.aidl b/core/java/android/app/IBackupAgent.aidl
index 087f83c..451af99 100644
--- a/core/java/android/app/IBackupAgent.aidl
+++ b/core/java/android/app/IBackupAgent.aidl
@@ -76,8 +76,9 @@
      * @param callbackBinder Binder on which to indicate operation completion,
      *        passed here as a convenience to the agent.
      */
-    void doRestore(in ParcelFileDescriptor data, int appVersionCode,
-            in ParcelFileDescriptor newState, int token, IBackupManager callbackBinder);
+    void doRestore(in ParcelFileDescriptor data,
+            int appVersionCode, in ParcelFileDescriptor newState,
+            int token, IBackupManager callbackBinder);
 
     /**
      * Perform a "full" backup to the given file descriptor.  The output file is presumed
@@ -112,8 +113,38 @@
      * @param path Relative path of the file within its semantic domain.
      * @param mode Access mode of the file system entity, e.g. 0660.
      * @param mtime Last modification time of the file system entity.
+     * @param token Opaque token identifying this transaction.  This must
+     *        be echoed back to the backup service binder once the agent is
+     *        finished restoring the application based on the restore data
+     *        contents.
+     * @param callbackBinder Binder on which to indicate operation completion,
+     *        passed here as a convenience to the agent.
      */
     void doRestoreFile(in ParcelFileDescriptor data, long size,
             int type, String domain, String path, long mode, long mtime,
             int token, IBackupManager callbackBinder);
+
+    /**
+     * Provide the app with a canonical "all data has been delivered" end-of-restore
+     * callback so that it can do any postprocessing of the restored data that might
+     * be appropriate.  This is issued after both key/value and full data restore
+     * operations have completed.
+     *
+     * @param token Opaque token identifying this transaction.  This must
+     *        be echoed back to the backup service binder once the agent is
+     *        finished restoring the application based on the restore data
+     *        contents.
+     * @param callbackBinder Binder on which to indicate operation completion,
+     *        passed here as a convenience to the agent.
+     */
+    void doRestoreFinished(int token, IBackupManager callbackBinder);
+
+    /**
+     * Out of band: instruct the agent to crash within the client process.  This is used
+     * when the backup infrastructure detects a semantic error post-hoc and needs to
+     * pass the problem back to the app.
+     *
+     * @param message The message to be passed to the agent's application in an exception.
+     */
+    void fail(String message);
 }
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 9911467..bdcff38 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -18,11 +18,18 @@
 package android.app;
 
 import android.app.ITransientNotification;
-import android.service.notification.StatusBarNotification;
 import android.app.Notification;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.ParceledListSlice;
+import android.net.Uri;
+import android.os.Bundle;
+import android.service.notification.Condition;
+import android.service.notification.IConditionListener;
+import android.service.notification.IConditionProvider;
 import android.service.notification.INotificationListener;
+import android.service.notification.StatusBarNotification;
+import android.service.notification.ZenModeConfig;
 
 /** {@hide} */
 interface INotificationManager
@@ -31,13 +38,21 @@
 
     void enqueueToast(String pkg, ITransientNotification callback, int duration);
     void cancelToast(String pkg, ITransientNotification callback);
-    void enqueueNotificationWithTag(String pkg, String basePkg, String tag, int id,
+    void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
             in Notification notification, inout int[] idReceived, int userId);
     void cancelNotificationWithTag(String pkg, String tag, int id, int userId);
 
     void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled);
     boolean areNotificationsEnabledForPackage(String pkg, int uid);
 
+    void setPackagePriority(String pkg, int uid, int priority);
+    int getPackagePriority(String pkg, int uid);
+
+    void setPackageVisibilityOverride(String pkg, int uid, int visibility);
+    int getPackageVisibilityOverride(String pkg, int uid);
+
+    // TODO: Remove this when callers have been migrated to the equivalent
+    // INotificationListener method.
     StatusBarNotification[] getActiveNotifications(String callingPkg);
     StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count);
 
@@ -47,6 +62,21 @@
     void cancelNotificationFromListener(in INotificationListener token, String pkg, String tag, int id);
     void cancelNotificationsFromListener(in INotificationListener token, in String[] keys);
 
-    StatusBarNotification[] getActiveNotificationsFromListener(in INotificationListener token, in String[] keys);
-    String[] getActiveNotificationKeysFromListener(in INotificationListener token);
-}
\ No newline at end of file
+    ParceledListSlice getActiveNotificationsFromListener(in INotificationListener token, in String[] keys, int trim);
+    void requestHintsFromListener(in INotificationListener token, int hints);
+    int getHintsFromListener(in INotificationListener token);
+    void requestInterruptionFilterFromListener(in INotificationListener token, int interruptionFilter);
+    int getInterruptionFilterFromListener(in INotificationListener token);
+    void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim);
+
+    ComponentName getEffectsSuppressor();
+    boolean matchesCallFilter(in Bundle extras);
+
+    ZenModeConfig getZenModeConfig();
+    boolean setZenModeConfig(in ZenModeConfig config);
+    oneway void notifyConditions(String pkg, in IConditionProvider provider, in Condition[] conditions);
+    oneway void requestZenModeConditions(in IConditionListener callback, int relevance);
+    oneway void setZenModeCondition(in Condition condition);
+    oneway void setAutomaticZenModeConditions(in Uri[] conditionIds);
+    Condition[] getAutomaticZenModeConditions();
+}
diff --git a/core/java/android/app/IProcessObserver.aidl b/core/java/android/app/IProcessObserver.aidl
index e587912..ecf2c73 100644
--- a/core/java/android/app/IProcessObserver.aidl
+++ b/core/java/android/app/IProcessObserver.aidl
@@ -20,7 +20,7 @@
 oneway interface IProcessObserver {
 
     void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities);
-    void onImportanceChanged(int pid, int uid, int importance);
+    void onProcessStateChanged(int pid, int uid, int procState);
     void onProcessDied(int pid, int uid);
 
 }
diff --git a/core/java/android/app/IThumbnailReceiver.aidl b/core/java/android/app/IThumbnailReceiver.aidl
deleted file mode 100644
index 7943f2c..0000000
--- a/core/java/android/app/IThumbnailReceiver.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* //device/java/android/android/app/IThumbnailReceiver.aidl
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-package android.app;
-
-import android.graphics.Bitmap;
-
-/**
- * System private API for receiving updated thumbnails from a checkpoint.
- *
- * {@hide}
- */
-oneway interface IThumbnailReceiver {
-    void newThumbnail(int id, in Bitmap thumbnail, CharSequence description);
-    void finished();
-}
-
diff --git a/core/java/android/app/IThumbnailRetriever.aidl b/core/java/android/app/IThumbnailRetriever.aidl
deleted file mode 100644
index 410cc20..0000000
--- a/core/java/android/app/IThumbnailRetriever.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-package android.app;
-
-import android.graphics.Bitmap;
-
-/**
- * System private API for retrieving thumbnails
- * {@hide}
- */
-interface IThumbnailRetriever {
-    Bitmap getThumbnail(int index);
-}
diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl
index 09bf829..8ab9ac3 100644
--- a/core/java/android/app/IUiAutomationConnection.aidl
+++ b/core/java/android/app/IUiAutomationConnection.aidl
@@ -19,6 +19,8 @@
 import android.accessibilityservice.IAccessibilityServiceClient;
 import android.graphics.Bitmap;
 import android.view.InputEvent;
+import android.view.WindowContentFrameStats;
+import android.view.WindowAnimationFrameStats;
 import android.os.ParcelFileDescriptor;
 
 /**
@@ -26,7 +28,7 @@
  * on behalf of an instrumentation that it runs. These operations require
  * special permissions which the shell user has but the instrumentation does
  * not. Running privileged operations by the shell user on behalf of an
- * instrumentation is needed for running UiTestCases. 
+ * instrumentation is needed for running UiTestCases.
  *
  * {@hide}
  */
@@ -37,4 +39,9 @@
     boolean setRotation(int rotation);
     Bitmap takeScreenshot(int width, int height);
     void shutdown();
+    boolean clearWindowContentFrameStats(int windowId);
+    WindowContentFrameStats getWindowContentFrameStats(int windowId);
+    void clearWindowAnimationFrameStats();
+    WindowAnimationFrameStats getWindowAnimationFrameStats();
+    void executeShellCommand(String command, in ParcelFileDescriptor fd);
 }
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 181eb63..3b5900b 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.app.IWallpaperManagerCallback;
@@ -73,6 +74,11 @@
     int getHeightHint();
 
     /**
+     * Sets extra padding that we would like the wallpaper to have outside of the display.
+     */
+    void setDisplayPadding(in Rect padding);
+
+    /**
      * Returns the name of the wallpaper. Private API.
      */
     String getName();
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 028fa68..ba3a234 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -30,6 +30,7 @@
 import android.os.Looper;
 import android.os.MessageQueue;
 import android.os.PerformanceCollector;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -187,6 +188,9 @@
             endPerformanceSnapshot();
         }
         if (mPerfMetrics != null) {
+            if (results == null) {
+                results = new Bundle();
+            }
             results.putAll(mPerfMetrics);
         }
         if (mUiAutomation != null) {
@@ -1035,10 +1039,10 @@
             IllegalAccessException {
         Activity activity = (Activity)clazz.newInstance();
         ActivityThread aThread = null;
-        activity.attach(context, aThread, this, token, application, intent,
+        activity.attach(context, aThread, this, token, 0, application, intent,
                 info, title, parent, id,
                 (Activity.NonConfigurationInstances)lastNonConfigurationInstance,
-                new Configuration());
+                new Configuration(), null);
         return activity;
     }
 
@@ -1061,15 +1065,7 @@
         return (Activity)cl.loadClass(className).newInstance();
     }
 
-    /**
-     * Perform calling of an activity's {@link Activity#onCreate}
-     * method.  The default implementation simply calls through to that method.
-     * 
-     * @param activity The activity being created.
-     * @param icicle The previously frozen state (or null) to pass through to
-     *               onCreate().
-     */
-    public void callActivityOnCreate(Activity activity, Bundle icicle) {
+    private void prePerformCreate(Activity activity) {
         if (mWaitingActivities != null) {
             synchronized (mSync) {
                 final int N = mWaitingActivities.size();
@@ -1083,9 +1079,9 @@
                 }
             }
         }
-        
-        activity.performCreate(icicle);
-        
+    }
+
+    private void postPerformCreate(Activity activity) {
         if (mActivityMonitors != null) {
             synchronized (mSync) {
                 final int N = mActivityMonitors.size();
@@ -1096,6 +1092,33 @@
             }
         }
     }
+
+    /**
+     * Perform calling of an activity's {@link Activity#onCreate}
+     * method.  The default implementation simply calls through to that method.
+     *
+     * @param activity The activity being created.
+     * @param icicle The previously frozen state (or null) to pass through to onCreate().
+     */
+    public void callActivityOnCreate(Activity activity, Bundle icicle) {
+        prePerformCreate(activity);
+        activity.performCreate(icicle);
+        postPerformCreate(activity);
+    }
+
+    /**
+     * Perform calling of an activity's {@link Activity#onCreate}
+     * method.  The default implementation simply calls through to that method.
+     *  @param activity The activity being created.
+     * @param icicle The previously frozen state (or null) to pass through to
+     * @param persistentState The previously persisted state (or null)
+     */
+    public void callActivityOnCreate(Activity activity, Bundle icicle,
+            PersistableBundle persistentState) {
+        prePerformCreate(activity);
+        activity.performCreate(icicle, persistentState);
+        postPerformCreate(activity);
+    }
     
     public void callActivityOnDestroy(Activity activity) {
       // TODO: the following block causes intermittent hangs when using startActivity
@@ -1130,7 +1153,7 @@
     /**
      * Perform calling of an activity's {@link Activity#onRestoreInstanceState}
      * method.  The default implementation simply calls through to that method.
-     * 
+     *
      * @param activity The activity being restored.
      * @param savedInstanceState The previously saved state being restored.
      */
@@ -1139,9 +1162,22 @@
     }
 
     /**
+     * Perform calling of an activity's {@link Activity#onRestoreInstanceState}
+     * method.  The default implementation simply calls through to that method.
+     *
+     * @param activity The activity being restored.
+     * @param savedInstanceState The previously saved state being restored.
+     * @param persistentState The previously persisted state (or null)
+     */
+    public void callActivityOnRestoreInstanceState(Activity activity, Bundle savedInstanceState,
+            PersistableBundle persistentState) {
+        activity.performRestoreInstanceState(savedInstanceState, persistentState);
+    }
+
+    /**
      * Perform calling of an activity's {@link Activity#onPostCreate} method.
      * The default implementation simply calls through to that method.
-     * 
+     *
      * @param activity The activity being created.
      * @param icicle The previously frozen state (or null) to pass through to
      *               onPostCreate().
@@ -1151,6 +1187,19 @@
     }
 
     /**
+     * Perform calling of an activity's {@link Activity#onPostCreate} method.
+     * The default implementation simply calls through to that method.
+     *
+     * @param activity The activity being created.
+     * @param icicle The previously frozen state (or null) to pass through to
+     *               onPostCreate().
+     */
+    public void callActivityOnPostCreate(Activity activity, Bundle icicle,
+            PersistableBundle persistentState) {
+        activity.onPostCreate(icicle, persistentState);
+    }
+
+    /**
      * Perform calling of an activity's {@link Activity#onNewIntent}
      * method.  The default implementation simply calls through to that method.
      * 
@@ -1215,7 +1264,7 @@
     /**
      * Perform calling of an activity's {@link Activity#onSaveInstanceState}
      * method.  The default implementation simply calls through to that method.
-     * 
+     *
      * @param activity The activity being saved.
      * @param outState The bundle to pass to the call.
      */
@@ -1224,6 +1273,18 @@
     }
 
     /**
+     * Perform calling of an activity's {@link Activity#onSaveInstanceState}
+     * method.  The default implementation simply calls through to that method.
+     *  @param activity The activity being saved.
+     * @param outState The bundle to pass to the call.
+     * @param outPersistentState The persistent bundle to pass to the call.
+     */
+    public void callActivityOnSaveInstanceState(Activity activity, Bundle outState,
+            PersistableBundle outPersistentState) {
+        activity.performSaveInstanceState(outState, outPersistentState);
+    }
+
+    /**
      * Perform calling of an activity's {@link Activity#onPause} method.  The
      * default implementation simply calls through to that method.
      * 
@@ -1420,7 +1481,7 @@
                 .startActivity(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
-                        requestCode, 0, null, null, options);
+                        requestCode, 0, null, options);
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
         }
@@ -1428,7 +1489,7 @@
     }
 
     /**
-     * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int)},
+     * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int, Bundle)},
      * but accepts an array of activities to be started.  Note that active
      * {@link ActivityMonitor} objects only match against the first activity in
      * the array.
@@ -1442,7 +1503,7 @@
     }
 
     /**
-     * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int)},
+     * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int, Bundle)},
      * but accepts an array of activities to be started.  Note that active
      * {@link ActivityMonitor} objects only match against the first activity in
      * the array.
@@ -1537,7 +1598,7 @@
                 .startActivity(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mWho : null,
-                        requestCode, 0, null, null, options);
+                        requestCode, 0, null, options);
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
         }
@@ -1545,7 +1606,7 @@
     }
 
     /**
-     * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int)},
+     * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int, Bundle)},
      * but for starting as a particular user.
      *
      * @param who The Context from which the activity is being started.
@@ -1597,13 +1658,84 @@
                 .startActivityAsUser(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
-                        requestCode, 0, null, null, options, user.getIdentifier());
+                        requestCode, 0, null, options, user.getIdentifier());
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
         }
         return null;
     }
 
+    /**
+     * Special version!
+     * @hide
+     */
+    public ActivityResult execStartActivityAsCaller(
+            Context who, IBinder contextThread, IBinder token, Activity target,
+            Intent intent, int requestCode, Bundle options) {
+        IApplicationThread whoThread = (IApplicationThread) contextThread;
+        if (mActivityMonitors != null) {
+            synchronized (mSync) {
+                final int N = mActivityMonitors.size();
+                for (int i=0; i<N; i++) {
+                    final ActivityMonitor am = mActivityMonitors.get(i);
+                    if (am.match(who, null, intent)) {
+                        am.mHits++;
+                        if (am.isBlocking()) {
+                            return requestCode >= 0 ? am.getResult() : null;
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+        try {
+            intent.migrateExtraStreamToClipData();
+            intent.prepareToLeaveProcess();
+            int result = ActivityManagerNative.getDefault()
+                .startActivityAsCaller(whoThread, who.getBasePackageName(), intent,
+                        intent.resolveTypeIfNeeded(who.getContentResolver()),
+                        token, target != null ? target.mEmbeddedID : null,
+                        requestCode, 0, null, options);
+            checkStartActivityResult(result, intent);
+        } catch (RemoteException e) {
+        }
+        return null;
+    }
+
+    /**
+     * Special version!
+     * @hide
+     */
+    public void execStartActivityFromAppTask(
+            Context who, IBinder contextThread, IAppTask appTask,
+            Intent intent, Bundle options) {
+        IApplicationThread whoThread = (IApplicationThread) contextThread;
+        if (mActivityMonitors != null) {
+            synchronized (mSync) {
+                final int N = mActivityMonitors.size();
+                for (int i=0; i<N; i++) {
+                    final ActivityMonitor am = mActivityMonitors.get(i);
+                    if (am.match(who, null, intent)) {
+                        am.mHits++;
+                        if (am.isBlocking()) {
+                            return;
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+        try {
+            intent.migrateExtraStreamToClipData();
+            intent.prepareToLeaveProcess();
+            int result = appTask.startActivity(whoThread.asBinder(), who.getBasePackageName(),
+                    intent, intent.resolveTypeIfNeeded(who.getContentResolver()), options);
+            checkStartActivityResult(result, intent);
+        } catch (RemoteException e) {
+        }
+        return;
+    }
+
     /*package*/ final void init(ActivityThread thread,
             Context instrContext, Context appContext, ComponentName component, 
             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection) {
@@ -1616,7 +1748,8 @@
         mUiAutomationConnection = uiAutomationConnection;
     }
 
-    /*package*/ static void checkStartActivityResult(int res, Object intent) {
+    /** @hide */
+    public static void checkStartActivityResult(int res, Object intent) {
         if (res >= ActivityManager.START_SUCCESS) {
             return;
         }
@@ -1640,6 +1773,9 @@
             case ActivityManager.START_NOT_ACTIVITY:
                 throw new IllegalArgumentException(
                         "PendingIntent is not an activity");
+            case ActivityManager.START_NOT_VOICE_COMPATIBLE:
+                throw new SecurityException(
+                        "Starting under voice control not allowed for: " + intent);
             default:
                 throw new AndroidRuntimeException("Unknown error code "
                         + res + " when starting " + intent);
diff --git a/core/java/android/app/JobSchedulerImpl.java b/core/java/android/app/JobSchedulerImpl.java
new file mode 100644
index 0000000..09038d5
--- /dev/null
+++ b/core/java/android/app/JobSchedulerImpl.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// in android.app so ContextImpl has package access
+package android.app;
+
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.app.job.IJobScheduler;
+import android.os.RemoteException;
+
+import java.util.List;
+
+
+/**
+ * Concrete implementation of the JobScheduler interface
+ * @hide 
+ */
+public class JobSchedulerImpl extends JobScheduler {
+    IJobScheduler mBinder;
+
+    /* package */ JobSchedulerImpl(IJobScheduler binder) {
+        mBinder = binder;
+    }
+
+    @Override
+    public int schedule(JobInfo job) {
+        try {
+            return mBinder.schedule(job);
+        } catch (RemoteException e) {
+            return JobScheduler.RESULT_FAILURE;
+        }
+    }
+
+    @Override
+    public void cancel(int jobId) {
+        try {
+            mBinder.cancel(jobId);
+        } catch (RemoteException e) {}
+
+    }
+
+    @Override
+    public void cancelAll() {
+        try {
+            mBinder.cancelAll();
+        } catch (RemoteException e) {}
+
+    }
+
+    @Override
+    public List<JobInfo> getAllPendingJobs() {
+        try {
+            return mBinder.getAllPendingJobs();
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+}
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index aab6ed8..cc9aed8 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.content.Intent;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.os.IBinder;
@@ -24,7 +25,7 @@
 import android.view.WindowManagerGlobal;
 
 /**
- * Class that can be used to lock and unlock the keyboard. Get an instance of this 
+ * Class that can be used to lock and unlock the keyboard. Get an instance of this
  * class by calling {@link android.content.Context#getSystemService(java.lang.String)}
  * with argument {@link android.content.Context#KEYGUARD_SERVICE}. The
  * actual class to control the keyboard locking is
@@ -34,6 +35,45 @@
     private IWindowManager mWM;
 
     /**
+     * Intent used to prompt user for device credentials.
+     * @hide
+     */
+    public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL =
+            "android.app.action.CONFIRM_DEVICE_CREDENTIAL";
+
+    /**
+     * A CharSequence dialog title to show to the user when used with a
+     * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
+     * @hide
+     */
+    public static final String EXTRA_TITLE = "android.app.extra.TITLE";
+
+    /**
+     * A CharSequence description to show to the user when used with
+     * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
+     * @hide
+     */
+    public static final String EXTRA_DESCRIPTION = "android.app.extra.DESCRIPTION";
+
+    /**
+     * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
+     * for the current user of the device. The caller is expected to launch this activity using
+     * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
+     * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
+     *
+     * @return the intent for launching the activity or null if no password is required.
+     **/
+    public Intent createConfirmDeviceCredentialIntent(CharSequence title, CharSequence description) {
+        if (!isKeyguardSecure()) return null;
+        Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL);
+        intent.putExtra(EXTRA_TITLE, title);
+        intent.putExtra(EXTRA_DESCRIPTION, description);
+        // For security reasons, only allow this to come from system settings.
+        intent.setPackage("com.android.settings");
+        return intent;
+    }
+
+    /**
      * @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD}
      * and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED}
      * instead; this allows you to seamlessly hide the keyguard as your application
@@ -44,8 +84,8 @@
      * you to disable / reenable the keyguard.
      */
     public class KeyguardLock {
-        private IBinder mToken = new Binder();
-        private String mTag;
+        private final IBinder mToken = new Binder();
+        private final String mTag;
 
         KeyguardLock(String tag) {
             mTag = tag;
@@ -58,7 +98,7 @@
          *
          * A good place to call this is from {@link android.app.Activity#onResume()}
          *
-         * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager} 
+         * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
          * is enabled that requires a password.
          *
          * <p>This method requires the caller to hold the permission
@@ -121,7 +161,7 @@
      * permissions be requested.
      *
      * Enables you to lock or unlock the keyboard. Get an instance of this class by
-     * calling {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}. 
+     * calling {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
      * This class is wrapped by {@link android.app.KeyguardManager KeyguardManager}.
      * @param tag A tag that informally identifies who you are (for debugging who
      *   is disabling he keyguard).
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index d409352..d143b86 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -16,8 +16,8 @@
 
 package android.app;
 
+import android.text.TextUtils;
 import android.util.ArrayMap;
-import com.android.internal.util.ArrayUtils;
 
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -40,16 +40,24 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.util.AndroidRuntimeException;
+import android.util.Log;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.view.DisplayAdjustments;
 import android.view.Display;
+import dalvik.system.VMRuntime;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.Objects;
 
 final class IntentReceiverLeaked extends AndroidRuntimeException {
     public IntentReceiverLeaked(String msg) {
@@ -76,6 +84,8 @@
     final String mPackageName;
     private final String mAppDir;
     private final String mResDir;
+    private final String[] mSplitAppDirs;
+    private final String[] mSplitResDirs;
     private final String[] mOverlayDirs;
     private final String[] mSharedLibraries;
     private final String mDataDir;
@@ -84,6 +94,7 @@
     private final ClassLoader mBaseClassLoader;
     private final boolean mSecurityViolation;
     private final boolean mIncludeCode;
+    private final boolean mRegisterPackage;
     private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
     Resources mResources;
     private ClassLoader mClassLoader;
@@ -112,14 +123,17 @@
      */
     public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
             CompatibilityInfo compatInfo, ClassLoader baseLoader,
-            boolean securityViolation, boolean includeCode) {
+            boolean securityViolation, boolean includeCode, boolean registerPackage) {
+        final int myUid = Process.myUid();
+        aInfo = adjustNativeLibraryPaths(aInfo);
+
         mActivityThread = activityThread;
         mApplicationInfo = aInfo;
         mPackageName = aInfo.packageName;
         mAppDir = aInfo.sourceDir;
-        final int myUid = Process.myUid();
-        mResDir = aInfo.uid == myUid ? aInfo.sourceDir
-                : aInfo.publicSourceDir;
+        mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;
+        mSplitAppDirs = aInfo.splitSourceDirs;
+        mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs;
         mOverlayDirs = aInfo.resourceDirs;
         if (!UserHandle.isSameUser(aInfo.uid, myUid) && !Process.isIsolated()) {
             aInfo.dataDir = PackageManager.getDataDirForUser(UserHandle.getUserId(myUid),
@@ -132,9 +146,31 @@
         mBaseClassLoader = baseLoader;
         mSecurityViolation = securityViolation;
         mIncludeCode = includeCode;
+        mRegisterPackage = registerPackage;
         mDisplayAdjustments.setCompatibilityInfo(compatInfo);
     }
 
+    private static ApplicationInfo adjustNativeLibraryPaths(ApplicationInfo info) {
+        // If we're dealing with a multi-arch application that has both
+        // 32 and 64 bit shared libraries, we might need to choose the secondary
+        // depending on what the current runtime's instruction set is.
+        if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
+            final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
+            final String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
+
+            // If the runtimeIsa is the same as the primary isa, then we do nothing.
+            // Everything will be set up correctly because info.nativeLibraryDir will
+            // correspond to the right ISA.
+            if (runtimeIsa.equals(secondaryIsa)) {
+                final ApplicationInfo modified = new ApplicationInfo(info);
+                modified.nativeLibraryDir = modified.secondaryNativeLibraryDir;
+                return modified;
+            }
+        }
+
+        return info;
+    }
+
     /**
      * Create information about the system package.
      * Must call {@link #installSystemApplicationInfo} later.
@@ -146,6 +182,8 @@
         mPackageName = "android";
         mAppDir = null;
         mResDir = null;
+        mSplitAppDirs = null;
+        mSplitResDirs = null;
         mOverlayDirs = null;
         mSharedLibraries = null;
         mDataDir = null;
@@ -154,6 +192,7 @@
         mBaseClassLoader = null;
         mSecurityViolation = false;
         mIncludeCode = true;
+        mRegisterPackage = false;
         mClassLoader = ClassLoader.getSystemClassLoader();
         mResources = Resources.getSystem();
     }
@@ -161,9 +200,10 @@
     /**
      * Sets application info about the system package.
      */
-    void installSystemApplicationInfo(ApplicationInfo info) {
+    void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
         assert info.packageName.equals("android");
         mApplicationInfo = info;
+        mClassLoader = classLoader;
     }
 
     public String getPackageName() {
@@ -211,53 +251,6 @@
         return ai.sharedLibraryFiles;
     }
 
-    /**
-     * Combines two arrays (of library names) such that they are
-     * concatenated in order but are devoid of duplicates. The
-     * result is a single string with the names of the libraries
-     * separated by colons, or <code>null</code> if both lists
-     * were <code>null</code> or empty.
-     *
-     * @param list1 null-ok; the first list
-     * @param list2 null-ok; the second list
-     * @return null-ok; the combination
-     */
-    private static String combineLibs(String[] list1, String[] list2) {
-        StringBuilder result = new StringBuilder(300);
-        boolean first = true;
-
-        if (list1 != null) {
-            for (String s : list1) {
-                if (first) {
-                    first = false;
-                } else {
-                    result.append(':');
-                }
-                result.append(s);
-            }
-        }
-
-        // Only need to check for duplicates if list1 was non-empty.
-        boolean dupCheck = !first;
-
-        if (list2 != null) {
-            for (String s : list2) {
-                if (dupCheck && ArrayUtils.contains(list1, s)) {
-                    continue;
-                }
-
-                if (first) {
-                    first = false;
-                } else {
-                    result.append(':');
-                }
-                result.append(s);
-            }
-        }
-
-        return result.toString();
-    }
-
     public ClassLoader getClassLoader() {
         synchronized (this) {
             if (mClassLoader != null) {
@@ -265,8 +258,34 @@
             }
 
             if (mIncludeCode && !mPackageName.equals("android")) {
-                String zip = mAppDir;
-                String libraryPath = mLibDir;
+                // Avoid the binder call when the package is the current application package.
+                // The activity manager will perform ensure that dexopt is performed before
+                // spinning up the process.
+                if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) {
+                    final String isa = VMRuntime.getRuntime().vmInstructionSet();
+                    try {
+                        ActivityThread.getPackageManager().performDexOptIfNeeded(mPackageName, isa);
+                    } catch (RemoteException re) {
+                        // Ignored.
+                    }
+                }
+
+                final ArrayList<String> zipPaths = new ArrayList<>();
+                final ArrayList<String> libPaths = new ArrayList<>();
+
+                if (mRegisterPackage) {
+                    try {
+                        ActivityManagerNative.getDefault().addPackageDependency(mPackageName);
+                    } catch (RemoteException e) {
+                    }
+                }
+
+                zipPaths.add(mAppDir);
+                if (mSplitAppDirs != null) {
+                    Collections.addAll(zipPaths, mSplitAppDirs);
+                }
+
+                libPaths.add(mLibDir);
 
                 /*
                  * The following is a bit of a hack to inject
@@ -277,50 +296,70 @@
                  * concatenation of both apps' shared library lists.
                  */
 
-                String instrumentationAppDir =
-                        mActivityThread.mInstrumentationAppDir;
-                String instrumentationAppLibraryDir =
-                        mActivityThread.mInstrumentationAppLibraryDir;
-                String instrumentationAppPackage =
-                        mActivityThread.mInstrumentationAppPackage;
-                String instrumentedAppDir =
-                        mActivityThread.mInstrumentedAppDir;
-                String instrumentedAppLibraryDir =
-                        mActivityThread.mInstrumentedAppLibraryDir;
+                String instrumentationPackageName = mActivityThread.mInstrumentationPackageName;
+                String instrumentationAppDir = mActivityThread.mInstrumentationAppDir;
+                String[] instrumentationSplitAppDirs = mActivityThread.mInstrumentationSplitAppDirs;
+                String instrumentationLibDir = mActivityThread.mInstrumentationLibDir;
+
+                String instrumentedAppDir = mActivityThread.mInstrumentedAppDir;
+                String[] instrumentedSplitAppDirs = mActivityThread.mInstrumentedSplitAppDirs;
+                String instrumentedLibDir = mActivityThread.mInstrumentedLibDir;
                 String[] instrumentationLibs = null;
 
                 if (mAppDir.equals(instrumentationAppDir)
                         || mAppDir.equals(instrumentedAppDir)) {
-                    zip = instrumentationAppDir + ":" + instrumentedAppDir;
-                    libraryPath = instrumentationAppLibraryDir + ":" + instrumentedAppLibraryDir;
-                    if (! instrumentedAppDir.equals(instrumentationAppDir)) {
-                        instrumentationLibs =
-                            getLibrariesFor(instrumentationAppPackage);
+                    zipPaths.clear();
+                    zipPaths.add(instrumentationAppDir);
+                    if (instrumentationSplitAppDirs != null) {
+                        Collections.addAll(zipPaths, instrumentationSplitAppDirs);
+                    }
+                    zipPaths.add(instrumentedAppDir);
+                    if (instrumentedSplitAppDirs != null) {
+                        Collections.addAll(zipPaths, instrumentedSplitAppDirs);
+                    }
+
+                    libPaths.clear();
+                    libPaths.add(instrumentationLibDir);
+                    libPaths.add(instrumentedLibDir);
+
+                    if (!instrumentedAppDir.equals(instrumentationAppDir)) {
+                        instrumentationLibs = getLibrariesFor(instrumentationPackageName);
                     }
                 }
 
-                if ((mSharedLibraries != null) ||
-                        (instrumentationLibs != null)) {
-                    zip =
-                        combineLibs(mSharedLibraries, instrumentationLibs)
-                        + ':' + zip;
+                if (mSharedLibraries != null) {
+                    for (String lib : mSharedLibraries) {
+                        if (!zipPaths.contains(lib)) {
+                            zipPaths.add(0, lib);
+                        }
+                    }
                 }
 
+                if (instrumentationLibs != null) {
+                    for (String lib : instrumentationLibs) {
+                        if (!zipPaths.contains(lib)) {
+                            zipPaths.add(0, lib);
+                        }
+                    }
+                }
+
+                final String zip = TextUtils.join(File.pathSeparator, zipPaths);
+                final String lib = TextUtils.join(File.pathSeparator, libPaths);
+
                 /*
                  * With all the combination done (if necessary, actually
                  * create the class loader.
                  */
 
                 if (ActivityThread.localLOGV)
-                    Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + libraryPath);
+                    Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + lib);
 
                 // Temporarily disable logging of disk reads on the Looper thread
                 // as this is early and necessary.
                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
 
-                mClassLoader =
-                    ApplicationLoaders.getDefault().getClassLoader(
-                        zip, libraryPath, mBaseClassLoader);
+                mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, lib,
+                        mBaseClassLoader);
                 initializeJavaContextClassLoader();
 
                 StrictMode.setThreadPolicy(oldPolicy);
@@ -466,6 +505,14 @@
         return mResDir;
     }
 
+    public String[] getSplitAppDirs() {
+        return mSplitAppDirs;
+    }
+
+    public String[] getSplitResDirs() {
+        return mSplitResDirs;
+    }
+
     public String[] getOverlayDirs() {
         return mOverlayDirs;
     }
@@ -484,8 +531,8 @@
 
     public Resources getResources(ActivityThread mainThread) {
         if (mResources == null) {
-            mResources = mainThread.getTopLevelResources(mResDir, mOverlayDirs,
-                    Display.DEFAULT_DISPLAY, null, this);
+            mResources = mainThread.getTopLevelResources(mResDir, mSplitResDirs, mOverlayDirs,
+                    mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, null, this);
         }
         return mResources;
     }
@@ -530,10 +577,56 @@
                 }
             }
         }
-        
+
+        // Rewrite the R 'constants' for all library apks.
+        SparseArray<String> packageIdentifiers = getAssets(mActivityThread)
+                .getAssignedPackageIdentifiers();
+        final int N = packageIdentifiers.size();
+        for (int i = 0; i < N; i++) {
+            final int id = packageIdentifiers.keyAt(i);
+            if (id == 0x01 || id == 0x7f) {
+                continue;
+            }
+
+            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
+        }
+
         return app;
     }
 
+    private void rewriteRValues(ClassLoader cl, String packageName, int id) {
+        final Class<?> rClazz;
+        try {
+            rClazz = cl.loadClass(packageName + ".R");
+        } catch (ClassNotFoundException e) {
+            // This is not necessarily an error, as some packages do not ship with resources
+            // (or they do not need rewriting).
+            Log.i(TAG, "No resource references to update in package " + packageName);
+            return;
+        }
+
+        final Method callback;
+        try {
+            callback = rClazz.getMethod("onResourcesLoaded", int.class);
+        } catch (NoSuchMethodException e) {
+            // No rewriting to be done.
+            return;
+        }
+
+        Throwable cause;
+        try {
+            callback.invoke(null, id);
+            return;
+        } catch (IllegalAccessException e) {
+            cause = e;
+        } catch (InvocationTargetException e) {
+            cause = e.getCause();
+        }
+
+        throw new RuntimeException("Failed to rewrite resource references for " + packageName,
+                cause);
+    }
+
     public void removeContextRegistrations(Context context,
             String who, String what) {
         final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index a7982f4..fa2813e 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -73,13 +73,18 @@
     }
 
     public MediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public MediaRouteButton(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         mRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
         mCallback = new MediaRouterCallback();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.MediaRouteButton, defStyleAttr, 0);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.MediaRouteButton, defStyleAttr, defStyleRes);
         setRemoteIndicatorDrawable(a.getDrawable(
                 com.android.internal.R.styleable.MediaRouteButton_externalRouteEnabledDrawable));
         mMinWidth = a.getDimensionPixelSize(
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index d51c397..4b3aefe 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -16,13 +16,23 @@
 
 package android.app;
 
+import android.annotation.IntDef;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
 import android.content.Intent;
-import android.content.res.Resources;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.media.AudioAttributes;
 import android.media.AudioManager;
+import android.media.session.MediaSession;
 import android.net.Uri;
 import android.os.BadParcelableException;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -30,6 +40,7 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.MathUtils;
 import android.util.TypedValue;
 import android.view.Gravity;
 import android.view.View;
@@ -37,7 +48,11 @@
 import android.widget.RemoteViews;
 
 import com.android.internal.R;
+import com.android.internal.util.NotificationColorUtil;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Constructor;
 import java.text.NumberFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -63,6 +78,15 @@
     private static final String TAG = "Notification";
 
     /**
+     * An activity that provides a user interface for adjusting notification preferences for its
+     * containing application. Optional but recommended for apps that post
+     * {@link android.app.Notification Notifications}.
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES
+            = "android.intent.category.NOTIFICATION_PREFERENCES";
+
+    /**
      * Use all default values (where applicable).
      */
     public static final int DEFAULT_ALL = ~0;
@@ -71,7 +95,10 @@
      * Use the default notification sound. This will ignore any given
      * {@link #sound}.
      *
-
+     * <p>
+     * A notification that is noisy is more likely to be presented as a heads-up notification.
+     * </p>
+     *
      * @see #defaults
      */
 
@@ -82,6 +109,10 @@
      * {@link #vibrate}. Using phone vibration requires the
      * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
      *
+     * <p>
+     * A notification that vibrates is more likely to be presented as a heads-up notification.
+     * </p>
+     *
      * @see #defaults
      */
 
@@ -98,6 +129,14 @@
     public static final int DEFAULT_LIGHTS = 4;
 
     /**
+     * Maximum length of CharSequences accepted by Builder and friends.
+     *
+     * <p>
+     * Avoids spamming the system with overly large strings such as full e-mails.
+     */
+    private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024;
+
+    /**
      * A timestamp related to this notification, in milliseconds since the epoch.
      *
      * Default value: {@link System#currentTimeMillis() Now}.
@@ -175,22 +214,32 @@
     /**
      * An intent to launch instead of posting the notification to the status bar.
      *
+     * <p>
+     * The system UI may choose to display a heads-up notification, instead of
+     * launching this intent, while the user is using the device.
+     * </p>
+     *
      * @see Notification.Builder#setFullScreenIntent
      */
     public PendingIntent fullScreenIntent;
 
     /**
-     * Text to scroll across the screen when this item is added to
-     * the status bar on large and smaller devices.
+     * Text that summarizes this notification for accessibility services.
+     *
+     * As of the L release, this text is no longer shown on screen, but it is still useful to
+     * accessibility services (where it serves as an audible announcement of the notification's
+     * appearance).
      *
      * @see #tickerView
      */
     public CharSequence tickerText;
 
     /**
-     * The view to show as the ticker in the status bar when the notification
-     * is posted.
+     * Formerly, a view showing the {@link #tickerText}.
+     *
+     * No longer displayed in the status bar as of API 21.
      */
+    @Deprecated
     public RemoteViews tickerView;
 
     /**
@@ -205,6 +254,15 @@
      */
     public RemoteViews bigContentView;
 
+
+    /**
+     * A medium-format version of {@link #contentView}, providing the Notification an
+     * opportunity to add action buttons to contentView. At its discretion, the system UI may
+     * choose to show this as a heads-up notification, which will pop up so the user can see
+     * it without leaving their current activity.
+     */
+    public RemoteViews headsUpContentView;
+
     /**
      * The bitmap that may escape the bounds of the panel and bar.
      */
@@ -214,6 +272,10 @@
      * The sound to play.
      *
      * <p>
+     * A notification that is noisy is more likely to be presented as a heads-up notification.
+     * </p>
+     *
+     * <p>
      * To play the default notification sound, see {@link #defaults}.
      * </p>
      */
@@ -223,23 +285,46 @@
      * Use this constant as the value for audioStreamType to request that
      * the default stream type for notifications be used.  Currently the
      * default stream type is {@link AudioManager#STREAM_NOTIFICATION}.
+     *
+     * @deprecated Use {@link #audioAttributes} instead.
      */
+    @Deprecated
     public static final int STREAM_DEFAULT = -1;
 
     /**
      * The audio stream type to use when playing the sound.
      * Should be one of the STREAM_ constants from
      * {@link android.media.AudioManager}.
+     *
+     * @deprecated Use {@link #audioAttributes} instead.
      */
+    @Deprecated
     public int audioStreamType = STREAM_DEFAULT;
 
     /**
+     * The default value of {@link #audioAttributes}.
+     */
+    public static final AudioAttributes AUDIO_ATTRIBUTES_DEFAULT = new AudioAttributes.Builder()
+            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+            .setUsage(AudioAttributes.USAGE_NOTIFICATION)
+            .build();
+
+    /**
+     * The {@link AudioAttributes audio attributes} to use when playing the sound.
+     */
+    public AudioAttributes audioAttributes = AUDIO_ATTRIBUTES_DEFAULT;
+
+    /**
      * The pattern with which to vibrate.
      *
      * <p>
      * To vibrate the default pattern, see {@link #defaults}.
      * </p>
      *
+     * <p>
+     * A notification that vibrates is more likely to be presented as a heads-up notification.
+     * </p>
+     *
      * @see android.os.Vibrator#vibrate(long[],int)
      */
     public long[] vibrate;
@@ -369,6 +454,11 @@
 
     public int flags;
 
+    /** @hide */
+    @IntDef({PRIORITY_DEFAULT,PRIORITY_LOW,PRIORITY_MIN,PRIORITY_HIGH,PRIORITY_MAX})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Priority {}
+
     /**
      * Default notification {@link #priority}. If your application does not prioritize its own
      * notifications, use this value for all notifications.
@@ -409,78 +499,131 @@
      * situations, while the user might be interrupted for a higher-priority notification. The
      * system will make a determination about how to interpret this priority when presenting
      * the notification.
+     *
+     * <p>
+     * A notification that is at least {@link #PRIORITY_HIGH} is more likely to be presented
+     * as a heads-up notification.
+     * </p>
+     *
      */
+    @Priority
     public int priority;
 
     /**
+     * Accent color (an ARGB integer like the constants in {@link android.graphics.Color})
+     * to be applied by the standard Style templates when presenting this notification.
+     *
+     * The current template design constructs a colorful header image by overlaying the
+     * {@link #icon} image (stenciled in white) atop a field of this color. Alpha components are
+     * ignored.
+     */
+    public int color = COLOR_DEFAULT;
+
+    /**
+     * Special value of {@link #color} telling the system not to decorate this notification with
+     * any special color but instead use default colors when presenting this notification.
+     */
+    public static final int COLOR_DEFAULT = 0; // AKA Color.TRANSPARENT
+
+    /**
+     * Sphere of visibility of this notification, which affects how and when the SystemUI reveals 
+     * the notification's presence and contents in untrusted situations (namely, on the secure 
+     * lockscreen).
+     *
+     * The default level, {@link #VISIBILITY_PRIVATE}, behaves exactly as notifications have always
+     * done on Android: The notification's {@link #icon} and {@link #tickerText} (if available) are
+     * shown in all situations, but the contents are only available if the device is unlocked for
+     * the appropriate user.
+     *
+     * A more permissive policy can be expressed by {@link #VISIBILITY_PUBLIC}; such a notification
+     * can be read even in an "insecure" context (that is, above a secure lockscreen).
+     * To modify the public version of this notification—for example, to redact some portions—see
+     * {@link Builder#setPublicVersion(Notification)}.
+     *
+     * Finally, a notification can be made {@link #VISIBILITY_SECRET}, which will suppress its icon
+     * and ticker until the user has bypassed the lockscreen.
+     */
+    public int visibility;
+
+    /**
+     * Notification visibility: Show this notification in its entirety on all lockscreens.
+     *
+     * {@see #visibility}
+     */
+    public static final int VISIBILITY_PUBLIC = 1;
+
+    /**
+     * Notification visibility: Show this notification on all lockscreens, but conceal sensitive or
+     * private information on secure lockscreens.
+     *
+     * {@see #visibility}
+     */
+    public static final int VISIBILITY_PRIVATE = 0;
+
+    /**
+     * Notification visibility: Do not reveal any part of this notification on a secure lockscreen.
+     *
+     * {@see #visibility}
+     */
+    public static final int VISIBILITY_SECRET = -1;
+
+    /**
      * Notification category: incoming call (voice or video) or similar synchronous communication request.
-     * @hide
      */
     public static final String CATEGORY_CALL = "call";
 
     /**
      * Notification category: incoming direct message (SMS, instant message, etc.).
-     * @hide
      */
     public static final String CATEGORY_MESSAGE = "msg";
 
     /**
      * Notification category: asynchronous bulk message (email).
-     * @hide
      */
     public static final String CATEGORY_EMAIL = "email";
 
     /**
      * Notification category: calendar event.
-     * @hide
      */
     public static final String CATEGORY_EVENT = "event";
 
     /**
      * Notification category: promotion or advertisement.
-     * @hide
      */
     public static final String CATEGORY_PROMO = "promo";
 
     /**
      * Notification category: alarm or timer.
-     * @hide
      */
     public static final String CATEGORY_ALARM = "alarm";
 
     /**
      * Notification category: progress of a long-running background operation.
-     * @hide
      */
     public static final String CATEGORY_PROGRESS = "progress";
 
     /**
      * Notification category: social network or sharing update.
-     * @hide
      */
     public static final String CATEGORY_SOCIAL = "social";
 
     /**
      * Notification category: error in background operation or authentication status.
-     * @hide
      */
     public static final String CATEGORY_ERROR = "err";
 
     /**
      * Notification category: media transport control for playback.
-     * @hide
      */
     public static final String CATEGORY_TRANSPORT = "transport";
 
     /**
      * Notification category: system or device status update.  Reserved for system use.
-     * @hide
      */
     public static final String CATEGORY_SYSTEM = "sys";
 
     /**
      * Notification category: indication of running background service.
-     * @hide
      */
     public static final String CATEGORY_SERVICE = "service";
 
@@ -488,20 +631,17 @@
      * Notification category: a specific, timely recommendation for a single thing.
      * For example, a news app might want to recommend a news story it believes the user will
      * want to read next.
-     * @hide
      */
     public static final String CATEGORY_RECOMMENDATION = "recommendation";
 
     /**
      * Notification category: ongoing information about device or contextual status.
-     * @hide
      */
     public static final String CATEGORY_STATUS = "status";
 
     /**
      * One of the predefined notification categories (see the <code>CATEGORY_*</code> constants)
      * that best describes this Notification.  May be used by the system for ranking and filtering.
-     * @hide
      */
     public String category;
 
@@ -581,6 +721,13 @@
     public static final String EXTRA_SUMMARY_TEXT = "android.summaryText";
 
     /**
+     * {@link #extras} key: this is the longer text shown in the big form of a
+     * {@link BigTextStyle} notification, as supplied to
+     * {@link BigTextStyle#bigText(CharSequence)}.
+     */
+    public static final String EXTRA_BIG_TEXT = "android.bigText";
+
+    /**
      * {@link #extras} key: this is the resource ID of the notification's main small icon, as
      * supplied to {@link Builder#setSmallIcon(int)}.
      */
@@ -645,20 +792,20 @@
     public static final String EXTRA_TEXT_LINES = "android.textLines";
 
     /**
-     * {@link #extras} key: An array of people that this notification relates to, specified
-     * by contacts provider contact URI.
+     * {@link #extras} key: A string representing the name of the specific
+     * {@link android.app.Notification.Style} used to create this notification.
+     */
+    public static final String EXTRA_TEMPLATE = "android.template";
+
+    /**
+     * {@link #extras} key: A String array containing the people that this notification relates to,
+     * each of which was supplied to {@link Builder#addPerson(String)}.
      */
     public static final String EXTRA_PEOPLE = "android.people";
 
     /**
-     * @hide
-     * Extra added by NotificationManagerService to indicate whether a NotificationScorer
-     * modified the Notifications's score.
-     */
-    public static final String EXTRA_SCORE_MODIFIED = "android.scoreModified";
-
-    /**
-     * Not used.
+     * {@link #extras} key: used to provide hints about the appropriateness of
+     * displaying this notification as a heads-up notification.
      * @hide
      */
     public static final String EXTRA_AS_HEADS_UP = "headsup";
@@ -671,19 +818,58 @@
     public static final String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup";
 
     /**
-     * Value for {@link #EXTRA_AS_HEADS_UP}.
+     * {@link #extras} key: A
+     * {@link android.content.ContentUris content URI} pointing to an image that can be displayed
+     * in the background when the notification is selected. The URI must point to an image stream
+     * suitable for passing into
+     * {@link android.graphics.BitmapFactory#decodeStream(java.io.InputStream)
+     * BitmapFactory.decodeStream}; all other content types will be ignored. The content provider
+     * URI used for this purpose must require no permissions to read the image data.
+     */
+    public static final String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
+
+    /**
+     * {@link #extras} key: A
+     * {@link android.media.session.MediaSession.Token} associated with a
+     * {@link android.app.Notification.MediaStyle} notification.
+     */
+    public static final String EXTRA_MEDIA_SESSION = "android.mediaSession";
+
+    /**
+     * {@link #extras} key: the indices of actions to be shown in the compact view,
+     * as supplied to (e.g.) {@link MediaStyle#setShowActionsInCompactView(int...)}.
+     */
+    public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+
+    /**
+     * {@link #extras} key: the user that built the notification.
+     *
+     * @hide
+     */
+    public static final String EXTRA_ORIGINATING_USERID = "android.originatingUserId";
+
+    /**
+     * Value for {@link #EXTRA_AS_HEADS_UP} that indicates this notification should not be
+     * displayed in the heads up space.
+     *
+     * <p>
+     * If this notification has a {@link #fullScreenIntent}, then it will always launch the
+     * full-screen intent when posted.
+     * </p>
      * @hide
      */
     public static final int HEADS_UP_NEVER = 0;
 
     /**
-     * Default value for {@link #EXTRA_AS_HEADS_UP}.
+     * Default value for {@link #EXTRA_AS_HEADS_UP} that indicates this notification may be
+     * displayed as a heads up.
      * @hide
      */
     public static final int HEADS_UP_ALLOWED = 1;
 
     /**
-     * Value for {@link #EXTRA_AS_HEADS_UP}.
+     * Value for {@link #EXTRA_AS_HEADS_UP} that indicates this notification is a
+     * good candidate for display as a heads up.
      * @hide
      */
     public static final int HEADS_UP_REQUESTED = 2;
@@ -1019,6 +1205,13 @@
     public Action[] actions;
 
     /**
+     * Replacement version of this notification whose content will be shown
+     * in an insecure context such as atop a secure keyguard. See {@link #visibility}
+     * and {@link #VISIBILITY_PUBLIC}.
+     */
+    public Notification publicVersion;
+
+    /**
      * Constructs a Notification object with default values.
      * You might want to consider using {@link Builder} instead.
      */
@@ -1096,6 +1289,9 @@
         }
 
         audioStreamType = parcel.readInt();
+        if (parcel.readInt() != 0) {
+            audioAttributes = AudioAttributes.CREATOR.createFromParcel(parcel);
+        }
         vibrate = parcel.createLongArray();
         ledARGB = parcel.readInt();
         ledOnMS = parcel.readInt();
@@ -1121,6 +1317,18 @@
         if (parcel.readInt() != 0) {
             bigContentView = RemoteViews.CREATOR.createFromParcel(parcel);
         }
+
+        if (parcel.readInt() != 0) {
+            headsUpContentView = RemoteViews.CREATOR.createFromParcel(parcel);
+        }
+
+        visibility = parcel.readInt();
+
+        if (parcel.readInt() != 0) {
+            publicVersion = Notification.CREATOR.createFromParcel(parcel);
+        }
+
+        color = parcel.readInt();
     }
 
     @Override
@@ -1160,6 +1368,9 @@
         that.iconLevel = this.iconLevel;
         that.sound = this.sound; // android.net.Uri is immutable
         that.audioStreamType = this.audioStreamType;
+        if (this.audioAttributes != null) {
+            that.audioAttributes = new AudioAttributes.Builder(this.audioAttributes).build();
+        }
 
         final long[] vibrate = this.vibrate;
         if (vibrate != null) {
@@ -1205,6 +1416,19 @@
             that.bigContentView = this.bigContentView.clone();
         }
 
+        if (heavy && this.headsUpContentView != null) {
+            that.headsUpContentView = this.headsUpContentView.clone();
+        }
+
+        that.visibility = this.visibility;
+
+        if (this.publicVersion != null) {
+            that.publicVersion = new Notification();
+            this.publicVersion.cloneInto(that.publicVersion, heavy);
+        }
+
+        that.color = this.color;
+
         if (!heavy) {
             that.lightenPayload(); // will clean out extras
         }
@@ -1219,11 +1443,15 @@
         tickerView = null;
         contentView = null;
         bigContentView = null;
+        headsUpContentView = null;
         largeIcon = null;
         if (extras != null) {
             extras.remove(Notification.EXTRA_LARGE_ICON);
             extras.remove(Notification.EXTRA_LARGE_ICON_BIG);
             extras.remove(Notification.EXTRA_PICTURE);
+            extras.remove(Notification.EXTRA_BIG_TEXT);
+            // Prevent light notifications from being rebuilt.
+            extras.remove(Builder.EXTRA_NEEDS_REBUILD);
         }
     }
 
@@ -1233,6 +1461,10 @@
      * @hide
      */
     public static CharSequence safeCharSequence(CharSequence cs) {
+        if (cs == null) return cs;
+        if (cs.length() > MAX_CHARSEQUENCE_LENGTH) {
+            cs = cs.subSequence(0, MAX_CHARSEQUENCE_LENGTH);
+        }
         if (cs instanceof Parcelable) {
             Log.e(TAG, "warning: " + cs.getClass().getCanonicalName()
                     + " instance is a custom Parcelable and not allowed in Notification");
@@ -1303,6 +1535,14 @@
             parcel.writeInt(0);
         }
         parcel.writeInt(audioStreamType);
+
+        if (audioAttributes != null) {
+            parcel.writeInt(1);
+            audioAttributes.writeToParcel(parcel, 0);
+        } else {
+            parcel.writeInt(0);
+        }
+
         parcel.writeLongArray(vibrate);
         parcel.writeInt(ledARGB);
         parcel.writeInt(ledOnMS);
@@ -1334,6 +1574,24 @@
         } else {
             parcel.writeInt(0);
         }
+
+        if (headsUpContentView != null) {
+            parcel.writeInt(1);
+            headsUpContentView.writeToParcel(parcel, 0);
+        } else {
+            parcel.writeInt(0);
+        }
+
+        parcel.writeInt(visibility);
+
+        if (publicVersion != null) {
+            parcel.writeInt(1);
+            publicVersion.writeToParcel(parcel, 0);
+        } else {
+            parcel.writeInt(0);
+        }
+
+        parcel.writeInt(color);
     }
 
     /**
@@ -1383,6 +1641,7 @@
         builder.setPriority(this.priority);
         builder.setTicker(this.tickerText);
         builder.setNumber(this.number);
+        builder.setColor(this.color);
         builder.mFlags = this.flags;
         builder.setSound(this.sound, this.audioStreamType);
         builder.setDefaults(this.defaults);
@@ -1412,7 +1671,6 @@
         } else {
             sb.append("null");
         }
-        // TODO(dsandler): defaults take precedence over local values, so reorder the branches below
         sb.append(" vibrate=");
         if ((this.defaults & DEFAULT_VIBRATE) != 0) {
             sb.append("default");
@@ -1442,6 +1700,7 @@
         sb.append(Integer.toHexString(this.defaults));
         sb.append(" flags=0x");
         sb.append(Integer.toHexString(this.flags));
+        sb.append(String.format(" color=0x%08x", this.color));
         if (this.category != null) {
             sb.append(" category=");
             sb.append(this.category);
@@ -1455,29 +1714,56 @@
             sb.append(this.mSortKey);
         }
         if (actions != null) {
-            sb.append(" ");
+            sb.append(" actions=");
             sb.append(actions.length);
-            sb.append(" action");
-            if (actions.length > 1) sb.append("s");
+        }
+        sb.append(" vis=");
+        sb.append(visibilityToString(this.visibility));
+        if (this.publicVersion != null) {
+            sb.append(" publicVersion=");
+            sb.append(publicVersion.toString());
         }
         sb.append(")");
         return sb.toString();
     }
 
-    /** {@hide} */
-    public void setUser(UserHandle user) {
-        if (user.getIdentifier() == UserHandle.USER_ALL) {
-            user = UserHandle.OWNER;
+    /**
+     * {@hide}
+     */
+    public static String visibilityToString(int vis) {
+        switch (vis) {
+            case VISIBILITY_PRIVATE:
+                return "PRIVATE";
+            case VISIBILITY_PUBLIC:
+                return "PUBLIC";
+            case VISIBILITY_SECRET:
+                return "SECRET";
+            default:
+                return "UNKNOWN(" + String.valueOf(vis) + ")";
         }
-        if (tickerView != null) {
-            tickerView.setUser(user);
-        }
-        if (contentView != null) {
-            contentView.setUser(user);
-        }
-        if (bigContentView != null) {
-            bigContentView.setUser(user);
-        }
+    }
+
+    /**
+     * @hide
+     */
+    public boolean isValid() {
+        // Would like to check for icon!=0 here, too, but NotificationManagerService accepts that
+        // for legacy reasons.
+        return contentView != null || extras.getBoolean(Builder.EXTRA_REBUILD_CONTENT_VIEW);
+    }
+
+    /**
+     * @hide
+     */
+    public boolean isGroupSummary() {
+        return mGroupKey != null && (flags & FLAG_GROUP_SUMMARY) != 0;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean isGroupChild() {
+        return mGroupKey != null && (flags & FLAG_GROUP_SUMMARY) == 0;
     }
 
     /**
@@ -1503,6 +1789,58 @@
      */
     public static class Builder {
         private static final int MAX_ACTION_BUTTONS = 3;
+        private static final float LARGE_TEXT_SCALE = 1.3f;
+
+        /**
+         * @hide
+         */
+        public static final String EXTRA_NEEDS_REBUILD = "android.rebuild";
+
+        /**
+         * @hide
+         */
+        public static final String EXTRA_REBUILD_LARGE_ICON = "android.rebuild.largeIcon";
+        /**
+         * @hide
+         */
+        public static final String EXTRA_REBUILD_CONTENT_VIEW = "android.rebuild.contentView";
+        /**
+         * @hide
+         */
+        public static final String EXTRA_REBUILD_CONTENT_VIEW_ACTION_COUNT =
+                "android.rebuild.contentViewActionCount";
+        /**
+         * @hide
+         */
+        public static final String EXTRA_REBUILD_BIG_CONTENT_VIEW
+                = "android.rebuild.bigView";
+        /**
+         * @hide
+         */
+        public static final String EXTRA_REBUILD_BIG_CONTENT_VIEW_ACTION_COUNT
+                = "android.rebuild.bigViewActionCount";
+        /**
+         * @hide
+         */
+        public static final String EXTRA_REBUILD_HEADS_UP_CONTENT_VIEW
+                = "android.rebuild.hudView";
+        /**
+         * @hide
+         */
+        public static final String EXTRA_REBUILD_HEADS_UP_CONTENT_VIEW_ACTION_COUNT
+                = "android.rebuild.hudViewActionCount";
+
+        /**
+         * The ApplicationInfo of the package that created the notification, used to create
+         * a context to rebuild the notification via a Builder.
+         * @hide
+         */
+        private static final String EXTRA_REBUILD_CONTEXT_APPLICATION_INFO =
+                "android.rebuild.applicationInfo";
+
+        // Whether to enable stripping (at post time) & rebuilding (at listener receive time) of
+        // memory intensive resources.
+        private static final boolean STRIP_AND_REBUILD = true;
 
         private Context mContext;
 
@@ -1523,6 +1861,7 @@
         private Bitmap mLargeIcon;
         private Uri mSound;
         private int mAudioStreamType;
+        private AudioAttributes mAudioAttributes;
         private long[] mVibrate;
         private int mLedArgb;
         private int mLedOnMs;
@@ -1541,6 +1880,35 @@
         private boolean mUseChronometer;
         private Style mStyle;
         private boolean mShowWhen = true;
+        private int mVisibility = VISIBILITY_PRIVATE;
+        private Notification mPublicVersion = null;
+        private final NotificationColorUtil mColorUtil;
+        private ArrayList<String> mPeople;
+        private int mColor = COLOR_DEFAULT;
+
+        /**
+         * The user that built the notification originally.
+         */
+        private int mOriginatingUserId;
+
+        /**
+         * Contains extras related to rebuilding during the build phase.
+         */
+        private Bundle mRebuildBundle = new Bundle();
+        /**
+         * Contains the notification to rebuild when this Builder is in "rebuild" mode.
+         * Null otherwise.
+         */
+        private Notification mRebuildNotification = null;
+
+        /**
+         * Whether the build notification has three lines. This is used to make the top padding for
+         * both the contracted and expanded layout consistent.
+         *
+         * <p>
+         * This field is only valid during the build phase.
+         */
+        private boolean mHasThreeLines;
 
         /**
          * Constructs a new Builder with the defaults:
@@ -1562,12 +1930,60 @@
          *            object.
          */
         public Builder(Context context) {
+            /*
+             * Important compatibility note!
+             * Some apps out in the wild create a Notification.Builder in their Activity subclass
+             * constructor for later use. At this point Activities - themselves subclasses of
+             * ContextWrapper - do not have their inner Context populated yet. This means that
+             * any calls to Context methods from within this constructor can cause NPEs in existing
+             * apps. Any data populated from mContext should therefore be populated lazily to
+             * preserve compatibility.
+             */
             mContext = context;
 
             // Set defaults to match the defaults of a Notification
             mWhen = System.currentTimeMillis();
             mAudioStreamType = STREAM_DEFAULT;
+            mAudioAttributes = AUDIO_ATTRIBUTES_DEFAULT;
             mPriority = PRIORITY_DEFAULT;
+            mPeople = new ArrayList<String>();
+
+            mColorUtil = context.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.L ?
+                    NotificationColorUtil.getInstance(mContext) : null;
+        }
+
+        /**
+         * Creates a Builder for rebuilding the given Notification.
+         * <p>
+         * Call {@link #rebuild()} to retrieve the rebuilt version of 'n'.
+         */
+        private Builder(Context context, Notification n) {
+            this(context);
+            mRebuildNotification = n;
+            restoreFromNotification(n);
+
+            Style style = null;
+            Bundle extras = n.extras;
+            String templateClass = extras.getString(EXTRA_TEMPLATE);
+            if (!TextUtils.isEmpty(templateClass)) {
+                Class<? extends Style> styleClass = getNotificationStyleClass(templateClass);
+                if (styleClass == null) {
+                    Log.d(TAG, "Unknown style class: " + styleClass);
+                    return;
+                }
+
+                try {
+                    Constructor<? extends Style> constructor = styleClass.getConstructor();
+                    style = constructor.newInstance();
+                    style.restoreFromExtras(extras);
+                } catch (Throwable t) {
+                    Log.e(TAG, "Could not create Style", t);
+                    return;
+                }
+            }
+            if (style != null) {
+                setStyle(style);
+            }
         }
 
         /**
@@ -1747,6 +2163,11 @@
          * to turn it off and use a normal notification, as this can be extremely
          * disruptive.
          *
+         * <p>
+         * The system UI may choose to display a heads-up notification, instead of
+         * launching this intent, while the user is using the device.
+         * </p>
+         *
          * @param intent The pending intent to launch.
          * @param highPriority Passing true will cause this notification to be sent
          *          even if other notifications are suppressed.
@@ -1760,8 +2181,7 @@
         }
 
         /**
-         * Set the "ticker" text which is displayed in the status bar when the notification first
-         * arrives.
+         * Set the "ticker" text which is sent to accessibility services.
          *
          * @see Notification#tickerText
          */
@@ -1771,16 +2191,13 @@
         }
 
         /**
-         * Set the text that is displayed in the status bar when the notification first
-         * arrives, and also a RemoteViews object that may be displayed instead on some
-         * devices.
+         * Obsolete version of {@link #setTicker(CharSequence)}.
          *
-         * @see Notification#tickerText
-         * @see Notification#tickerView
          */
+        @Deprecated
         public Builder setTicker(CharSequence tickerText, RemoteViews views) {
             mTickerText = safeCharSequence(tickerText);
-            mTickerView = views;
+            mTickerView = views; // we'll save it for you anyway
             return this;
         }
 
@@ -1800,13 +2217,18 @@
         /**
          * Set the sound to play.
          *
-         * It will be played on the {@link #STREAM_DEFAULT default stream} for notifications.
+         * It will be played using the {@link #AUDIO_ATTRIBUTES_DEFAULT default audio attributes}
+         * for notifications.
+         *
+         * <p>
+         * A notification that is noisy is more likely to be presented as a heads-up notification.
+         * </p>
          *
          * @see Notification#sound
          */
         public Builder setSound(Uri sound) {
             mSound = sound;
-            mAudioStreamType = STREAM_DEFAULT;
+            mAudioAttributes = AUDIO_ATTRIBUTES_DEFAULT;
             return this;
         }
 
@@ -1815,8 +2237,13 @@
          *
          * See {@link android.media.AudioManager} for the <code>STREAM_</code> constants.
          *
+         * <p>
+         * A notification that is noisy is more likely to be presented as a heads-up notification.
+         * </p>
+         * @deprecated use {@link #setSound(Uri, AudioAttributes)} instead.
          * @see Notification#sound
          */
+        @Deprecated
         public Builder setSound(Uri sound, int streamType) {
             mSound = sound;
             mAudioStreamType = streamType;
@@ -1824,13 +2251,31 @@
         }
 
         /**
+         * Set the sound to play, along with specific {@link AudioAttributes audio attributes} to
+         * use during playback.
+         *
+         * <p>
+         * A notification that is noisy is more likely to be presented as a heads-up notification.
+         * </p>
+         *
+         * @see Notification#sound
+         */
+        public Builder setSound(Uri sound, AudioAttributes audioAttributes) {
+            mSound = sound;
+            mAudioAttributes = audioAttributes;
+            return this;
+        }
+
+        /**
          * Set the vibration pattern to use.
          *
-
          * See {@link android.os.Vibrator#vibrate(long[], int)} for a discussion of the
          * <code>pattern</code> parameter.
          *
-
+         * <p>
+         * A notification that vibrates is more likely to be presented as a heads-up notification.
+         * </p>
+         *
          * @see Notification#vibrate
          */
         public Builder setVibrate(long[] pattern) {
@@ -1930,7 +2375,7 @@
          *
          * @see Notification#priority
          */
-        public Builder setPriority(int pri) {
+        public Builder setPriority(@Priority int pri) {
             mPriority = pri;
             return this;
         }
@@ -1939,7 +2384,6 @@
          * Set the notification category.
          *
          * @see Notification#category
-         * @hide
          */
         public Builder setCategory(String category) {
             mCategory = category;
@@ -1947,6 +2391,33 @@
         }
 
         /**
+         * Add a person that is relevant to this notification.
+         *
+         * <P>
+         * Depending on user preferences, this annotation may allow the notification to pass
+         * through interruption filters, and to appear more prominently in the user interface.
+         * </P>
+         *
+         * <P>
+         * The person should be specified by the {@code String} representation of a
+         * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}.
+         * </P>
+         *
+         * <P>The system will also attempt to resolve {@code mailto:} and {@code tel:} schema
+         * URIs.  The path part of these URIs must exist in the contacts database, in the
+         * appropriate column, or the reference will be discarded as invalid. Telephone schema
+         * URIs will be resolved by {@link android.provider.ContactsContract.PhoneLookup}.
+         * </P>
+         *
+         * @param uri A URI for the person.
+         * @see Notification#EXTRA_PEOPLE
+         */
+        public Builder addPerson(String uri) {
+            mPeople.add(uri);
+            return this;
+        }
+
+        /**
          * Set this notification to be part of a group of notifications sharing the same key.
          * Grouped notifications may display in a cluster or stack on devices which
          * support such rendering.
@@ -2101,6 +2572,30 @@
         }
 
         /**
+         * Specify the value of {@link #visibility}.
+         *
+         * @param visibility One of {@link #VISIBILITY_PRIVATE} (the default),
+         * {@link #VISIBILITY_SECRET}, or {@link #VISIBILITY_PUBLIC}.
+         *
+         * @return The same Builder.
+         */
+        public Builder setVisibility(int visibility) {
+            mVisibility = visibility;
+            return this;
+        }
+
+        /**
+         * Supply a replacement Notification whose contents should be shown in insecure contexts
+         * (i.e. atop the secure lockscreen). See {@link #visibility} and {@link #VISIBILITY_PUBLIC}.
+         * @param n A replacement notification, presumably with some or all info redacted.
+         * @return The same Builder.
+         */
+        public Builder setPublicVersion(Notification n) {
+            mPublicVersion = n;
+            return this;
+        }
+
+        /**
          * Apply an extender to this notification builder. Extenders may be used to add
          * metadata or change options on this builder.
          */
@@ -2117,47 +2612,143 @@
             }
         }
 
-        private RemoteViews applyStandardTemplate(int resId, boolean fitIn1U) {
-            RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
+        /**
+         * Sets {@link Notification#color}.
+         *
+         * @param argb The accent color to use
+         *
+         * @return The same Builder.
+         */
+        public Builder setColor(int argb) {
+            mColor = argb;
+            return this;
+        }
+
+        private Drawable getProfileBadgeDrawable() {
+            // Note: This assumes that the current user can read the profile badge of the
+            // originating user.
+            return mContext.getPackageManager().getUserBadgeForDensity(
+                    new UserHandle(mOriginatingUserId), 0);
+        }
+
+        private Bitmap getProfileBadge() {
+            Drawable badge = getProfileBadgeDrawable();
+            if (badge == null) {
+                return null;
+            }
+            final int size = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.notification_badge_size);
+            Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
+            Canvas canvas = new Canvas(bitmap);
+            badge.setBounds(0, 0, size, size);
+            badge.draw(canvas);
+            return bitmap;
+        }
+
+        private boolean addProfileBadge(RemoteViews contentView, int resId) {
+            Bitmap profileBadge = getProfileBadge();
+
+            contentView.setViewVisibility(R.id.profile_badge_large_template, View.GONE);
+            contentView.setViewVisibility(R.id.profile_badge_line2, View.GONE);
+            contentView.setViewVisibility(R.id.profile_badge_line3, View.GONE);
+
+            if (profileBadge != null) {
+                contentView.setImageViewBitmap(resId, profileBadge);
+                contentView.setViewVisibility(resId, View.VISIBLE);
+
+                // Make sure Line 3 is visible. As badge will be here if there
+                // is no text to display.
+                if (resId == R.id.profile_badge_line3) {
+                    contentView.setViewVisibility(R.id.line3, View.VISIBLE);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        private void shrinkLine3Text(RemoteViews contentView) {
+            float subTextSize = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.notification_subtext_size);
+            contentView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_PX, subTextSize);
+        }
+
+        private void unshrinkLine3Text(RemoteViews contentView) {
+            float regularTextSize = mContext.getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.notification_text_size);
+            contentView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_PX, regularTextSize);
+        }
+
+        private void resetStandardTemplate(RemoteViews contentView) {
+            removeLargeIconBackground(contentView);
+            contentView.setViewPadding(R.id.icon, 0, 0, 0, 0);
+            contentView.setImageViewResource(R.id.icon, 0);
+            contentView.setInt(R.id.icon, "setBackgroundResource", 0);
+            contentView.setViewVisibility(R.id.right_icon, View.GONE);
+            contentView.setInt(R.id.right_icon, "setBackgroundResource", 0);
+            contentView.setImageViewResource(R.id.right_icon, 0);
+            contentView.setImageViewResource(R.id.icon, 0);
+            contentView.setTextViewText(R.id.title, null);
+            contentView.setTextViewText(R.id.text, null);
+            unshrinkLine3Text(contentView);
+            contentView.setTextViewText(R.id.text2, null);
+            contentView.setViewVisibility(R.id.text2, View.GONE);
+            contentView.setViewVisibility(R.id.info, View.GONE);
+            contentView.setViewVisibility(R.id.time, View.GONE);
+            contentView.setViewVisibility(R.id.line3, View.GONE);
+            contentView.setViewVisibility(R.id.overflow_divider, View.GONE);
+            contentView.setViewVisibility(R.id.progress, View.GONE);
+            contentView.setViewVisibility(R.id.chronometer, View.GONE);
+            contentView.setViewVisibility(R.id.time, View.GONE);
+        }
+
+        private RemoteViews applyStandardTemplate(int resId) {
+            return applyStandardTemplate(resId, true /* hasProgress */);
+        }
+
+        /**
+         * @param hasProgress whether the progress bar should be shown and set
+         */
+        private RemoteViews applyStandardTemplate(int resId, boolean hasProgress) {
+            RemoteViews contentView = new BuilderRemoteViews(mContext.getApplicationInfo(), resId);
+
+            resetStandardTemplate(contentView);
+
             boolean showLine3 = false;
             boolean showLine2 = false;
-            int smallIconImageViewId = R.id.icon;
+            boolean contentTextInLine2 = false;
+
             if (mLargeIcon != null) {
                 contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
-                smallIconImageViewId = R.id.right_icon;
-            }
-            if (mPriority < PRIORITY_LOW) {
-                contentView.setInt(R.id.icon,
-                        "setBackgroundResource", R.drawable.notification_template_icon_low_bg);
-                contentView.setInt(R.id.status_bar_latest_event_content,
-                        "setBackgroundResource", R.drawable.notification_bg_low);
-            }
-            if (mSmallIcon != 0) {
-                contentView.setImageViewResource(smallIconImageViewId, mSmallIcon);
-                contentView.setViewVisibility(smallIconImageViewId, View.VISIBLE);
-            } else {
-                contentView.setViewVisibility(smallIconImageViewId, View.GONE);
+                processLargeLegacyIcon(mLargeIcon, contentView);
+                contentView.setImageViewResource(R.id.right_icon, mSmallIcon);
+                contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
+                processSmallRightIcon(mSmallIcon, contentView);
+            } else { // small icon at left
+                contentView.setImageViewResource(R.id.icon, mSmallIcon);
+                contentView.setViewVisibility(R.id.icon, View.VISIBLE);
+                processSmallIconAsLarge(mSmallIcon, contentView);
             }
             if (mContentTitle != null) {
-                contentView.setTextViewText(R.id.title, mContentTitle);
+                contentView.setTextViewText(R.id.title, processLegacyText(mContentTitle));
             }
             if (mContentText != null) {
-                contentView.setTextViewText(R.id.text, mContentText);
+                contentView.setTextViewText(R.id.text, processLegacyText(mContentText));
                 showLine3 = true;
             }
             if (mContentInfo != null) {
-                contentView.setTextViewText(R.id.info, mContentInfo);
+                contentView.setTextViewText(R.id.info, processLegacyText(mContentInfo));
                 contentView.setViewVisibility(R.id.info, View.VISIBLE);
                 showLine3 = true;
             } else if (mNumber > 0) {
                 final int tooBig = mContext.getResources().getInteger(
                         R.integer.status_bar_notification_info_maxnum);
                 if (mNumber > tooBig) {
-                    contentView.setTextViewText(R.id.info, mContext.getResources().getString(
-                                R.string.status_bar_notification_info_overflow));
+                    contentView.setTextViewText(R.id.info, processLegacyText(
+                            mContext.getResources().getString(
+                                    R.string.status_bar_notification_info_overflow)));
                 } else {
                     NumberFormat f = NumberFormat.getIntegerInstance();
-                    contentView.setTextViewText(R.id.info, f.format(mNumber));
+                    contentView.setTextViewText(R.id.info, processLegacyText(f.format(mNumber)));
                 }
                 contentView.setViewVisibility(R.id.info, View.VISIBLE);
                 showLine3 = true;
@@ -2167,38 +2758,33 @@
 
             // Need to show three lines?
             if (mSubText != null) {
-                contentView.setTextViewText(R.id.text, mSubText);
+                contentView.setTextViewText(R.id.text, processLegacyText(mSubText));
                 if (mContentText != null) {
-                    contentView.setTextViewText(R.id.text2, mContentText);
+                    contentView.setTextViewText(R.id.text2, processLegacyText(mContentText));
                     contentView.setViewVisibility(R.id.text2, View.VISIBLE);
                     showLine2 = true;
+                    contentTextInLine2 = true;
                 } else {
                     contentView.setViewVisibility(R.id.text2, View.GONE);
                 }
             } else {
                 contentView.setViewVisibility(R.id.text2, View.GONE);
-                if (mProgressMax != 0 || mProgressIndeterminate) {
+                if (hasProgress && (mProgressMax != 0 || mProgressIndeterminate)) {
+                    contentView.setViewVisibility(R.id.progress, View.VISIBLE);
                     contentView.setProgressBar(
                             R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);
-                    contentView.setViewVisibility(R.id.progress, View.VISIBLE);
                     showLine2 = true;
                 } else {
                     contentView.setViewVisibility(R.id.progress, View.GONE);
                 }
             }
             if (showLine2) {
-                if (fitIn1U) {
-                    // need to shrink all the type to make sure everything fits
-                    final Resources res = mContext.getResources();
-                    final float subTextSize = res.getDimensionPixelSize(
-                            R.dimen.notification_subtext_size);
-                    contentView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_PX, subTextSize);
-                }
-                // vertical centering
-                contentView.setViewPadding(R.id.line1, 0, 0, 0, 0);
+
+                // need to shrink all the type to make sure everything fits
+                shrinkLine3Text(contentView);
             }
 
-            if (mWhen != 0 && mShowWhen) {
+            if (showsTimeOrChronometer()) {
                 if (mUseChronometer) {
                     contentView.setViewVisibility(R.id.chronometer, View.VISIBLE);
                     contentView.setLong(R.id.chronometer, "setBase",
@@ -2208,28 +2794,92 @@
                     contentView.setViewVisibility(R.id.time, View.VISIBLE);
                     contentView.setLong(R.id.time, "setTime", mWhen);
                 }
-            } else {
-                contentView.setViewVisibility(R.id.time, View.GONE);
             }
 
+            // Adjust padding depending on line count and font size.
+            contentView.setViewPadding(R.id.line1, 0, calculateTopPadding(mContext,
+                    mHasThreeLines, mContext.getResources().getConfiguration().fontScale),
+                    0, 0);
+
+            // We want to add badge to first line of text.
+            boolean addedBadge = addProfileBadge(contentView,
+                    contentTextInLine2 ? R.id.profile_badge_line2 : R.id.profile_badge_line3);
+            // If we added the badge to line 3 then we should show line 3.
+            if (addedBadge && !contentTextInLine2) {
+                showLine3 = true;
+            }
+
+            // Note getStandardView may hide line 3 again.
             contentView.setViewVisibility(R.id.line3, showLine3 ? View.VISIBLE : View.GONE);
             contentView.setViewVisibility(R.id.overflow_divider, showLine3 ? View.VISIBLE : View.GONE);
             return contentView;
         }
 
+        /**
+         * @return true if the built notification will show the time or the chronometer; false
+         *         otherwise
+         */
+        private boolean showsTimeOrChronometer() {
+            return mWhen != 0 && mShowWhen;
+        }
+
+        /**
+         * Logic to find out whether the notification is going to have three lines in the contracted
+         * layout. This is used to adjust the top padding.
+         *
+         * @return true if the notification is going to have three lines; false if the notification
+         *         is going to have one or two lines
+         */
+        private boolean hasThreeLines() {
+            boolean contentTextInLine2 = mSubText != null && mContentText != null;
+            boolean hasProgress = mStyle == null || mStyle.hasProgress();
+            // If we have content text in line 2, badge goes into line 2, or line 3 otherwise
+            boolean badgeInLine3 = getProfileBadgeDrawable() != null && !contentTextInLine2;
+            boolean hasLine3 = mContentText != null || mContentInfo != null || mNumber > 0
+                    || badgeInLine3;
+            boolean hasLine2 = (mSubText != null && mContentText != null) ||
+                    (hasProgress && mSubText == null
+                            && (mProgressMax != 0 || mProgressIndeterminate));
+            return hasLine2 && hasLine3;
+        }
+
+        /**
+         * @hide
+         */
+        public static int calculateTopPadding(Context ctx, boolean hasThreeLines,
+                float fontScale) {
+            int padding = ctx.getResources().getDimensionPixelSize(hasThreeLines
+                    ? R.dimen.notification_top_pad_narrow
+                    : R.dimen.notification_top_pad);
+            int largePadding = ctx.getResources().getDimensionPixelSize(hasThreeLines
+                    ? R.dimen.notification_top_pad_large_text_narrow
+                    : R.dimen.notification_top_pad_large_text);
+            float largeFactor = (MathUtils.constrain(fontScale, 1.0f, LARGE_TEXT_SCALE) - 1f)
+                    / (LARGE_TEXT_SCALE - 1f);
+
+            // Linearly interpolate the padding between large and normal with the font scale ranging
+            // from 1f to LARGE_TEXT_SCALE
+            return Math.round((1 - largeFactor) * padding + largeFactor * largePadding);
+        }
+
+        private void resetStandardTemplateWithActions(RemoteViews big) {
+            big.setViewVisibility(R.id.actions, View.GONE);
+            big.setViewVisibility(R.id.action_divider, View.GONE);
+            big.removeAllViews(R.id.actions);
+        }
+
         private RemoteViews applyStandardTemplateWithActions(int layoutId) {
-            RemoteViews big = applyStandardTemplate(layoutId, false);
+            RemoteViews big = applyStandardTemplate(layoutId);
+
+            resetStandardTemplateWithActions(big);
 
             int N = mActions.size();
             if (N > 0) {
-                // Log.d("Notification", "has actions: " + mContentText);
                 big.setViewVisibility(R.id.actions, View.VISIBLE);
                 big.setViewVisibility(R.id.action_divider, View.VISIBLE);
                 if (N>MAX_ACTION_BUTTONS) N=MAX_ACTION_BUTTONS;
-                big.removeAllViews(R.id.actions);
                 for (int i=0; i<N; i++) {
                     final RemoteViews button = generateActionButton(mActions.get(i));
-                    //Log.d("Notification", "adding action " + i + ": " + mActions.get(i).title);
                     big.addView(R.id.actions, button);
                 }
             }
@@ -2240,45 +2890,154 @@
             if (mContentView != null) {
                 return mContentView;
             } else {
-                return applyStandardTemplate(R.layout.notification_template_base, true); // no more special large_icon flavor
+                return applyStandardTemplate(getBaseLayoutResource());
             }
         }
 
         private RemoteViews makeTickerView() {
             if (mTickerView != null) {
                 return mTickerView;
-            } else {
-                if (mContentView == null) {
-                    return applyStandardTemplate(mLargeIcon == null
-                            ? R.layout.status_bar_latest_event_ticker
-                            : R.layout.status_bar_latest_event_ticker_large_icon, true);
-                } else {
-                    return null;
-                }
             }
+            return null; // tickers are not created by default anymore
         }
 
         private RemoteViews makeBigContentView() {
             if (mActions.size() == 0) return null;
 
-            return applyStandardTemplateWithActions(R.layout.notification_template_big_base);
+            return applyStandardTemplateWithActions(getBigBaseLayoutResource());
         }
 
+        private RemoteViews makeHeadsUpContentView() {
+            if (mActions.size() == 0) return null;
+
+            return applyStandardTemplateWithActions(getBigBaseLayoutResource());
+        }
+
+
         private RemoteViews generateActionButton(Action action) {
             final boolean tombstone = (action.actionIntent == null);
             RemoteViews button = new RemoteViews(mContext.getPackageName(),
-                    tombstone ? R.layout.notification_action_tombstone
-                              : R.layout.notification_action);
+                    tombstone ? getActionTombstoneLayoutResource()
+                              : getActionLayoutResource());
             button.setTextViewCompoundDrawablesRelative(R.id.action0, action.icon, 0, 0, 0);
-            button.setTextViewText(R.id.action0, action.title);
+            button.setTextViewText(R.id.action0, processLegacyText(action.title));
             if (!tombstone) {
                 button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
             }
             button.setContentDescription(R.id.action0, action.title);
+            processLegacyAction(action, button);
             return button;
         }
 
         /**
+         * @return Whether we are currently building a notification from a legacy (an app that
+         *         doesn't create material notifications by itself) app.
+         */
+        private boolean isLegacy() {
+            return mColorUtil != null;
+        }
+
+        private void processLegacyAction(Action action, RemoteViews button) {
+            if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, action.icon)) {
+                button.setTextViewCompoundDrawablesRelativeColorFilter(R.id.action0, 0,
+                        mContext.getResources().getColor(R.color.notification_action_color_filter),
+                        PorterDuff.Mode.MULTIPLY);
+            }
+        }
+
+        private CharSequence processLegacyText(CharSequence charSequence) {
+            if (isLegacy()) {
+                return mColorUtil.invertCharSequenceColors(charSequence);
+            } else {
+                return charSequence;
+            }
+        }
+
+        /**
+         * Apply any necessary background to smallIcons being used in the largeIcon spot.
+         */
+        private void processSmallIconAsLarge(int largeIconId, RemoteViews contentView) {
+            if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, largeIconId)) {
+                applyLargeIconBackground(contentView);
+            }
+        }
+
+        /**
+         * Apply any necessary background to a largeIcon if it's a fake smallIcon (that is,
+         * if it's grayscale).
+         */
+        // TODO: also check bounds, transparency, that sort of thing.
+        private void processLargeLegacyIcon(Bitmap largeIcon, RemoteViews contentView) {
+            if (isLegacy() && mColorUtil.isGrayscaleIcon(largeIcon)) {
+                applyLargeIconBackground(contentView);
+            } else {
+                removeLargeIconBackground(contentView);
+            }
+        }
+
+        /**
+         * Add a colored circle behind the largeIcon slot.
+         */
+        private void applyLargeIconBackground(RemoteViews contentView) {
+            contentView.setInt(R.id.icon, "setBackgroundResource",
+                    R.drawable.notification_icon_legacy_bg);
+
+            contentView.setDrawableParameters(
+                    R.id.icon,
+                    true,
+                    -1,
+                    resolveColor(),
+                    PorterDuff.Mode.SRC_ATOP,
+                    -1);
+
+            int padding = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.notification_large_icon_circle_padding);
+            contentView.setViewPadding(R.id.icon, padding, padding, padding, padding);
+        }
+
+        private void removeLargeIconBackground(RemoteViews contentView) {
+            contentView.setInt(R.id.icon, "setBackgroundResource", 0);
+        }
+
+        /**
+         * Recolor small icons when used in the R.id.right_icon slot.
+         */
+        private void processSmallRightIcon(int smallIconDrawableId,
+                RemoteViews contentView) {
+            if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, smallIconDrawableId)) {
+                contentView.setDrawableParameters(R.id.right_icon, false, -1,
+                        0xFFFFFFFF,
+                        PorterDuff.Mode.SRC_ATOP, -1);
+
+                contentView.setInt(R.id.right_icon,
+                        "setBackgroundResource",
+                        R.drawable.notification_icon_legacy_bg);
+
+                contentView.setDrawableParameters(
+                        R.id.right_icon,
+                        true,
+                        -1,
+                        resolveColor(),
+                        PorterDuff.Mode.SRC_ATOP,
+                        -1);
+            }
+        }
+
+        private int sanitizeColor() {
+            if (mColor != COLOR_DEFAULT) {
+                mColor |= 0xFF000000; // no alpha for custom colors
+            }
+            return mColor;
+        }
+
+        private int resolveColor() {
+            if (mColor == COLOR_DEFAULT) {
+                return mContext.getResources().getColor(R.color.notification_icon_bg_color);
+            }
+            return mColor;
+        }
+
+        /**
          * Apply the unstyled operations and return a new {@link Notification} object.
          * @hide
          */
@@ -2288,7 +3047,10 @@
             n.icon = mSmallIcon;
             n.iconLevel = mSmallIconLevel;
             n.number = mNumber;
-            n.contentView = makeContentView();
+
+            n.color = sanitizeColor();
+
+            setBuilderContentView(n, makeContentView());
             n.contentIntent = mContentIntent;
             n.deleteIntent = mDeleteIntent;
             n.fullScreenIntent = mFullScreenIntent;
@@ -2297,13 +3059,15 @@
             n.largeIcon = mLargeIcon;
             n.sound = mSound;
             n.audioStreamType = mAudioStreamType;
+            n.audioAttributes = mAudioAttributes;
             n.vibrate = mVibrate;
             n.ledARGB = mLedArgb;
             n.ledOnMS = mLedOnMs;
             n.ledOffMS = mLedOffMs;
             n.defaults = mDefaults;
             n.flags = mFlags;
-            n.bigContentView = makeBigContentView();
+            setBuilderBigContentView(n, makeBigContentView());
+            setBuilderHeadsUpContentView(n, makeHeadsUpContentView());
             if (mLedOnMs != 0 || mLedOffMs != 0) {
                 n.flags |= FLAG_SHOW_LIGHTS;
             }
@@ -2318,6 +3082,13 @@
                 n.actions = new Action[mActions.size()];
                 mActions.toArray(n.actions);
             }
+            n.visibility = mVisibility;
+
+            if (mPublicVersion != null) {
+                n.publicVersion = new Notification();
+                mPublicVersion.cloneInto(n.publicVersion, true);
+            }
+            // Note: If you're adding new fields, also update restoreFromNotitification().
             return n;
         }
 
@@ -2328,6 +3099,9 @@
          */
         public void populateExtras(Bundle extras) {
             // Store original information used in the construction of this object
+            extras.putInt(EXTRA_ORIGINATING_USERID, mOriginatingUserId);
+            extras.putParcelable(EXTRA_REBUILD_CONTEXT_APPLICATION_INFO,
+                    mContext.getApplicationInfo());
             extras.putCharSequence(EXTRA_TITLE, mContentTitle);
             extras.putCharSequence(EXTRA_TEXT, mContentText);
             extras.putCharSequence(EXTRA_SUB_TEXT, mSubText);
@@ -2341,6 +3115,240 @@
             if (mLargeIcon != null) {
                 extras.putParcelable(EXTRA_LARGE_ICON, mLargeIcon);
             }
+            if (!mPeople.isEmpty()) {
+                extras.putStringArray(EXTRA_PEOPLE, mPeople.toArray(new String[mPeople.size()]));
+            }
+            // NOTE: If you're adding new extras also update restoreFromNotification().
+        }
+
+
+        /**
+         * @hide
+         */
+        public static void stripForDelivery(Notification n) {
+            if (!STRIP_AND_REBUILD) {
+                return;
+            }
+
+            String templateClass = n.extras.getString(EXTRA_TEMPLATE);
+            // Only strip views for known Styles because we won't know how to
+            // re-create them otherwise.
+            boolean stripViews = TextUtils.isEmpty(templateClass) ||
+                    getNotificationStyleClass(templateClass) != null;
+
+            boolean isStripped = false;
+
+            if (n.largeIcon != null && n.extras.containsKey(EXTRA_LARGE_ICON)) {
+                // TODO: Would like to check for equality here, but if the notification
+                // has been cloned, we can't.
+                n.largeIcon = null;
+                n.extras.putBoolean(EXTRA_REBUILD_LARGE_ICON, true);
+                isStripped = true;
+            }
+            // Get rid of unmodified BuilderRemoteViews.
+
+            if (stripViews &&
+                    n.contentView instanceof BuilderRemoteViews &&
+                    n.extras.getInt(EXTRA_REBUILD_CONTENT_VIEW_ACTION_COUNT, -1) ==
+                            n.contentView.getSequenceNumber()) {
+                n.contentView = null;
+                n.extras.putBoolean(EXTRA_REBUILD_CONTENT_VIEW, true);
+                n.extras.remove(EXTRA_REBUILD_CONTENT_VIEW_ACTION_COUNT);
+                isStripped = true;
+            }
+            if (stripViews &&
+                    n.bigContentView instanceof BuilderRemoteViews &&
+                    n.extras.getInt(EXTRA_REBUILD_BIG_CONTENT_VIEW_ACTION_COUNT, -1) ==
+                            n.bigContentView.getSequenceNumber()) {
+                n.bigContentView = null;
+                n.extras.putBoolean(EXTRA_REBUILD_BIG_CONTENT_VIEW, true);
+                n.extras.remove(EXTRA_REBUILD_BIG_CONTENT_VIEW_ACTION_COUNT);
+                isStripped = true;
+            }
+            if (stripViews &&
+                    n.headsUpContentView instanceof BuilderRemoteViews &&
+                    n.extras.getInt(EXTRA_REBUILD_HEADS_UP_CONTENT_VIEW_ACTION_COUNT, -1) ==
+                            n.headsUpContentView.getSequenceNumber()) {
+                n.headsUpContentView = null;
+                n.extras.putBoolean(EXTRA_REBUILD_HEADS_UP_CONTENT_VIEW, true);
+                n.extras.remove(EXTRA_REBUILD_HEADS_UP_CONTENT_VIEW_ACTION_COUNT);
+                isStripped = true;
+            }
+
+            if (isStripped) {
+                n.extras.putBoolean(EXTRA_NEEDS_REBUILD, true);
+            }
+        }
+
+        /**
+         * @hide
+         */
+        public static Notification rebuild(Context context, Notification n) {
+            Bundle extras = n.extras;
+            if (!extras.getBoolean(EXTRA_NEEDS_REBUILD)) return n;
+            extras.remove(EXTRA_NEEDS_REBUILD);
+
+            // Re-create notification context so we can access app resources.
+            ApplicationInfo applicationInfo = extras.getParcelable(
+                    EXTRA_REBUILD_CONTEXT_APPLICATION_INFO);
+            Context builderContext;
+            try {
+                builderContext = context.createApplicationContext(applicationInfo,
+                        Context.CONTEXT_RESTRICTED);
+            } catch (NameNotFoundException e) {
+                Log.e(TAG, "ApplicationInfo " + applicationInfo + " not found");
+                builderContext = context;  // try with our context
+            }
+
+            Builder b = new Builder(builderContext, n);
+            return b.rebuild();
+        }
+
+        /**
+         * Rebuilds the notification passed in to the rebuild-constructor
+         * {@link #Builder(Context, Notification)}.
+         *
+         * <p>
+         * Throws IllegalStateException when invoked on a Builder that isn't in rebuild mode.
+         *
+         * @hide
+         */
+        private Notification rebuild() {
+            if (mRebuildNotification == null) {
+                throw new IllegalStateException("rebuild() only valid when in 'rebuild' mode.");
+            }
+            mHasThreeLines = hasThreeLines();
+
+            Bundle extras = mRebuildNotification.extras;
+
+            if (extras.getBoolean(EXTRA_REBUILD_LARGE_ICON)) {
+                mRebuildNotification.largeIcon = extras.getParcelable(EXTRA_LARGE_ICON);
+            }
+            extras.remove(EXTRA_REBUILD_LARGE_ICON);
+
+            if (extras.getBoolean(EXTRA_REBUILD_CONTENT_VIEW)) {
+                setBuilderContentView(mRebuildNotification, makeContentView());
+                if (mStyle != null) {
+                    mStyle.populateContentView(mRebuildNotification);
+                }
+            }
+            extras.remove(EXTRA_REBUILD_CONTENT_VIEW);
+
+            if (extras.getBoolean(EXTRA_REBUILD_BIG_CONTENT_VIEW)) {
+                setBuilderBigContentView(mRebuildNotification, makeBigContentView());
+                if (mStyle != null) {
+                    mStyle.populateBigContentView(mRebuildNotification);
+                }
+            }
+            extras.remove(EXTRA_REBUILD_BIG_CONTENT_VIEW);
+
+            if (extras.getBoolean(EXTRA_REBUILD_HEADS_UP_CONTENT_VIEW)) {
+                setBuilderHeadsUpContentView(mRebuildNotification, makeHeadsUpContentView());
+                if (mStyle != null) {
+                    mStyle.populateHeadsUpContentView(mRebuildNotification);
+                }
+            }
+            extras.remove(EXTRA_REBUILD_HEADS_UP_CONTENT_VIEW);
+
+            mHasThreeLines = false;
+            return mRebuildNotification;
+        }
+
+        private static Class<? extends Style> getNotificationStyleClass(String templateClass) {
+            Class<? extends Style>[] classes = new Class[]{
+                    BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class};
+            for (Class<? extends Style> innerClass : classes) {
+                if (templateClass.equals(innerClass.getName())) {
+                    return innerClass;
+                }
+            }
+            return null;
+        }
+
+        private void setBuilderContentView(Notification n, RemoteViews contentView) {
+            n.contentView = contentView;
+            if (contentView instanceof BuilderRemoteViews) {
+                mRebuildBundle.putInt(Builder.EXTRA_REBUILD_CONTENT_VIEW_ACTION_COUNT,
+                        contentView.getSequenceNumber());
+            }
+        }
+
+        private void setBuilderBigContentView(Notification n, RemoteViews bigContentView) {
+            n.bigContentView = bigContentView;
+            if (bigContentView instanceof BuilderRemoteViews) {
+                mRebuildBundle.putInt(Builder.EXTRA_REBUILD_BIG_CONTENT_VIEW_ACTION_COUNT,
+                        bigContentView.getSequenceNumber());
+            }
+        }
+
+        private void setBuilderHeadsUpContentView(Notification n,
+                RemoteViews headsUpContentView) {
+            n.headsUpContentView = headsUpContentView;
+            if (headsUpContentView instanceof BuilderRemoteViews) {
+                mRebuildBundle.putInt(Builder.EXTRA_REBUILD_HEADS_UP_CONTENT_VIEW_ACTION_COUNT,
+                        headsUpContentView.getSequenceNumber());
+            }
+        }
+
+        private void restoreFromNotification(Notification n) {
+
+            // Notification fields.
+            mWhen = n.when;
+            mSmallIcon = n.icon;
+            mSmallIconLevel = n.iconLevel;
+            mNumber = n.number;
+
+            mColor = n.color;
+
+            mContentView = n.contentView;
+            mDeleteIntent = n.deleteIntent;
+            mFullScreenIntent = n.fullScreenIntent;
+            mTickerText = n.tickerText;
+            mTickerView = n.tickerView;
+            mLargeIcon = n.largeIcon;
+            mSound = n.sound;
+            mAudioStreamType = n.audioStreamType;
+            mAudioAttributes = n.audioAttributes;
+
+            mVibrate = n.vibrate;
+            mLedArgb = n.ledARGB;
+            mLedOnMs = n.ledOnMS;
+            mLedOffMs = n.ledOffMS;
+            mDefaults = n.defaults;
+            mFlags = n.flags;
+
+            mCategory = n.category;
+            mGroupKey = n.mGroupKey;
+            mSortKey = n.mSortKey;
+            mPriority = n.priority;
+            mActions.clear();
+            if (n.actions != null) {
+                Collections.addAll(mActions, n.actions);
+            }
+            mVisibility = n.visibility;
+
+            mPublicVersion = n.publicVersion;
+
+            // Extras.
+            Bundle extras = n.extras;
+            mOriginatingUserId = extras.getInt(EXTRA_ORIGINATING_USERID);
+            mContentTitle = extras.getCharSequence(EXTRA_TITLE);
+            mContentText = extras.getCharSequence(EXTRA_TEXT);
+            mSubText = extras.getCharSequence(EXTRA_SUB_TEXT);
+            mContentInfo = extras.getCharSequence(EXTRA_INFO_TEXT);
+            mSmallIcon = extras.getInt(EXTRA_SMALL_ICON);
+            mProgress = extras.getInt(EXTRA_PROGRESS);
+            mProgressMax = extras.getInt(EXTRA_PROGRESS_MAX);
+            mProgressIndeterminate = extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE);
+            mUseChronometer = extras.getBoolean(EXTRA_SHOW_CHRONOMETER);
+            mShowWhen = extras.getBoolean(EXTRA_SHOW_WHEN);
+            if (extras.containsKey(EXTRA_LARGE_ICON)) {
+                mLargeIcon = extras.getParcelable(EXTRA_LARGE_ICON);
+            }
+            if (extras.containsKey(EXTRA_PEOPLE)) {
+                mPeople.clear();
+                Collections.addAll(mPeople, extras.getStringArray(EXTRA_PEOPLE));
+            }
         }
 
         /**
@@ -2356,19 +3364,30 @@
          * object.
          */
         public Notification build() {
+            mOriginatingUserId = mContext.getUserId();
+            mHasThreeLines = hasThreeLines();
+
             Notification n = buildUnstyled();
 
             if (mStyle != null) {
                 n = mStyle.buildStyled(n);
             }
 
-            n.extras = mExtras != null ? new Bundle(mExtras) : new Bundle();
+            if (mExtras != null) {
+                n.extras.putAll(mExtras);
+            }
+
+            if (mRebuildBundle.size() > 0) {
+                n.extras.putAll(mRebuildBundle);
+                mRebuildBundle.clear();
+            }
 
             populateExtras(n.extras);
             if (mStyle != null) {
                 mStyle.addExtras(n.extras);
             }
 
+            mHasThreeLines = false;
             return n;
         }
 
@@ -2381,6 +3400,34 @@
             build().cloneInto(n, true);
             return n;
         }
+
+        private int getBaseLayoutResource() {
+            return R.layout.notification_template_material_base;
+        }
+
+        private int getBigBaseLayoutResource() {
+            return R.layout.notification_template_material_big_base;
+        }
+
+        private int getBigPictureLayoutResource() {
+            return R.layout.notification_template_material_big_picture;
+        }
+
+        private int getBigTextLayoutResource() {
+            return R.layout.notification_template_material_big_text;
+        }
+
+        private int getInboxLayoutResource() {
+            return R.layout.notification_template_material_inbox;
+        }
+
+        private int getActionLayoutResource() {
+            return R.layout.notification_material_action;
+        }
+
+        private int getActionTombstoneLayoutResource() {
+            return R.layout.notification_material_action_tombstone;
+        }
     }
 
     /**
@@ -2389,8 +3436,16 @@
      */
     public static abstract class Style {
         private CharSequence mBigContentTitle;
-        private CharSequence mSummaryText = null;
-        private boolean mSummaryTextSet = false;
+
+        /**
+         * @hide
+         */
+        protected CharSequence mSummaryText = null;
+
+        /**
+         * @hide
+         */
+        protected boolean mSummaryTextSet = false;
 
         protected Builder mBuilder;
 
@@ -2428,12 +3483,16 @@
         protected RemoteViews getStandardView(int layoutId) {
             checkBuilder();
 
+            // Nasty.
+            CharSequence oldBuilderContentTitle = mBuilder.mContentTitle;
             if (mBigContentTitle != null) {
                 mBuilder.setContentTitle(mBigContentTitle);
             }
 
             RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(layoutId);
 
+            mBuilder.mContentTitle = oldBuilderContentTitle;
+
             if (mBigContentTitle != null && mBigContentTitle.equals("")) {
                 contentView.setViewVisibility(R.id.line1, View.GONE);
             } else {
@@ -2445,10 +3504,12 @@
                     mSummaryTextSet ? mSummaryText
                                     : mBuilder.mSubText;
             if (overflowText != null) {
-                contentView.setTextViewText(R.id.text, overflowText);
+                contentView.setTextViewText(R.id.text, mBuilder.processLegacyText(overflowText));
                 contentView.setViewVisibility(R.id.overflow_divider, View.VISIBLE);
                 contentView.setViewVisibility(R.id.line3, View.VISIBLE);
             } else {
+                // Clear text in case we use the line to show the profile badge.
+                contentView.setTextViewText(R.id.text, "");
                 contentView.setViewVisibility(R.id.overflow_divider, View.GONE);
                 contentView.setViewVisibility(R.id.line3, View.GONE);
             }
@@ -2457,6 +3518,19 @@
         }
 
         /**
+         * Changes the padding of the first line such that the big and small content view have the
+         * same top padding.
+         *
+         * @hide
+         */
+        protected void applyTopPadding(RemoteViews contentView) {
+            int topPadding = Builder.calculateTopPadding(mBuilder.mContext,
+                    mBuilder.mHasThreeLines,
+                    mBuilder.mContext.getResources().getConfiguration().fontScale);
+            contentView.setViewPadding(R.id.line1, 0, topPadding, 0, 0);
+        }
+
+        /**
          * @hide
          */
         public void addExtras(Bundle extras) {
@@ -2466,12 +3540,53 @@
             if (mBigContentTitle != null) {
                 extras.putCharSequence(EXTRA_TITLE_BIG, mBigContentTitle);
             }
+            extras.putString(EXTRA_TEMPLATE, this.getClass().getName());
         }
 
         /**
          * @hide
          */
-        public abstract Notification buildStyled(Notification wip);
+        protected void restoreFromExtras(Bundle extras) {
+            if (extras.containsKey(EXTRA_SUMMARY_TEXT)) {
+                mSummaryText = extras.getCharSequence(EXTRA_SUMMARY_TEXT);
+                mSummaryTextSet = true;
+            }
+            if (extras.containsKey(EXTRA_TITLE_BIG)) {
+                mBigContentTitle = extras.getCharSequence(EXTRA_TITLE_BIG);
+            }
+        }
+
+
+        /**
+         * @hide
+         */
+        public Notification buildStyled(Notification wip) {
+            populateTickerView(wip);
+            populateContentView(wip);
+            populateBigContentView(wip);
+            populateHeadsUpContentView(wip);
+            return wip;
+        }
+
+        // The following methods are split out so we can re-create notification partially.
+        /**
+         * @hide
+         */
+        protected void populateTickerView(Notification wip) {}
+        /**
+         * @hide
+         */
+        protected void populateContentView(Notification wip) {}
+
+        /**
+         * @hide
+         */
+        protected void populateBigContentView(Notification wip) {}
+
+        /**
+         * @hide
+         */
+        protected void populateHeadsUpContentView(Notification wip) {}
 
         /**
          * Calls {@link android.app.Notification.Builder#build()} on the Builder this Style is
@@ -2483,6 +3598,15 @@
             checkBuilder();
             return mBuilder.build();
         }
+
+        /**
+         * @hide
+         * @return true if the style positions the progress bar on the second line; false if the
+         *         style hides the progress bar
+         */
+        protected boolean hasProgress() {
+            return true;
+        }
     }
 
     /**
@@ -2549,10 +3673,15 @@
         }
 
         private RemoteViews makeBigContentView() {
-            RemoteViews contentView = getStandardView(R.layout.notification_template_big_picture);
+            RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource());
 
             contentView.setImageViewBitmap(R.id.big_picture, mPicture);
 
+            applyTopPadding(contentView);
+
+            boolean twoTextLines = mBuilder.mSubText != null && mBuilder.mContentText != null;
+            mBuilder.addProfileBadge(contentView,
+                    twoTextLines ? R.id.profile_badge_line2 : R.id.profile_badge_line3);
             return contentView;
         }
 
@@ -2572,12 +3701,21 @@
          * @hide
          */
         @Override
-        public Notification buildStyled(Notification wip) {
-            if (mBigLargeIconSet ) {
-                mBuilder.mLargeIcon = mBigLargeIcon;
+        protected void restoreFromExtras(Bundle extras) {
+            super.restoreFromExtras(extras);
+
+            if (extras.containsKey(EXTRA_LARGE_ICON_BIG)) {
+                mBigLargeIcon = extras.getParcelable(EXTRA_LARGE_ICON_BIG);
             }
-            wip.bigContentView = makeBigContentView();
-            return wip;
+            mPicture = extras.getParcelable(EXTRA_PICTURE);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void populateBigContentView(Notification wip) {
+            mBuilder.setBuilderBigContentView(wip, makeBigContentView());
         }
     }
 
@@ -2599,6 +3737,11 @@
      * @see Notification#bigContentView
      */
     public static class BigTextStyle extends Style {
+
+        private static final int MAX_LINES = 13;
+        private static final int LINES_CONSUMED_BY_ACTIONS = 3;
+        private static final int LINES_CONSUMED_BY_SUMMARY = 2;
+
         private CharSequence mBigText;
 
         public BigTextStyle() {
@@ -2640,38 +3783,67 @@
         public void addExtras(Bundle extras) {
             super.addExtras(extras);
 
-            extras.putCharSequence(EXTRA_TEXT, mBigText);
-        }
-
-        private RemoteViews makeBigContentView() {
-            // Remove the content text so line3 only shows if you have a summary
-            final boolean hadThreeLines = (mBuilder.mContentText != null && mBuilder.mSubText != null);
-            mBuilder.mContentText = null;
-
-            RemoteViews contentView = getStandardView(R.layout.notification_template_big_text);
-
-            if (hadThreeLines) {
-                // vertical centering
-                contentView.setViewPadding(R.id.line1, 0, 0, 0, 0);
-            }
-
-            contentView.setTextViewText(R.id.big_text, mBigText);
-            contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
-            contentView.setViewVisibility(R.id.text2, View.GONE);
-
-            return contentView;
+            extras.putCharSequence(EXTRA_BIG_TEXT, mBigText);
         }
 
         /**
          * @hide
          */
         @Override
-        public Notification buildStyled(Notification wip) {
-            wip.bigContentView = makeBigContentView();
+        protected void restoreFromExtras(Bundle extras) {
+            super.restoreFromExtras(extras);
 
-            wip.extras.putCharSequence(EXTRA_TEXT, mBigText);
+            mBigText = extras.getCharSequence(EXTRA_BIG_TEXT);
+        }
 
-            return wip;
+        private RemoteViews makeBigContentView() {
+
+            // Nasty
+            CharSequence oldBuilderContentText = mBuilder.mContentText;
+            mBuilder.mContentText = null;
+
+            RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource());
+
+            mBuilder.mContentText = oldBuilderContentText;
+
+            contentView.setTextViewText(R.id.big_text, mBuilder.processLegacyText(mBigText));
+            contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
+            contentView.setInt(R.id.big_text, "setMaxLines", calculateMaxLines());
+            contentView.setViewVisibility(R.id.text2, View.GONE);
+
+            applyTopPadding(contentView);
+
+            mBuilder.shrinkLine3Text(contentView);
+
+            mBuilder.addProfileBadge(contentView, R.id.profile_badge_large_template);
+
+            return contentView;
+        }
+
+        private int calculateMaxLines() {
+            int lineCount = MAX_LINES;
+            boolean hasActions = mBuilder.mActions.size() > 0;
+            boolean hasSummary = (mSummaryTextSet ? mSummaryText : mBuilder.mSubText) != null;
+            if (hasActions) {
+                lineCount -= LINES_CONSUMED_BY_ACTIONS;
+            }
+            if (hasSummary) {
+                lineCount -= LINES_CONSUMED_BY_SUMMARY;
+            }
+
+            // If we have less top padding at the top, we can fit less lines.
+            if (!mBuilder.mHasThreeLines) {
+                lineCount--;
+            }
+            return lineCount;
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void populateBigContentView(Notification wip) {
+            mBuilder.setBuilderBigContentView(wip, makeBigContentView());
         }
     }
 
@@ -2735,14 +3907,34 @@
          */
         public void addExtras(Bundle extras) {
             super.addExtras(extras);
+
             CharSequence[] a = new CharSequence[mTexts.size()];
             extras.putCharSequenceArray(EXTRA_TEXT_LINES, mTexts.toArray(a));
         }
 
+        /**
+         * @hide
+         */
+        @Override
+        protected void restoreFromExtras(Bundle extras) {
+            super.restoreFromExtras(extras);
+
+            mTexts.clear();
+            if (extras.containsKey(EXTRA_TEXT_LINES)) {
+                Collections.addAll(mTexts, extras.getCharSequenceArray(EXTRA_TEXT_LINES));
+            }
+        }
+
         private RemoteViews makeBigContentView() {
             // Remove the content text so line3 disappears unless you have a summary
+
+            // Nasty
+            CharSequence oldBuilderContentText = mBuilder.mContentText;
             mBuilder.mContentText = null;
-            RemoteViews contentView = getStandardView(R.layout.notification_template_inbox);
+
+            RemoteViews contentView = getStandardView(mBuilder.getInboxLayoutResource());
+
+            mBuilder.mContentText = oldBuilderContentText;
 
             contentView.setViewVisibility(R.id.text2, View.GONE);
 
@@ -2754,13 +3946,20 @@
                 contentView.setViewVisibility(rowId, View.GONE);
             }
 
-
+            final boolean largeText =
+                    mBuilder.mContext.getResources().getConfiguration().fontScale > 1f;
+            final float subTextSize = mBuilder.mContext.getResources().getDimensionPixelSize(
+                    R.dimen.notification_subtext_size);
             int i=0;
             while (i < mTexts.size() && i < rowIds.length) {
                 CharSequence str = mTexts.get(i);
                 if (str != null && !str.equals("")) {
                     contentView.setViewVisibility(rowIds[i], View.VISIBLE);
-                    contentView.setTextViewText(rowIds[i], str);
+                    contentView.setTextViewText(rowIds[i], mBuilder.processLegacyText(str));
+                    if (largeText) {
+                        contentView.setTextViewTextSize(rowIds[i], TypedValue.COMPLEX_UNIT_PX,
+                                subTextSize);
+                    }
                 }
                 i++;
             }
@@ -2771,6 +3970,12 @@
             contentView.setViewVisibility(R.id.inbox_more,
                     mTexts.size() > rowIds.length ? View.VISIBLE : View.GONE);
 
+            applyTopPadding(contentView);
+
+            mBuilder.shrinkLine3Text(contentView);
+
+            mBuilder.addProfileBadge(contentView, R.id.profile_badge_large_template);
+
             return contentView;
         }
 
@@ -2778,14 +3983,247 @@
          * @hide
          */
         @Override
-        public Notification buildStyled(Notification wip) {
-            wip.bigContentView = makeBigContentView();
-
-            return wip;
+        public void populateBigContentView(Notification wip) {
+            mBuilder.setBuilderBigContentView(wip, makeBigContentView());
         }
     }
 
     /**
+     * Notification style for media playback notifications.
+     *
+     * In the expanded form, {@link Notification#bigContentView}, up to 5
+     * {@link Notification.Action}s specified with
+     * {@link Notification.Builder#addAction(int, CharSequence, PendingIntent) addAction} will be
+     * shown as icon-only pushbuttons, suitable for transport controls. The Bitmap given to
+     * {@link Notification.Builder#setLargeIcon(android.graphics.Bitmap) setLargeIcon()} will be
+     * treated as album artwork.
+     *
+     * Unlike the other styles provided here, MediaStyle can also modify the standard-size
+     * {@link Notification#contentView}; by providing action indices to
+     * {@link #setShowActionsInCompactView(int...)} you can promote up to 2 actions to be displayed
+     * in the standard view alongside the usual content.
+     *
+     * Notifications created with MediaStyle will have their category set to
+     * {@link Notification#CATEGORY_TRANSPORT CATEGORY_TRANSPORT} unless you set a different
+     * category using {@link Notification.Builder#setCategory(String) setCategory()}.
+     *
+     * Finally, if you attach a {@link android.media.session.MediaSession.Token} using
+     * {@link android.app.Notification.MediaStyle#setMediaSession(MediaSession.Token)},
+     * the System UI can identify this as a notification representing an active media session
+     * and respond accordingly (by showing album artwork in the lockscreen, for example).
+     *
+     * To use this style with your Notification, feed it to
+     * {@link Notification.Builder#setStyle(android.app.Notification.Style)} like so:
+     * <pre class="prettyprint">
+     * Notification noti = new Notification.Builder()
+     *     .setSmallIcon(R.drawable.ic_stat_player)
+     *     .setContentTitle(&quot;Track title&quot;)     // these three lines are optional
+     *     .setContentText(&quot;Artist - Album&quot;)   // if you use
+     *     .setLargeIcon(albumArtBitmap))      // setMediaSession(token)
+     *     .setStyle(<b>new Notification.MediaStyle()</b>
+     *         .setMediaSession(mySession))
+     *     .build();
+     * </pre>
+     *
+     * @see Notification#bigContentView
+     */
+    public static class MediaStyle extends Style {
+        static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3;
+        static final int MAX_MEDIA_BUTTONS = 5;
+
+        private int[] mActionsToShowInCompact = null;
+        private MediaSession.Token mToken;
+
+        public MediaStyle() {
+        }
+
+        public MediaStyle(Builder builder) {
+            setBuilder(builder);
+        }
+
+        /**
+         * Request up to 3 actions (by index in the order of addition) to be shown in the compact
+         * notification view.
+         *
+         * @param actions the indices of the actions to show in the compact notification view
+         */
+        public MediaStyle setShowActionsInCompactView(int...actions) {
+            mActionsToShowInCompact = actions;
+            return this;
+        }
+
+        /**
+         * Attach a {@link android.media.session.MediaSession.Token} to this Notification
+         * to provide additional playback information and control to the SystemUI.
+         */
+        public MediaStyle setMediaSession(MediaSession.Token token) {
+            mToken = token;
+            return this;
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public Notification buildStyled(Notification wip) {
+            super.buildStyled(wip);
+            if (wip.category == null) {
+                wip.category = Notification.CATEGORY_TRANSPORT;
+            }
+            return wip;
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void populateContentView(Notification wip) {
+            mBuilder.setBuilderContentView(wip, makeMediaContentView());
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void populateBigContentView(Notification wip) {
+            mBuilder.setBuilderBigContentView(wip, makeMediaBigContentView());
+        }
+
+        /** @hide */
+        @Override
+        public void addExtras(Bundle extras) {
+            super.addExtras(extras);
+
+            if (mToken != null) {
+                extras.putParcelable(EXTRA_MEDIA_SESSION, mToken);
+            }
+            if (mActionsToShowInCompact != null) {
+                extras.putIntArray(EXTRA_COMPACT_ACTIONS, mActionsToShowInCompact);
+            }
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        protected void restoreFromExtras(Bundle extras) {
+            super.restoreFromExtras(extras);
+
+            if (extras.containsKey(EXTRA_MEDIA_SESSION)) {
+                mToken = extras.getParcelable(EXTRA_MEDIA_SESSION);
+            }
+            if (extras.containsKey(EXTRA_COMPACT_ACTIONS)) {
+                mActionsToShowInCompact = extras.getIntArray(EXTRA_COMPACT_ACTIONS);
+            }
+        }
+
+        private RemoteViews generateMediaActionButton(Action action) {
+            final boolean tombstone = (action.actionIntent == null);
+            RemoteViews button = new RemoteViews(mBuilder.mContext.getPackageName(),
+                    R.layout.notification_material_media_action);
+            button.setImageViewResource(R.id.action0, action.icon);
+            button.setDrawableParameters(R.id.action0, false, -1,
+                    0xFFFFFFFF,
+                    PorterDuff.Mode.SRC_ATOP, -1);
+            if (!tombstone) {
+                button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
+            }
+            button.setContentDescription(R.id.action0, action.title);
+            return button;
+        }
+
+        private RemoteViews makeMediaContentView() {
+            RemoteViews view = mBuilder.applyStandardTemplate(
+                    R.layout.notification_template_material_media, false /* hasProgress */);
+
+            final int numActions = mBuilder.mActions.size();
+            final int N = mActionsToShowInCompact == null
+                    ? 0
+                    : Math.min(mActionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT);
+            if (N > 0) {
+                view.removeAllViews(com.android.internal.R.id.media_actions);
+                for (int i = 0; i < N; i++) {
+                    if (i >= numActions) {
+                        throw new IllegalArgumentException(String.format(
+                                "setShowActionsInCompactView: action %d out of bounds (max %d)",
+                                i, numActions - 1));
+                    }
+
+                    final Action action = mBuilder.mActions.get(mActionsToShowInCompact[i]);
+                    final RemoteViews button = generateMediaActionButton(action);
+                    view.addView(com.android.internal.R.id.media_actions, button);
+                }
+            }
+            styleText(view);
+            hideRightIcon(view);
+            return view;
+        }
+
+        private RemoteViews makeMediaBigContentView() {
+            final int actionCount = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS);
+            RemoteViews big = mBuilder.applyStandardTemplate(getBigLayoutResource(actionCount),
+                    false /* hasProgress */);
+
+            if (actionCount > 0) {
+                big.removeAllViews(com.android.internal.R.id.media_actions);
+                for (int i = 0; i < actionCount; i++) {
+                    final RemoteViews button = generateMediaActionButton(mBuilder.mActions.get(i));
+                    big.addView(com.android.internal.R.id.media_actions, button);
+                }
+            }
+            styleText(big);
+            hideRightIcon(big);
+            applyTopPadding(big);
+            big.setViewVisibility(android.R.id.progress, View.GONE);
+            return big;
+        }
+
+        private int getBigLayoutResource(int actionCount) {
+            if (actionCount <= 3) {
+                return R.layout.notification_template_material_big_media_narrow;
+            } else {
+                return R.layout.notification_template_material_big_media;
+            }
+        }
+
+        private void hideRightIcon(RemoteViews contentView) {
+            contentView.setViewVisibility(R.id.right_icon, View.GONE);
+        }
+
+        /**
+         * Applies the special text colors for media notifications to all text views.
+         */
+        private void styleText(RemoteViews contentView) {
+            int primaryColor = mBuilder.mContext.getResources().getColor(
+                    R.color.notification_media_primary_color);
+            int secondaryColor = mBuilder.mContext.getResources().getColor(
+                    R.color.notification_media_secondary_color);
+            contentView.setTextColor(R.id.title, primaryColor);
+            if (mBuilder.showsTimeOrChronometer()) {
+                if (mBuilder.mUseChronometer) {
+                    contentView.setTextColor(R.id.chronometer, secondaryColor);
+                } else {
+                    contentView.setTextColor(R.id.time, secondaryColor);
+                }
+            }
+            contentView.setTextColor(R.id.text2, secondaryColor);
+            contentView.setTextColor(R.id.text, secondaryColor);
+            contentView.setTextColor(R.id.info, secondaryColor);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        protected boolean hasProgress() {
+            return false;
+        }
+    }
+
+    // When adding a new Style subclass here, don't forget to update
+    // Builder.getNotificationStyleClass.
+
+    /**
      * Extender interface for use with {@link Builder#extend}. Extenders may be used to add
      * metadata or change options on a notification builder.
      */
@@ -3452,4 +4890,24 @@
         bundle.putParcelableArray(key, typedArray);
         return typedArray;
     }
+
+    private static class BuilderRemoteViews extends RemoteViews {
+        public BuilderRemoteViews(Parcel parcel) {
+            super(parcel);
+        }
+
+        public BuilderRemoteViews(ApplicationInfo appInfo, int layoutId) {
+            super(appInfo, layoutId);
+        }
+
+        @Override
+        public BuilderRemoteViews clone() {
+            Parcel p = Parcel.obtain();
+            writeToParcel(p, 0);
+            p.setDataPosition(0);
+            BuilderRemoteViews brv = new BuilderRemoteViews(p);
+            p.recycle();
+            return brv;
+        }
+    }
 }
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 3ee4306..7dc1ad64 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -16,7 +16,11 @@
 
 package android.app;
 
+import android.annotation.SdkConstant;
+import android.app.Notification.Builder;
+import android.content.ComponentName;
 import android.content.Context;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -71,6 +75,16 @@
     private static String TAG = "NotificationManager";
     private static boolean localLOGV = false;
 
+    /**
+     * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
+     * This broadcast is only sent to registered receivers.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
+            = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
+
     private static INotificationManager sService;
 
     /** @hide */
@@ -132,9 +146,11 @@
             }
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
+        Notification stripped = notification.clone();
+        Builder.stripForDelivery(stripped);
         try {
             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
-                    notification, idOut, UserHandle.myUserId());
+                    stripped, idOut, UserHandle.myUserId());
             if (id != idOut[0]) {
                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
             }
@@ -157,9 +173,11 @@
             }
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
+        Notification stripped = notification.clone();
+        Builder.stripForDelivery(stripped);
         try {
             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
-                    notification, idOut, user.getIdentifier());
+                    stripped, idOut, user.getIdentifier());
             if (id != idOut[0]) {
                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
             }
@@ -222,5 +240,29 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    public ComponentName getEffectsSuppressor() {
+        INotificationManager service = getService();
+        try {
+            return service.getEffectsSuppressor();
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public boolean matchesCallFilter(Bundle extras) {
+        INotificationManager service = getService();
+        try {
+            return service.matchesCallFilter(extras);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
     private Context mContext;
 }
diff --git a/core/java/android/app/OnActivityPausedListener.java b/core/java/android/app/OnActivityPausedListener.java
index 379f133..5003973 100644
--- a/core/java/android/app/OnActivityPausedListener.java
+++ b/core/java/android/app/OnActivityPausedListener.java
@@ -5,7 +5,7 @@
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *	    http://www.apache.org/licenses/LICENSE-2.0
+ *        http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/core/java/android/app/PackageDeleteObserver.java b/core/java/android/app/PackageDeleteObserver.java
new file mode 100644
index 0000000..9b83ec1
--- /dev/null
+++ b/core/java/android/app/PackageDeleteObserver.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.Intent;
+import android.content.pm.IPackageDeleteObserver2;
+
+/** {@hide} */
+public class PackageDeleteObserver {
+    private final IPackageDeleteObserver2.Stub mBinder = new IPackageDeleteObserver2.Stub() {
+        @Override
+        public void onUserActionRequired(Intent intent) {
+            PackageDeleteObserver.this.onUserActionRequired(intent);
+        }
+
+        @Override
+        public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
+            PackageDeleteObserver.this.onPackageDeleted(basePackageName, returnCode, msg);
+        }
+    };
+
+    /** {@hide} */
+    public IPackageDeleteObserver2 getBinder() {
+        return mBinder;
+    }
+
+    public void onUserActionRequired(Intent intent) {
+    }
+
+    public void onPackageDeleted(String basePackageName, int returnCode, String msg) {
+    }
+}
diff --git a/core/java/android/app/PackageInstallObserver.java b/core/java/android/app/PackageInstallObserver.java
new file mode 100644
index 0000000..ff28679
--- /dev/null
+++ b/core/java/android/app/PackageInstallObserver.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.Intent;
+import android.content.pm.IPackageInstallObserver2;
+import android.os.Bundle;
+
+/** {@hide} */
+public class PackageInstallObserver {
+    private final IPackageInstallObserver2.Stub mBinder = new IPackageInstallObserver2.Stub() {
+        @Override
+        public void onUserActionRequired(Intent intent) {
+            PackageInstallObserver.this.onUserActionRequired(intent);
+        }
+
+        @Override
+        public void onPackageInstalled(String basePackageName, int returnCode,
+                String msg, Bundle extras) {
+            PackageInstallObserver.this.onPackageInstalled(basePackageName, returnCode, msg,
+                    extras);
+        }
+    };
+
+    /** {@hide} */
+    public IPackageInstallObserver2 getBinder() {
+        return mBinder;
+    }
+
+    public void onUserActionRequired(Intent intent) {
+    }
+
+    /**
+     * This method will be called to report the result of the package
+     * installation attempt.
+     *
+     * @param basePackageName Name of the package whose installation was
+     *            attempted
+     * @param extras If non-null, this Bundle contains extras providing
+     *            additional information about an install failure. See
+     *            {@link android.content.pm.PackageManager} for documentation
+     *            about which extras apply to various failures; in particular
+     *            the strings named EXTRA_FAILURE_*.
+     * @param returnCode The numeric success or failure code indicating the
+     *            basic outcome
+     * @hide
+     */
+    public void onPackageInstalled(String basePackageName, int returnCode, String msg,
+            Bundle extras) {
+    }
+}
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 7129e9e..cf14202 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -16,6 +16,9 @@
 
 package android.app;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IIntentReceiver;
@@ -30,6 +33,9 @@
 import android.os.UserHandle;
 import android.util.AndroidException;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A description of an Intent and target action to perform with it.  Instances
  * of this class are created with {@link #getActivity}, {@link #getActivities},
@@ -86,6 +92,26 @@
 public final class PendingIntent implements Parcelable {
     private final IIntentSender mTarget;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                    FLAG_ONE_SHOT,
+                    FLAG_NO_CREATE,
+                    FLAG_CANCEL_CURRENT,
+                    FLAG_UPDATE_CURRENT,
+
+                    Intent.FILL_IN_ACTION,
+                    Intent.FILL_IN_DATA,
+                    Intent.FILL_IN_CATEGORIES,
+                    Intent.FILL_IN_COMPONENT,
+                    Intent.FILL_IN_PACKAGE,
+                    Intent.FILL_IN_SOURCE_BOUNDS,
+                    Intent.FILL_IN_SELECTOR,
+                    Intent.FILL_IN_CLIP_DATA
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Flags {}
+
     /**
      * Flag indicating that this PendingIntent can be used only once.
      * For use with {@link #getActivity}, {@link #getBroadcast}, and
@@ -222,7 +248,7 @@
      * supplied.
      */
     public static PendingIntent getActivity(Context context, int requestCode,
-            Intent intent, int flags) {
+            Intent intent, @Flags int flags) {
         return getActivity(context, requestCode, intent, flags, null);
     }
 
@@ -255,7 +281,7 @@
      * supplied.
      */
     public static PendingIntent getActivity(Context context, int requestCode,
-            Intent intent, int flags, Bundle options) {
+            @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) {
         String packageName = context.getPackageName();
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
@@ -280,7 +306,7 @@
      * activity is started, not when the pending intent is created.
      */
     public static PendingIntent getActivityAsUser(Context context, int requestCode,
-            Intent intent, int flags, Bundle options, UserHandle user) {
+            @NonNull Intent intent, int flags, Bundle options, UserHandle user) {
         String packageName = context.getPackageName();
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
@@ -345,7 +371,7 @@
      * supplied.
      */
     public static PendingIntent getActivities(Context context, int requestCode,
-            Intent[] intents, int flags) {
+            @NonNull Intent[] intents, @Flags int flags) {
         return getActivities(context, requestCode, intents, flags, null);
     }
 
@@ -395,7 +421,7 @@
      * supplied.
      */
     public static PendingIntent getActivities(Context context, int requestCode,
-            Intent[] intents, int flags, Bundle options) {
+            @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) {
         String packageName = context.getPackageName();
         String[] resolvedTypes = new String[intents.length];
         for (int i=0; i<intents.length; i++) {
@@ -421,7 +447,7 @@
      * activity is started, not when the pending intent is created.
      */
     public static PendingIntent getActivitiesAsUser(Context context, int requestCode,
-            Intent[] intents, int flags, Bundle options, UserHandle user) {
+            @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) {
         String packageName = context.getPackageName();
         String[] resolvedTypes = new String[intents.length];
         for (int i=0; i<intents.length; i++) {
@@ -465,7 +491,7 @@
      * supplied.
      */
     public static PendingIntent getBroadcast(Context context, int requestCode,
-            Intent intent, int flags) {
+            Intent intent, @Flags int flags) {
         return getBroadcastAsUser(context, requestCode, intent, flags,
                 new UserHandle(UserHandle.myUserId()));
     }
@@ -519,7 +545,7 @@
      * supplied.
      */
     public static PendingIntent getService(Context context, int requestCode,
-            Intent intent, int flags) {
+            @NonNull Intent intent, @Flags int flags) {
         String packageName = context.getPackageName();
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
@@ -749,6 +775,7 @@
      * @return The package name of the PendingIntent, or null if there is
      * none associated with it.
      */
+    @Nullable
     public String getCreatorPackage() {
         try {
             return ActivityManagerNative.getDefault()
@@ -807,6 +834,7 @@
      * @return The user handle of the PendingIntent, or null if there is
      * none associated with it.
      */
+    @Nullable
     public UserHandle getCreatorUserHandle() {
         try {
             int uid = ActivityManagerNative.getDefault()
@@ -861,6 +889,20 @@
     }
 
     /**
+     * @hide
+     * Return descriptive tag for this PendingIntent.
+     */
+    public String getTag(String prefix) {
+        try {
+            return ActivityManagerNative.getDefault()
+                .getTagForIntentSender(mTarget, prefix);
+        } catch (RemoteException e) {
+            // Should never happen.
+            return null;
+        }
+    }
+
+    /**
      * Comparison operator on two PendingIntent objects, such that true
      * is returned then they both represent the same operation from the
      * same package.  This allows you to use {@link #getActivity},
@@ -922,8 +964,8 @@
      * @param sender The PendingIntent to write, or null.
      * @param out Where to write the PendingIntent.
      */
-    public static void writePendingIntentOrNullToParcel(PendingIntent sender,
-            Parcel out) {
+    public static void writePendingIntentOrNullToParcel(@Nullable PendingIntent sender,
+            @NonNull Parcel out) {
         out.writeStrongBinder(sender != null ? sender.mTarget.asBinder()
                 : null);
     }
@@ -938,7 +980,8 @@
      * @return Returns the Messenger read from the Parcel, or null if null had
      * been written.
      */
-    public static PendingIntent readPendingIntentOrNullFromParcel(Parcel in) {
+    @Nullable
+    public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) {
         IBinder b = in.readStrongBinder();
         return b != null ? new PendingIntent(b) : null;
     }
diff --git a/core/java/android/app/ProfilerInfo.java b/core/java/android/app/ProfilerInfo.java
new file mode 100644
index 0000000..cea7c3c
--- /dev/null
+++ b/core/java/android/app/ProfilerInfo.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * System private API for passing profiler settings.
+ *
+ * {@hide}
+ */
+public class ProfilerInfo implements Parcelable {
+
+    /* Name of profile output file. */
+    public final String profileFile;
+
+    /* File descriptor for profile output file, can be null. */
+    public ParcelFileDescriptor profileFd;
+
+    /* Indicates sample profiling when nonzero, interval in microseconds. */
+    public final int samplingInterval;
+
+    /* Automatically stop the profiler when the app goes idle. */
+    public final boolean autoStopProfiler;
+
+    public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop) {
+        profileFile = filename;
+        profileFd = fd;
+        samplingInterval = interval;
+        autoStopProfiler = autoStop;
+    }
+
+    public int describeContents() {
+        if (profileFd != null) {
+            return profileFd.describeContents();
+        } else {
+            return 0;
+        }
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(profileFile);
+        if (profileFd != null) {
+            out.writeInt(1);
+            profileFd.writeToParcel(out, flags);
+        } else {
+            out.writeInt(0);
+        }
+        out.writeInt(samplingInterval);
+        out.writeInt(autoStopProfiler ? 1 : 0);
+    }
+
+    public static final Parcelable.Creator<ProfilerInfo> CREATOR =
+            new Parcelable.Creator<ProfilerInfo>() {
+        public ProfilerInfo createFromParcel(Parcel in) {
+            return new ProfilerInfo(in);
+        }
+
+        public ProfilerInfo[] newArray(int size) {
+            return new ProfilerInfo[size];
+        }
+    };
+
+    private ProfilerInfo(Parcel in) {
+        profileFile = in.readString();
+        profileFd = in.readInt() != 0 ? ParcelFileDescriptor.CREATOR.createFromParcel(in) : null;
+        samplingInterval = in.readInt();
+        autoStopProfiler = in.readInt() != 0;
+    }
+}
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 728f372..1691d8e 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -144,14 +144,16 @@
      * Creates the top level Resources for applications with the given compatibility info.
      *
      * @param resDir the resource directory.
+     * @param overlayDirs the resource overlay directories.
+     * @param libDirs the shared library resource dirs this app references.
      * @param compatInfo the compability info. Must not be null.
      * @param token the application token for determining stack bounds.
      */
-    public Resources getTopLevelResources(String resDir, String[] overlayDirs, int displayId,
+    public Resources getTopLevelResources(String resDir, String[] splitResDirs,
+            String[] overlayDirs, String[] libDirs, int displayId,
             Configuration overrideConfiguration, CompatibilityInfo compatInfo, IBinder token) {
         final float scale = compatInfo.applicationScale;
-        ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
-                token);
+        ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale, token);
         Resources r;
         synchronized (this) {
             // Resources is app scale dependent.
@@ -176,8 +178,21 @@
         //}
 
         AssetManager assets = new AssetManager();
-        if (assets.addAssetPath(resDir) == 0) {
-            return null;
+        // resDir can be null if the 'android' package is creating a new Resources object.
+        // This is fine, since each AssetManager automatically loads the 'android' package
+        // already.
+        if (resDir != null) {
+            if (assets.addAssetPath(resDir) == 0) {
+                return null;
+            }
+        }
+
+        if (splitResDirs != null) {
+            for (String splitResDir : splitResDirs) {
+                if (assets.addAssetPath(splitResDir) == 0) {
+                    return null;
+                }
+            }
         }
 
         if (overlayDirs != null) {
@@ -186,6 +201,15 @@
             }
         }
 
+        if (libDirs != null) {
+            for (String libDir : libDirs) {
+                if (assets.addAssetPath(libDir) == 0) {
+                    Slog.w(TAG, "Asset path '" + libDir +
+                            "' does not exist or contains no resources.");
+                }
+            }
+        }
+
         //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
         DisplayMetrics dm = getDisplayMetricsLocked(displayId);
         Configuration config;
diff --git a/core/java/android/app/ResultInfo.java b/core/java/android/app/ResultInfo.java
index 48a0fc2..5e0867c 100644
--- a/core/java/android/app/ResultInfo.java
+++ b/core/java/android/app/ResultInfo.java
@@ -17,12 +17,8 @@
 package android.app;
 
 import android.content.Intent;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Bundle;
-
-import java.util.Map;
 
 /**
  * {@hide}
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index d04e9db..af1810b 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -188,8 +188,7 @@
                 mSearchView.findViewById(com.android.internal.R.id.search_src_text);
         mAppIcon = (ImageView) findViewById(com.android.internal.R.id.search_app_icon);
         mSearchPlate = mSearchView.findViewById(com.android.internal.R.id.search_plate);
-        mWorkingSpinner = getContext().getResources().
-                getDrawable(com.android.internal.R.drawable.search_spinner);
+        mWorkingSpinner = getContext().getDrawable(com.android.internal.R.drawable.search_spinner);
         // TODO: Restore the spinner for slow suggestion lookups
         // mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
         //        null, null, mWorkingSpinner, null);
@@ -458,7 +457,7 @@
 
         // optionally show one or the other.
         if (mSearchable.useBadgeIcon()) {
-            icon = mActivityContext.getResources().getDrawable(mSearchable.getIconId());
+            icon = mActivityContext.getDrawable(mSearchable.getIconId());
             visibility = View.VISIBLE;
             if (DBG) Log.d(LOG_TAG, "Using badge icon: " + mSearchable.getIconId());
         } else if (mSearchable.useBadgeLabel()) {
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index f9c245e..261b15d 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.database.Cursor;
 import android.graphics.Rect;
@@ -34,7 +33,6 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Slog;
 import android.view.KeyEvent;
 
 import java.util.List;
@@ -255,6 +253,7 @@
      * for more information on these schemes.
      */
     public final static String SUGGEST_COLUMN_ICON_1 = "suggest_icon_1";
+
     /**
      * Column name for suggestions cursor.  <i>Optional.</i>  If your cursor includes this column,
      *  then all suggestions will be provided in a format that includes space for two small icons,
@@ -271,6 +270,24 @@
      * for more information on these schemes.
      */
     public final static String SUGGEST_COLUMN_ICON_2 = "suggest_icon_2";
+
+    /**
+     * Column name for suggestions cursor.  <i>Optional.</i>  If your cursor includes this column,
+     * then the image will be displayed when forming the suggestion. The suggested dimension for
+     * the image is 270x400 px for portrait mode and 400x225 px for landscape mode. The data in the
+     * column must be a resource ID of a drawable, or a URI in one of the following formats:
+     *
+     * <ul>
+     * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+     * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
+     * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+     * </ul>
+     *
+     * See {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)}
+     * for more information on these schemes.
+     */
+    public final static String SUGGEST_COLUMN_RESULT_CARD_IMAGE = "suggest_result_card_image";
+
     /**
      * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
      * this element exists at the given row, this is the action that will be used when
@@ -281,6 +298,7 @@
      * it from the cursor.
      */
     public final static String SUGGEST_COLUMN_INTENT_ACTION = "suggest_intent_action";
+
     /**
      * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
      * this element exists at the given row, this is the data that will be used when
@@ -291,6 +309,7 @@
      * it is more efficient to specify it using XML metadata and omit it from the cursor.
      */
     public final static String SUGGEST_COLUMN_INTENT_DATA = "suggest_intent_data";
+
     /**
      * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
      * this element exists at the given row, this is the data that will be used when
@@ -299,6 +318,7 @@
      * an extra under the key {@link #EXTRA_DATA_KEY}.
      */
     public final static String SUGGEST_COLUMN_INTENT_EXTRA_DATA = "suggest_intent_extra_data";
+
     /**
      * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
      * this element exists at the given row, then "/" and this value will be appended to the data
@@ -306,6 +326,7 @@
      * appropriate base string.
      */
     public final static String SUGGEST_COLUMN_INTENT_DATA_ID = "suggest_intent_data_id";
+
     /**
      * Column name for suggestions cursor.  <i>Required if action is
      * {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH}, optional otherwise.</i>  If this
@@ -333,6 +354,89 @@
             "suggest_spinner_while_refreshing";
 
     /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content is media type, you
+     * should provide this column so search app could understand more about your content. The data
+     * in the column must specify the MIME type of the content.
+     */
+    public final static String SUGGEST_COLUMN_CONTENT_TYPE = "suggest_content_type";
+
+    /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content is media type, you
+     * should provide this column to specify whether your content is live media such as live video
+     * or live audio. The value in the column is of integer type with value of either 0 indicating
+     * non-live content or 1 indicating live content.
+     */
+    public final static String SUGGEST_COLUMN_IS_LIVE = "suggest_is_live";
+
+    /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content is video, you should
+     * provide this column to specify the number of vertical lines. The data in the column is of
+     * integer type.
+     */
+    public final static String SUGGEST_COLUMN_VIDEO_WIDTH = "suggest_video_width";
+
+    /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content is video, you should
+     * provide this column to specify the number of horizontal lines. The data in the column is of
+     * integer type.
+     */
+    public final static String SUGGEST_COLUMN_VIDEO_HEIGHT = "suggest_video_height";
+
+    /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content contains audio, you
+     * should provide this column to specify the audio channel configuration. The data in the
+     * column is string with format like "channels.subchannels" such as "1.0" or "5.1".
+     */
+    public final static String SUGGEST_COLUMN_AUDIO_CHANNEL_CONFIG = "suggest_audio_channel_config";
+
+    /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content is purchasable, you
+     * should provide this column to specify the displayable string representation of the purchase
+     * price of your content including the currency and the amount. If it's free, you should
+     * provide localized string to specify that it's free. This column can be omitted if the content
+     * is not applicable to purchase.
+     */
+    public final static String SUGGEST_COLUMN_PURCHASE_PRICE = "suggest_purchase_price";
+
+    /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content is rentable, you
+     * should provide this column to specify the displayable string representation of the rental
+     * price of your content including the currency and the amount. If it's free, you should
+     * provide localized string to specify that it's free. This column can be ommitted if the
+     * content is not applicable to rent.
+     */
+    public final static String SUGGEST_COLUMN_RENTAL_PRICE = "suggest_rental_price";
+
+    /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content has a rating, you
+     * should provide this column to specify the rating style of your content. The data in the
+     * column must be one of the constant values specified in {@link android.media.Rating}
+     */
+    public final static String SUGGEST_COLUMN_RATING_STYLE = "suggest_rating_style";
+
+    /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content has a rating, you
+     * should provide this column to specify the rating score of your content. The data in the
+     * column is of float type. See {@link android.media.Rating} about valid rating scores for each
+     * rating style.
+     */
+    public final static String SUGGEST_COLUMN_RATING_SCORE = "suggest_rating_score";
+
+    /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content is video or audio and
+     * has a known production year, you should provide this column to specify the production year
+     * of your content. The data in the column is of integer type.
+     */
+    public final static String SUGGEST_COLUMN_PRODUCTION_YEAR = "suggest_production_year";
+
+    /**
+     * Column name for suggestions cursor. <i>Optional.</i>  If your content is video or audio, you
+     * should provide this column to specify the duration of your content in milliseconds. The data
+     * in the column is of long type.
+     */
+    public final static String SUGGEST_COLUMN_DURATION = "suggest_duration";
+
+    /**
      * Column name for suggestions cursor. <i>Optional.</i> This column is used to specify
      * additional flags per item. Multiple flags can be specified.
      * <p>
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 3967740..ec9960d 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -401,7 +401,7 @@
     
     /**
      * This flag is set in {@link #onStartCommand} if the Intent is a
-     * a retry because the original attempt never got to or returned from
+     * retry because the original attempt never got to or returned from
      * {@link #onStartCommand(Intent, int, int)}.
      */
     public static final int START_FLAG_RETRY = 0x0002;
diff --git a/core/java/android/app/SharedElementCallback.java b/core/java/android/app/SharedElementCallback.java
new file mode 100644
index 0000000..060bbe6
--- /dev/null
+++ b/core/java/android/app/SharedElementCallback.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.RectF;
+import android.graphics.drawable.BitmapDrawable;
+import android.os.Parcelable;
+import android.transition.TransitionUtils;
+import android.view.View;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Listener provided in
+ * {@link Activity#setEnterSharedElementCallback(SharedElementCallback)} and
+ * {@link Activity#setExitSharedElementCallback(SharedElementCallback)} as well as
+ * {@link Fragment#setEnterSharedElementCallback(SharedElementCallback)} and
+ * {@link Fragment#setExitSharedElementCallback(SharedElementCallback)}
+ * to monitor the Shared element transitions. The events can be used to customize Activity
+ * and Fragment Transition behavior.
+ */
+public abstract class SharedElementCallback {
+    private Matrix mTempMatrix;
+
+    static final SharedElementCallback NULL_CALLBACK = new SharedElementCallback() {
+    };
+
+    /**
+     * Called immediately after the start state is set for the shared element.
+     * The shared element will start at the size and position of the shared element
+     * in the launching Activity or Fragment.
+     *
+     * @param sharedElementNames The names of the shared elements that were accepted into
+     *                           the View hierarchy.
+     * @param sharedElements The shared elements that are part of the View hierarchy.
+     * @param sharedElementSnapshots The Views containing snap shots of the shared element
+     *                               from the launching Window. These elements will not
+     *                               be part of the scene, but will be positioned relative
+     *                               to the Window decor View. This list is null for Fragment
+     *                               Transitions.
+     */
+    public void onSharedElementStart(List<String> sharedElementNames,
+            List<View> sharedElements, List<View> sharedElementSnapshots) {}
+
+    /**
+     * Called after the end state is set for the shared element, but before the end state
+     * is captured by the shared element transition.
+     * <p>
+     *     Any customization done in
+     *     {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)}
+     *     may need to be modified to the final state of the shared element if it is not
+     *     automatically corrected by layout. For example, rotation or scale will not
+     *     be affected by layout and if changed in {@link #onSharedElementStart(java.util.List,
+     *     java.util.List, java.util.List)}, it will also have to be set here again to correct
+     *     the end state.
+     * </p>
+     *
+     * @param sharedElementNames The names of the shared elements that were accepted into
+     *                           the View hierarchy.
+     * @param sharedElements The shared elements that are part of the View hierarchy.
+     * @param sharedElementSnapshots The Views containing snap shots of the shared element
+     *                               from the launching Window. These elements will not
+     *                               be part of the scene, but will be positioned relative
+     *                               to the Window decor View. This list will be null for
+     *                               Fragment Transitions.
+     */
+    public void onSharedElementEnd(List<String> sharedElementNames,
+            List<View> sharedElements, List<View> sharedElementSnapshots) {}
+
+    /**
+     * Called after {@link #onMapSharedElements(java.util.List, java.util.Map)} when
+     * transferring shared elements in. Any shared elements that have no mapping will be in
+     * <var>rejectedSharedElements</var>. The elements remaining in
+     * <var>rejectedSharedElements</var> will be transitioned out of the Scene. If a
+     * View is removed from <var>rejectedSharedElements</var>, it must be handled by the
+     * <code>SharedElementCallback</code>.
+     * <p>
+     * Views in rejectedSharedElements will have their position and size set to the
+     * position of the calling shared element, relative to the Window decor View and contain
+     * snapshots of the View from the calling Activity or Fragment. This
+     * view may be safely added to the decor View's overlay to remain in position.
+     * </p>
+     * <p>This method is not called for Fragment Transitions. All rejected shared elements
+     * will be handled by the exit transition.</p>
+     *
+     * @param rejectedSharedElements Views containing visual information of shared elements
+     *                               that are not part of the entering scene. These Views
+     *                               are positioned relative to the Window decor View. A
+     *                               View removed from this list will not be transitioned
+     *                               automatically.
+     */
+    public void onRejectSharedElements(List<View> rejectedSharedElements) {}
+
+    /**
+     * Lets the SharedElementCallback adjust the mapping of shared element names to
+     * Views.
+     *
+     * @param names The names of all shared elements transferred from the calling Activity
+     *              or Fragment in the order they were provided.
+     * @param sharedElements The mapping of shared element names to Views. The best guess
+     *                       will be filled into sharedElements based on the transitionNames.
+     */
+    public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {}
+
+    /**
+     * Creates a snapshot of a shared element to be used by the remote Activity and reconstituted
+     * with {@link #onCreateSnapshotView(android.content.Context, android.os.Parcelable)}. A
+     * null return value will mean that the remote Activity will have a null snapshot View in
+     * {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} and
+     * {@link #onSharedElementEnd(java.util.List, java.util.List, java.util.List)}.
+     *
+     * <p>This is not called for Fragment Transitions.</p>
+     *
+     * @param sharedElement The shared element View to create a snapshot for.
+     * @param viewToGlobalMatrix A matrix containing a transform from the view to the screen
+     *                           coordinates.
+     * @param screenBounds The bounds of shared element in screen coordinate space. This is
+     *                     the bounds of the view with the viewToGlobalMatrix applied.
+     * @return A snapshot to send to the remote Activity to be reconstituted with
+     * {@link #onCreateSnapshotView(android.content.Context, android.os.Parcelable)} and passed
+     * into {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)} and
+     * {@link #onSharedElementEnd(java.util.List, java.util.List, java.util.List)}.
+     */
+    public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix,
+            RectF screenBounds) {
+        if (mTempMatrix == null) {
+            mTempMatrix = new Matrix(viewToGlobalMatrix);
+        } else {
+            mTempMatrix.set(viewToGlobalMatrix);
+        }
+        return TransitionUtils.createViewBitmap(sharedElement, mTempMatrix, screenBounds);
+    }
+
+    /**
+     * Reconstitutes a snapshot View from a Parcelable returned in
+     * {@link #onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix,
+     * android.graphics.RectF)} to be used in {@link #onSharedElementStart(java.util.List,
+     * java.util.List, java.util.List)} and {@link #onSharedElementEnd(java.util.List,
+     * java.util.List, java.util.List)}. The returned View will be sized and positioned after
+     * this call so that it is ready to be added to the decor View's overlay.
+     *
+     * <p>This is not called for Fragment Transitions.</p>
+     *
+     * @param context The Context used to create the snapshot View.
+     * @param snapshot The Parcelable returned by {@link #onCaptureSharedElementSnapshot(
+     * android.view.View, android.graphics.Matrix, android.graphics.RectF)}.
+     * @return A View to be sent in {@link #onSharedElementStart(java.util.List, java.util.List,
+     * java.util.List)} and {@link #onSharedElementEnd(java.util.List, java.util.List,
+     * java.util.List)}. A null value will produce a null snapshot value for those two methods.
+     */
+    public View onCreateSnapshotView(Context context, Parcelable snapshot) {
+        View view = null;
+        if (snapshot instanceof Bitmap) {
+            Bitmap bitmap = (Bitmap) snapshot;
+            view = new View(context);
+            Resources resources = context.getResources();
+            view.setBackground(new BitmapDrawable(resources, bitmap));
+        }
+        return view;
+    }
+}
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index a8896c2..4427ce1 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -45,7 +45,6 @@
 import java.util.Set;
 import java.util.WeakHashMap;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
 
 import libcore.io.IoUtils;
 
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 2045ed8..ce5306f 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -38,6 +38,7 @@
     public static final int DISABLE_NOTIFICATION_ICONS = View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS;
     public static final int DISABLE_NOTIFICATION_ALERTS
             = View.STATUS_BAR_DISABLE_NOTIFICATION_ALERTS;
+    @Deprecated
     public static final int DISABLE_NOTIFICATION_TICKER
             = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
     public static final int DISABLE_SYSTEM_INFO = View.STATUS_BAR_DISABLE_SYSTEM_INFO;
@@ -59,6 +60,7 @@
             | DISABLE_SEARCH;
 
     public static final int NAVIGATION_HINT_BACK_ALT      = 1 << 0;
+    public static final int NAVIGATION_HINT_IME_SHOWN     = 1 << 1;
 
     public static final int WINDOW_STATUS_BAR = 1;
     public static final int WINDOW_NAVIGATION_BAR = 2;
diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java
index 3e0ac7e..0077db1 100644
--- a/core/java/android/app/TaskStackBuilder.java
+++ b/core/java/android/app/TaskStackBuilder.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -244,7 +245,7 @@
      *
      * @return The obtained PendingIntent
      */
-    public PendingIntent getPendingIntent(int requestCode, int flags) {
+    public PendingIntent getPendingIntent(int requestCode, @PendingIntent.Flags int flags) {
         return getPendingIntent(requestCode, flags, null);
     }
 
@@ -263,7 +264,8 @@
      *
      * @return The obtained PendingIntent
      */
-    public PendingIntent getPendingIntent(int requestCode, int flags, Bundle options) {
+    public PendingIntent getPendingIntent(int requestCode, @PendingIntent.Flags int flags,
+            Bundle options) {
         if (mIntents.isEmpty()) {
             throw new IllegalStateException(
                     "No intents added to TaskStackBuilder; cannot getPendingIntent");
@@ -294,6 +296,7 @@
      *
      * @return An array containing the intents added to this builder.
      */
+    @NonNull
     public Intent[] getIntents() {
         Intent[] intents = new Intent[mIntents.size()];
         if (intents.length == 0) return intents;
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 952227f..64543673 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -16,16 +16,19 @@
 
 package android.app;
 
-import com.android.internal.R;
-
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.os.Bundle;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.Button;
 import android.widget.TimePicker;
 import android.widget.TimePicker.OnTimeChangedListener;
+import android.widget.TimePicker.ValidationCallback;
+
+import com.android.internal.R;
 
 /**
  * A dialog that prompts the user for the time of day using a {@link TimePicker}.
@@ -33,12 +36,23 @@
  * <p>See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
  * guide.</p>
  */
-public class TimePickerDialog extends AlertDialog
-        implements OnClickListener, OnTimeChangedListener {
+public class TimePickerDialog extends AlertDialog implements OnClickListener,
+        OnTimeChangedListener {
+
+    private static final String HOUR = "hour";
+    private static final String MINUTE = "minute";
+    private static final String IS_24_HOUR = "is24hour";
+
+    private final TimePicker mTimePicker;
+    private final OnTimeSetListener mTimeSetCallback;
+
+    private final int mInitialHourOfDay;
+    private final int mInitialMinute;
+    private final boolean mIs24HourView;
 
     /**
      * The callback interface used to indicate the user is done filling in
-     * the time (they clicked on the 'Set' button).
+     * the time (they clicked on the 'Done' button).
      */
     public interface OnTimeSetListener {
 
@@ -50,17 +64,6 @@
         void onTimeSet(TimePicker view, int hourOfDay, int minute);
     }
 
-    private static final String HOUR = "hour";
-    private static final String MINUTE = "minute";
-    private static final String IS_24_HOUR = "is24hour";
-
-    private final TimePicker mTimePicker;
-    private final OnTimeSetListener mCallback;
-
-    int mInitialHourOfDay;
-    int mInitialMinute;
-    boolean mIs24HourView;
-
     /**
      * @param context Parent.
      * @param callBack How parent is notified.
@@ -74,6 +77,16 @@
         this(context, 0, callBack, hourOfDay, minute, is24HourView);
     }
 
+    static int resolveDialogTheme(Context context, int resid) {
+        if (resid == 0) {
+            final TypedValue outValue = new TypedValue();
+            context.getTheme().resolveAttribute(R.attr.timePickerDialogTheme, outValue, true);
+            return outValue.resourceId;
+        } else {
+            return resid;
+        }
+    }
+
     /**
      * @param context Parent.
      * @param theme the theme to apply to this dialog
@@ -82,65 +95,62 @@
      * @param minute The initial minute.
      * @param is24HourView Whether this is a 24 hour view, or AM/PM.
      */
-    public TimePickerDialog(Context context,
-            int theme,
-            OnTimeSetListener callBack,
-            int hourOfDay, int minute, boolean is24HourView) {
-        super(context, theme);
-        mCallback = callBack;
+    public TimePickerDialog(Context context, int theme, OnTimeSetListener callBack, int hourOfDay,
+            int minute, boolean is24HourView) {
+        super(context, resolveDialogTheme(context, theme));
+
+        mTimeSetCallback = callBack;
         mInitialHourOfDay = hourOfDay;
         mInitialMinute = minute;
         mIs24HourView = is24HourView;
 
-        setIcon(0);
-        setTitle(R.string.time_picker_dialog_title);
-
-        Context themeContext = getContext();
-        setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this);
-
-        LayoutInflater inflater =
-                (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        View view = inflater.inflate(R.layout.time_picker_dialog, null);
+        final Context themeContext = getContext();
+        final LayoutInflater inflater = LayoutInflater.from(themeContext);
+        final View view = inflater.inflate(R.layout.time_picker_dialog, null);
         setView(view);
-        mTimePicker = (TimePicker) view.findViewById(R.id.timePicker);
+        setButton(BUTTON_POSITIVE, themeContext.getString(R.string.ok), this);
+        setButton(BUTTON_NEGATIVE, themeContext.getString(R.string.cancel), this);
+        setButtonPanelLayoutHint(LAYOUT_HINT_SIDE);
 
-        // initialize state
+        mTimePicker = (TimePicker) view.findViewById(R.id.timePicker);
         mTimePicker.setIs24HourView(mIs24HourView);
         mTimePicker.setCurrentHour(mInitialHourOfDay);
         mTimePicker.setCurrentMinute(mInitialMinute);
         mTimePicker.setOnTimeChangedListener(this);
+        mTimePicker.setValidationCallback(mValidationCallback);
     }
 
-    public void onClick(DialogInterface dialog, int which) {
-        tryNotifyTimeSet();
-    }
-
-    public void updateTime(int hourOfDay, int minutOfHour) {
-        mTimePicker.setCurrentHour(hourOfDay);
-        mTimePicker.setCurrentMinute(minutOfHour);
-    }
-
+    @Override
     public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
         /* do nothing */
     }
 
-    private void tryNotifyTimeSet() {
-        if (mCallback != null) {
-            mTimePicker.clearFocus();
-            mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
-                    mTimePicker.getCurrentMinute());
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        switch (which) {
+            case BUTTON_POSITIVE:
+                if (mTimeSetCallback != null) {
+                    mTimeSetCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
+                            mTimePicker.getCurrentMinute());
+                }
+                break;
         }
     }
 
-    @Override
-    protected void onStop() {
-        tryNotifyTimeSet();
-        super.onStop();
+    /**
+     * Sets the current time.
+     *
+     * @param hourOfDay The current hour within the day.
+     * @param minuteOfHour The current minute within the hour.
+     */
+    public void updateTime(int hourOfDay, int minuteOfHour) {
+        mTimePicker.setCurrentHour(hourOfDay);
+        mTimePicker.setCurrentMinute(minuteOfHour);
     }
 
     @Override
     public Bundle onSaveInstanceState() {
-        Bundle state = super.onSaveInstanceState();
+        final Bundle state = super.onSaveInstanceState();
         state.putInt(HOUR, mTimePicker.getCurrentHour());
         state.putInt(MINUTE, mTimePicker.getCurrentMinute());
         state.putBoolean(IS_24_HOUR, mTimePicker.is24HourView());
@@ -150,10 +160,20 @@
     @Override
     public void onRestoreInstanceState(Bundle savedInstanceState) {
         super.onRestoreInstanceState(savedInstanceState);
-        int hour = savedInstanceState.getInt(HOUR);
-        int minute = savedInstanceState.getInt(MINUTE);
+        final int hour = savedInstanceState.getInt(HOUR);
+        final int minute = savedInstanceState.getInt(MINUTE);
         mTimePicker.setIs24HourView(savedInstanceState.getBoolean(IS_24_HOUR));
         mTimePicker.setCurrentHour(hour);
         mTimePicker.setCurrentMinute(minute);
     }
+
+    private final ValidationCallback mValidationCallback = new ValidationCallback() {
+        @Override
+        public void onValidationChanged(boolean valid) {
+            final Button positive = getButton(BUTTON_POSITIVE);
+            if (positive != null) {
+                positive.setEnabled(valid);
+            }
+        }
+    };
 }
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 498fa42..4aec9e0 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -26,6 +26,7 @@
 import android.graphics.Point;
 import android.hardware.display.DisplayManagerGlobal;
 import android.os.Looper;
+import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.Log;
@@ -33,12 +34,18 @@
 import android.view.InputEvent;
 import android.view.KeyEvent;
 import android.view.Surface;
+import android.view.WindowAnimationFrameStats;
+import android.view.WindowContentFrameStats;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityInteractionConnection;
+import libcore.io.IoUtils;
 
+import java.io.IOException;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.TimeoutException;
 
 /**
@@ -269,10 +276,10 @@
      * @param action The action to perform.
      * @return Whether the action was successfully performed.
      *
-     * @see AccessibilityService#GLOBAL_ACTION_BACK
-     * @see AccessibilityService#GLOBAL_ACTION_HOME
-     * @see AccessibilityService#GLOBAL_ACTION_NOTIFICATIONS
-     * @see AccessibilityService#GLOBAL_ACTION_RECENTS
+     * @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_BACK
+     * @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_HOME
+     * @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_NOTIFICATIONS
+     * @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_RECENTS
      */
     public final boolean performGlobalAction(int action) {
         final IAccessibilityServiceConnection connection;
@@ -293,6 +300,28 @@
     }
 
     /**
+     * Find the view that has the specified focus type. The search is performed
+     * across all windows.
+     * <p>
+     * <strong>Note:</strong> In order to access the windows you have to opt-in
+     * to retrieve the interactive windows by setting the
+     * {@link AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS} flag.
+     * Otherwise, the search will be performed only in the active window.
+     * </p>
+     *
+     * @param focus The focus to find. One of {@link AccessibilityNodeInfo#FOCUS_INPUT} or
+     *         {@link AccessibilityNodeInfo#FOCUS_ACCESSIBILITY}.
+     * @return The node info of the focused view or null.
+     *
+     * @see AccessibilityNodeInfo#FOCUS_INPUT
+     * @see AccessibilityNodeInfo#FOCUS_ACCESSIBILITY
+     */
+    public AccessibilityNodeInfo findFocus(int focus) {
+        return AccessibilityInteractionClient.getInstance().findFocus(mConnectionId,
+                AccessibilityNodeInfo.ANY_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, focus);
+    }
+
+    /**
      * Gets the an {@link AccessibilityServiceInfo} describing this UiAutomation.
      * This method is useful if one wants to change some of the dynamically
      * configurable properties at runtime.
@@ -346,6 +375,33 @@
     }
 
     /**
+     * Gets the windows on the screen. This method returns only the windows
+     * that a sighted user can interact with, as opposed to all windows.
+     * For example, if there is a modal dialog shown and the user cannot touch
+     * anything behind it, then only the modal window will be reported
+     * (assuming it is the top one). For convenience the returned windows
+     * are ordered in a descending layer order, which is the windows that
+     * are higher in the Z-order are reported first.
+     * <p>
+     * <strong>Note:</strong> In order to access the windows you have to opt-in
+     * to retrieve the interactive windows by setting the
+     * {@link AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS} flag.
+     * </p>
+     *
+     * @return The windows if there are windows such, otherwise an empty list.
+     */
+    public List<AccessibilityWindowInfo> getWindows() {
+        final int connectionId;
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+            connectionId = mConnectionId;
+        }
+        // Calling out without a lock held.
+        return AccessibilityInteractionClient.getInstance()
+                .getWindows(connectionId);
+    }
+
+    /**
      * Gets the root {@link AccessibilityNodeInfo} in the active window.
      *
      * @return The root info.
@@ -617,6 +673,7 @@
             canvas.translate(- screenshotWidth / 2, - screenshotHeight / 2);
             canvas.drawBitmap(screenShot, 0, 0, null);
             canvas.setBitmap(null);
+            screenShot.recycle();
             screenShot = unrotatedScreenShot;
         }
 
@@ -632,7 +689,7 @@
      * potentially undesirable actions such as calling 911 or posting on public forums etc.
      *
      * @param enable whether to run in a "monkey" mode or not. Default is not.
-     * @see {@link ActivityManager#isUserAMonkey()}
+     * @see {@link android.app.ActivityManager#isUserAMonkey()}
      */
     public void setRunAsMonkey(boolean enable) {
         synchronized (mLock) {
@@ -645,6 +702,186 @@
         }
     }
 
+    /**
+     * Clears the frame statistics for the content of a given window. These
+     * statistics contain information about the most recently rendered content
+     * frames.
+     *
+     * @param windowId The window id.
+     * @return Whether the window is present and its frame statistics
+     *         were cleared.
+     *
+     * @see android.view.WindowContentFrameStats
+     * @see #getWindowContentFrameStats(int)
+     * @see #getWindows()
+     * @see AccessibilityWindowInfo#getId() AccessibilityWindowInfo.getId()
+     */
+    public boolean clearWindowContentFrameStats(int windowId) {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+        }
+        try {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Clearing content frame stats for window: " + windowId);
+            }
+            // Calling out without a lock held.
+            return mUiAutomationConnection.clearWindowContentFrameStats(windowId);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error clearing window content frame stats!", re);
+        }
+        return false;
+    }
+
+    /**
+     * Gets the frame statistics for a given window. These statistics contain
+     * information about the most recently rendered content frames.
+     * <p>
+     * A typical usage requires clearing the window frame statistics via {@link
+     * #clearWindowContentFrameStats(int)} followed by an interaction with the UI and
+     * finally getting the window frame statistics via calling this method.
+     * </p>
+     * <pre>
+     * // Assume we have at least one window.
+     * final int windowId = getWindows().get(0).getId();
+     *
+     * // Start with a clean slate.
+     * uiAutimation.clearWindowContentFrameStats(windowId);
+     *
+     * // Do stuff with the UI.
+     *
+     * // Get the frame statistics.
+     * WindowContentFrameStats stats = uiAutomation.getWindowContentFrameStats(windowId);
+     * </pre>
+     *
+     * @param windowId The window id.
+     * @return The window frame statistics, or null if the window is not present.
+     *
+     * @see android.view.WindowContentFrameStats
+     * @see #clearWindowContentFrameStats(int)
+     * @see #getWindows()
+     * @see AccessibilityWindowInfo#getId() AccessibilityWindowInfo.getId()
+     */
+    public WindowContentFrameStats getWindowContentFrameStats(int windowId) {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+        }
+        try {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Getting content frame stats for window: " + windowId);
+            }
+            // Calling out without a lock held.
+            return mUiAutomationConnection.getWindowContentFrameStats(windowId);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error getting window content frame stats!", re);
+        }
+        return null;
+    }
+
+    /**
+     * Clears the window animation rendering statistics. These statistics contain
+     * information about the most recently rendered window animation frames, i.e.
+     * for window transition animations.
+     *
+     * @see android.view.WindowAnimationFrameStats
+     * @see #getWindowAnimationFrameStats()
+     * @see android.R.styleable#WindowAnimation
+     */
+    public void clearWindowAnimationFrameStats() {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+        }
+        try {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Clearing window animation frame stats");
+            }
+            // Calling out without a lock held.
+            mUiAutomationConnection.clearWindowAnimationFrameStats();
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error clearing window animation frame stats!", re);
+        }
+    }
+
+    /**
+     * Gets the window animation frame statistics. These statistics contain
+     * information about the most recently rendered window animation frames, i.e.
+     * for window transition animations.
+     *
+     * <p>
+     * A typical usage requires clearing the window animation frame statistics via
+     * {@link #clearWindowAnimationFrameStats()} followed by an interaction that causes
+     * a window transition which uses a window animation and finally getting the window
+     * animation frame statistics by calling this method.
+     * </p>
+     * <pre>
+     * // Start with a clean slate.
+     * uiAutimation.clearWindowAnimationFrameStats();
+     *
+     * // Do stuff to trigger a window transition.
+     *
+     * // Get the frame statistics.
+     * WindowAnimationFrameStats stats = uiAutomation.getWindowAnimationFrameStats();
+     * </pre>
+     *
+     * @return The window animation frame statistics.
+     *
+     * @see android.view.WindowAnimationFrameStats
+     * @see #clearWindowAnimationFrameStats()
+     * @see android.R.styleable#WindowAnimation
+     */
+    public WindowAnimationFrameStats getWindowAnimationFrameStats() {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+        }
+        try {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Getting window animation frame stats");
+            }
+            // Calling out without a lock held.
+            return mUiAutomationConnection.getWindowAnimationFrameStats();
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error getting window animation frame stats!", re);
+        }
+        return null;
+    }
+
+    /**
+     * Executes a shell command. This method returs a file descriptor that points
+     * to the standard output stream. The command execution is similar to running
+     * "adb shell <command>" from a host connected to the device.
+     * <p>
+     * <strong>Note:</strong> It is your responsibility to close the retunred file
+     * descriptor once you are done reading.
+     * </p>
+     *
+     * @param command The command to execute.
+     * @return A file descriptor to the standard output stream.
+     */
+    public ParcelFileDescriptor executeShellCommand(String command) {
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+        }
+
+        ParcelFileDescriptor source = null;
+        ParcelFileDescriptor sink = null;
+
+        try {
+            ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+            source = pipe[0];
+            sink = pipe[1];
+
+            // Calling out without a lock held.
+            mUiAutomationConnection.executeShellCommand(command, sink);
+        } catch (IOException ioe) {
+            Log.e(LOG_TAG, "Error executing shell command!", ioe);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error executing shell command!", re);
+        } finally {
+            IoUtils.closeQuietly(sink);
+        }
+
+        return source;
+    }
+
     private static float getDegreesForRotation(int value) {
         switch (value) {
             case Surface.ROTATION_90: {
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 91b0d7c..81bcb39 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -22,14 +22,24 @@
 import android.graphics.Bitmap;
 import android.hardware.input.InputManager;
 import android.os.Binder;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.view.IWindowManager;
 import android.view.InputEvent;
 import android.view.SurfaceControl;
+import android.view.WindowAnimationFrameStats;
+import android.view.WindowContentFrameStats;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.IAccessibilityManager;
+import libcore.io.IoUtils;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 
 /**
  * This is a remote object that is passed from the shell to an instrumentation
@@ -47,6 +57,9 @@
     private final IWindowManager mWindowManager = IWindowManager.Stub.asInterface(
             ServiceManager.getService(Service.WINDOW_SERVICE));
 
+    private final IAccessibilityManager mAccessibilityManager = IAccessibilityManager.Stub
+            .asInterface(ServiceManager.getService(Service.ACCESSIBILITY_SERVICE));
+
     private final Object mLock = new Object();
 
     private final Binder mToken = new Binder();
@@ -144,6 +157,111 @@
     }
 
     @Override
+    public boolean clearWindowContentFrameStats(int windowId) throws RemoteException {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            IBinder token = mAccessibilityManager.getWindowToken(windowId);
+            if (token == null) {
+                return false;
+            }
+            return mWindowManager.clearWindowContentFrameStats(token);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public WindowContentFrameStats getWindowContentFrameStats(int windowId) throws RemoteException {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            IBinder token = mAccessibilityManager.getWindowToken(windowId);
+            if (token == null) {
+                return null;
+            }
+            return mWindowManager.getWindowContentFrameStats(token);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void clearWindowAnimationFrameStats() {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            SurfaceControl.clearAnimationFrameStats();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public WindowAnimationFrameStats getWindowAnimationFrameStats() {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            WindowAnimationFrameStats stats = new WindowAnimationFrameStats();
+            SurfaceControl.getAnimationFrameStats(stats);
+            return stats;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void executeShellCommand(String command, ParcelFileDescriptor sink)
+            throws RemoteException {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+
+        InputStream in = null;
+        OutputStream out = null;
+
+        try {
+            java.lang.Process process = Runtime.getRuntime().exec(command);
+
+            in = process.getInputStream();
+            out = new FileOutputStream(sink.getFileDescriptor());
+
+            final byte[] buffer = new byte[8192];
+            while (true) {
+                final int readByteCount = in.read(buffer);
+                if (readByteCount < 0) {
+                    break;
+                }
+                out.write(buffer, 0, readByteCount);
+            }
+        } catch (IOException ioe) {
+            throw new RuntimeException("Error running shell command", ioe);
+        } finally {
+            IoUtils.closeQuietly(in);
+            IoUtils.closeQuietly(out);
+            IoUtils.closeQuietly(sink);
+        }
+    }
+
+    @Override
     public void shutdown() {
         synchronized (mLock) {
             if (isConnectedLocked()) {
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index c6731c9..0a255f7 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -123,7 +123,18 @@
      * will switch to the car home activity even if we are already in car mode.
      */
     public static final int ENABLE_CAR_MODE_GO_CAR_HOME = 0x0001;
-    
+
+    /**
+     * Flag for use with {@link #enableCarMode(int)}: allow sleep mode while in car mode.
+     * By default, when this flag is not set, the system may hold a full wake lock to keep the
+     * screen turned on and prevent the system from entering sleep mode while in car mode.
+     * Setting this flag disables such behavior and the system may enter sleep mode
+     * if there is no other user activity and no other wake lock held.
+     * Setting this flag can be relevant for a car dock application that does not require the
+     * screen kept on.
+     */
+    public static final int ENABLE_CAR_MODE_ALLOW_SLEEP = 0x0002;
+
     /**
      * Force device into car mode, like it had been placed in the car dock.
      * This will cause the device to switch to the car home UI as part of
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
new file mode 100644
index 0000000..723cb9b
--- /dev/null
+++ b/core/java/android/app/VoiceInteractor.java
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
+import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.app.IVoiceInteractorCallback;
+import com.android.internal.app.IVoiceInteractorRequest;
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.SomeArgs;
+
+import java.util.ArrayList;
+
+/**
+ * @hide
+ * Interface for an {@link Activity} to interact with the user through voice.  Use
+ * {@link android.app.Activity#getVoiceInteractor() Activity.getVoiceInteractor}
+ * to retrieve the interface, if the activity is currently involved in a voice interaction.
+ *
+ * <p>The voice interactor revolves around submitting voice interaction requests to the
+ * back-end voice interaction service that is working with the user.  These requests are
+ * submitted with {@link #submitRequest}, providing a new instance of a
+ * {@link Request} subclass describing the type of operation to perform -- currently the
+ * possible requests are {@link ConfirmationRequest} and {@link CommandRequest}.
+ *
+ * <p>Once a request is submitted, the voice system will process it and eventually deliver
+ * the result to the request object.  The application can cancel a pending request at any
+ * time.
+ *
+ * <p>The VoiceInteractor is integrated with Activity's state saving mechanism, so that
+ * if an activity is being restarted with retained state, it will retain the current
+ * VoiceInteractor and any outstanding requests.  Because of this, you should always use
+ * {@link Request#getActivity() Request.getActivity} to get back to the activity of a
+ * request, rather than holding on to the activity instance yourself, either explicitly
+ * or implicitly through a non-static inner class.
+ */
+@SystemApi
+public class VoiceInteractor {
+    static final String TAG = "VoiceInteractor";
+    static final boolean DEBUG = true;
+
+    final IVoiceInteractor mInteractor;
+
+    Context mContext;
+    Activity mActivity;
+
+    final HandlerCaller mHandlerCaller;
+    final HandlerCaller.Callback mHandlerCallerCallback = new HandlerCaller.Callback() {
+        @Override
+        public void executeMessage(Message msg) {
+            SomeArgs args = (SomeArgs)msg.obj;
+            Request request;
+            switch (msg.what) {
+                case MSG_CONFIRMATION_RESULT:
+                    request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
+                    if (DEBUG) Log.d(TAG, "onConfirmResult: req="
+                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
+                            + " confirmed=" + msg.arg1 + " result=" + args.arg2);
+                    if (request != null) {
+                        ((ConfirmationRequest)request).onConfirmationResult(msg.arg1 != 0,
+                                (Bundle) args.arg2);
+                        request.clear();
+                    }
+                    break;
+                case MSG_COMPLETE_VOICE_RESULT:
+                    request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
+                    if (DEBUG) Log.d(TAG, "onCompleteVoice: req="
+                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
+                            + " result=" + args.arg1);
+                    if (request != null) {
+                        ((CompleteVoiceRequest)request).onCompleteResult((Bundle) args.arg2);
+                        request.clear();
+                    }
+                    break;
+                case MSG_ABORT_VOICE_RESULT:
+                    request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
+                    if (DEBUG) Log.d(TAG, "onAbortVoice: req="
+                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
+                            + " result=" + args.arg1);
+                    if (request != null) {
+                        ((AbortVoiceRequest)request).onAbortResult((Bundle) args.arg2);
+                        request.clear();
+                    }
+                    break;
+                case MSG_COMMAND_RESULT:
+                    request = pullRequest((IVoiceInteractorRequest)args.arg1, msg.arg1 != 0);
+                    if (DEBUG) Log.d(TAG, "onCommandResult: req="
+                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request
+                            + " result=" + args.arg2);
+                    if (request != null) {
+                        ((CommandRequest)request).onCommandResult((Bundle) args.arg2);
+                        if (msg.arg1 != 0) {
+                            request.clear();
+                        }
+                    }
+                    break;
+                case MSG_CANCEL_RESULT:
+                    request = pullRequest((IVoiceInteractorRequest)args.arg1, true);
+                    if (DEBUG) Log.d(TAG, "onCancelResult: req="
+                            + ((IVoiceInteractorRequest)args.arg1).asBinder() + "/" + request);
+                    if (request != null) {
+                        request.onCancel();
+                        request.clear();
+                    }
+                    break;
+            }
+        }
+    };
+
+    final IVoiceInteractorCallback.Stub mCallback = new IVoiceInteractorCallback.Stub() {
+        @Override
+        public void deliverConfirmationResult(IVoiceInteractorRequest request, boolean confirmed,
+                Bundle result) {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(
+                    MSG_CONFIRMATION_RESULT, confirmed ? 1 : 0, request, result));
+        }
+
+        @Override
+        public void deliverCompleteVoiceResult(IVoiceInteractorRequest request, Bundle result) {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOO(
+                    MSG_COMPLETE_VOICE_RESULT, request, result));
+        }
+
+        @Override
+        public void deliverAbortVoiceResult(IVoiceInteractorRequest request, Bundle result) {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOO(
+                    MSG_ABORT_VOICE_RESULT, request, result));
+        }
+
+        @Override
+        public void deliverCommandResult(IVoiceInteractorRequest request, boolean complete,
+                Bundle result) {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(
+                    MSG_COMMAND_RESULT, complete ? 1 : 0, request, result));
+        }
+
+        @Override
+        public void deliverCancel(IVoiceInteractorRequest request) throws RemoteException {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(
+                    MSG_CANCEL_RESULT, request));
+        }
+    };
+
+    final ArrayMap<IBinder, Request> mActiveRequests = new ArrayMap<IBinder, Request>();
+
+    static final int MSG_CONFIRMATION_RESULT = 1;
+    static final int MSG_COMPLETE_VOICE_RESULT = 2;
+    static final int MSG_ABORT_VOICE_RESULT = 3;
+    static final int MSG_COMMAND_RESULT = 4;
+    static final int MSG_CANCEL_RESULT = 5;
+
+    public static abstract class Request {
+        IVoiceInteractorRequest mRequestInterface;
+        Context mContext;
+        Activity mActivity;
+
+        public Request() {
+        }
+
+        public void cancel() {
+            try {
+                mRequestInterface.cancel();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Voice interactor has died", e);
+            }
+        }
+
+        public Context getContext() {
+            return mContext;
+        }
+
+        public Activity getActivity() {
+            return mActivity;
+        }
+
+        public void onCancel() {
+        }
+
+        public void onAttached(Activity activity) {
+        }
+
+        public void onDetached() {
+        }
+
+        void clear() {
+            mRequestInterface = null;
+            mContext = null;
+            mActivity = null;
+        }
+
+        abstract IVoiceInteractorRequest submit(IVoiceInteractor interactor,
+                String packageName, IVoiceInteractorCallback callback) throws RemoteException;
+    }
+
+    public static class ConfirmationRequest extends Request {
+        final CharSequence mPrompt;
+        final Bundle mExtras;
+
+        /**
+         * Confirms an operation with the user via the trusted system
+         * VoiceInteractionService.  This allows an Activity to complete an unsafe operation that
+         * would require the user to touch the screen when voice interaction mode is not enabled.
+         * The result of the confirmation will be returned through an asynchronous call to
+         * either {@link #onConfirmationResult(boolean, android.os.Bundle)} or
+         * {@link #onCancel()}.
+         *
+         * <p>In some cases this may be a simple yes / no confirmation or the confirmation could
+         * include context information about how the action will be completed
+         * (e.g. booking a cab might include details about how long until the cab arrives)
+         * so the user can give a confirmation.
+         * @param prompt Optional confirmation text to read to the user as the action being
+         * confirmed.
+         * @param extras Additional optional information.
+         */
+        public ConfirmationRequest(CharSequence prompt, Bundle extras) {
+            mPrompt = prompt;
+            mExtras = extras;
+        }
+
+        public void onConfirmationResult(boolean confirmed, Bundle result) {
+        }
+
+        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
+                IVoiceInteractorCallback callback) throws RemoteException {
+            return interactor.startConfirmation(packageName, callback, mPrompt, mExtras);
+        }
+    }
+
+    public static class CompleteVoiceRequest extends Request {
+        final CharSequence mMessage;
+        final Bundle mExtras;
+
+        /**
+         * Reports that the current interaction was successfully completed with voice, so the
+         * application can report the final status to the user. When the response comes back, the
+         * voice system has handled the request and is ready to switch; at that point the
+         * application can start a new non-voice activity or finish.  Be sure when starting the new
+         * activity to use {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK
+         * Intent.FLAG_ACTIVITY_NEW_TASK} to keep the new activity out of the current voice
+         * interaction task.
+         *
+         * @param message Optional message to tell user about the completion status of the task.
+         * @param extras Additional optional information.
+         */
+        public CompleteVoiceRequest(CharSequence message, Bundle extras) {
+            mMessage = message;
+            mExtras = extras;
+        }
+
+        public void onCompleteResult(Bundle result) {
+        }
+
+        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
+                IVoiceInteractorCallback callback) throws RemoteException {
+            return interactor.startCompleteVoice(packageName, callback, mMessage, mExtras);
+        }
+    }
+
+    public static class AbortVoiceRequest extends Request {
+        final CharSequence mMessage;
+        final Bundle mExtras;
+
+        /**
+         * Reports that the current interaction can not be complete with voice, so the
+         * application will need to switch to a traditional input UI.  Applications should
+         * only use this when they need to completely bail out of the voice interaction
+         * and switch to a traditional UI.  When the response comes back, the voice
+         * system has handled the request and is ready to switch; at that point the application
+         * can start a new non-voice activity.  Be sure when starting the new activity
+         * to use {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK
+         * Intent.FLAG_ACTIVITY_NEW_TASK} to keep the new activity out of the current voice
+         * interaction task.
+         *
+         * @param message Optional message to tell user about not being able to complete
+         * the interaction with voice.
+         * @param extras Additional optional information.
+         */
+        public AbortVoiceRequest(CharSequence message, Bundle extras) {
+            mMessage = message;
+            mExtras = extras;
+        }
+
+        public void onAbortResult(Bundle result) {
+        }
+
+        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
+                IVoiceInteractorCallback callback) throws RemoteException {
+            return interactor.startAbortVoice(packageName, callback, mMessage, mExtras);
+        }
+    }
+
+    public static class CommandRequest extends Request {
+        final String mCommand;
+        final Bundle mArgs;
+
+        /**
+         * Execute a command using the trusted system VoiceInteractionService.
+         * This allows an Activity to request additional information from the user needed to
+         * complete an action (e.g. booking a table might have several possible times that the
+         * user could select from or an app might need the user to agree to a terms of service).
+         * The result of the confirmation will be returned through an asynchronous call to
+         * either {@link #onCommandResult(android.os.Bundle)} or
+         * {@link #onCancel()}.
+         *
+         * <p>The command is a string that describes the generic operation to be performed.
+         * The command will determine how the properties in extras are interpreted and the set of
+         * available commands is expected to grow over time.  An example might be
+         * "com.google.voice.commands.REQUEST_NUMBER_BAGS" to request the number of bags as part of
+         * airline check-in.  (This is not an actual working example.)
+         *
+         * @param command The desired command to perform.
+         * @param args Additional arguments to control execution of the command.
+         */
+        public CommandRequest(String command, Bundle args) {
+            mCommand = command;
+            mArgs = args;
+        }
+
+        public void onCommandResult(Bundle result) {
+        }
+
+        IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
+                IVoiceInteractorCallback callback) throws RemoteException {
+            return interactor.startCommand(packageName, callback, mCommand, mArgs);
+        }
+   }
+
+    VoiceInteractor(IVoiceInteractor interactor, Context context, Activity activity,
+            Looper looper) {
+        mInteractor = interactor;
+        mContext = context;
+        mActivity = activity;
+        mHandlerCaller = new HandlerCaller(context, looper, mHandlerCallerCallback, true);
+    }
+
+    Request pullRequest(IVoiceInteractorRequest request, boolean complete) {
+        synchronized (mActiveRequests) {
+            Request req = mActiveRequests.get(request.asBinder());
+            if (req != null && complete) {
+                mActiveRequests.remove(request.asBinder());
+            }
+            return req;
+        }
+    }
+
+    private ArrayList<Request> makeRequestList() {
+        final int N = mActiveRequests.size();
+        if (N < 1) {
+            return null;
+        }
+        ArrayList<Request> list = new ArrayList<Request>(N);
+        for (int i=0; i<N; i++) {
+            list.add(mActiveRequests.valueAt(i));
+        }
+        return list;
+    }
+
+    void attachActivity(Activity activity) {
+        if (mActivity == activity) {
+            return;
+        }
+        mContext = activity;
+        mActivity = activity;
+        ArrayList<Request> reqs = makeRequestList();
+        if (reqs != null) {
+            for (int i=0; i<reqs.size(); i++) {
+                Request req = reqs.get(i);
+                req.mContext = activity;
+                req.mActivity = activity;
+                req.onAttached(activity);
+            }
+        }
+    }
+
+    void detachActivity() {
+        ArrayList<Request> reqs = makeRequestList();
+        if (reqs != null) {
+            for (int i=0; i<reqs.size(); i++) {
+                Request req = reqs.get(i);
+                req.onDetached();
+                req.mActivity = null;
+                req.mContext = null;
+            }
+        }
+        mContext = null;
+        mActivity = null;
+    }
+
+    public boolean submitRequest(Request request) {
+        try {
+            IVoiceInteractorRequest ireq = request.submit(mInteractor,
+                    mContext.getOpPackageName(), mCallback);
+            request.mRequestInterface = ireq;
+            request.mContext = mContext;
+            request.mActivity = mActivity;
+            synchronized (mActiveRequests) {
+                mActiveRequests.put(ireq.asBinder(), request);
+            }
+            return true;
+        } catch (RemoteException e) {
+            Log.w(TAG, "Remove voice interactor service died", e);
+            return false;
+        }
+    }
+
+    /**
+     * Queries the supported commands available from the VoiceinteractionService.
+     * The command is a string that describes the generic operation to be performed.
+     * An example might be "com.google.voice.commands.REQUEST_NUMBER_BAGS" to request the number
+     * of bags as part of airline check-in.  (This is not an actual working example.)
+     *
+     * @param commands
+     */
+    public boolean[] supportsCommands(String[] commands) {
+        try {
+            boolean[] res = mInteractor.supportsCommands(mContext.getOpPackageName(), commands);
+            if (DEBUG) Log.d(TAG, "supportsCommands: cmds=" + commands + " res=" + res);
+            return res;
+        } catch (RemoteException e) {
+            throw new RuntimeException("Voice interactor has died", e);
+        }
+    }
+}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index f87001a..8bfe6d3 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import android.annotation.SystemApi;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -41,15 +43,17 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.WindowManagerGlobal;
 
 import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -67,6 +71,11 @@
     private float mWallpaperXStep = -1;
     private float mWallpaperYStep = -1;
 
+    /** {@hide} */
+    private static final String PROP_WALLPAPER = "ro.config.wallpaper";
+    /** {@hide} */
+    private static final String PROP_WALLPAPER_COMPONENT = "ro.config.wallpaper_component";
+
     /**
      * Activity Action: Show settings for choosing wallpaper. Do not use directly to construct
      * an intent; instead, use {@link #getCropAndSetWallpaperIntent}.
@@ -220,24 +229,9 @@
         
         private static final int MSG_CLEAR_WALLPAPER = 1;
         
-        private final Handler mHandler;
-        
         Globals(Looper looper) {
             IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
             mService = IWallpaperManager.Stub.asInterface(b);
-            mHandler = new Handler(looper) {
-                @Override
-                public void handleMessage(Message msg) {
-                    switch (msg.what) {
-                        case MSG_CLEAR_WALLPAPER:
-                            synchronized (this) {
-                                mWallpaper = null;
-                                mDefaultWallpaper = null;
-                            }
-                            break;
-                    }
-                }
-            };
         }
         
         public void onWallpaperChanged() {
@@ -246,7 +240,10 @@
              * to null so if the user requests the wallpaper again then we'll
              * fetch it.
              */
-            mHandler.sendEmptyMessage(MSG_CLEAR_WALLPAPER);
+            synchronized (this) {
+                mWallpaper = null;
+                mDefaultWallpaper = null;
+            }
         }
 
         public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault) {
@@ -279,7 +276,6 @@
             synchronized (this) {
                 mWallpaper = null;
                 mDefaultWallpaper = null;
-                mHandler.removeMessages(MSG_CLEAR_WALLPAPER);
             }
         }
 
@@ -314,8 +310,7 @@
         }
         
         private Bitmap getDefaultWallpaperLocked(Context context) {
-            InputStream is = context.getResources().openRawResource(
-                    com.android.internal.R.drawable.default_wallpaper);
+            InputStream is = openDefaultWallpaper(context);
             if (is != null) {
                 try {
                     BitmapFactory.Options options = new BitmapFactory.Options();
@@ -413,8 +408,7 @@
         horizontalAlignment = Math.max(0, Math.min(1, horizontalAlignment));
         verticalAlignment = Math.max(0, Math.min(1, verticalAlignment));
 
-        InputStream is = new BufferedInputStream(
-                resources.openRawResource(com.android.internal.R.drawable.default_wallpaper));
+        InputStream is = new BufferedInputStream(openDefaultWallpaper(mContext));
 
         if (is == null) {
             Log.e(TAG, "default wallpaper input stream is null");
@@ -439,8 +433,7 @@
                     }
                 }
 
-                is = new BufferedInputStream(resources.openRawResource(
-                        com.android.internal.R.drawable.default_wallpaper));
+                is = new BufferedInputStream(openDefaultWallpaper(mContext));
 
                 RectF cropRectF;
 
@@ -489,8 +482,7 @@
 
                 if (crop == null) {
                     // BitmapRegionDecoder has failed, try to crop in-memory
-                    is = new BufferedInputStream(resources.openRawResource(
-                            com.android.internal.R.drawable.default_wallpaper));
+                    is = new BufferedInputStream(openDefaultWallpaper(mContext));
                     Bitmap fullSize = null;
                     if (is != null) {
                         BitmapFactory.Options options = new BitmapFactory.Options();
@@ -960,6 +952,48 @@
     }
 
     /**
+     * Specify extra padding that the wallpaper should have outside of the display.
+     * That is, the given padding supplies additional pixels the wallpaper should extend
+     * outside of the display itself.
+     * @param padding The number of pixels the wallpaper should extend beyond the display,
+     * on its left, top, right, and bottom sides.
+     * @hide
+     */
+    @SystemApi
+    public void setDisplayPadding(Rect padding) {
+        try {
+            if (sGlobals.mService == null) {
+                Log.w(TAG, "WallpaperService not running");
+            } else {
+                sGlobals.mService.setDisplayPadding(padding);
+            }
+        } catch (RemoteException e) {
+            // Ignore
+        }
+    }
+
+    /**
+     * Apply a raw offset to the wallpaper window.  Should only be used in
+     * combination with {@link #setDisplayPadding(android.graphics.Rect)} when you
+     * have ensured that the wallpaper will extend outside of the display area so that
+     * it can be moved without leaving part of the display uncovered.
+     * @param x The offset, in pixels, to apply to the left edge.
+     * @param y The offset, in pixels, to apply to the top edge.
+     * @hide
+     */
+    @SystemApi
+    public void setDisplayOffset(IBinder windowToken, int x, int y) {
+        try {
+            //Log.v(TAG, "Sending new wallpaper display offsets from app...");
+            WindowManagerGlobal.getWindowSession().setWallpaperDisplayOffset(
+                    windowToken, x, y);
+            //Log.v(TAG, "...app returning after sending display offset!");
+        } catch (RemoteException e) {
+            // Ignore.
+        }
+    }
+
+    /**
      * Set the position of the current wallpaper within any larger space, when
      * that wallpaper is visible behind the given window.  The X and Y offsets
      * are floating point numbers ranging from 0 to 1, representing where the
@@ -1052,6 +1086,53 @@
      * wallpaper.
      */
     public void clear() throws IOException {
-        setResource(com.android.internal.R.drawable.default_wallpaper);
+        setStream(openDefaultWallpaper(mContext));
+    }
+
+    /**
+     * Open stream representing the default static image wallpaper.
+     *
+     * @hide
+     */
+    public static InputStream openDefaultWallpaper(Context context) {
+        final String path = SystemProperties.get(PROP_WALLPAPER);
+        if (!TextUtils.isEmpty(path)) {
+            final File file = new File(path);
+            if (file.exists()) {
+                try {
+                    return new FileInputStream(file);
+                } catch (IOException e) {
+                    // Ignored, fall back to platform default below
+                }
+            }
+        }
+        return context.getResources().openRawResource(
+                com.android.internal.R.drawable.default_wallpaper);
+    }
+
+    /**
+     * Return {@link ComponentName} of the default live wallpaper, or
+     * {@code null} if none is defined.
+     *
+     * @hide
+     */
+    public static ComponentName getDefaultWallpaperComponent(Context context) {
+        String flat = SystemProperties.get(PROP_WALLPAPER_COMPONENT);
+        if (!TextUtils.isEmpty(flat)) {
+            final ComponentName cn = ComponentName.unflattenFromString(flat);
+            if (cn != null) {
+                return cn;
+            }
+        }
+
+        flat = context.getString(com.android.internal.R.string.default_wallpaper_component);
+        if (!TextUtils.isEmpty(flat)) {
+            final ComponentName cn = ComponentName.unflattenFromString(flat);
+            if (cn != null) {
+                return cn;
+            }
+        }
+
+        return null;
     }
 }
diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java
index 66fc816..3074b49 100644
--- a/core/java/android/app/admin/DeviceAdminInfo.java
+++ b/core/java/android/app/admin/DeviceAdminInfo.java
@@ -52,6 +52,22 @@
     static final String TAG = "DeviceAdminInfo";
 
     /**
+     * A type of policy that this device admin can use: device owner meta-policy
+     * for an admin that is designated as owner of the device.
+     *
+     * @hide
+     */
+    public static final int USES_POLICY_DEVICE_OWNER = -2;
+
+    /**
+     * A type of policy that this device admin can use: profile owner meta-policy
+     * for admins that have been installed as owner of some user profile.
+     *
+     * @hide
+     */
+    public static final int USES_POLICY_PROFILE_OWNER = -1;
+
+    /**
      * A type of policy that this device admin can use: limit the passwords
      * that the user can select, via {@link DevicePolicyManager#setPasswordQuality}
      * and {@link DevicePolicyManager#setPasswordMinimumLength}.
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 30b65de..e9cce51 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -16,6 +16,7 @@
 
 package android.app.admin;
 
+import android.accounts.AccountManager;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.Service;
@@ -29,25 +30,25 @@
  * Base class for implementing a device administration component.  This
  * class provides a convenience for interpreting the raw intent actions
  * that are sent by the system.
- * 
+ *
  * <p>The callback methods, like the base
  * {@link BroadcastReceiver#onReceive(Context, Intent) BroadcastReceiver.onReceive()}
  * method, happen on the main thread of the process.  Thus long running
  * operations must be done on another thread.  Note that because a receiver
  * is done once returning from its receive function, such long-running operations
  * should probably be done in a {@link Service}.
- * 
+ *
  * <p>When publishing your DeviceAdmin subclass as a receiver, it must
  * handle {@link #ACTION_DEVICE_ADMIN_ENABLED} and require the
  * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission.  A typical
  * manifest entry would look like:</p>
- * 
+ *
  * {@sample development/samples/ApiDemos/AndroidManifest.xml device_admin_declaration}
- *   
+ *
  * <p>The meta-data referenced here provides addition information specific
  * to the device administrator, as parsed by the {@link DeviceAdminInfo} class.
  * A typical file would be:</p>
- * 
+ *
  * {@sample development/samples/ApiDemos/res/xml/device_admin_sample.xml meta_data}
  *
  * <div class="special reference">
@@ -86,7 +87,7 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
             = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
-    
+
     /**
      * A CharSequence that can be shown to the user informing them of the
      * impact of disabling your admin.
@@ -94,7 +95,7 @@
      * @see #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
      */
     public static final String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
-    
+
     /**
      * Action sent to a device administrator when the user has disabled
      * it.  Upon return, the application no longer has access to the
@@ -107,7 +108,7 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_DEVICE_ADMIN_DISABLED
             = "android.app.action.DEVICE_ADMIN_DISABLED";
-    
+
     /**
      * Action sent to a device administrator when the user has changed the
      * password of their device.  You can at this point check the characteristics
@@ -115,7 +116,7 @@
      * DevicePolicyManager.isActivePasswordSufficient()}.
      * You will generally
      * handle this in {@link DeviceAdminReceiver#onPasswordChanged}.
-     * 
+     *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to receive
      * this broadcast.
@@ -123,7 +124,7 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PASSWORD_CHANGED
             = "android.app.action.ACTION_PASSWORD_CHANGED";
-    
+
     /**
      * Action sent to a device administrator when the user has failed at
      * attempted to enter the password.  You can at this point check the
@@ -131,7 +132,7 @@
      * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts
      * DevicePolicyManager.getCurrentFailedPasswordAttempts()}.  You will generally
      * handle this in {@link DeviceAdminReceiver#onPasswordFailed}.
-     * 
+     *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
      * this broadcast.
@@ -139,11 +140,11 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PASSWORD_FAILED
             = "android.app.action.ACTION_PASSWORD_FAILED";
-    
+
     /**
      * Action sent to a device administrator when the user has successfully
      * entered their password, after failing one or more times.
-     * 
+     *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
      * this broadcast.
@@ -165,15 +166,73 @@
             = "android.app.action.ACTION_PASSWORD_EXPIRING";
 
     /**
+     * Action sent to a device administrator to notify that the device is entering
+     * lock task mode from an authorized package.  The extra {@link #EXTRA_LOCK_TASK_PACKAGE}
+     * will describe the authorized package using lock task mode.
+     *
+     * @see DevicePolicyManager#isLockTaskPermitted(String)
+     *
+     * <p>The calling device admin must be the device owner or profile
+     * owner to receive this broadcast.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_LOCK_TASK_ENTERING
+            = "android.app.action.LOCK_TASK_ENTERING";
+
+    /**
+     * Action sent to a device administrator to notify that the device is exiting
+     * lock task mode from an authorized package.
+     *
+     * @see DevicePolicyManager#isLockTaskPermitted(String)
+     *
+     * <p>The calling device admin must be the device owner or profile
+     * owner to receive this broadcast.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_LOCK_TASK_EXITING
+            = "android.app.action.LOCK_TASK_EXITING";
+
+    /**
+     * A boolean describing whether the device is currently entering or exiting
+     * lock task mode.
+     *
+     * @see #ACTION_LOCK_TASK_CHANGED
+     */
+    public static final String EXTRA_LOCK_TASK_PACKAGE =
+            "android.app.extra.LOCK_TASK_PACKAGE";
+
+    /**
+     * Broadcast Action: This broadcast is sent to indicate that provisioning of a managed profile
+     * or managed device has completed successfully.
+     *
+     * <p>The broadcast is limited to the profile that will be managed by the application that
+     * requested provisioning. In the device owner case the profile is the primary user.
+     * The broadcast will also be limited to the {@link DeviceAdminReceiver} component
+     * specified in the original intent or NFC bump that started the provisioning process
+     * (@see DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE).
+     *
+     * <p>A device admin application which listens to this intent can find out if the device was
+     * provisioned for the device owner or profile owner case by calling respectively
+     * {@link android.app.admin.DevicePolicyManager#isDeviceOwnerApp} and
+     * {@link android.app.admin.DevicePolicyManager#isProfileOwnerApp}.
+     *
+     * <p>Input: Nothing.</p>
+     * <p>Output: Nothing</p>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PROFILE_PROVISIONING_COMPLETE =
+            "android.app.action.PROFILE_PROVISIONING_COMPLETE";
+
+    /**
      * Name under which a DevicePolicy component publishes information
      * about itself.  This meta-data must reference an XML resource containing
      * a device-admin tag.  XXX TO DO: describe syntax.
      */
     public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
-    
+
     private DevicePolicyManager mManager;
     private ComponentName mWho;
-    
+
     /**
      * Retrieve the DevicePolicyManager interface for this administrator to work
      * with the system.
@@ -186,7 +245,7 @@
                 Context.DEVICE_POLICY_SERVICE);
         return mManager;
     }
-    
+
     /**
      * Retrieve the ComponentName describing who this device administrator is, for
      * use in {@link DevicePolicyManager} APIs that require the administrator to
@@ -199,17 +258,23 @@
         mWho = new ComponentName(context, getClass());
         return mWho;
     }
-    
+
     /**
      * Called after the administrator is first enabled, as a result of
      * receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}.  At this point you
      * can use {@link DevicePolicyManager} to set your desired policies.
+     *
+     * <p> If the admin is activated by a device owner, then the intent
+     * may contain private extras that are relevant to user setup.
+     * {@see DevicePolicyManager#createAndInitializeUser(ComponentName, String, String,
+     *      ComponentName, Intent)}
+     *
      * @param context The running context as per {@link #onReceive}.
      * @param intent The received intent as per {@link #onReceive}.
      */
     public void onEnabled(Context context, Intent intent) {
     }
-    
+
     /**
      * Called when the user has asked to disable the administrator, as a result of
      * receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you
@@ -224,7 +289,7 @@
     public CharSequence onDisableRequested(Context context, Intent intent) {
         return null;
     }
-    
+
     /**
      * Called prior to the administrator being disabled, as a result of
      * receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}.  Upon return, you
@@ -235,7 +300,7 @@
      */
     public void onDisabled(Context context, Intent intent) {
     }
-    
+
     /**
      * Called after the user has changed their password, as a result of
      * receiving {@link #ACTION_PASSWORD_CHANGED}.  At this point you
@@ -247,7 +312,7 @@
      */
     public void onPasswordChanged(Context context, Intent intent) {
     }
-    
+
     /**
      * Called after the user has failed at entering their current password, as a result of
      * receiving {@link #ACTION_PASSWORD_FAILED}.  At this point you
@@ -258,7 +323,7 @@
      */
     public void onPasswordFailed(Context context, Intent intent) {
     }
-    
+
     /**
      * Called after the user has succeeded at entering their current password,
      * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}.  This will
@@ -292,6 +357,52 @@
     }
 
     /**
+     * Called when provisioning of a managed profile or managed device has completed successfully.
+     *
+     * <p> As a prerequisit for the execution of this callback the (@link DeviceAdminReceiver} has
+     * to declare an intent filter for {@link #ACTION_PROFILE_PROVISIONING_COMPLETE}.
+     * Its component must also be specified in the {@link DevicePolicyManager#EXTRA_DEVICE_ADMIN}
+     * of the {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE} intent that started the
+     * managed provisioning.
+     *
+     * <p>When provisioning is complete, the managed profile is hidden until the profile owner
+     * calls {DevicePolicyManager#setProfileEnabled(ComponentName admin)}. Typically a profile
+     * owner will enable the profile when it has finished any additional setup such as adding an
+     * account by using the {@link AccountManager} and calling apis to bring the profile into the
+     * desired state.
+     *
+     * <p> Note that provisioning completes without waiting for any server interactions, so the
+     * profile owner needs to wait for data to be available if required (e.g android device ids or
+     * other data that is set as a result of server interactions).
+     *
+     * @param context The running context as per {@link #onReceive}.
+     * @param intent The received intent as per {@link #onReceive}.
+     */
+    public void onProfileProvisioningComplete(Context context, Intent intent) {
+    }
+
+    /**
+     * Called when a device is entering lock task mode by a package authorized
+     * by {@link DevicePolicyManager#isLockTaskPermitted(String)}
+     *
+     * @param context The running context as per {@link #onReceive}.
+     * @param intent The received intent as per {@link #onReceive}.
+     * @param pkg If entering, the authorized package using lock task mode, otherwise null.
+     */
+    public void onLockTaskModeEntering(Context context, Intent intent, String pkg) {
+    }
+
+    /**
+     * Called when a device is exiting lock task mode by a package authorized
+     * by {@link DevicePolicyManager#isLockTaskPermitted(String)}
+     *
+     * @param context The running context as per {@link #onReceive}.
+     * @param intent The received intent as per {@link #onReceive}.
+     */
+    public void onLockTaskModeExiting(Context context, Intent intent) {
+    }
+
+    /**
      * Intercept standard device administrator broadcasts.  Implementations
      * should not override this method; it is better to implement the
      * convenience callbacks for each action.
@@ -299,6 +410,7 @@
     @Override
     public void onReceive(Context context, Intent intent) {
         String action = intent.getAction();
+
         if (ACTION_PASSWORD_CHANGED.equals(action)) {
             onPasswordChanged(context, intent);
         } else if (ACTION_PASSWORD_FAILED.equals(action)) {
@@ -317,6 +429,13 @@
             onDisabled(context, intent);
         } else if (ACTION_PASSWORD_EXPIRING.equals(action)) {
             onPasswordExpiring(context, intent);
+        } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) {
+            onProfileProvisioningComplete(context, intent);
+        } else if (ACTION_LOCK_TASK_ENTERING.equals(action)) {
+            String pkg = intent.getStringExtra(EXTRA_LOCK_TASK_PACKAGE);
+            onLockTaskModeEntering(context, intent, pkg);
+        } else if (ACTION_LOCK_TASK_EXITING.equals(action)) {
+            onLockTaskModeExiting(context, intent);
         }
     }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 49ed27b..2eba29a 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -16,33 +16,48 @@
 
 package android.app.admin;
 
-import org.xmlpull.v1.XmlPullParserException;
-
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
+import android.app.Activity;
+import android.app.admin.IDevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.net.ProxyInfo;
+import android.os.Bundle;
 import android.os.Handler;
+import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.security.Credentials;
+import android.service.restrictions.RestrictionsReceiver;
 import android.util.Log;
 
 import com.android.org.conscrypt.TrustedCertificateStore;
 
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
-import java.util.Set;
 
 /**
  * Public interface for managing policies enforced on a device.  Most clients
@@ -75,6 +90,263 @@
     }
 
     /**
+     * Activity action: Starts the provisioning flow which sets up a managed profile.
+     *
+     * <p>A managed profile allows data separation for example for the usage of a
+     * device as a personal and corporate device. The user which provisioning is started from and
+     * the managed profile share a launcher.
+     *
+     * <p>This intent will typically be sent by a mobile device management application (mdm).
+     * Provisioning adds a managed profile and sets the mdm as the profile owner who has full
+     * control over the profile
+     *
+     * <p>This intent must contain the extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}.
+     *
+     * <p> When managed provisioning has completed, an intent of the type
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcasted to the
+     * managed profile.
+     *
+     * <p> If provisioning fails, the managedProfile is removed so the device returns to its
+     * previous state.
+     *
+     * <p>Input: Nothing.</p>
+     * <p>Output: Nothing</p>
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_PROVISION_MANAGED_PROFILE
+        = "android.app.action.PROVISION_MANAGED_PROFILE";
+
+    /**
+     * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that allows
+     * a mobile device management application that starts managed profile provisioning to pass data
+     * to itself on the managed profile when provisioning completes. The mobile device management
+     * application sends this extra in an intent with the action
+     * {@link #ACTION_PROVISION_MANAGED_PROFILE} and receives it in
+     * {@link DeviceAdminReceiver#onProfileProvisioningComplete} via an intent with the action
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}. The bundle is not changed
+     * during the managed profile provisioning.
+     */
+    public static final String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE =
+            "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
+
+    /**
+     * A String extra holding the package name of the mobile device management application that
+     * will be set as the profile owner or device owner.
+     *
+     * <p>If an application starts provisioning directly via an intent with action
+     * {@link #ACTION_PROVISION_MANAGED_PROFILE} this package has to match the package name of the
+     * application that started provisioning. The package will be set as profile owner in that case.
+     *
+     * <p>This package is set as device owner when device owner provisioning is started by an Nfc
+     * message containing an Nfc record with MIME type {@link #MIME_TYPE_PROVISIONING_NFC}.
+     */
+    public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
+        = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
+
+    /**
+     * A String extra that, holds the email address of the account which a managed profile is
+     * created for. Used with {@link #ACTION_PROVISION_MANAGED_PROFILE} and
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}.
+     *
+     * <p> This extra is part of the {@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}.
+     *
+     * <p> If the {@link #ACTION_PROVISION_MANAGED_PROFILE} intent that starts managed provisioning
+     * contains this extra, it is forwarded in the
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} intent to the mobile
+     * device management application that was set as the profile owner during provisioning.
+     * It is usually used to avoid that the user has to enter their email address twice.
+     */
+    public static final String EXTRA_PROVISIONING_EMAIL_ADDRESS
+        = "android.app.extra.PROVISIONING_EMAIL_ADDRESS";
+
+    /**
+     * A String extra holding the time zone {@link android.app.AlarmManager} that the device
+     * will be set to.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_TIME_ZONE
+        = "android.app.extra.PROVISIONING_TIME_ZONE";
+
+    /**
+     * A Long extra holding the wall clock time (in milliseconds) to be set on the device's
+     * {@link android.app.AlarmManager}.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_LOCAL_TIME
+        = "android.app.extra.PROVISIONING_LOCAL_TIME";
+
+    /**
+     * A String extra holding the {@link java.util.Locale} that the device will be set to.
+     * Format: xx_yy, where xx is the language code, and yy the country code.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_LOCALE
+        = "android.app.extra.PROVISIONING_LOCALE";
+
+    /**
+     * A String extra holding the ssid of the wifi network that should be used during nfc device
+     * owner provisioning for downloading the mobile device management application.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_SSID
+        = "android.app.extra.PROVISIONING_WIFI_SSID";
+
+    /**
+     * A boolean extra indicating whether the wifi network in {@link #EXTRA_PROVISIONING_WIFI_SSID}
+     * is hidden or not.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_HIDDEN
+        = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
+
+    /**
+     * A String extra indicating the security type of the wifi network in
+     * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE
+        = "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE";
+
+    /**
+     * A String extra holding the password of the wifi network in
+     * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_PASSWORD
+        = "android.app.extra.PROVISIONING_WIFI_PASSWORD";
+
+    /**
+     * A String extra holding the proxy host for the wifi network in
+     * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_PROXY_HOST
+        = "android.app.extra.PROVISIONING_WIFI_PROXY_HOST";
+
+    /**
+     * An int extra holding the proxy port for the wifi network in
+     * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_PROXY_PORT
+        = "android.app.extra.PROVISIONING_WIFI_PROXY_PORT";
+
+    /**
+     * A String extra holding the proxy bypass for the wifi network in
+     * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_PROXY_BYPASS
+        = "android.app.extra.PROVISIONING_WIFI_PROXY_BYPASS";
+
+    /**
+     * A String extra holding the proxy auto-config (PAC) URL for the wifi network in
+     * {@link #EXTRA_PROVISIONING_WIFI_SSID}.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_PAC_URL
+        = "android.app.extra.PROVISIONING_WIFI_PAC_URL";
+
+    /**
+     * A String extra holding a url that specifies the download location of the device admin
+     * package. When not provided it is assumed that the device admin package is already installed.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION
+        = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
+
+    /**
+     * A String extra holding a http cookie header which should be used in the http request to the
+     * url specified in {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER
+        = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
+
+    /**
+     * A String extra holding the SHA-1 checksum of the file at download location specified in
+     * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}. If this doesn't match
+     * the file at the download location an error will be shown to the user and the user will be
+     * asked to factory reset the device.
+     *
+     * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an Nfc bump.
+     */
+    public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
+        = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
+
+    /**
+     * This MIME type is used for starting the Device Owner provisioning.
+     *
+     * <p>During device owner provisioning a device admin app is set as the owner of the device.
+     * A device owner has full control over the device. The device owner can not be modified by the
+     * user and the only way of resetting the device is if the device owner app calls a factory
+     * reset.
+     *
+     * <p> A typical use case would be a device that is owned by a company, but used by either an
+     * employee or client.
+     *
+     * <p> The Nfc message should be send to an unprovisioned device.
+     *
+     * <p>The Nfc record must contain a serialized {@link java.util.Properties} object which
+     * contains the following properties:
+     * <ul>
+     * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}</li>
+     * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}</li>
+     * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM}</li>
+     * <li>{@link #EXTRA_PROVISIONING_LOCAL_TIME} (convert to String), optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_TIME_ZONE}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_LOCALE}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_SSID}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_HIDDEN} (convert to String), optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_PASSWORD}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_HOST}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT} (convert to String), optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li></ul>
+     *
+     * <p> When device owner provisioning has completed, an intent of the type
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcasted to the
+     * device owner.
+     *
+     * <p>
+     * If provisioning fails, the device is factory reset.
+     *
+     * <p>Input: Nothing.</p>
+     * <p>Output: Nothing</p>
+     */
+    public static final String MIME_TYPE_PROVISIONING_NFC
+        = "application/com.android.managedprovisioning";
+
+    /**
      * Activity action: ask the user to add a new device administrator to the system.
      * The desired policy is the ComponentName of the policy in the
      * {@link #EXTRA_DEVICE_ADMIN} extra field.  This will invoke a UI to
@@ -95,6 +367,40 @@
             = "android.app.action.ADD_DEVICE_ADMIN";
 
     /**
+     * @hide
+     * Activity action: ask the user to add a new device administrator as the profile owner
+     * for this user. Only system privileged apps that have MANAGE_USERS and MANAGE_DEVICE_ADMINS
+     * permission can call this API.
+     *
+     * <p>The ComponentName of the profile owner admin is pass in {@link #EXTRA_DEVICE_ADMIN} extra
+     * field. This will invoke a UI to bring the user through adding the profile owner admin
+     * to remotely control restrictions on the user.
+     *
+     * <p>The intent must be invoked via {@link Activity#startActivityForResult()} to receive the
+     * result of whether or not the user approved the action. If approved, the result will
+     * be {@link Activity#RESULT_OK} and the component will be set as an active admin as well
+     * as a profile owner.
+     *
+     * <p>You can optionally include the {@link #EXTRA_ADD_EXPLANATION}
+     * field to provide the user with additional explanation (in addition
+     * to your component's description) about what is being added.
+     *
+     * <p>If there is already a profile owner active or the caller doesn't have the required
+     * permissions, the operation will return a failure result.
+     */
+    @SystemApi
+    public static final String ACTION_SET_PROFILE_OWNER
+            = "android.app.action.SET_PROFILE_OWNER";
+
+    /**
+     * @hide
+     * Name of the profile owner admin that controls the user.
+     */
+    @SystemApi
+    public static final String EXTRA_PROFILE_OWNER_NAME
+            = "android.app.extra.PROFILE_OWNER_NAME";
+
+    /**
      * Activity action: send when any policy admin changes a policy.
      * This is generally used to find out when a new policy is in effect.
      *
@@ -133,13 +439,33 @@
             = "android.app.action.SET_NEW_PASSWORD";
 
     /**
+     * Flag used by {@link #addCrossProfileIntentFilter} to allow access of certain intents from a
+     * managed profile to its parent.
+     */
+    public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 0x0001;
+
+    /**
+     * Flag used by {@link #addCrossProfileIntentFilter} to allow access of certain intents from the
+     * parent to its managed profile.
+     */
+    public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 0x0002;
+
+    /**
      * Return true if the given administrator component is currently
      * active (enabled) in the system.
      */
     public boolean isAdminActive(ComponentName who) {
+        return isAdminActiveAsUser(who, UserHandle.myUserId());
+    }
+
+    /**
+     * @see #isAdminActive(ComponentName)
+     * @hide
+     */
+    public boolean isAdminActiveAsUser(ComponentName who, int userId) {
         if (mService != null) {
             try {
-                return mService.isAdminActive(who, UserHandle.myUserId());
+                return mService.isAdminActive(who, userId);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -153,9 +479,17 @@
      * returned.
      */
     public List<ComponentName> getActiveAdmins() {
+        return getActiveAdminsAsUser(UserHandle.myUserId());
+    }
+
+    /**
+     * @see #getActiveAdmins()
+     * @hide
+     */
+    public List<ComponentName> getActiveAdminsAsUser(int userId) {
         if (mService != null) {
             try {
-                return mService.getActiveAdmins(UserHandle.myUserId());
+                return mService.getActiveAdmins(userId);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -246,6 +580,14 @@
 
     /**
      * Constant for {@link #setPasswordQuality}: the user must have entered a
+     * password containing at least numeric characters with no repeating (4444)
+     * or ordered (1234, 4321, 2468) sequences.  Note that quality
+     * constants are ordered so that higher values are more restrictive.
+     */
+    public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 0x30000;
+
+    /**
+     * Constant for {@link #setPasswordQuality}: the user must have entered a
      * password containing at least alphabetic (or other symbol) characters.
      * Note that quality constants are ordered so that higher values are more
      * restrictive.
@@ -293,8 +635,9 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param quality The new desired quality.  One of
      * {@link #PASSWORD_QUALITY_UNSPECIFIED}, {@link #PASSWORD_QUALITY_SOMETHING},
-     * {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_ALPHABETIC},
-     * {@link #PASSWORD_QUALITY_ALPHANUMERIC} or {@link #PASSWORD_QUALITY_COMPLEX}.
+     * {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX},
+     * {@link #PASSWORD_QUALITY_ALPHABETIC}, {@link #PASSWORD_QUALITY_ALPHANUMERIC}
+     * or {@link #PASSWORD_QUALITY_COMPLEX}.
      */
     public void setPasswordQuality(ComponentName admin, int quality) {
         if (mService != null) {
@@ -307,8 +650,8 @@
     }
 
     /**
-     * Retrieve the current minimum password quality for all admins
-     * or a particular one.
+     * Retrieve the current minimum password quality for all admins of this user
+     * and its profiles or a particular one.
      * @param admin The name of the admin component to check, or null to aggregate
      * all admins.
      */
@@ -337,9 +680,9 @@
      * take place immediately.  To prompt the user for a new password, use
      * {@link #ACTION_SET_NEW_PASSWORD} after setting this value.  This
      * constraint is only imposed if the administrator has also requested either
-     * {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_ALPHABETIC}
-     * {@link #PASSWORD_QUALITY_ALPHANUMERIC}, or {@link #PASSWORD_QUALITY_COMPLEX}
-     * with {@link #setPasswordQuality}.
+     * {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX},
+     * {@link #PASSWORD_QUALITY_ALPHABETIC}, {@link #PASSWORD_QUALITY_ALPHANUMERIC},
+     * or {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}.
      *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
@@ -360,8 +703,8 @@
     }
 
     /**
-     * Retrieve the current minimum password length for all admins
-     * or a particular one.
+     * Retrieve the current minimum password length for all admins of this
+     * user and its profiles or a particular one.
      * @param admin The name of the admin component to check, or null to aggregate
      * all admins.
      */
@@ -415,8 +758,9 @@
 
     /**
      * Retrieve the current number of upper case letters required in the
-     * password for all admins or a particular one. This is the same value as
-     * set by {#link {@link #setPasswordMinimumUpperCase(ComponentName, int)}
+     * password for all admins of this user and its profiles or a particular one.
+     * This is the same value as set by
+     * {#link {@link #setPasswordMinimumUpperCase(ComponentName, int)}
      * and only applies when the password quality is
      * {@link #PASSWORD_QUALITY_COMPLEX}.
      *
@@ -475,8 +819,9 @@
 
     /**
      * Retrieve the current number of lower case letters required in the
-     * password for all admins or a particular one. This is the same value as
-     * set by {#link {@link #setPasswordMinimumLowerCase(ComponentName, int)}
+     * password for all admins of this user and its profiles or a particular one.
+     * This is the same value as set by
+     * {#link {@link #setPasswordMinimumLowerCase(ComponentName, int)}
      * and only applies when the password quality is
      * {@link #PASSWORD_QUALITY_COMPLEX}.
      *
@@ -592,8 +937,9 @@
 
     /**
      * Retrieve the current number of numerical digits required in the password
-     * for all admins or a particular one. This is the same value as
-     * set by {#link {@link #setPasswordMinimumNumeric(ComponentName, int)}
+     * for all admins of this user and its profiles or a particular one.
+     * This is the same value as set by
+     * {#link {@link #setPasswordMinimumNumeric(ComponentName, int)}
      * and only applies when the password quality is
      * {@link #PASSWORD_QUALITY_COMPLEX}.
      *
@@ -708,8 +1054,9 @@
 
     /**
      * Retrieve the current number of non-letter characters required in the
-     * password for all admins or a particular one. This is the same value as
-     * set by {#link {@link #setPasswordMinimumNonLetter(ComponentName, int)}
+     * password for all admins of this user and its profiles or a particular one.
+     * This is the same value as set by
+     * {#link {@link #setPasswordMinimumNonLetter(ComponentName, int)}
      * and only applies when the password quality is
      * {@link #PASSWORD_QUALITY_COMPLEX}.
      *
@@ -741,9 +1088,9 @@
    * the change does not take place immediately. To prompt the user for a new
    * password, use {@link #ACTION_SET_NEW_PASSWORD} after setting this value.
    * This constraint is only imposed if the administrator has also requested
-   * either {@link #PASSWORD_QUALITY_NUMERIC},
-   * {@link #PASSWORD_QUALITY_ALPHABETIC}, or
-   * {@link #PASSWORD_QUALITY_ALPHANUMERIC} with {@link #setPasswordQuality}.
+   * either {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_NUMERIC_COMPLEX}
+   * {@link #PASSWORD_QUALITY_ALPHABETIC}, or {@link #PASSWORD_QUALITY_ALPHANUMERIC}
+   * with {@link #setPasswordQuality}.
    *
    * <p>
    * The calling device admin must have requested
@@ -780,6 +1127,9 @@
      * {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to be able to call this
      * method; if it has not, a security exception will be thrown.
      *
+     * <p> Note that setting the password will automatically reset the expiration time for all
+     * active admins. Active admins do not need to explicitly call this method in that case.
+     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param timeout The limit (in ms) that a password can remain in effect. A value of 0
      *        means there is no restriction (unlimited).
@@ -816,9 +1166,10 @@
 
     /**
      * Get the current password expiration time for the given admin or an aggregate of
-     * all admins if admin is null. If the password is expired, this will return the time since
-     * the password expired as a negative number.  If admin is null, then a composite of all
-     * expiration timeouts is returned - which will be the minimum of all timeouts.
+     * all admins of this user and its profiles if admin is null. If the password is
+     * expired, this will return the time since the password expired as a negative number.
+     * If admin is null, then a composite of all expiration timeouts is returned
+     * - which will be the minimum of all timeouts.
      *
      * @param admin The name of the admin component to check, or null to aggregate all admins.
      * @return The password expiration time, in ms.
@@ -835,8 +1186,8 @@
     }
 
     /**
-     * Retrieve the current password history length for all admins
-     * or a particular one.
+     * Retrieve the current password history length for all admins of this
+     * user and its profiles or a particular one.
      * @param admin The name of the admin component to check, or null to aggregate
      * all admins.
      * @return The length of the password history
@@ -871,14 +1222,13 @@
     /**
      * Determine whether the current password the user has set is sufficient
      * to meet the policy requirements (quality, minimum length) that have been
-     * requested.
+     * requested by the admins of this user and its profiles.
      *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
      * this method; if it has not, a security exception will be thrown.
      *
-     * @return Returns true if the password meets the current requirements,
-     * else false.
+     * @return Returns true if the password meets the current requirements, else false.
      */
     public boolean isActivePasswordSufficient() {
         if (mService != null) {
@@ -941,7 +1291,7 @@
 
     /**
      * Retrieve the current maximum number of login attempts that are allowed
-     * before the device wipes itself, for all admins
+     * before the device wipes itself, for all admins of this user and its profiles
      * or a particular one.
      * @param admin The name of the admin component to check, or null to aggregate
      * all admins.
@@ -985,6 +1335,8 @@
      * {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} to be able to call
      * this method; if it has not, a security exception will be thrown.
      *
+     * Can not be called from a managed profile.
+     *
      * @param password The new password for the user.
      * @param flags May be 0 or {@link #RESET_PASSWORD_REQUIRE_ENTRY}.
      * @return Returns true if the password was applied, or false if it is
@@ -1025,10 +1377,12 @@
     }
 
     /**
-     * Retrieve the current maximum time to unlock for all admins
-     * or a particular one.
+     * Retrieve the current maximum time to unlock for all admins of this user
+     * and its profiles or a particular one.
      * @param admin The name of the admin component to check, or null to aggregate
      * all admins.
+     * @return time in milliseconds for the given admin or the minimum value (strictest) of
+     * all admins if admin is null. Returns 0 if there are no restrictions.
      */
     public long getMaximumTimeToLock(ComponentName admin) {
         return getMaximumTimeToLock(admin, UserHandle.myUserId());
@@ -1153,7 +1507,9 @@
                         }
                         exclSpec = listBuilder.toString();
                     }
-                    android.net.Proxy.validate(hostName, Integer.toString(port), exclSpec);
+                    if (android.net.Proxy.validate(hostName, Integer.toString(port), exclSpec)
+                            != android.net.Proxy.PROXY_VALID)
+                        throw new IllegalArgumentException();
                 }
                 return mService.setGlobalProxy(admin, hostSpec, exclSpec, UserHandle.myUserId());
             } catch (RemoteException e) {
@@ -1164,6 +1520,32 @@
     }
 
     /**
+     * Set a network-independent global HTTP proxy.  This is not normally what you want
+     * for typical HTTP proxies - they are generally network dependent.  However if you're
+     * doing something unusual like general internal filtering this may be useful.  On
+     * a private network where the proxy is not accessible, you may break HTTP using this.
+     *
+     * <p>This method requires the caller to be the device owner.
+     *
+     * <p>This proxy is only a recommendation and it is possible that some apps will ignore it.
+     * @see ProxyInfo
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated
+     *            with.
+     * @param proxyInfo The a {@link ProxyInfo} object defining the new global
+     *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
+     */
+    public void setRecommendedGlobalProxy(ComponentName admin, ProxyInfo proxyInfo) {
+        if (mService != null) {
+            try {
+                mService.setRecommendedGlobalProxy(admin, proxyInfo);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
      * Returns the component name setting the global proxy.
      * @return ComponentName object of the device admin that set the global proxy, or
      *            null if no admin has set the proxy.
@@ -1225,7 +1607,7 @@
     public static final int KEYGUARD_DISABLE_FEATURES_NONE = 0;
 
     /**
-     * Disable all keyguard widgets
+     * Disable all keyguard widgets. Has no effect.
      */
     public static final int KEYGUARD_DISABLE_WIDGETS_ALL = 1 << 0;
 
@@ -1235,6 +1617,27 @@
     public static final int KEYGUARD_DISABLE_SECURE_CAMERA = 1 << 1;
 
     /**
+     * Disable showing all notifications on secure keyguard screens (e.g. PIN/Pattern/Password)
+     */
+    public static final int KEYGUARD_DISABLE_SECURE_NOTIFICATIONS = 1 << 2;
+
+    /**
+     * Only allow redacted notifications on secure keyguard screens (e.g. PIN/Pattern/Password)
+     */
+    public static final int KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS = 1 << 3;
+
+    /**
+     * Ignore trust agent state on secure keyguard screens
+     * (e.g. PIN/Pattern/Password).
+     */
+    public static final int KEYGUARD_DISABLE_TRUST_AGENTS = 1 << 4;
+
+    /**
+     * Disable fingerprint sensor on keyguard secure screens (e.g. PIN/Pattern/Password).
+     */
+    public static final int KEYGUARD_DISABLE_FINGERPRINT = 1 << 5;
+
+    /**
      * Disable all current and future keyguard customizations.
      */
     public static final int KEYGUARD_DISABLE_FEATURES_ALL = 0x7fffffff;
@@ -1314,7 +1717,7 @@
      * storage.  If the result is {@link #ENCRYPTION_STATUS_ACTIVATING} or
      * {@link #ENCRYPTION_STATUS_ACTIVE}, no further action is required.
      *
-     * @return current status of encryption.  The value will be one of
+     * @return current status of encryption. The value will be one of
      * {@link #ENCRYPTION_STATUS_UNSUPPORTED}, {@link #ENCRYPTION_STATUS_INACTIVE},
      * {@link #ENCRYPTION_STATUS_ACTIVATING}, or{@link #ENCRYPTION_STATUS_ACTIVE}.
      */
@@ -1335,16 +1738,18 @@
     }
 
     /**
-     * Installs the given certificate as a User CA.
+     * Installs the given certificate as a user CA.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param certBuffer encoded form of the certificate to install.
      *
      * @return false if the certBuffer cannot be parsed or installation is
-     *         interrupted, otherwise true
-     * @hide
+     *         interrupted, true otherwise.
      */
-    public boolean installCaCert(byte[] certBuffer) {
+    public boolean installCaCert(ComponentName admin, byte[] certBuffer) {
         if (mService != null) {
             try {
-                return mService.installCaCert(certBuffer);
+                return mService.installCaCert(admin, certBuffer);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1353,14 +1758,18 @@
     }
 
     /**
-     * Uninstalls the given certificate from the list of User CAs, if present.
+     * Uninstalls the given certificate from trusted user CAs, if present.
      *
-     * @hide
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param certBuffer encoded form of the certificate to remove.
      */
-    public void uninstallCaCert(byte[] certBuffer) {
+    public void uninstallCaCert(ComponentName admin, byte[] certBuffer) {
         if (mService != null) {
             try {
-                mService.uninstallCaCert(certBuffer);
+                final String alias = getCaCertAlias(certBuffer);
+                mService.uninstallCaCert(admin, alias);
+            } catch (CertificateException e) {
+                Log.w(TAG, "Unable to parse certificate", e);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1368,37 +1777,109 @@
     }
 
     /**
-     * Returns whether there are any user-installed CA certificates.
+     * Returns all CA certificates that are currently trusted, excluding system CA certificates.
+     * If a user has installed any certificates by other means than device policy these will be
+     * included too.
      *
-     * @hide
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @return a List of byte[] arrays, each encoding one user CA certificate.
      */
-    public static boolean hasAnyCaCertsInstalled() {
-        TrustedCertificateStore certStore = new TrustedCertificateStore();
-        Set<String> aliases = certStore.userAliases();
-        return aliases != null && !aliases.isEmpty();
+    public List<byte[]> getInstalledCaCerts(ComponentName admin) {
+        List<byte[]> certs = new ArrayList<byte[]>();
+        if (mService != null) {
+            try {
+                mService.enforceCanManageCaCerts(admin);
+                final TrustedCertificateStore certStore = new TrustedCertificateStore();
+                for (String alias : certStore.userAliases()) {
+                    try {
+                        certs.add(certStore.getCertificate(alias).getEncoded());
+                    } catch (CertificateException ce) {
+                        Log.w(TAG, "Could not encode certificate: " + alias, ce);
+                    }
+                }
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed talking with device policy service", re);
+            }
+        }
+        return certs;
     }
 
     /**
-     * Returns whether this certificate has been installed as a User CA.
+     * Uninstalls all custom trusted CA certificates from the profile. Certificates installed by
+     * means other than device policy will also be removed, except for system CA certificates.
      *
-     * @hide
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      */
-    public boolean hasCaCertInstalled(byte[] certBuffer) {
-        TrustedCertificateStore certStore = new TrustedCertificateStore();
-        String alias;
-        byte[] pemCert;
+    public void uninstallAllUserCaCerts(ComponentName admin) {
+        if (mService != null) {
+            for (String alias : new TrustedCertificateStore().userAliases()) {
+                try {
+                    mService.uninstallCaCert(admin, alias);
+                } catch (RemoteException re) {
+                    Log.w(TAG, "Failed talking with device policy service", re);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns whether this certificate is installed as a trusted CA.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param certBuffer encoded form of the certificate to look up.
+     */
+    public boolean hasCaCertInstalled(ComponentName admin, byte[] certBuffer) {
+        if (mService != null) {
+            try {
+                mService.enforceCanManageCaCerts(admin);
+                return getCaCertAlias(certBuffer) != null;
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed talking with device policy service", re);
+            } catch (CertificateException ce) {
+                Log.w(TAG, "Could not parse certificate", ce);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by a device or profile owner to install a certificate and private key pair. The
+     * keypair will be visible to all apps within the profile.
+     *
+     * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param privKey The private key to install.
+     * @param cert The certificate to install.
+     * @param alias The private key alias under which to install the certificate. If a certificate
+     * with that alias already exists, it will be overwritten.
+     * @return {@code true} if the keys were installed, {@code false} otherwise.
+     */
+    public boolean installKeyPair(ComponentName who, PrivateKey privKey, Certificate cert,
+            String alias) {
         try {
-            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
-            X509Certificate cert = (X509Certificate) certFactory.generateCertificate(
-                            new ByteArrayInputStream(certBuffer));
-            return certStore.getCertificateAlias(cert) != null;
-        } catch (CertificateException ce) {
-            Log.w(TAG, "Could not parse certificate", ce);
+            final byte[] pemCert = Credentials.convertToPem(cert);
+            return mService.installKeyPair(who, privKey.getEncoded(), pemCert, alias);
+        } catch (CertificateException e) {
+            Log.w(TAG, "Error encoding certificate", e);
+        } catch (IOException e) {
+            Log.w(TAG, "Error writing certificate", e);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed talking with device policy service", e);
         }
         return false;
     }
 
     /**
+     * Returns the alias of a given CA certificate in the certificate store, or null if it
+     * doesn't exist.
+     */
+    private static String getCaCertAlias(byte[] certBuffer) throws CertificateException {
+        final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        final X509Certificate cert = (X509Certificate) certFactory.generateCertificate(
+                              new ByteArrayInputStream(certBuffer));
+        return new TrustedCertificateStore().getCertificateAlias(cert);
+    }
+
+    /**
      * Called by an application that is administering the device to disable all cameras
      * on the device.  After setting this, no applications will be able to access any cameras
      * on the device.
@@ -1443,6 +1924,86 @@
     }
 
     /**
+     * Called by a device/profile owner to set whether the screen capture is disabled. Disabling
+     * screen capture also prevents the content from being shown on display devices that do not have
+     * a secure video output. See {@link android.view.Display#FLAG_SECURE} for more details about
+     * secure surfaces and secure displays.
+     *
+     * <p>The calling device admin must be a device or profile owner. If it is not, a
+     * security exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param disabled Whether screen capture is disabled or not.
+     */
+    public void setScreenCaptureDisabled(ComponentName admin, boolean disabled) {
+        if (mService != null) {
+            try {
+                mService.setScreenCaptureDisabled(admin, UserHandle.myUserId(), disabled);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Determine whether or not screen capture has been disabled by the current
+     * admin, if specified, or all admins.
+     * @param admin The name of the admin component to check, or null to check if any admins
+     * have disabled screen capture.
+     */
+    public boolean getScreenCaptureDisabled(ComponentName admin) {
+        return getScreenCaptureDisabled(admin, UserHandle.myUserId());
+    }
+
+    /** @hide per-user version */
+    public boolean getScreenCaptureDisabled(ComponentName admin, int userHandle) {
+        if (mService != null) {
+            try {
+                return mService.getScreenCaptureDisabled(admin, userHandle);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by a device owner to set whether auto time is required. If auto time is
+     * required the user cannot set the date and time, but has to use network date and time.
+     *
+     * <p>Note: if auto time is required the user can still manually set the time zone.
+     *
+     * <p>The calling device admin must be a device owner. If it is not, a security exception will
+     * be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param required Whether auto time is set required or not.
+     */
+    public void setAutoTimeRequired(ComponentName admin, boolean required) {
+        if (mService != null) {
+            try {
+                mService.setAutoTimeRequired(admin, UserHandle.myUserId(), required);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * @return true if auto time is required.
+     */
+    public boolean getAutoTimeRequired() {
+        if (mService != null) {
+            try {
+                return mService.getAutoTimeRequired();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+    /**
      * Called by an application that is administering the device to disable keyguard customizations,
      * such as widgets. After setting this, keyguard features will be disabled according to the
      * provided feature list.
@@ -1454,7 +2015,8 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param which {@link #KEYGUARD_DISABLE_FEATURES_NONE} (default),
      * {@link #KEYGUARD_DISABLE_WIDGETS_ALL}, {@link #KEYGUARD_DISABLE_SECURE_CAMERA},
-     * {@link #KEYGUARD_DISABLE_FEATURES_ALL}
+     * {@link #KEYGUARD_DISABLE_SECURE_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_TRUST_AGENTS},
+     * {@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_FEATURES_ALL}
      */
     public void setKeyguardDisabledFeatures(ComponentName admin, int which) {
         if (mService != null) {
@@ -1493,10 +2055,10 @@
     /**
      * @hide
      */
-    public void setActiveAdmin(ComponentName policyReceiver, boolean refreshing) {
+    public void setActiveAdmin(ComponentName policyReceiver, boolean refreshing, int userHandle) {
         if (mService != null) {
             try {
-                mService.setActiveAdmin(policyReceiver, refreshing, UserHandle.myUserId());
+                mService.setActiveAdmin(policyReceiver, refreshing, userHandle);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed talking with device policy service", e);
             }
@@ -1504,6 +2066,13 @@
     }
 
     /**
+     * @hide
+     */
+    public void setActiveAdmin(ComponentName policyReceiver, boolean refreshing) {
+        setActiveAdmin(policyReceiver, refreshing, UserHandle.myUserId());
+    }
+
+    /**
      * Returns the DeviceAdminInfo as defined by the administrator's package info & meta-data
      * @hide
      */
@@ -1625,7 +2194,6 @@
         return false;
     }
 
-
     /**
      * Used to determine if a particular package has been registered as a Device Owner app.
      * A device owner app is a special device admin that cannot be deactivated by the user, once
@@ -1658,7 +2226,27 @@
         return isDeviceOwnerApp(packageName);
     }
 
+    /**
+     * Clears the current device owner.  The caller must be the device owner.
+     *
+     * This function should be used cautiously as once it is called it cannot
+     * be undone.  The device owner can only be set as a part of device setup
+     * before setup completes.
+     *
+     * @param packageName The package name of the device owner.
+     */
+    public void clearDeviceOwnerApp(String packageName) {
+        if (mService != null) {
+            try {
+                mService.clearDeviceOwner(packageName);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to clear device owner");
+            }
+        }
+    }
+
     /** @hide */
+    @SystemApi
     public String getDeviceOwner() {
         if (mService != null) {
             try {
@@ -1681,4 +2269,1202 @@
         }
         return null;
     }
+
+    /**
+     * @hide
+     * @deprecated Use #ACTION_SET_PROFILE_OWNER
+     * Sets the given component as an active admin and registers the package as the profile
+     * owner for this user. The package must already be installed and there shouldn't be
+     * an existing profile owner registered for this user. Also, this method must be called
+     * before the user setup has been completed.
+     * <p>
+     * This method can only be called by system apps that hold MANAGE_USERS permission and
+     * MANAGE_DEVICE_ADMINS permission.
+     * @param admin The component to register as an active admin and profile owner.
+     * @param ownerName The user-visible name of the entity that is managing this user.
+     * @return whether the admin was successfully registered as the profile owner.
+     * @throws IllegalArgumentException if packageName is null, the package isn't installed, or
+     *         the user has already been set up.
+     */
+    @SystemApi
+    public boolean setActiveProfileOwner(ComponentName admin, String ownerName)
+            throws IllegalArgumentException {
+        if (mService != null) {
+            try {
+                final int myUserId = UserHandle.myUserId();
+                mService.setActiveAdmin(admin, false, myUserId);
+                return mService.setProfileOwner(admin, ownerName, myUserId);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to set profile owner " + re);
+                throw new IllegalArgumentException("Couldn't set profile owner.", re);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     * Clears the active profile owner and removes all user restrictions. The caller must
+     * be from the same package as the active profile owner for this user, otherwise a
+     * SecurityException will be thrown.
+     *
+     * @param admin The component to remove as the profile owner.
+     * @return
+     */
+    @SystemApi
+    public void clearProfileOwner(ComponentName admin) {
+        if (mService != null) {
+            try {
+                mService.clearProfileOwner(admin);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to clear profile owner " + admin + re);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Checks if the user was already setup.
+     */
+    public boolean hasUserSetupCompleted() {
+        if (mService != null) {
+            try {
+                return mService.hasUserSetupCompleted();
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to check if user setup has completed");
+            }
+        }
+        return true;
+    }
+
+    /**
+     * @deprecated Use setProfileOwner(ComponentName ...)
+     * @hide
+     * Sets the given package as the profile owner of the given user profile. The package must
+     * already be installed and there shouldn't be an existing profile owner registered for this
+     * user. Also, this method must be called before the user has been used for the first time.
+     * @param packageName the package name of the application to be registered as profile owner.
+     * @param ownerName the human readable name of the organisation associated with this DPM.
+     * @param userHandle the userId to set the profile owner for.
+     * @return whether the package was successfully registered as the profile owner.
+     * @throws IllegalArgumentException if packageName is null, the package isn't installed, or
+     *         the user has already been set up.
+     */
+    public boolean setProfileOwner(String packageName, String ownerName, int userHandle)
+            throws IllegalArgumentException {
+        if (packageName == null) {
+            throw new NullPointerException("packageName cannot be null");
+        }
+        return setProfileOwner(new ComponentName(packageName, ""), ownerName, userHandle);
+    }
+
+    /**
+     * @hide
+     * Sets the given component as the profile owner of the given user profile. The package must
+     * already be installed and there shouldn't be an existing profile owner registered for this
+     * user. Only the system can call this API if the user has already completed setup.
+     * @param admin the component name to be registered as profile owner.
+     * @param ownerName the human readable name of the organisation associated with this DPM.
+     * @param userHandle the userId to set the profile owner for.
+     * @return whether the component was successfully registered as the profile owner.
+     * @throws IllegalArgumentException if admin is null, the package isn't installed, or
+     *         the user has already been set up.
+     */
+    public boolean setProfileOwner(ComponentName admin, String ownerName, int userHandle)
+            throws IllegalArgumentException {
+        if (admin == null) {
+            throw new NullPointerException("admin cannot be null");
+        }
+        if (mService != null) {
+            try {
+                if (ownerName == null) {
+                    ownerName = "";
+                }
+                return mService.setProfileOwner(admin, ownerName, userHandle);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to set profile owner", re);
+                throw new IllegalArgumentException("Couldn't set profile owner.", re);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Sets the enabled state of the profile. A profile should be enabled only once it is ready to
+     * be used. Only the profile owner can call this.
+     *
+     * @see #isProfileOwnerApp
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     */
+    public void setProfileEnabled(ComponentName admin) {
+        if (mService != null) {
+            try {
+                mService.setProfileEnabled(admin);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Sets the name of the profile. In the device owner case it sets the name of the user
+     * which it is called from. Only a profile owner or device owner can call this. If this is
+     * never called by the profile or device owner, the name will be set to default values.
+     *
+     * @see #isProfileOwnerApp
+     * @see #isDeviceOwnerApp
+     *
+     * @param profileName The name of the profile.
+     */
+    public void setProfileName(ComponentName who, String profileName) {
+        if (mService != null) {
+            try {
+            mService.setProfileName(who, profileName);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed talking with device policy service", e);
+        }
+    }
+}
+
+    /**
+     * Used to determine if a particular package is registered as the profile owner for the
+     * current user. A profile owner is a special device admin that has additional privileges
+     * within the profile.
+     *
+     * @param packageName The package name of the app to compare with the registered profile owner.
+     * @return Whether or not the package is registered as the profile owner.
+     */
+    public boolean isProfileOwnerApp(String packageName) {
+        if (mService != null) {
+            try {
+                ComponentName profileOwner = mService.getProfileOwner(
+                        Process.myUserHandle().getIdentifier());
+                return profileOwner != null
+                        && profileOwner.getPackageName().equals(packageName);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to check profile owner");
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     * @return the packageName of the owner of the given user profile or null if no profile
+     * owner has been set for that user.
+     * @throws IllegalArgumentException if the userId is invalid.
+     */
+    @SystemApi
+    public ComponentName getProfileOwner() throws IllegalArgumentException {
+        return getProfileOwnerAsUser(Process.myUserHandle().getIdentifier());
+    }
+
+    /**
+     * @see #getProfileOwner()
+     * @hide
+     */
+    public ComponentName getProfileOwnerAsUser(final int userId) throws IllegalArgumentException {
+        if (mService != null) {
+            try {
+                return mService.getProfileOwner(userId);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to get profile owner");
+                throw new IllegalArgumentException(
+                        "Requested profile owner for invalid userId", re);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @hide
+     * @return the human readable name of the organisation associated with this DPM or null if
+     *         one is not set.
+     * @throws IllegalArgumentException if the userId is invalid.
+     */
+    public String getProfileOwnerName() throws IllegalArgumentException {
+        if (mService != null) {
+            try {
+                return mService.getProfileOwnerName(Process.myUserHandle().getIdentifier());
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to get profile owner");
+                throw new IllegalArgumentException(
+                        "Requested profile owner for invalid userId", re);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @hide
+     * @param user The user for whom to fetch the profile owner name, if any.
+     * @return the human readable name of the organisation associated with this profile owner or
+     *         null if one is not set.
+     * @throws IllegalArgumentException if the userId is invalid.
+     */
+    @SystemApi
+    public String getProfileOwnerNameAsUser(int userId) throws IllegalArgumentException {
+        if (mService != null) {
+            try {
+                return mService.getProfileOwnerName(userId);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to get profile owner");
+                throw new IllegalArgumentException(
+                        "Requested profile owner for invalid userId", re);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Called by a profile owner or device owner to add a default intent handler activity for
+     * intents that match a certain intent filter. This activity will remain the default intent
+     * handler even if the set of potential event handlers for the intent filter changes and if
+     * the intent preferences are reset.
+     *
+     * <p>The default disambiguation mechanism takes over if the activity is not installed
+     * (anymore). When the activity is (re)installed, it is automatically reset as default
+     * intent handler for the filter.
+     *
+     * <p>The calling device admin must be a profile owner or device owner. If it is not, a
+     * security exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param filter The IntentFilter for which a default handler is added.
+     * @param activity The Activity that is added as default intent handler.
+     */
+    public void addPersistentPreferredActivity(ComponentName admin, IntentFilter filter,
+            ComponentName activity) {
+        if (mService != null) {
+            try {
+                mService.addPersistentPreferredActivity(admin, filter, activity);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Called by a profile owner or device owner to remove all persistent intent handler preferences
+     * associated with the given package that were set by {@link #addPersistentPreferredActivity}.
+     *
+     * <p>The calling device admin must be a profile owner. If it is not, a security
+     * exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The name of the package for which preferences are removed.
+     */
+    public void clearPackagePersistentPreferredActivities(ComponentName admin,
+            String packageName) {
+        if (mService != null) {
+            try {
+                mService.clearPackagePersistentPreferredActivities(admin, packageName);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Called by a profile or device owner to set the application restrictions for a given target
+     * application running in the profile.
+     *
+     * <p>The provided {@link Bundle} consists of key-value pairs, where the types of values may be
+     * boolean, int, String, or String[].
+     *
+     * <p>The application restrictions are only made visible to the target application and the
+     * profile or device owner.
+     *
+     * <p>The calling device admin must be a profile or device owner; if it is not, a security
+     * exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The name of the package to update restricted settings for.
+     * @param settings A {@link Bundle} to be parsed by the receiving application, conveying a new
+     * set of active restrictions.
+     */
+    public void setApplicationRestrictions(ComponentName admin, String packageName,
+            Bundle settings) {
+        if (mService != null) {
+            try {
+                mService.setApplicationRestrictions(admin, packageName, settings);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Sets a list of features to enable for a TrustAgent component. This is meant to be
+     * used in conjunction with {@link #KEYGUARD_DISABLE_TRUST_AGENTS}, which will disable all
+     * trust agents but those with features enabled by this function call.
+     *
+     * <p>The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call
+     * this method; if it has not, a security exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param agent Which component to enable features for.
+     * @param features List of features to enable. Consult specific TrustAgent documentation for
+     * the feature list.
+     * @hide
+     */
+    public void setTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent,
+            List<String> features) {
+        if (mService != null) {
+            try {
+                mService.setTrustAgentFeaturesEnabled(admin, agent, features, UserHandle.myUserId());
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Gets list of enabled features for the given TrustAgent component. If admin is
+     * null, this will return the intersection of all features enabled for the given agent by all
+     * admins.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param agent Which component to get enabled features for.
+     * @return List of enabled features.
+     * @hide
+     */
+    public List<String> getTrustAgentFeaturesEnabled(ComponentName admin, ComponentName agent) {
+        if (mService != null) {
+            try {
+                return mService.getTrustAgentFeaturesEnabled(admin, agent, UserHandle.myUserId());
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return new ArrayList<String>(); // empty list
+    }
+
+    /**
+     * Called by a profile owner of a managed profile to set whether caller-Id information from
+     * the managed profile will be shown in the parent profile, for incoming calls.
+     *
+     * <p>The calling device admin must be a profile owner. If it is not, a
+     * security exception will be thrown.
+     *
+     * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param disabled If true caller-Id information in the managed profile is not displayed.
+     */
+    public void setCrossProfileCallerIdDisabled(ComponentName who, boolean disabled) {
+        if (mService != null) {
+            try {
+                mService.setCrossProfileCallerIdDisabled(who, disabled);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Called by a profile owner of a managed profile to determine whether or not caller-Id
+     * information has been disabled.
+     *
+     * <p>The calling device admin must be a profile owner. If it is not, a
+     * security exception will be thrown.
+     *
+     * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+     */
+    public boolean getCrossProfileCallerIdDisabled(ComponentName who) {
+        if (mService != null) {
+            try {
+                return mService.getCrossProfileCallerIdDisabled(who);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Determine whether or not caller-Id information has been disabled.
+     *
+     * @param userHandle The user for whom to check the caller-id permission
+     * @hide
+     */
+    public boolean getCrossProfileCallerIdDisabled(UserHandle userHandle) {
+        if (mService != null) {
+            try {
+                return mService.getCrossProfileCallerIdDisabledForUser(userHandle.getIdentifier());
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by the profile owner of a managed profile so that some intents sent in the managed
+     * profile can also be resolved in the parent, or vice versa.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param filter The {@link IntentFilter} the intent has to match to be also resolved in the
+     * other profile
+     * @param flags {@link DevicePolicyManager#FLAG_MANAGED_CAN_ACCESS_PARENT} and
+     * {@link DevicePolicyManager#FLAG_PARENT_CAN_ACCESS_MANAGED} are supported.
+     */
+    public void addCrossProfileIntentFilter(ComponentName admin, IntentFilter filter, int flags) {
+        if (mService != null) {
+            try {
+                mService.addCrossProfileIntentFilter(admin, filter, flags);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Called by a profile owner of a managed profile to remove the cross-profile intent filters
+     * that go from the managed profile to the parent, or from the parent to the managed profile.
+     * Only removes those that have been set by the profile owner.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     */
+    public void clearCrossProfileIntentFilters(ComponentName admin) {
+        if (mService != null) {
+            try {
+                mService.clearCrossProfileIntentFilters(admin);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Called by a profile or device owner to set the permitted accessibility services. When
+     * set by a device owner or profile owner the restriction applies to all profiles of the
+     * user the device owner or profile owner is an admin for.
+     *
+     * By default the user can use any accessiblity service. When zero or more packages have
+     * been added, accessiblity services that are not in the list and not part of the system
+     * can not be enabled by the user.
+     *
+     * <p> Calling with a null value for the list disables the restriction so that all services
+     * can be used, calling with an empty list only allows the builtin system's services.
+     *
+     * <p> System accesibility services are always available to the user the list can't modify
+     * this.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageNames List of accessibility service package names.
+     *
+     * @return true if setting the restriction succeeded. It fail if there is
+     * one or more non-system accessibility services enabled, that are not in the list.
+     */
+    public boolean setPermittedAccessibilityServices(ComponentName admin,
+            List<String> packageNames) {
+        if (mService != null) {
+            try {
+                return mService.setPermittedAccessibilityServices(admin, packageNames);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the list of permitted accessibility services set by this device or profile owner.
+     *
+     * <p>An empty list means no accessibility services except system services are allowed.
+     * Null means all accessibility services are allowed.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @return List of accessiblity service package names.
+     */
+    public List<String> getPermittedAccessibilityServices(ComponentName admin) {
+        if (mService != null) {
+            try {
+                return mService.getPermittedAccessibilityServices(admin);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the list of accessibility services permitted by the device or profiles
+     * owners of this user.
+     *
+     * <p>Null means all accessibility services are allowed, if a non-null list is returned
+     * it will contain the intersection of the permitted lists for any device or profile
+     * owners that apply to this user. It will also include any system accessibility services.
+     *
+     * @param userId which user to check for.
+     * @return List of accessiblity service package names.
+     * @hide
+     */
+     @SystemApi
+     public List<String> getPermittedAccessibilityServices(int userId) {
+        if (mService != null) {
+            try {
+                return mService.getPermittedAccessibilityServicesForUser(userId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return null;
+     }
+
+    /**
+     * Called by a profile or device owner to set the permitted input methods services. When
+     * set by a device owner or profile owner the restriction applies to all profiles of the
+     * user the device owner or profile owner is an admin for.
+     *
+     * By default the user can use any input method. When zero or more packages have
+     * been added, input method that are not in the list and not part of the system
+     * can not be enabled by the user.
+     *
+     * This method will fail if it is called for a admin that is not for the foreground user
+     * or a profile of the foreground user.
+     *
+     * <p> Calling with a null value for the list disables the restriction so that all input methods
+     * can be used, calling with an empty list disables all but the system's own input methods.
+     *
+     * <p> System input methods are always available to the user this method can't modify this.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageNames List of input method package names.
+     * @return true if setting the restriction succeeded. It will fail if there is
+     *     one or more input method enabled, that are not in the list or user if the foreground
+     *     user.
+     */
+    public boolean setPermittedInputMethods(ComponentName admin, List<String> packageNames) {
+        if (mService != null) {
+            try {
+                return mService.setPermittedInputMethods(admin, packageNames);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * Returns the list of permitted input methods set by this device or profile owner.
+     *
+     * <p>An empty list means no input methods except system input methods are allowed.
+     * Null means all input methods are allowed.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @return List of input method package names.
+     */
+    public List<String> getPermittedInputMethods(ComponentName admin) {
+        if (mService != null) {
+            try {
+                return mService.getPermittedInputMethods(admin);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the list of input methods permitted by the device or profiles
+     * owners of the current user.
+     *
+     * <p>Null means all input methods are allowed, if a non-null list is returned
+     * it will contain the intersection of the permitted lists for any device or profile
+     * owners that apply to this user. It will also include any system input methods.
+     *
+     * @return List of input method package names.
+     * @hide
+     */
+    @SystemApi
+    public List<String> getPermittedInputMethodsForCurrentUser() {
+        if (mService != null) {
+            try {
+                return mService.getPermittedInputMethodsForCurrentUser();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Called by a device owner to create a user with the specified name. The UserHandle returned
+     * by this method should not be persisted as user handles are recycled as users are removed and
+     * created. If you need to persist an identifier for this user, use
+     * {@link UserManager#getSerialNumberForUser}.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param name the user's name
+     * @see UserHandle
+     * @return the UserHandle object for the created user, or null if the user could not be created.
+     */
+    public UserHandle createUser(ComponentName admin, String name) {
+        try {
+            return mService.createUser(admin, name);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not create a user", re);
+        }
+        return null;
+    }
+
+    /**
+     * Called by a device owner to create a user with the specified name. The UserHandle returned
+     * by this method should not be persisted as user handles are recycled as users are removed and
+     * created. If you need to persist an identifier for this user, use
+     * {@link UserManager#getSerialNumberForUser}.  The new user will be started in the background
+     * immediately.
+     *
+     * <p> profileOwnerComponent is the {@link DeviceAdminReceiver} to be the profile owner as well
+     * as registered as an active admin on the new user.  The profile owner package will be
+     * installed on the new user if it already is installed on the device.
+     *
+     * <p>If the optionalInitializeData is not null, then the extras will be passed to the
+     * profileOwnerComponent when onEnable is called.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param name the user's name
+     * @param ownerName the human readable name of the organisation associated with this DPM.
+     * @param profileOwnerComponent The {@link DeviceAdminReceiver} that will be an active admin on
+     *      the user.
+     * @param adminExtras Extras that will be passed to onEnable of the admin receiver
+     *      on the new user.
+     * @see UserHandle
+     * @return the UserHandle object for the created user, or null if the user could not be created.
+     */
+    public UserHandle createAndInitializeUser(ComponentName admin, String name, String ownerName,
+            ComponentName profileOwnerComponent, Bundle adminExtras) {
+        try {
+            return mService.createAndInitializeUser(admin, name, ownerName, profileOwnerComponent,
+                    adminExtras);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not create a user", re);
+        }
+        return null;
+    }
+
+    /**
+     * Called by a device owner to remove a user and all associated data. The primary user can
+     * not be removed.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param userHandle the user to remove.
+     * @return {@code true} if the user was removed, {@code false} otherwise.
+     */
+    public boolean removeUser(ComponentName admin, UserHandle userHandle) {
+        try {
+            return mService.removeUser(admin, userHandle);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not remove user ", re);
+            return false;
+        }
+    }
+
+    /**
+     * Called by a device owner to switch the specified user to the foreground.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param userHandle the user to switch to; null will switch to primary.
+     * @return {@code true} if the switch was successful, {@code false} otherwise.
+     *
+     * @see Intent#ACTION_USER_FOREGROUND
+     */
+    public boolean switchUser(ComponentName admin, UserHandle userHandle) {
+        try {
+            return mService.switchUser(admin, userHandle);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not switch user ", re);
+            return false;
+        }
+    }
+
+    /**
+     * Called by a profile or device owner to get the application restrictions for a given target
+     * application running in the profile.
+     *
+     * <p>The calling device admin must be a profile or device owner; if it is not, a security
+     * exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The name of the package to fetch restricted settings of.
+     * @return {@link Bundle} of settings corresponding to what was set last time
+     * {@link DevicePolicyManager#setApplicationRestrictions} was called, or an empty {@link Bundle}
+     * if no restrictions have been set.
+     */
+    public Bundle getApplicationRestrictions(ComponentName admin, String packageName) {
+        if (mService != null) {
+            try {
+                return mService.getApplicationRestrictions(admin, packageName);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Called by a profile or device owner to set a user restriction specified
+     * by the key.
+     * <p>
+     * The calling device admin must be a profile or device owner; if it is not,
+     * a security exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated
+     *            with.
+     * @param key The key of the restriction. See the constants in
+     *            {@link android.os.UserManager} for the list of keys.
+     */
+    public void addUserRestriction(ComponentName admin, String key) {
+        if (mService != null) {
+            try {
+                mService.setUserRestriction(admin, key, true);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Called by a profile or device owner to clear a user restriction specified
+     * by the key.
+     * <p>
+     * The calling device admin must be a profile or device owner; if it is not,
+     * a security exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated
+     *            with.
+     * @param key The key of the restriction. See the constants in
+     *            {@link android.os.UserManager} for the list of keys.
+     */
+    public void clearUserRestriction(ComponentName admin, String key) {
+        if (mService != null) {
+            try {
+                mService.setUserRestriction(admin, key, false);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Called by device or profile owner to hide or unhide packages. When a package is hidden it
+     * is unavailable for use, but the data and actual package file remain.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The name of the package to hide or unhide.
+     * @param hidden {@code true} if the package should be hidden, {@code false} if it should be
+     *                 unhidden.
+     * @return boolean Whether the hidden setting of the package was successfully updated.
+     */
+    public boolean setApplicationHidden(ComponentName admin, String packageName,
+            boolean hidden) {
+        if (mService != null) {
+            try {
+                return mService.setApplicationHidden(admin, packageName, hidden);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by device or profile owner to determine if a package is hidden.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The name of the package to retrieve the hidden status of.
+     * @return boolean {@code true} if the package is hidden, {@code false} otherwise.
+     */
+    public boolean isApplicationHidden(ComponentName admin, String packageName) {
+        if (mService != null) {
+            try {
+                return mService.isApplicationHidden(admin, packageName);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by profile or device owner to re-enable a system app that was disabled by default
+     * when the user was initialized.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The package to be re-enabled in the current profile.
+     */
+    public void enableSystemApp(ComponentName admin, String packageName) {
+        if (mService != null) {
+            try {
+                mService.enableSystemApp(admin, packageName);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to install package: " + packageName);
+            }
+        }
+    }
+
+    /**
+     * Called by profile or device owner to re-enable system apps by intent that were disabled
+     * by default when the user was initialized.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param intent An intent matching the app(s) to be installed. All apps that resolve for this
+     *               intent will be re-enabled in the current profile.
+     * @return int The number of activities that matched the intent and were installed.
+     */
+    public int enableSystemApp(ComponentName admin, Intent intent) {
+        if (mService != null) {
+            try {
+                return mService.enableSystemAppWithIntent(admin, intent);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to install packages matching filter: " + intent);
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Called by a profile owner to disable account management for a specific type of account.
+     *
+     * <p>The calling device admin must be a profile owner. If it is not, a
+     * security exception will be thrown.
+     *
+     * <p>When account management is disabled for an account type, adding or removing an account
+     * of that type will not be possible.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param accountType For which account management is disabled or enabled.
+     * @param disabled The boolean indicating that account management will be disabled (true) or
+     * enabled (false).
+     */
+    public void setAccountManagementDisabled(ComponentName admin, String accountType,
+            boolean disabled) {
+        if (mService != null) {
+            try {
+                mService.setAccountManagementDisabled(admin, accountType, disabled);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Gets the array of accounts for which account management is disabled by the profile owner.
+     *
+     * <p> Account management can be disabled/enabled by calling
+     * {@link #setAccountManagementDisabled}.
+     *
+     * @return a list of account types for which account management has been disabled.
+     *
+     * @see #setAccountManagementDisabled
+     */
+    public String[] getAccountTypesWithManagementDisabled() {
+        return getAccountTypesWithManagementDisabledAsUser(UserHandle.myUserId());
+    }
+
+    /**
+     * @see #getAccountTypesWithManagementDisabled()
+     * @hide
+     */
+    public String[] getAccountTypesWithManagementDisabledAsUser(int userId) {
+        if (mService != null) {
+            try {
+                return mService.getAccountTypesWithManagementDisabledAsUser(userId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Sets which packages may enter lock task mode.
+     *
+     * <p>Any packages that shares uid with an allowed package will also be allowed
+     * to activate lock task.
+     *
+     * This function can only be called by the device owner.
+     * @param packages The list of packages allowed to enter lock task mode
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     *
+     * @see Activity#startLockTask()
+     * @see DeviceAdminReceiver#onLockTaskModeChanged(Context, Intent, boolean, String)
+     * @see UserManager#DISALLOW_CREATE_WINDOWS
+     */
+    public void setLockTaskPackages(ComponentName admin, String[] packages)
+            throws SecurityException {
+        if (mService != null) {
+            try {
+                mService.setLockTaskPackages(admin, packages);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * This function returns the list of packages allowed to start the lock task mode.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @hide
+     */
+    public String[] getLockTaskPackages(ComponentName admin) {
+        if (mService != null) {
+            try {
+                return mService.getLockTaskPackages(admin);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * This function lets the caller know whether the given component is allowed to start the
+     * lock task mode.
+     * @param pkg The package to check
+     */
+    public boolean isLockTaskPermitted(String pkg) {
+        if (mService != null) {
+            try {
+                return mService.isLockTaskPermitted(pkg);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by device owners to update {@link Settings.Global} settings. Validation that the value
+     * of the setting is in the correct form for the setting type should be performed by the caller.
+     * <p>The settings that can be updated with this method are:
+     * <ul>
+     * <li>{@link Settings.Global#ADB_ENABLED}</li>
+     * <li>{@link Settings.Global#AUTO_TIME}</li>
+     * <li>{@link Settings.Global#AUTO_TIME_ZONE}</li>
+     * <li>{@link Settings.Global#BLUETOOTH_ON}</li>
+     * <li>{@link Settings.Global#DATA_ROAMING}</li>
+     * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li>
+     * <li>{@link Settings.Global#MODE_RINGER}</li>
+     * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li>
+     * <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</li>
+     * <li>{@link Settings.Global#WIFI_ON}</li>
+     * <li>{@link Settings.Global#WIFI_SLEEP_POLICY}</li>
+     * </ul>
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param setting The name of the setting to update.
+     * @param value The value to update the setting to.
+     */
+    public void setGlobalSetting(ComponentName admin, String setting, String value) {
+        if (mService != null) {
+            try {
+                mService.setGlobalSetting(admin, setting, value);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Called by profile or device owners to update {@link Settings.Secure} settings. Validation
+     * that the value of the setting is in the correct form for the setting type should be performed
+     * by the caller.
+     * <p>The settings that can be updated by a profile or device owner with this method are:
+     * <ul>
+     * <li>{@link Settings.Secure#DEFAULT_INPUT_METHOD}</li>
+     * <li>{@link Settings.Secure#SKIP_FIRST_USE_HINTS}</li>
+     * </ul>
+     * <p>A device owner can additionally update the following settings:
+     * <ul>
+     * <li>{@link Settings.Secure#LOCATION_MODE}</li>
+     * </ul>
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param setting The name of the setting to update.
+     * @param value The value to update the setting to.
+     */
+    public void setSecureSetting(ComponentName admin, String setting, String value) {
+        if (mService != null) {
+            try {
+                mService.setSecureSetting(admin, setting, value);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Designates a specific service component as the provider for
+     * making permission requests of a local or remote administrator of the user.
+     * <p/>
+     * Only a profile owner can designate the restrictions provider.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param provider The component name of the service that implements
+     * {@link RestrictionsReceiver}. If this param is null,
+     * it removes the restrictions provider previously assigned.
+     */
+    public void setRestrictionsProvider(ComponentName admin, ComponentName provider) {
+        if (mService != null) {
+            try {
+                mService.setRestrictionsProvider(admin, provider);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to set permission provider on device policy service");
+            }
+        }
+    }
+
+    /**
+     * Called by profile or device owners to set the master volume mute on or off.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param on {@code true} to mute master volume, {@code false} to turn mute off.
+     */
+    public void setMasterVolumeMuted(ComponentName admin, boolean on) {
+        if (mService != null) {
+            try {
+                mService.setMasterVolumeMuted(admin, on);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to setMasterMute on device policy service");
+            }
+        }
+    }
+
+    /**
+     * Called by profile or device owners to check whether the master volume mute is on or off.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @return {@code true} if master volume is muted, {@code false} if it's not.
+     */
+    public boolean isMasterVolumeMuted(ComponentName admin) {
+        if (mService != null) {
+            try {
+                return mService.isMasterVolumeMuted(admin);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to get isMasterMute on device policy service");
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by profile or device owners to change whether a user can uninstall
+     * a package.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName package to change.
+     * @param uninstallBlocked true if the user shouldn't be able to uninstall the package.
+     */
+    public void setUninstallBlocked(ComponentName admin, String packageName,
+            boolean uninstallBlocked) {
+        if (mService != null) {
+            try {
+                mService.setUninstallBlocked(admin, packageName, uninstallBlocked);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to call block uninstall on device policy service");
+            }
+        }
+    }
+
+    /**
+     * Called by profile or device owners to check whether a user has been blocked from
+     * uninstalling a package.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName package to check.
+     * @return true if the user shouldn't be able to uninstall the package.
+     */
+    public boolean isUninstallBlocked(ComponentName admin, String packageName) {
+        if (mService != null) {
+            try {
+                return mService.isUninstallBlocked(admin, packageName);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to call block uninstall on device policy service");
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by the profile owner of a managed profile to enable widget providers from a
+     * given package to be available in the parent profile. As a result the user will be able to
+     * add widgets from the white-listed package running under the profile to a widget
+     * host which runs under the parent profile, for example the home screen. Note that
+     * a package may have zero or more provider components, where each component
+     * provides a different widget type.
+     * <p>
+     * <strong>Note:</strong> By default no widget provider package is white-listed.
+     * </p>
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The package from which widget providers are white-listed.
+     * @return Whether the package was added.
+     *
+     * @see #removeCrossProfileWidgetProvider(android.content.ComponentName, String)
+     * @see #getCrossProfileWidgetProviders(android.content.ComponentName)
+     */
+    public boolean addCrossProfileWidgetProvider(ComponentName admin, String packageName) {
+        if (mService != null) {
+            try {
+                return mService.addCrossProfileWidgetProvider(admin, packageName);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Error calling addCrossProfileWidgetProvider", re);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by the profile owner of a managed profile to disable widget providers from a given
+     * package to be available in the parent profile. For this method to take effect the
+     * package should have been added via {@link #addCrossProfileWidgetProvider(
+     * android.content.ComponentName, String)}.
+     * <p>
+     * <strong>Note:</strong> By default no widget provider package is white-listed.
+     * </p>
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The package from which widget providers are no longer
+     *     white-listed.
+     * @return Whether the package was removed.
+     *
+     * @see #addCrossProfileWidgetProvider(android.content.ComponentName, String)
+     * @see #getCrossProfileWidgetProviders(android.content.ComponentName)
+     */
+    public boolean removeCrossProfileWidgetProvider(ComponentName admin, String packageName) {
+        if (mService != null) {
+            try {
+                return mService.removeCrossProfileWidgetProvider(admin, packageName);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Error calling removeCrossProfileWidgetProvider", re);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called by the profile owner of a managed profile to query providers from which packages are
+     * available in the parent profile.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @return The white-listed package list.
+     *
+     * @see #addCrossProfileWidgetProvider(android.content.ComponentName, String)
+     * @see #removeCrossProfileWidgetProvider(android.content.ComponentName, String)
+     */
+    public List<String> getCrossProfileWidgetProviders(ComponentName admin) {
+        if (mService != null) {
+            try {
+                List<String> providers = mService.getCrossProfileWidgetProviders(admin);
+                if (providers != null) {
+                    return providers;
+                }
+            } catch (RemoteException re) {
+                Log.w(TAG, "Error calling getCrossProfileWidgetProviders", re);
+            }
+        }
+        return Collections.emptyList();
+    }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
new file mode 100644
index 0000000..a1f1d92
--- /dev/null
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import java.util.List;
+
+/**
+ * Device policy manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class DevicePolicyManagerInternal {
+
+    /**
+     * Listener for changes in the white-listed packages to show cross-profile
+     * widgets.
+     */
+    public interface OnCrossProfileWidgetProvidersChangeListener {
+
+        /**
+         * Called when the white-listed packages to show cross-profile widgets
+         * have changed for a given user.
+         *
+         * @param profileId The profile for which the white-listed packages changed.
+         * @param packages The white-listed packages.
+         */
+        public void onCrossProfileWidgetProvidersChanged(int profileId, List<String> packages);
+    }
+
+    /**
+     * Gets the packages whose widget providers are white-listed to be
+     * available in the parent user.
+     *
+     * @param profileId The profile id.
+     * @return The list of packages if such or empty list if there are
+     *    no white-listed packages or the profile id is not a managed
+     *    profile.
+     */
+    public abstract List<String> getCrossProfileWidgetProviders(int profileId);
+
+    /**
+     * Adds a listener for changes in the white-listed packages to show
+     * cross-profile app widgets.
+     *
+     * @param listener The listener to add.
+     */
+    public abstract void addOnCrossProfileWidgetProvidersChangeListener(
+            OnCrossProfileWidgetProvidersChangeListener listener);
+}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 172c47c2..c8e1780 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -18,7 +18,13 @@
 package android.app.admin;
 
 import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ProxyInfo;
+import android.os.Bundle;
 import android.os.RemoteCallback;
+import android.os.UserHandle;
+import java.util.List;
 
 /**
  * Internal IPC interface to the device policy service.
@@ -74,6 +80,7 @@
 
     ComponentName setGlobalProxy(in ComponentName admin, String proxySpec, String exclusionList, int userHandle);
     ComponentName getGlobalProxyAdmin(int userHandle);
+    void setRecommendedGlobalProxy(in ComponentName admin, in ProxyInfo proxyInfo);
 
     int setStorageEncryption(in ComponentName who, boolean encrypt, int userHandle);
     boolean getStorageEncryption(in ComponentName who, int userHandle);
@@ -82,6 +89,9 @@
     void setCameraDisabled(in ComponentName who, boolean disabled, int userHandle);
     boolean getCameraDisabled(in ComponentName who, int userHandle);
 
+    void setScreenCaptureDisabled(in ComponentName who, int userHandle, boolean disabled);
+    boolean getScreenCaptureDisabled(in ComponentName who, int userHandle);
+
     void setKeyguardDisabledFeatures(in ComponentName who, int which, int userHandle);
     int getKeyguardDisabledFeatures(in ComponentName who, int userHandle);
 
@@ -102,7 +112,84 @@
     boolean isDeviceOwner(String packageName);
     String getDeviceOwner();
     String getDeviceOwnerName();
+    void clearDeviceOwner(String packageName);
 
-    boolean installCaCert(in byte[] certBuffer);
-    void uninstallCaCert(in byte[] certBuffer);
+    boolean setProfileOwner(in ComponentName who, String ownerName, int userHandle);
+    ComponentName getProfileOwner(int userHandle);
+    String getProfileOwnerName(int userHandle);
+    void setProfileEnabled(in ComponentName who);
+    void setProfileName(in ComponentName who, String profileName);
+    void clearProfileOwner(in ComponentName who);
+    boolean hasUserSetupCompleted();
+
+    boolean installCaCert(in ComponentName admin, in byte[] certBuffer);
+    void uninstallCaCert(in ComponentName admin, in String alias);
+    void enforceCanManageCaCerts(in ComponentName admin);
+
+    boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer, String alias);
+
+    void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
+    void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);
+
+    void setApplicationRestrictions(in ComponentName who, in String packageName, in Bundle settings);
+    Bundle getApplicationRestrictions(in ComponentName who, in String packageName);
+
+    void setRestrictionsProvider(in ComponentName who, in ComponentName provider);
+    ComponentName getRestrictionsProvider(int userHandle);
+
+    void setUserRestriction(in ComponentName who, in String key, boolean enable);
+    void addCrossProfileIntentFilter(in ComponentName admin, in IntentFilter filter, int flags);
+    void clearCrossProfileIntentFilters(in ComponentName admin);
+
+    boolean setPermittedAccessibilityServices(in ComponentName admin,in List packageList);
+    List getPermittedAccessibilityServices(in ComponentName admin);
+    List getPermittedAccessibilityServicesForUser(int userId);
+
+    boolean setPermittedInputMethods(in ComponentName admin,in List packageList);
+    List getPermittedInputMethods(in ComponentName admin);
+    List getPermittedInputMethodsForCurrentUser();
+
+    boolean setApplicationHidden(in ComponentName admin, in String packageName, boolean hidden);
+    boolean isApplicationHidden(in ComponentName admin, in String packageName);
+
+    UserHandle createUser(in ComponentName who, in String name);
+    UserHandle createAndInitializeUser(in ComponentName who, in String name, in String profileOwnerName, in ComponentName profileOwnerComponent, in Bundle adminExtras);
+    boolean removeUser(in ComponentName who, in UserHandle userHandle);
+    boolean switchUser(in ComponentName who, in UserHandle userHandle);
+
+    void enableSystemApp(in ComponentName admin, in String packageName);
+    int enableSystemAppWithIntent(in ComponentName admin, in Intent intent);
+
+    void setAccountManagementDisabled(in ComponentName who, in String accountType, in boolean disabled);
+    String[] getAccountTypesWithManagementDisabled();
+    String[] getAccountTypesWithManagementDisabledAsUser(int userId);
+
+    void setLockTaskPackages(in ComponentName who, in String[] packages);
+    String[] getLockTaskPackages(in ComponentName who);
+    boolean isLockTaskPermitted(in String pkg);
+
+    void setGlobalSetting(in ComponentName who, in String setting, in String value);
+    void setSecureSetting(in ComponentName who, in String setting, in String value);
+
+    void setMasterVolumeMuted(in ComponentName admin, boolean on);
+    boolean isMasterVolumeMuted(in ComponentName admin);
+
+    void notifyLockTaskModeChanged(boolean isEnabled, String pkg, int userId);
+
+    void setUninstallBlocked(in ComponentName admin, in String packageName, boolean uninstallBlocked);
+    boolean isUninstallBlocked(in ComponentName admin, in String packageName);
+
+    void setCrossProfileCallerIdDisabled(in ComponentName who, boolean disabled);
+    boolean getCrossProfileCallerIdDisabled(in ComponentName who);
+    boolean getCrossProfileCallerIdDisabledForUser(int userId);
+
+    void setTrustAgentFeaturesEnabled(in ComponentName admin, in ComponentName agent, in List<String> features, int userId);
+    List<String> getTrustAgentFeaturesEnabled(in ComponentName admin, in ComponentName agent, int userId);
+
+    boolean addCrossProfileWidgetProvider(in ComponentName admin, String packageName);
+    boolean removeCrossProfileWidgetProvider(in ComponentName admin, String packageName);
+    List<String> getCrossProfileWidgetProviders(in ComponentName admin);
+
+    void setAutoTimeRequired(in ComponentName who, int userHandle, boolean required);
+    boolean getAutoTimeRequired();
 }
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 70a3797..87d785a 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -127,6 +127,13 @@
 
     Handler mHandler = null;
 
+    Handler getHandler() {
+        if (mHandler == null) {
+            mHandler = new Handler(Looper.getMainLooper());
+        }
+        return mHandler;
+    }
+
     class SharedPrefsSynchronizer implements Runnable {
         public final CountDownLatch mLatch = new CountDownLatch(1);
 
@@ -139,12 +146,9 @@
 
     // Syncing shared preferences deferred writes needs to happen on the main looper thread
     private void waitForSharedPrefs() {
-        if (mHandler == null) {
-            mHandler = new Handler(Looper.getMainLooper());
-        }
-
+        Handler h = getHandler();
         final SharedPrefsSynchronizer s = new SharedPrefsSynchronizer();
-        mHandler.postAtFrontOfQueue(s);
+        h.postAtFrontOfQueue(s);
         try {
             s.mLatch.await();
         } catch (InterruptedException e) { /* ignored */ }
@@ -205,7 +209,7 @@
      *            output stream.
      */
     public abstract void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
-             ParcelFileDescriptor newState) throws IOException;
+            ParcelFileDescriptor newState) throws IOException;
 
     /**
      * The application is being restored from backup and should replace any
@@ -239,16 +243,43 @@
      *            When a full-backup dataset is being restored, this will be <code>null</code>.
      */
     public abstract void onRestore(BackupDataInput data, int appVersionCode,
-            ParcelFileDescriptor newState)
-            throws IOException;
+            ParcelFileDescriptor newState) throws IOException;
 
     /**
-     * The default implementation backs up the entirety of the application's "owned"
-     * file system trees to the output.
+     * The application is having its entire file system contents backed up.  {@code data}
+     * points to the backup destination, and the app has the opportunity to choose which
+     * files are to be stored.  To commit a file as part of the backup, call the
+     * {@link #fullBackupFile(File, FullBackupDataOutput)} helper method.  After all file
+     * data is written to the output, the agent returns from this method and the backup
+     * operation concludes.
+     *
+     * <p>Certain parts of the app's data are never backed up even if the app explicitly
+     * sends them to the output:
+     *
+     * <ul>
+     * <li>The contents of the {@link #getCacheDir()} directory</li>
+     * <li>The contents of the {@link #getNoBackupFilesDir()} directory</li>
+     * <li>The contents of the app's shared library directory</li>
+     * </ul>
+     *
+     * <p>The default implementation of this method backs up the entirety of the
+     * application's "owned" file system trees to the output other than the few exceptions
+     * listed above.  Apps only need to override this method if they need to impose special
+     * limitations on which files are being stored beyond the control that
+     * {@link #getNoBackupFilesDir()} offers.
+     *
+     * @param data A structured wrapper pointing to the backup destination.
+     * @throws IOException
+     *
+     * @see Context#getNoBackupFilesDir()
+     * @see #fullBackupFile(File, FullBackupDataOutput)
+     * @see #onRestoreFile(ParcelFileDescriptor, long, File, int, long, long)
      */
     public void onFullBackup(FullBackupDataOutput data) throws IOException {
         ApplicationInfo appInfo = getApplicationInfo();
 
+        // Note that we don't need to think about the no_backup dir because it's outside
+        // all of the ones we will be traversing
         String rootDir = new File(appInfo.dataDir).getCanonicalPath();
         String filesDir = getFilesDir().getCanonicalPath();
         String databaseDir = getDatabasePath("foo").getParentFile().getCanonicalPath();
@@ -307,6 +338,10 @@
      * to place it with the proper location and permissions on the device where the
      * data is restored.
      *
+     * <p class="note">It is safe to explicitly back up files underneath your application's
+     * {@link #getNoBackupFilesDir()} directory, and they will be restored to that
+     * location correctly.
+     *
      * @param file The file to be backed up.  The file must exist and be readable by
      *     the caller.
      * @param output The destination to which the backed-up file data will be sent.
@@ -315,6 +350,7 @@
         // Look up where all of our various well-defined dir trees live on this device
         String mainDir;
         String filesDir;
+        String nbFilesDir;
         String dbDir;
         String spDir;
         String cacheDir;
@@ -327,6 +363,7 @@
         try {
             mainDir = new File(appInfo.dataDir).getCanonicalPath();
             filesDir = getFilesDir().getCanonicalPath();
+            nbFilesDir = getNoBackupFilesDir().getCanonicalPath();
             dbDir = getDatabasePath("foo").getParentFile().getCanonicalPath();
             spDir = getSharedPrefsFile("foo").getParentFile().getCanonicalPath();
             cacheDir = getCacheDir().getCanonicalPath();
@@ -350,8 +387,10 @@
             return;
         }
 
-        if (filePath.startsWith(cacheDir) || filePath.startsWith(libDir)) {
-            Log.w(TAG, "lib and cache files are not backed up");
+        if (filePath.startsWith(cacheDir)
+                || filePath.startsWith(libDir)
+                || filePath.startsWith(nbFilesDir)) {
+            Log.w(TAG, "lib, cache, and no_backup files are not backed up");
             return;
         }
 
@@ -504,6 +543,8 @@
                     mode = -1;  // < 0 is a token to skip attempting a chmod()
                 }
             }
+        } else if (domain.equals(FullBackup.NO_BACKUP_TREE_TOKEN)) {
+            basePath = getNoBackupFilesDir().getCanonicalPath();
         } else {
             // Not a supported location
             Log.i(TAG, "Unrecognized domain " + domain);
@@ -533,6 +574,20 @@
         FullBackup.restoreFile(data, size, type, mode, mtime, null);
     }
 
+    /**
+     * The application's restore operation has completed.  This method is called after
+     * all available data has been delivered to the application for restore (via either
+     * the {@link #onRestore(BackupDataInput, int, ParcelFileDescriptor) onRestore()} or
+     * {@link #onRestoreFile(ParcelFileDescriptor, long, File, int, long, long) onRestoreFile()}
+     * callbacks).  This provides the app with a stable end-of-restore opportunity to
+     * perform any appropriate post-processing on the data that was just delivered.
+     *
+     * @see #onRestore(BackupDataInput, int, ParcelFileDescriptor)
+     * @see #onRestoreFile(ParcelFileDescriptor, long, File, int, long, long)
+     */
+    public void onRestoreFinished() {
+    }
+
     // ----- Core implementation -----
 
     /** @hide */
@@ -679,5 +734,41 @@
                 }
             }
         }
+
+        @Override
+        public void doRestoreFinished(int token, IBackupManager callbackBinder) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                BackupAgent.this.onRestoreFinished();
+            } finally {
+                // Ensure that any side-effect SharedPreferences writes have landed
+                waitForSharedPrefs();
+
+                Binder.restoreCallingIdentity(ident);
+                try {
+                    callbackBinder.opComplete(token);
+                } catch (RemoteException e) {
+                    // we'll time out anyway, so we're safe
+                }
+            }
+        }
+
+        @Override
+        public void fail(String message) {
+            getHandler().post(new FailRunnable(message));
+        }
+    }
+
+    static class FailRunnable implements Runnable {
+        private String mMessage;
+
+        FailRunnable(String message) {
+            mMessage = message;
+        }
+
+        @Override
+        public void run() {
+            throw new IllegalStateException(mMessage);
+        }
     }
 }
diff --git a/core/java/android/app/backup/BackupDataInput.java b/core/java/android/app/backup/BackupDataInput.java
index 03205fb..26f9e3e 100644
--- a/core/java/android/app/backup/BackupDataInput.java
+++ b/core/java/android/app/backup/BackupDataInput.java
@@ -16,6 +16,8 @@
 
 package android.app.backup;
 
+import android.annotation.SystemApi;
+
 import java.io.FileDescriptor;
 import java.io.IOException;
 
@@ -70,6 +72,7 @@
     }
 
     /** @hide */
+    @SystemApi
     public BackupDataInput(FileDescriptor fd) {
         if (fd == null) throw new NullPointerException();
         mBackupReader = ctor(fd);
@@ -79,6 +82,7 @@
     }
 
     /** @hide */
+    @Override
     protected void finalize() throws Throwable {
         try {
             dtor(mBackupReader);
@@ -174,7 +178,7 @@
      * for further processing.  This allows a {@link android.app.backup.BackupAgent} to
      * efficiently discard obsolete or otherwise uninteresting records during the
      * restore operation.
-     * 
+     *
      * @throws IOException if an error occurred when trying to read the restore data stream
      */
     public void skipEntityData() throws IOException {
diff --git a/core/java/android/app/backup/BackupDataOutput.java b/core/java/android/app/backup/BackupDataOutput.java
index 3a070b6..048a4bb 100644
--- a/core/java/android/app/backup/BackupDataOutput.java
+++ b/core/java/android/app/backup/BackupDataOutput.java
@@ -16,7 +16,9 @@
 
 package android.app.backup;
 
+import android.annotation.SystemApi;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -65,6 +67,7 @@
     long mBackupWriter;
 
     /** @hide */
+    @SystemApi
     public BackupDataOutput(FileDescriptor fd) {
         if (fd == null) throw new NullPointerException();
         mBackupWriter = ctor(fd);
@@ -76,7 +79,8 @@
     /**
      * Mark the beginning of one record in the backup data stream. This must be called before
      * {@link #writeEntityData}.
-     * @param key A string key that uniquely identifies the data record within the application
+     * @param key A string key that uniquely identifies the data record within the application.
+     *    Keys whose first character is \uFF00 or higher are not valid.
      * @param dataSize The size in bytes of this record's data.  Passing a dataSize
      *    of -1 indicates that the record under this key should be deleted.
      * @return The number of bytes written to the backup stream
@@ -113,6 +117,7 @@
     }
 
     /** @hide */
+    @Override
     protected void finalize() throws Throwable {
         try {
             dtor(mBackupWriter);
diff --git a/core/java/android/app/backup/BackupHelper.java b/core/java/android/app/backup/BackupHelper.java
index e3f0d54..7cbbbc3 100644
--- a/core/java/android/app/backup/BackupHelper.java
+++ b/core/java/android/app/backup/BackupHelper.java
@@ -37,10 +37,9 @@
  */
 public interface BackupHelper {
     /**
-     * Based on <code>oldState</code>, determine which of the files from the
-     * application's data directory need to be backed up, write them to
-     * <code>data</code>, and fill in <code>newState</code> with the state as it
-     * exists now.
+     * Based on <code>oldState</code>, determine what application content
+     * needs to be backed up, write it to <code>data</code>, and fill in
+     * <code>newState</code> with the complete state as it exists now.
      * <p>
      * Implementing this method is much like implementing
      * {@link BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index be8108c..9151a16 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -16,6 +16,7 @@
 
 package android.app.backup;
 
+import android.annotation.SystemApi;
 import android.app.backup.RestoreSession;
 import android.app.backup.IBackupManager;
 import android.app.backup.IRestoreSession;
@@ -114,7 +115,7 @@
             try {
                 sService.dataChanged(packageName);
             } catch (RemoteException e) {
-                Log.d(TAG, "dataChanged(pkg) couldn't connect");
+                Log.e(TAG, "dataChanged(pkg) couldn't connect");
             }
         }
     }
@@ -150,7 +151,7 @@
                     result = session.restorePackage(mContext.getPackageName(), observer);
                 }
             } catch (RemoteException e) {
-                Log.w(TAG, "restoreSelf() unable to contact service");
+                Log.e(TAG, "restoreSelf() unable to contact service");
             } finally {
                 if (session != null) {
                     session.endRestoreSession();
@@ -160,11 +161,14 @@
         return result;
     }
 
+    // system APIs start here
+
     /**
      * Begin the process of restoring data from backup.  See the
      * {@link android.app.backup.RestoreSession} class for documentation on that process.
      * @hide
      */
+    @SystemApi
     public RestoreSession beginRestoreSession() {
         RestoreSession session = null;
         checkServiceBinder();
@@ -176,9 +180,163 @@
                     session = new RestoreSession(mContext, binder);
                 }
             } catch (RemoteException e) {
-                Log.w(TAG, "beginRestoreSession() couldn't connect");
+                Log.e(TAG, "beginRestoreSession() couldn't connect");
             }
         }
         return session;
     }
+
+    /**
+     * Enable/disable the backup service entirely.  When disabled, no backup
+     * or restore operations will take place.  Data-changed notifications will
+     * still be observed and collected, however, so that changes made while the
+     * mechanism was disabled will still be backed up properly if it is enabled
+     * at some point in the future.
+     *
+     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     *
+     * @hide
+     */
+    @SystemApi
+    public void setBackupEnabled(boolean isEnabled) {
+        checkServiceBinder();
+        if (sService != null) {
+            try {
+                sService.setBackupEnabled(isEnabled);
+            } catch (RemoteException e) {
+                Log.e(TAG, "setBackupEnabled() couldn't connect");
+            }
+        }
+    }
+
+    /**
+     * Report whether the backup mechanism is currently enabled.
+     *
+     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean isBackupEnabled() {
+        checkServiceBinder();
+        if (sService != null) {
+            try {
+                return sService.isBackupEnabled();
+            } catch (RemoteException e) {
+                Log.e(TAG, "isBackupEnabled() couldn't connect");
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Enable/disable data restore at application install time.  When enabled, app
+     * installation will include an attempt to fetch the app's historical data from
+     * the archival restore dataset (if any).  When disabled, no such attempt will
+     * be made.
+     *
+     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     *
+     * @hide
+     */
+    @SystemApi
+    public void setAutoRestore(boolean isEnabled) {
+        checkServiceBinder();
+        if (sService != null) {
+            try {
+                sService.setAutoRestore(isEnabled);
+            } catch (RemoteException e) {
+                Log.e(TAG, "setAutoRestore() couldn't connect");
+            }
+        }
+    }
+
+    /**
+     * Identify the currently selected transport.  Callers must hold the
+     * android.permission.BACKUP permission to use this method.
+     * @return The name of the currently active backup transport.  In case of
+     *   failure or if no transport is currently active, this method returns {@code null}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public String getCurrentTransport() {
+        checkServiceBinder();
+        if (sService != null) {
+            try {
+                return sService.getCurrentTransport();
+            } catch (RemoteException e) {
+                Log.e(TAG, "getCurrentTransport() couldn't connect");
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Request a list of all available backup transports' names.  Callers must
+     * hold the android.permission.BACKUP permission to use this method.
+     *
+     * @hide
+     */
+    @SystemApi
+    public String[] listAllTransports() {
+        checkServiceBinder();
+        if (sService != null) {
+            try {
+                return sService.listAllTransports();
+            } catch (RemoteException e) {
+                Log.e(TAG, "listAllTransports() couldn't connect");
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Specify the current backup transport.  Callers must hold the
+     * android.permission.BACKUP permission to use this method.
+     *
+     * @param transport The name of the transport to select.  This should be one
+     *   of the names returned by {@link #listAllTransports()}.
+     * @return The name of the previously selected transport.  If the given transport
+     *   name is not one of the currently available transports, no change is made to
+     *   the current transport setting and the method returns null.
+     *
+     * @hide
+     */
+    @SystemApi
+    public String selectBackupTransport(String transport) {
+        checkServiceBinder();
+        if (sService != null) {
+            try {
+                return sService.selectBackupTransport(transport);
+            } catch (RemoteException e) {
+                Log.e(TAG, "selectBackupTransport() couldn't connect");
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Schedule an immediate backup attempt for all pending key/value updates.  This
+     * is primarily intended for transports to use when they detect a suitable
+     * opportunity for doing a backup pass.  If there are no pending updates to
+     * be sent, no action will be taken.  Even if some updates are pending, the
+     * transport will still be asked to confirm via the usual requestBackupTime()
+     * method.
+     *
+     * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+     *
+     * @hide
+     */
+    @SystemApi
+    public void backupNow() {
+        checkServiceBinder();
+        if (sService != null) {
+            try {
+                sService.backupNow();
+            } catch (RemoteException e) {
+                Log.e(TAG, "backupNow() couldn't connect");
+            }
+        }
+    }
 }
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
new file mode 100644
index 0000000..70bb5e4
--- /dev/null
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.backup;
+
+import android.annotation.SystemApi;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+
+import com.android.internal.backup.IBackupTransport;
+
+/**
+ * Concrete class that provides a stable-API bridge between IBackupTransport
+ * and its implementations.
+ *
+ * @hide
+ */
+@SystemApi
+public class BackupTransport {
+    // Zero return always means things are okay.  If returned from
+    // getNextFullRestoreDataChunk(), it means that no data could be delivered at
+    // this time, but the restore is still running and the caller should simply
+    // retry.
+    public static final int TRANSPORT_OK = 0;
+
+    // -1 is special; it is used in getNextFullRestoreDataChunk() to indicate that
+    // we've delivered the entire data stream for the current restore target.
+    public static final int NO_MORE_DATA = -1;
+
+    // Result codes that indicate real errors are negative and not -1
+    public static final int TRANSPORT_ERROR = -1000;
+    public static final int TRANSPORT_NOT_INITIALIZED = -1001;
+    public static final int TRANSPORT_PACKAGE_REJECTED = -1002;
+    public static final int AGENT_ERROR = -1003;
+    public static final int AGENT_UNKNOWN = -1004;
+
+    IBackupTransport mBinderImpl = new TransportImpl();
+
+    public IBinder getBinder() {
+        return mBinderImpl.asBinder();
+    }
+
+    // ------------------------------------------------------------------------------------
+    // Transport self-description and general configuration interfaces
+    //
+
+    /**
+     * Ask the transport for the name under which it should be registered.  This will
+     * typically be its host service's component name, but need not be.
+     */
+    public String name() {
+        throw new UnsupportedOperationException("Transport name() not implemented");
+    }
+
+    /**
+     * Ask the transport for an Intent that can be used to launch any internal
+     * configuration Activity that it wishes to present.  For example, the transport
+     * may offer a UI for allowing the user to supply login credentials for the
+     * transport's off-device backend.
+     *
+     * <p>If the transport does not supply any user-facing configuration UI, it should
+     * return {@code null} from this method.
+     *
+     * @return An Intent that can be passed to Context.startActivity() in order to
+     *         launch the transport's configuration UI.  This method will return {@code null}
+     *         if the transport does not offer any user-facing configuration UI.
+     */
+    public Intent configurationIntent() {
+        return null;
+    }
+
+    /**
+     * On demand, supply a one-line string that can be shown to the user that
+     * describes the current backend destination.  For example, a transport that
+     * can potentially associate backup data with arbitrary user accounts should
+     * include the name of the currently-active account here.
+     *
+     * @return A string describing the destination to which the transport is currently
+     *         sending data.  This method should not return null.
+     */
+    public String currentDestinationString() {
+        throw new UnsupportedOperationException(
+                "Transport currentDestinationString() not implemented");
+    }
+
+    /**
+     * Ask the transport for an Intent that can be used to launch a more detailed
+     * secondary data management activity.  For example, the configuration intent might
+     * be one for allowing the user to select which account they wish to associate
+     * their backups with, and the management intent might be one which presents a
+     * UI for managing the data on the backend.
+     *
+     * <p>In the Settings UI, the configuration intent will typically be invoked
+     * when the user taps on the preferences item labeled with the current
+     * destination string, and the management intent will be placed in an overflow
+     * menu labelled with the management label string.
+     *
+     * <p>If the transport does not supply any user-facing data management
+     * UI, then it should return {@code null} from this method.
+     *
+     * @return An intent that can be passed to Context.startActivity() in order to
+     *         launch the transport's data-management UI.  This method will return
+     *         {@code null} if the transport does not offer any user-facing data
+     *         management UI.
+     */
+    public Intent dataManagementIntent() {
+        return null;
+    }
+
+    /**
+     * On demand, supply a short string that can be shown to the user as the label
+     * on an overflow menu item used to invoked the data management UI.
+     *
+     * @return A string to be used as the label for the transport's data management
+     *         affordance.  If the transport supplies a data management intent, this
+     *         method must not return {@code null}.
+     */
+    public String dataManagementLabel() {
+        throw new UnsupportedOperationException(
+                "Transport dataManagementLabel() not implemented");
+    }
+
+    /**
+     * Ask the transport where, on local device storage, to keep backup state blobs.
+     * This is per-transport so that mock transports used for testing can coexist with
+     * "live" backup services without interfering with the live bookkeeping.  The
+     * returned string should be a name that is expected to be unambiguous among all
+     * available backup transports; the name of the class implementing the transport
+     * is a good choice.
+     *
+     * @return A unique name, suitable for use as a file or directory name, that the
+     *         Backup Manager could use to disambiguate state files associated with
+     *         different backup transports.
+     */
+    public String transportDirName() {
+        throw new UnsupportedOperationException(
+                "Transport transportDirName() not implemented");
+    }
+
+    // ------------------------------------------------------------------------------------
+    // Device-level operations common to both key/value and full-data storage
+
+    /**
+     * Initialize the server side storage for this device, erasing all stored data.
+     * The transport may send the request immediately, or may buffer it.  After
+     * this is called, {@link #finishBackup} will be called to ensure the request
+     * is sent and received successfully.
+     *
+     * @return One of {@link BackupTransport#TRANSPORT_OK} (OK so far) or
+     *   {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure).
+     */
+    public int initializeDevice() {
+        return BackupTransport.TRANSPORT_ERROR;
+    }
+
+    /**
+     * Erase the given application's data from the backup destination.  This clears
+     * out the given package's data from the current backup set, making it as though
+     * the app had never yet been backed up.  After this is called, {@link finishBackup}
+     * must be called to ensure that the operation is recorded successfully.
+     *
+     * @return the same error codes as {@link #performBackup}.
+     */
+    public int clearBackupData(PackageInfo packageInfo) {
+        return BackupTransport.TRANSPORT_ERROR;
+    }
+
+    /**
+     * Finish sending application data to the backup destination.  This must be
+     * called after {@link #performBackup}, {@link #performFullBackup}, or {@link clearBackupData}
+     * to ensure that all data is sent and the operation properly finalized.  Only when this
+     * method returns true can a backup be assumed to have succeeded.
+     *
+     * @return the same error codes as {@link #performBackup} or {@link #performFullBackup}.
+     */
+    public int finishBackup() {
+        return BackupTransport.TRANSPORT_ERROR;
+    }
+
+    // ------------------------------------------------------------------------------------
+    // Key/value incremental backup support interfaces
+
+    /**
+     * Verify that this is a suitable time for a key/value backup pass.  This should return zero
+     * if a backup is reasonable right now, some positive value otherwise.  This method
+     * will be called outside of the {@link #performBackup}/{@link #finishBackup} pair.
+     *
+     * <p>If this is not a suitable time for a backup, the transport should return a
+     * backoff delay, in milliseconds, after which the Backup Manager should try again.
+     *
+     * @return Zero if this is a suitable time for a backup pass, or a positive time delay
+     *   in milliseconds to suggest deferring the backup pass for a while.
+     */
+    public long requestBackupTime() {
+        return 0;
+    }
+
+    /**
+     * Send one application's key/value data update to the backup destination.  The
+     * transport may send the data immediately, or may buffer it.  After this is called,
+     * {@link #finishBackup} will be called to ensure the data is sent and recorded successfully.
+     *
+     * @param packageInfo The identity of the application whose data is being backed up.
+     *   This specifically includes the signature list for the package.
+     * @param data The data stream that resulted from invoking the application's
+     *   BackupService.doBackup() method.  This may be a pipe rather than a file on
+     *   persistent media, so it may not be seekable.
+     * @param wipeAllFirst When true, <i>all</i> backed-up data for the current device/account
+     *   must be erased prior to the storage of the data provided here.  The purpose of this
+     *   is to provide a guarantee that no stale data exists in the restore set when the
+     *   device begins providing incremental backups.
+     * @return one of {@link BackupTransport#TRANSPORT_OK} (OK so far),
+     *  {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure), or
+     *  {@link BackupTransport#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has
+     *  become lost due to inactivity purge or some other reason and needs re-initializing)
+     */
+    public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd) {
+        return BackupTransport.TRANSPORT_ERROR;
+    }
+
+    // ------------------------------------------------------------------------------------
+    // Key/value dataset restore interfaces
+
+    /**
+     * Get the set of all backups currently available over this transport.
+     *
+     * @return Descriptions of the set of restore images available for this device,
+     *   or null if an error occurred (the attempt should be rescheduled).
+     **/
+    public RestoreSet[] getAvailableRestoreSets() {
+        return null;
+    }
+
+    /**
+     * Get the identifying token of the backup set currently being stored from
+     * this device.  This is used in the case of applications wishing to restore
+     * their last-known-good data.
+     *
+     * @return A token that can be passed to {@link #startRestore}, or 0 if there
+     *   is no backup set available corresponding to the current device state.
+     */
+    public long getCurrentRestoreSet() {
+        return 0;
+    }
+
+    /**
+     * Start restoring application data from backup.  After calling this function,
+     * alternate calls to {@link #nextRestorePackage} and {@link #nextRestoreData}
+     * to walk through the actual application data.
+     *
+     * @param token A backup token as returned by {@link #getAvailableRestoreSets}
+     *   or {@link #getCurrentRestoreSet}.
+     * @param packages List of applications to restore (if data is available).
+     *   Application data will be restored in the order given.
+     * @return One of {@link BackupTransport#TRANSPORT_OK} (OK so far, call
+     *   {@link #nextRestorePackage}) or {@link BackupTransport#TRANSPORT_ERROR}
+     *   (an error occurred, the restore should be aborted and rescheduled).
+     */
+    public int startRestore(long token, PackageInfo[] packages) {
+        return BackupTransport.TRANSPORT_ERROR;
+    }
+
+    /**
+     * Get the package name of the next application with data in the backup store, plus
+     * a description of the structure of the restored archive: either TYPE_KEY_VALUE for
+     * an original-API key/value dataset, or TYPE_FULL_STREAM for a tarball-type archive stream.
+     *
+     * <p>If the package name in the returned RestoreDescription object is the singleton
+     * {@link RestoreDescription#NO_MORE_PACKAGES}, it indicates that no further data is available
+     * in the current restore session: all packages described in startRestore() have been
+     * processed.
+     *
+     * <p>If this method returns {@code null}, it means that a transport-level error has
+     * occurred and the entire restore operation should be abandoned.
+     *
+     * <p class="note">The OS may call {@link #nextRestorePackage()} multiple times
+     * before calling either {@link #getRestoreData(ParcelFileDescriptor) getRestoreData()}
+     * or {@link #getNextFullRestoreDataChunk(ParcelFileDescriptor) getNextFullRestoreDataChunk()}.
+     * It does this when it has determined that it needs to skip restore of one or more
+     * packages.  The transport should not actually transfer any restore data for
+     * the given package in response to {@link #nextRestorePackage()}, but rather wait
+     * for an explicit request before doing so.
+     *
+     * @return A RestoreDescription object containing the name of one of the packages
+     *   supplied to {@link #startRestore} plus an indicator of the data type of that
+     *   restore data; or {@link RestoreDescription#NO_MORE_PACKAGES} to indicate that
+     *   no more packages can be restored in this session; or {@code null} to indicate
+     *   a transport-level error.
+     */
+    public RestoreDescription nextRestorePackage() {
+        return null;
+    }
+
+    /**
+     * Get the data for the application returned by {@link #nextRestorePackage}, if that
+     * method reported {@link RestoreDescription#TYPE_KEY_VALUE} as its delivery type.
+     * If the package has only TYPE_FULL_STREAM data, then this method will return an
+     * error.
+     *
+     * @param data An open, writable file into which the key/value backup data should be stored.
+     * @return the same error codes as {@link #startRestore}.
+     */
+    public int getRestoreData(ParcelFileDescriptor outFd) {
+        return BackupTransport.TRANSPORT_ERROR;
+    }
+
+    /**
+     * End a restore session (aborting any in-process data transfer as necessary),
+     * freeing any resources and connections used during the restore process.
+     */
+    public void finishRestore() {
+        throw new UnsupportedOperationException(
+                "Transport finishRestore() not implemented");
+    }
+
+    // ------------------------------------------------------------------------------------
+    // Full backup interfaces
+
+    /**
+     * Verify that this is a suitable time for a full-data backup pass.  This should return zero
+     * if a backup is reasonable right now, some positive value otherwise.  This method
+     * will be called outside of the {@link #performFullBackup}/{@link #finishBackup} pair.
+     *
+     * <p>If this is not a suitable time for a backup, the transport should return a
+     * backoff delay, in milliseconds, after which the Backup Manager should try again.
+     *
+     * @return Zero if this is a suitable time for a backup pass, or a positive time delay
+     *   in milliseconds to suggest deferring the backup pass for a while.
+     *
+     * @see #requestBackupTime()
+     */
+    public long requestFullBackupTime() {
+        return 0;
+    }
+
+    /**
+     * Begin the process of sending an application's full-data archive to the backend.
+     * The description of the package whose data will be delivered is provided, as well as
+     * the socket file descriptor on which the transport will receive the data itself.
+     *
+     * <p>If the package is not eligible for backup, the transport should return
+     * {@link BackupTransport#TRANSPORT_PACKAGE_REJECTED}.  In this case the system will
+     * simply proceed with the next candidate if any, or finish the full backup operation
+     * if all apps have been processed.
+     *
+     * <p>After the transport returns {@link BackupTransport#TRANSPORT_OK} from this
+     * method, the OS will proceed to call {@link #sendBackupData()} one or more times
+     * to deliver the application's data as a streamed tarball.  The transport should not
+     * read() from the socket except as instructed to via the {@link #sendBackupData(int)}
+     * method.
+     *
+     * <p>After all data has been delivered to the transport, the system will call
+     * {@link #finishBackup()}.  At this point the transport should commit the data to
+     * its datastore, if appropriate, and close the socket that had been provided in
+     * {@link #performFullBackup(PackageInfo, ParcelFileDescriptor)}.
+     *
+     * <p class="note">If the transport returns TRANSPORT_OK from this method, then the
+     * OS will always provide a matching call to {@link #finishBackup()} even if sending
+     * data via {@link #sendBackupData(int)} failed at some point.
+     *
+     * @param targetPackage The package whose data is to follow.
+     * @param socket The socket file descriptor through which the data will be provided.
+     *    If the transport returns {@link #TRANSPORT_PACKAGE_REJECTED} here, it must still
+     *    close this file descriptor now; otherwise it should be cached for use during
+     *    succeeding calls to {@link #sendBackupData(int)}, and closed in response to
+     *    {@link #finishBackup()}.
+     * @return TRANSPORT_PACKAGE_REJECTED to indicate that the stated application is not
+     *    to be backed up; TRANSPORT_OK to indicate that the OS may proceed with delivering
+     *    backup data; TRANSPORT_ERROR to indicate a fatal error condition that precludes
+     *    performing a backup at this time.
+     */
+    public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) {
+        return BackupTransport.TRANSPORT_PACKAGE_REJECTED;
+    }
+
+    /**
+     * Tells the transport to read {@code numBytes} bytes of data from the socket file
+     * descriptor provided in the {@link #performFullBackup(PackageInfo, ParcelFileDescriptor)}
+     * call, and deliver those bytes to the datastore.
+     *
+     * @param numBytes The number of bytes of tarball data available to be read from the
+     *    socket.
+     * @return TRANSPORT_OK on successful processing of the data; TRANSPORT_ERROR to
+     *    indicate a fatal error situation.  If an error is returned, the system will
+     *    call finishBackup() and stop attempting backups until after a backoff and retry
+     *    interval.
+     */
+    public int sendBackupData(int numBytes) {
+        return BackupTransport.TRANSPORT_ERROR;
+    }
+
+    /**
+     * Tells the transport to cancel the currently-ongoing full backup operation.  This
+     * will happen between {@link #performFullBackup()} and {@link #finishBackup()}
+     * if the OS needs to abort the backup operation for any reason, such as a crash in
+     * the application undergoing backup.
+     *
+     * <p>When it receives this call, the transport should discard any partial archive
+     * that it has stored so far.  If possible it should also roll back to the previous
+     * known-good archive in its datastore.
+     *
+     * <p>If the transport receives this callback, it will <em>not</em> receive a
+     * call to {@link #finishBackup()}.  It needs to tear down any ongoing backup state
+     * here.
+     */
+    public void cancelFullBackup() {
+        throw new UnsupportedOperationException(
+                "Transport cancelFullBackup() not implemented");
+    }
+
+    // ------------------------------------------------------------------------------------
+    // Full restore interfaces
+
+    /**
+     * Ask the transport to provide data for the "current" package being restored.  This
+     * is the package that was just reported by {@link #nextRestorePackage()} as having
+     * {@link RestoreDescription#TYPE_FULL_STREAM} data.
+     *
+     * The transport writes some data to the socket supplied to this call, and returns
+     * the number of bytes written.  The system will then read that many bytes and
+     * stream them to the application's agent for restore, then will call this method again
+     * to receive the next chunk of the archive.  This sequence will be repeated until the
+     * transport returns zero indicating that all of the package's data has been delivered
+     * (or returns a negative value indicating some sort of hard error condition at the
+     * transport level).
+     *
+     * <p>After this method returns zero, the system will then call
+     * {@link #getNextFullRestorePackage()} to begin the restore process for the next
+     * application, and the sequence begins again.
+     *
+     * <p>The transport should always close this socket when returning from this method.
+     * Do not cache this socket across multiple calls or you may leak file descriptors.
+     *
+     * @param socket The file descriptor that the transport will use for delivering the
+     *    streamed archive.  The transport must close this socket in all cases when returning
+     *    from this method.
+     * @return {@link #NO_MORE_DATA} when no more data for the current package is available.
+     *    A positive value indicates the presence of that many bytes to be delivered to the app.
+     *    A value of zero indicates that no data was deliverable at this time, but the restore
+     *    is still running and the caller should retry.  {@link #TRANSPORT_PACKAGE_REJECTED}
+     *    means that the current package's restore operation should be aborted, but that
+     *    the transport itself is still in a good state and so a multiple-package restore
+     *    sequence can still be continued.  Any other negative return value is treated as a
+     *    fatal error condition that aborts all further restore operations on the current dataset.
+     */
+    public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
+        return 0;
+    }
+
+    /**
+     * If the OS encounters an error while processing {@link RestoreDescription#TYPE_FULL_STREAM}
+     * data for restore, it will invoke this method to tell the transport that it should
+     * abandon the data download for the current package.  The OS will then either call
+     * {@link #nextRestorePackage()} again to move on to restoring the next package in the
+     * set being iterated over, or will call {@link #finishRestore()} to shut down the restore
+     * operation.
+     *
+     * @return {@link #TRANSPORT_OK} if the transport was successful in shutting down the
+     *    current stream cleanly, or {@link #TRANSPORT_ERROR} to indicate a serious
+     *    transport-level failure.  If the transport reports an error here, the entire restore
+     *    operation will immediately be finished with no further attempts to restore app data.
+     */
+    public int abortFullRestore() {
+        return BackupTransport.TRANSPORT_OK;
+    }
+
+    /**
+     * Bridge between the actual IBackupTransport implementation and the stable API.  If the
+     * binder interface needs to change, we use this layer to translate so that we can
+     * (if appropriate) decouple those framework-side changes from the BackupTransport
+     * implementations.
+     */
+    class TransportImpl extends IBackupTransport.Stub {
+
+        @Override
+        public String name() throws RemoteException {
+            return BackupTransport.this.name();
+        }
+
+        @Override
+        public Intent configurationIntent() throws RemoteException {
+            return BackupTransport.this.configurationIntent();
+        }
+
+        @Override
+        public String currentDestinationString() throws RemoteException {
+            return BackupTransport.this.currentDestinationString();
+        }
+
+        @Override
+        public Intent dataManagementIntent() {
+            return BackupTransport.this.dataManagementIntent();
+        }
+
+        @Override
+        public String dataManagementLabel() {
+            return BackupTransport.this.dataManagementLabel();
+        }
+
+        @Override
+        public String transportDirName() throws RemoteException {
+            return BackupTransport.this.transportDirName();
+        }
+
+        @Override
+        public long requestBackupTime() throws RemoteException {
+            return BackupTransport.this.requestBackupTime();
+        }
+
+        @Override
+        public int initializeDevice() throws RemoteException {
+            return BackupTransport.this.initializeDevice();
+        }
+
+        @Override
+        public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd)
+                throws RemoteException {
+            return BackupTransport.this.performBackup(packageInfo, inFd);
+        }
+
+        @Override
+        public int clearBackupData(PackageInfo packageInfo) throws RemoteException {
+            return BackupTransport.this.clearBackupData(packageInfo);
+        }
+
+        @Override
+        public int finishBackup() throws RemoteException {
+            return BackupTransport.this.finishBackup();
+        }
+
+        @Override
+        public RestoreSet[] getAvailableRestoreSets() throws RemoteException {
+            return BackupTransport.this.getAvailableRestoreSets();
+        }
+
+        @Override
+        public long getCurrentRestoreSet() throws RemoteException {
+            return BackupTransport.this.getCurrentRestoreSet();
+        }
+
+        @Override
+        public int startRestore(long token, PackageInfo[] packages) throws RemoteException {
+            return BackupTransport.this.startRestore(token, packages);
+        }
+
+        @Override
+        public RestoreDescription nextRestorePackage() throws RemoteException {
+            return BackupTransport.this.nextRestorePackage();
+        }
+
+        @Override
+        public int getRestoreData(ParcelFileDescriptor outFd) throws RemoteException {
+            return BackupTransport.this.getRestoreData(outFd);
+        }
+
+        @Override
+        public void finishRestore() throws RemoteException {
+            BackupTransport.this.finishRestore();
+        }
+
+        @Override
+        public long requestFullBackupTime() throws RemoteException {
+            return BackupTransport.this.requestFullBackupTime();
+        }
+
+        @Override
+        public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) throws RemoteException {
+            return BackupTransport.this.performFullBackup(targetPackage, socket);
+        }
+
+        @Override
+        public int sendBackupData(int numBytes) throws RemoteException {
+            return BackupTransport.this.sendBackupData(numBytes);
+        }
+
+        @Override
+        public void cancelFullBackup() throws RemoteException {
+            BackupTransport.this.cancelFullBackup();
+        }
+
+        @Override
+        public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
+            return BackupTransport.this.getNextFullRestoreDataChunk(socket);
+        }
+
+        @Override
+        public int abortFullRestore() {
+            return BackupTransport.this.abortFullRestore();
+        }
+    }
+}
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index 477285d..e5b47c6 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -16,9 +16,6 @@
 
 package android.app.backup;
 
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.os.ParcelFileDescriptor;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -43,6 +40,7 @@
     public static final String OBB_TREE_TOKEN = "obb";
     public static final String ROOT_TREE_TOKEN = "r";
     public static final String DATA_TREE_TOKEN = "f";
+    public static final String NO_BACKUP_TREE_TOKEN = "nb";
     public static final String DATABASE_TREE_TOKEN = "db";
     public static final String SHAREDPREFS_TREE_TOKEN = "sp";
     public static final String MANAGED_EXTERNAL_TREE_TOKEN = "ef";
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index 12ee3b6..8a44c8e 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -167,8 +167,16 @@
      *     are to be backed up.  The <code>allApps</code> parameter supersedes this.
      */
     void fullBackup(in ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
-            boolean includeShared, boolean allApps, boolean allIncludesSystem,
-            in String[] packageNames);
+            boolean includeShared, boolean doWidgets, boolean allApps, boolean allIncludesSystem,
+            boolean doCompress, in String[] packageNames);
+
+    /**
+     * Perform a full-dataset backup of the given applications via the currently active
+     * transport.
+     *
+     * @param packageNames The package names of the apps whose data are to be backed up.
+     */
+    void fullTransportBackup(in String[] packageNames);
 
     /**
      * Restore device content from the data stream passed through the given socket.  The
@@ -242,6 +250,18 @@
     String getDestinationString(String transport);
 
     /**
+     * Get the manage-data UI intent, if any, from the given transport.  Callers must
+     * hold the android.permission.BACKUP permission in order to use this method.
+     */
+    Intent getDataManagementIntent(String transport);
+
+    /**
+     * Get the manage-data menu label, if any, from the given transport.  Callers must
+     * hold the android.permission.BACKUP permission in order to use this method.
+     */
+    String getDataManagementLabel(String transport);
+
+    /**
      * Begin a restore session.  Either or both of packageName and transportID
      * may be null.  If packageName is non-null, then only the given package will be
      * considered for restore.  If transportID is null, then the restore will use
diff --git a/core/java/android/app/backup/RestoreDescription.aidl b/core/java/android/app/backup/RestoreDescription.aidl
new file mode 100644
index 0000000..9cbea78
--- /dev/null
+++ b/core/java/android/app/backup/RestoreDescription.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.backup;
+
+parcelable RestoreDescription;
diff --git a/core/java/android/app/backup/RestoreDescription.java b/core/java/android/app/backup/RestoreDescription.java
new file mode 100644
index 0000000..611ff07
--- /dev/null
+++ b/core/java/android/app/backup/RestoreDescription.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.backup;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Description of the available restore data for a given package.  Returned by a
+ * BackupTransport in response to a request about the next available restorable
+ * package.
+ *
+ * @see BackupTransport#nextRestorePackage()
+ *
+ * @hide
+ */
+@SystemApi
+public class RestoreDescription implements Parcelable {
+    private final String mPackageName;
+    private final int mDataType;
+
+    private static final String NO_MORE_PACKAGES_SENTINEL = "";
+
+    /**
+     * Return this constant RestoreDescription from BackupTransport.nextRestorePackage()
+     * to indicate that no more package data is available in the current restore operation.
+     */
+    public static final RestoreDescription NO_MORE_PACKAGES =
+            new RestoreDescription(NO_MORE_PACKAGES_SENTINEL, 0);
+
+    // ---------------------------------------
+    // Data type identifiers
+
+    /** This package's restore data is an original-style key/value dataset */
+    public static final int TYPE_KEY_VALUE = 1;
+
+    /** This package's restore data is a tarball-type full data stream */
+    public static final int TYPE_FULL_STREAM = 2;
+
+    @Override
+    public String toString() {
+        return "RestoreDescription{" + mPackageName + " : "
+                + ((mDataType == TYPE_KEY_VALUE) ? "KEY_VALUE" : "STREAM")
+                + '}';
+    }
+
+    // ---------------------------------------
+    // API
+
+    public RestoreDescription(String packageName, int dataType) {
+        mPackageName = packageName;
+        mDataType = dataType;
+    }
+
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    public int getDataType() {
+        return mDataType;
+    }
+
+    // ---------------------------------------
+    // Parcelable implementation - not used by transport
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mPackageName);
+        out.writeInt(mDataType);
+    }
+
+    public static final Parcelable.Creator<RestoreDescription> CREATOR
+            = new Parcelable.Creator<RestoreDescription>() {
+        public RestoreDescription createFromParcel(Parcel in) {
+            final RestoreDescription unparceled = new RestoreDescription(in);
+            return (NO_MORE_PACKAGES_SENTINEL.equals(unparceled.mPackageName))
+                    ? NO_MORE_PACKAGES
+                    : unparceled;
+        }
+
+        public RestoreDescription[] newArray(int size) {
+            return new RestoreDescription[size];
+        }
+    };
+
+    private RestoreDescription(Parcel in) {
+        mPackageName = in.readString();
+        mDataType = in.readInt();
+    }
+}
diff --git a/core/java/android/app/backup/RestoreObserver.java b/core/java/android/app/backup/RestoreObserver.java
index dbddb78..b4a23d0 100644
--- a/core/java/android/app/backup/RestoreObserver.java
+++ b/core/java/android/app/backup/RestoreObserver.java
@@ -17,6 +17,8 @@
 package android.app.backup;
 
 import java.lang.String;
+
+import android.annotation.SystemApi;
 import android.app.backup.RestoreSet;
 
 /**
@@ -36,6 +38,7 @@
      *
      * @hide
      */
+    @SystemApi
     public void restoreSetsAvailable(RestoreSet[] result) {
     }
 
diff --git a/core/java/android/app/backup/RestoreSession.java b/core/java/android/app/backup/RestoreSession.java
index 7181c61..0a885b6 100644
--- a/core/java/android/app/backup/RestoreSession.java
+++ b/core/java/android/app/backup/RestoreSession.java
@@ -16,6 +16,7 @@
 
 package android.app.backup;
 
+import android.annotation.SystemApi;
 import android.app.backup.RestoreObserver;
 import android.app.backup.RestoreSet;
 import android.app.backup.IRestoreObserver;
@@ -30,6 +31,7 @@
  * Interface for managing a restore session.
  * @hide
  */
+@SystemApi
 public class RestoreSession {
     static final String TAG = "RestoreSession";
 
diff --git a/core/java/android/app/backup/RestoreSet.java b/core/java/android/app/backup/RestoreSet.java
index 0431977..aacaf7c 100644
--- a/core/java/android/app/backup/RestoreSet.java
+++ b/core/java/android/app/backup/RestoreSet.java
@@ -16,6 +16,7 @@
 
 package android.app.backup;
 
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -25,6 +26,7 @@
  *
  * @hide
  */
+@SystemApi
 public class RestoreSet implements Parcelable {
     /**
      * Name of this restore set.  May be user generated, may simply be the name
diff --git a/core/java/android/app/backup/SharedPreferencesBackupHelper.java b/core/java/android/app/backup/SharedPreferencesBackupHelper.java
index 213bd31..939616b 100644
--- a/core/java/android/app/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/app/backup/SharedPreferencesBackupHelper.java
@@ -18,7 +18,6 @@
 
 import android.app.QueuedWork;
 import android.content.Context;
-import android.content.SharedPreferences;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
index 9e8ab2c..b8575d7 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -80,17 +80,17 @@
         mFiles = files;
         mKeys = keys;
 
-        WallpaperManager wpm;
-        wpm = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
-        mDesiredMinWidth = (double) wpm.getDesiredMinimumWidth();
+        final WindowManager wm =
+                (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        final WallpaperManager wpm =
+                (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
+        final Display d = wm.getDefaultDisplay();
+        final Point size = new Point();
+        d.getSize(size);
+        mDesiredMinWidth = size.x;
         mDesiredMinHeight = (double) wpm.getDesiredMinimumHeight();
 
-        if (mDesiredMinWidth <= 0 || mDesiredMinHeight <= 0) {
-            WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-            Display d = wm.getDefaultDisplay();
-            Point size = new Point();
-            d.getSize(size);
-            mDesiredMinWidth = size.x;
+        if (mDesiredMinHeight <= 0) {
             mDesiredMinHeight = size.y;
         }
 
@@ -130,25 +130,25 @@
                     if (DEBUG) Slog.d(TAG, "Restoring wallpaper image w=" + options.outWidth
                             + " h=" + options.outHeight);
 
-                    // How much does the image differ from our preference?  The threshold
-                    // here is set to accept any image larger than our target, because
-                    // scaling down is acceptable; but to reject images that are deemed
-                    // "too small" to scale up attractively.  The value 1.33 is just barely
-                    // too low to pass Nexus 1 or Droid wallpapers for use on a Xoom, but
-                    // will pass anything relatively larger.
-                    double widthRatio = mDesiredMinWidth / options.outWidth;
-                    double heightRatio = mDesiredMinHeight / options.outHeight;
-                    if (widthRatio > 0 && widthRatio < 1.33
+                    // We accept any wallpaper that is at least as wide as our preference
+                    // (i.e. wide enough to fill the screen), and is within a comfortable
+                    // factor of the target height, to avoid significant clipping/scaling/
+                    // letterboxing.
+                    final double heightRatio = mDesiredMinHeight / options.outHeight;
+                    if (options.outWidth >= mDesiredMinWidth
                             && heightRatio > 0 && heightRatio < 1.33) {
                         // sufficiently close to our resolution; go ahead and use it
-                        if (DEBUG) Slog.d(TAG, "wallpaper dimension match; using");
+                        Slog.d(TAG, "Applying restored wallpaper image.");
                         f.renameTo(new File(WALLPAPER_IMAGE));
                         // TODO: spin a service to copy the restored image to sd/usb storage,
                         // since it does not exist anywhere other than the private wallpaper
                         // file.
                     } else {
-                        if (DEBUG) Slog.d(TAG, "dimensions too far off: wr=" + widthRatio
-                                + " hr=" + heightRatio);
+                        Slog.i(TAG, "Restored image dimensions (w="
+                                + options.outWidth + ", h=" + options.outHeight
+                                + ") too far off target (tw="
+                                + mDesiredMinWidth + ", th=" + mDesiredMinHeight
+                                + "); falling back to default wallpaper.");
                         f.delete();
                     }
                 }
diff --git a/core/java/android/app/job/IJobCallback.aidl b/core/java/android/app/job/IJobCallback.aidl
new file mode 100644
index 0000000..2d3948f
--- /dev/null
+++ b/core/java/android/app/job/IJobCallback.aidl
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.job;
+
+/**
+ * The server side of the JobScheduler IPC protocols.  The app-side implementation
+ * invokes on this interface to indicate completion of the (asynchronous) instructions
+ * issued by the server.
+ *
+ * In all cases, the 'who' parameter is the caller's service binder, used to track
+ * which Job Service instance is reporting.
+ *
+ * {@hide}
+ */
+interface IJobCallback {
+    /**
+     * Immediate callback to the system after sending a start signal, used to quickly detect ANR.
+     *
+     * @param jobId Unique integer used to identify this job.
+     * @param ongoing True to indicate that the client is processing the job. False if the job is
+     * complete
+     */
+    void acknowledgeStartMessage(int jobId, boolean ongoing);
+    /**
+     * Immediate callback to the system after sending a stop signal, used to quickly detect ANR.
+     *
+     * @param jobId Unique integer used to identify this job.
+     * @param reschedule Whether or not to reschedule this job.
+     */
+    void acknowledgeStopMessage(int jobId, boolean reschedule);
+    /*
+     * Tell the job manager that the client is done with its execution, so that it can go on to
+     * the next one and stop attributing wakelock time to us etc.
+     *
+     * @param jobId Unique integer used to identify this job.
+     * @param reschedule Whether or not to reschedule this job.
+     */
+    void jobFinished(int jobId, boolean reschedule);
+}
diff --git a/core/java/android/app/job/IJobScheduler.aidl b/core/java/android/app/job/IJobScheduler.aidl
new file mode 100644
index 0000000..f1258ae
--- /dev/null
+++ b/core/java/android/app/job/IJobScheduler.aidl
@@ -0,0 +1,30 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.job;
+
+import android.app.job.JobInfo;
+
+ /**
+  * IPC interface that supports the app-facing {@link #JobScheduler} api.
+  * {@hide}
+  */
+interface IJobScheduler {
+    int schedule(in JobInfo job);
+    void cancel(int jobId);
+    void cancelAll();
+    List<JobInfo> getAllPendingJobs();
+}
diff --git a/core/java/android/app/job/IJobService.aidl b/core/java/android/app/job/IJobService.aidl
new file mode 100644
index 0000000..7f55d29
--- /dev/null
+++ b/core/java/android/app/job/IJobService.aidl
@@ -0,0 +1,32 @@
+/**
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.job;
+
+import android.app.job.JobParameters;
+
+/**
+ * Interface that the framework uses to communicate with application code that implements a
+ * JobService.  End user code does not implement this interface directly; instead, the app's
+ * service implementation will extend android.app.job.JobService.
+ * {@hide}
+ */
+oneway interface IJobService {
+    /** Begin execution of application's job. */
+    void startJob(in JobParameters jobParams);
+    /** Stop execution of application's job. */
+    void stopJob(in JobParameters jobParams);
+}
diff --git a/core/java/android/app/job/JobInfo.aidl b/core/java/android/app/job/JobInfo.aidl
new file mode 100644
index 0000000..7b198a8
--- /dev/null
+++ b/core/java/android/app/job/JobInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.job;
+
+parcelable JobInfo;
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
new file mode 100644
index 0000000..0d9e778
--- /dev/null
+++ b/core/java/android/app/job/JobInfo.java
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.job;
+
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.PersistableBundle;
+
+/**
+ * Container of data passed to the {@link android.app.job.JobScheduler} fully encapsulating the
+ * parameters required to schedule work against the calling application. These are constructed
+ * using the {@link JobInfo.Builder}.
+ * You must specify at least one sort of constraint on the JobInfo object that you are creating.
+ * The goal here is to provide the scheduler with high-level semantics about the work you want to
+ * accomplish. Doing otherwise with throw an exception in your app.
+ */
+public class JobInfo implements Parcelable {
+    /** Default. */
+    public static final int NETWORK_TYPE_NONE = 0;
+    /** This job requires network connectivity. */
+    public static final int NETWORK_TYPE_ANY = 1;
+    /** This job requires network connectivity that is unmetered. */
+    public static final int NETWORK_TYPE_UNMETERED = 2;
+
+    /**
+     * Amount of backoff a job has initially by default, in milliseconds.
+     */
+    public static final long DEFAULT_INITIAL_BACKOFF_MILLIS = 30000L;  // 30 seconds.
+
+    /**
+     * Maximum backoff we allow for a job, in milliseconds.
+     */
+    public static final long MAX_BACKOFF_DELAY_MILLIS = 5 * 60 * 60 * 1000;  // 5 hours.
+
+    /**
+     * Linearly back-off a failed job. See
+     * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}
+     * retry_time(current_time, num_failures) =
+     *     current_time + initial_backoff_millis * num_failures, num_failures >= 1
+     */
+    public static final int BACKOFF_POLICY_LINEAR = 0;
+
+    /**
+     * Exponentially back-off a failed job. See
+     * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}
+     *
+     * retry_time(current_time, num_failures) =
+     *     current_time + initial_backoff_millis * 2 ^ (num_failures - 1), num_failures >= 1
+     */
+    public static final int BACKOFF_POLICY_EXPONENTIAL = 1;
+
+    /**
+     * Default type of backoff.
+     * @hide
+     */
+    public static final int DEFAULT_BACKOFF_POLICY = BACKOFF_POLICY_EXPONENTIAL;
+
+    private final int jobId;
+    private final PersistableBundle extras;
+    private final ComponentName service;
+    private final boolean requireCharging;
+    private final boolean requireDeviceIdle;
+    private final boolean hasEarlyConstraint;
+    private final boolean hasLateConstraint;
+    private final int networkType;
+    private final long minLatencyMillis;
+    private final long maxExecutionDelayMillis;
+    private final boolean isPeriodic;
+    private final boolean isPersisted;
+    private final long intervalMillis;
+    private final long initialBackoffMillis;
+    private final int backoffPolicy;
+
+    /**
+     * Unique job id associated with this class. This is assigned to your job by the scheduler.
+     */
+    public int getId() {
+        return jobId;
+    }
+
+    /**
+     * Bundle of extras which are returned to your application at execution time.
+     */
+    public PersistableBundle getExtras() {
+        return extras;
+    }
+
+    /**
+     * Name of the service endpoint that will be called back into by the JobScheduler.
+     */
+    public ComponentName getService() {
+        return service;
+    }
+
+    /**
+     * Whether this job needs the device to be plugged in.
+     */
+    public boolean isRequireCharging() {
+        return requireCharging;
+    }
+
+    /**
+     * Whether this job needs the device to be in an Idle maintenance window.
+     */
+    public boolean isRequireDeviceIdle() {
+        return requireDeviceIdle;
+    }
+
+    /**
+     * One of {@link android.app.job.JobInfo#NETWORK_TYPE_ANY},
+     * {@link android.app.job.JobInfo#NETWORK_TYPE_NONE}, or
+     * {@link android.app.job.JobInfo#NETWORK_TYPE_UNMETERED}.
+     */
+    public int getNetworkType() {
+        return networkType;
+    }
+
+    /**
+     * Set for a job that does not recur periodically, to specify a delay after which the job
+     * will be eligible for execution. This value is not set if the job recurs periodically.
+     */
+    public long getMinLatencyMillis() {
+        return minLatencyMillis;
+    }
+
+    /**
+     * See {@link Builder#setOverrideDeadline(long)}. This value is not set if the job recurs
+     * periodically.
+     */
+    public long getMaxExecutionDelayMillis() {
+        return maxExecutionDelayMillis;
+    }
+
+    /**
+     * Track whether this job will repeat with a given period.
+     */
+    public boolean isPeriodic() {
+        return isPeriodic;
+    }
+
+    /**
+     * @return Whether or not this job should be persisted across device reboots.
+     */
+    public boolean isPersisted() {
+        return isPersisted;
+    }
+
+    /**
+     * Set to the interval between occurrences of this job. This value is <b>not</b> set if the
+     * job does not recur periodically.
+     */
+    public long getIntervalMillis() {
+        return intervalMillis;
+    }
+
+    /**
+     * The amount of time the JobScheduler will wait before rescheduling a failed job. This value
+     * will be increased depending on the backoff policy specified at job creation time. Defaults
+     * to 5 seconds.
+     */
+    public long getInitialBackoffMillis() {
+        return initialBackoffMillis;
+    }
+
+    /**
+     * One of either {@link android.app.job.JobInfo#BACKOFF_POLICY_EXPONENTIAL}, or
+     * {@link android.app.job.JobInfo#BACKOFF_POLICY_LINEAR}, depending on which criteria you set
+     * when creating this job.
+     */
+    public int getBackoffPolicy() {
+        return backoffPolicy;
+    }
+
+    /**
+     * User can specify an early constraint of 0L, which is valid, so we keep track of whether the
+     * function was called at all.
+     * @hide
+     */
+    public boolean hasEarlyConstraint() {
+        return hasEarlyConstraint;
+    }
+
+    /**
+     * User can specify a late constraint of 0L, which is valid, so we keep track of whether the
+     * function was called at all.
+     * @hide
+     */
+    public boolean hasLateConstraint() {
+        return hasLateConstraint;
+    }
+
+    private JobInfo(Parcel in) {
+        jobId = in.readInt();
+        extras = in.readPersistableBundle();
+        service = in.readParcelable(null);
+        requireCharging = in.readInt() == 1;
+        requireDeviceIdle = in.readInt() == 1;
+        networkType = in.readInt();
+        minLatencyMillis = in.readLong();
+        maxExecutionDelayMillis = in.readLong();
+        isPeriodic = in.readInt() == 1;
+        isPersisted = in.readInt() == 1;
+        intervalMillis = in.readLong();
+        initialBackoffMillis = in.readLong();
+        backoffPolicy = in.readInt();
+        hasEarlyConstraint = in.readInt() == 1;
+        hasLateConstraint = in.readInt() == 1;
+    }
+
+    private JobInfo(JobInfo.Builder b) {
+        jobId = b.mJobId;
+        extras = b.mExtras;
+        service = b.mJobService;
+        requireCharging = b.mRequiresCharging;
+        requireDeviceIdle = b.mRequiresDeviceIdle;
+        networkType = b.mNetworkType;
+        minLatencyMillis = b.mMinLatencyMillis;
+        maxExecutionDelayMillis = b.mMaxExecutionDelayMillis;
+        isPeriodic = b.mIsPeriodic;
+        isPersisted = b.mIsPersisted;
+        intervalMillis = b.mIntervalMillis;
+        initialBackoffMillis = b.mInitialBackoffMillis;
+        backoffPolicy = b.mBackoffPolicy;
+        hasEarlyConstraint = b.mHasEarlyConstraint;
+        hasLateConstraint = b.mHasLateConstraint;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(jobId);
+        out.writePersistableBundle(extras);
+        out.writeParcelable(service, flags);
+        out.writeInt(requireCharging ? 1 : 0);
+        out.writeInt(requireDeviceIdle ? 1 : 0);
+        out.writeInt(networkType);
+        out.writeLong(minLatencyMillis);
+        out.writeLong(maxExecutionDelayMillis);
+        out.writeInt(isPeriodic ? 1 : 0);
+        out.writeInt(isPersisted ? 1 : 0);
+        out.writeLong(intervalMillis);
+        out.writeLong(initialBackoffMillis);
+        out.writeInt(backoffPolicy);
+        out.writeInt(hasEarlyConstraint ? 1 : 0);
+        out.writeInt(hasLateConstraint ? 1 : 0);
+    }
+
+    public static final Creator<JobInfo> CREATOR = new Creator<JobInfo>() {
+        @Override
+        public JobInfo createFromParcel(Parcel in) {
+            return new JobInfo(in);
+        }
+
+        @Override
+        public JobInfo[] newArray(int size) {
+            return new JobInfo[size];
+        }
+    };
+
+    @Override
+    public String toString() {
+        return "(job:" + jobId + "/" + service.flattenToShortString() + ")";
+    }
+
+    /** Builder class for constructing {@link JobInfo} objects. */
+    public static final class Builder {
+        private int mJobId;
+        private PersistableBundle mExtras = PersistableBundle.EMPTY;
+        private ComponentName mJobService;
+        // Requirements.
+        private boolean mRequiresCharging;
+        private boolean mRequiresDeviceIdle;
+        private int mNetworkType;
+        private boolean mIsPersisted;
+        // One-off parameters.
+        private long mMinLatencyMillis;
+        private long mMaxExecutionDelayMillis;
+        // Periodic parameters.
+        private boolean mIsPeriodic;
+        private boolean mHasEarlyConstraint;
+        private boolean mHasLateConstraint;
+        private long mIntervalMillis;
+        // Back-off parameters.
+        private long mInitialBackoffMillis = DEFAULT_INITIAL_BACKOFF_MILLIS;
+        private int mBackoffPolicy = DEFAULT_BACKOFF_POLICY;
+        /** Easy way to track whether the client has tried to set a back-off policy. */
+        private boolean mBackoffPolicySet = false;
+
+        /**
+         * @param jobId Application-provided id for this job. Subsequent calls to cancel, or
+         *               jobs created with the same jobId, will update the pre-existing job with
+         *               the same id.
+         * @param jobService The endpoint that you implement that will receive the callback from the
+         *            JobScheduler.
+         */
+        public Builder(int jobId, ComponentName jobService) {
+            mJobService = jobService;
+            mJobId = jobId;
+        }
+
+        /**
+         * Set optional extras. This is persisted, so we only allow primitive types.
+         * @param extras Bundle containing extras you want the scheduler to hold on to for you.
+         */
+        public Builder setExtras(PersistableBundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Set some description of the kind of network type your job needs to have.
+         * Not calling this function means the network is not necessary, as the default is
+         * {@link #NETWORK_TYPE_NONE}.
+         * Bear in mind that calling this function defines network as a strict requirement for your
+         * job. If the network requested is not available your job will never run. See
+         * {@link #setOverrideDeadline(long)} to change this behaviour.
+         */
+        public Builder setRequiredNetworkType(int networkType) {
+            mNetworkType = networkType;
+            return this;
+        }
+
+        /**
+         * Specify that to run this job, the device needs to be plugged in. This defaults to
+         * false.
+         * @param requiresCharging Whether or not the device is plugged in.
+         */
+        public Builder setRequiresCharging(boolean requiresCharging) {
+            mRequiresCharging = requiresCharging;
+            return this;
+        }
+
+        /**
+         * Specify that to run, the job needs the device to be in idle mode. This defaults to
+         * false.
+         * <p>Idle mode is a loose definition provided by the system, which means that the device
+         * is not in use, and has not been in use for some time. As such, it is a good time to
+         * perform resource heavy jobs. Bear in mind that battery usage will still be attributed
+         * to your application, and surfaced to the user in battery stats.</p>
+         * @param requiresDeviceIdle Whether or not the device need be within an idle maintenance
+         *                           window.
+         */
+        public Builder setRequiresDeviceIdle(boolean requiresDeviceIdle) {
+            mRequiresDeviceIdle = requiresDeviceIdle;
+            return this;
+        }
+
+        /**
+         * Specify that this job should recur with the provided interval, not more than once per
+         * period. You have no control over when within this interval this job will be executed,
+         * only the guarantee that it will be executed at most once within this interval.
+         * Setting this function on the builder with {@link #setMinimumLatency(long)} or
+         * {@link #setOverrideDeadline(long)} will result in an error.
+         * @param intervalMillis Millisecond interval for which this job will repeat.
+         */
+        public Builder setPeriodic(long intervalMillis) {
+            mIsPeriodic = true;
+            mIntervalMillis = intervalMillis;
+            mHasEarlyConstraint = mHasLateConstraint = true;
+            return this;
+        }
+
+        /**
+         * Specify that this job should be delayed by the provided amount of time.
+         * Because it doesn't make sense setting this property on a periodic job, doing so will
+         * throw an {@link java.lang.IllegalArgumentException} when
+         * {@link android.app.job.JobInfo.Builder#build()} is called.
+         * @param minLatencyMillis Milliseconds before which this job will not be considered for
+         *                         execution.
+         */
+        public Builder setMinimumLatency(long minLatencyMillis) {
+            mMinLatencyMillis = minLatencyMillis;
+            mHasEarlyConstraint = true;
+            return this;
+        }
+
+        /**
+         * Set deadline which is the maximum scheduling latency. The job will be run by this
+         * deadline even if other requirements are not met. Because it doesn't make sense setting
+         * this property on a periodic job, doing so will throw an
+         * {@link java.lang.IllegalArgumentException} when
+         * {@link android.app.job.JobInfo.Builder#build()} is called.
+         */
+        public Builder setOverrideDeadline(long maxExecutionDelayMillis) {
+            mMaxExecutionDelayMillis = maxExecutionDelayMillis;
+            mHasLateConstraint = true;
+            return this;
+        }
+
+        /**
+         * Set up the back-off/retry policy.
+         * This defaults to some respectable values: {30 seconds, Exponential}. We cap back-off at
+         * 5hrs.
+         * Note that trying to set a backoff criteria for a job with
+         * {@link #setRequiresDeviceIdle(boolean)} will throw an exception when you call build().
+         * This is because back-off typically does not make sense for these types of jobs. See
+         * {@link android.app.job.JobService#jobFinished(android.app.job.JobParameters, boolean)}
+         * for more description of the return value for the case of a job executing while in idle
+         * mode.
+         * @param initialBackoffMillis Millisecond time interval to wait initially when job has
+         *                             failed.
+         * @param backoffPolicy is one of {@link #BACKOFF_POLICY_LINEAR} or
+         * {@link #BACKOFF_POLICY_EXPONENTIAL}
+         */
+        public Builder setBackoffCriteria(long initialBackoffMillis, int backoffPolicy) {
+            mBackoffPolicySet = true;
+            mInitialBackoffMillis = initialBackoffMillis;
+            mBackoffPolicy = backoffPolicy;
+            return this;
+        }
+
+        /**
+         * Set whether or not to persist this job across device reboots. This will only have an
+         * effect if your application holds the permission
+         * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED}. Otherwise an exception will
+         * be thrown.
+         * @param isPersisted True to indicate that the job will be written to disk and loaded at
+         *                    boot.
+         */
+        public Builder setPersisted(boolean isPersisted) {
+            mIsPersisted = isPersisted;
+            return this;
+        }
+
+        /**
+         * @return The job object to hand to the JobScheduler. This object is immutable.
+         */
+        public JobInfo build() {
+            // Allow jobs with no constraints - What am I, a database?
+            if (!mHasEarlyConstraint && !mHasLateConstraint && !mRequiresCharging &&
+                    !mRequiresDeviceIdle && mNetworkType == NETWORK_TYPE_NONE) {
+                throw new IllegalArgumentException("You're trying to build a job with no " +
+                        "constraints, this is not allowed.");
+            }
+            mExtras = new PersistableBundle(mExtras);  // Make our own copy.
+            // Check that a deadline was not set on a periodic job.
+            if (mIsPeriodic && (mMaxExecutionDelayMillis != 0L)) {
+                throw new IllegalArgumentException("Can't call setOverrideDeadline() on a " +
+                        "periodic job.");
+            }
+            if (mIsPeriodic && (mMinLatencyMillis != 0L)) {
+                throw new IllegalArgumentException("Can't call setMinimumLatency() on a " +
+                        "periodic job");
+            }
+            if (mBackoffPolicySet && mRequiresDeviceIdle) {
+                throw new IllegalArgumentException("An idle mode job will not respect any" +
+                        " back-off policy, so calling setBackoffCriteria with" +
+                        " setRequiresDeviceIdle is an error.");
+            }
+            return new JobInfo(this);
+        }
+    }
+
+}
diff --git a/core/java/android/app/job/JobParameters.aidl b/core/java/android/app/job/JobParameters.aidl
new file mode 100644
index 0000000..e7551b9
--- /dev/null
+++ b/core/java/android/app/job/JobParameters.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.job;
+
+parcelable JobParameters;
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
new file mode 100644
index 0000000..62734f2
--- /dev/null
+++ b/core/java/android/app/job/JobParameters.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.job;
+
+import android.app.job.IJobCallback;
+import android.app.job.IJobCallback.Stub;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.PersistableBundle;
+
+/**
+ * Contains the parameters used to configure/identify your job. You do not create this object
+ * yourself, instead it is handed in to your application by the System.
+ */
+public class JobParameters implements Parcelable {
+
+    private final int jobId;
+    private final PersistableBundle extras;
+    private final IBinder callback;
+    private final boolean overrideDeadlineExpired;
+
+    /** @hide */
+    public JobParameters(IBinder callback, int jobId, PersistableBundle extras,
+                         boolean overrideDeadlineExpired) {
+        this.jobId = jobId;
+        this.extras = extras;
+        this.callback = callback;
+        this.overrideDeadlineExpired = overrideDeadlineExpired;
+    }
+
+    /**
+     * @return The unique id of this job, specified at creation time.
+     */
+    public int getJobId() {
+        return jobId;
+    }
+
+    /**
+     * @return The extras you passed in when constructing this job with
+     * {@link android.app.job.JobInfo.Builder#setExtras(android.os.PersistableBundle)}. This will
+     * never be null. If you did not set any extras this will be an empty bundle.
+     */
+    public PersistableBundle getExtras() {
+        return extras;
+    }
+
+    /**
+     * For jobs with {@link android.app.job.JobInfo.Builder#setOverrideDeadline(long)} set, this
+     * provides an easy way to tell whether the job is being executed due to the deadline
+     * expiring. Note: If the job is running because its deadline expired, it implies that its
+     * constraints will not be met.
+     */
+    public boolean isOverrideDeadlineExpired() {
+        return overrideDeadlineExpired;
+    }
+
+    /** @hide */
+    public IJobCallback getCallback() {
+        return IJobCallback.Stub.asInterface(callback);
+    }
+
+    private JobParameters(Parcel in) {
+        jobId = in.readInt();
+        extras = in.readPersistableBundle();
+        callback = in.readStrongBinder();
+        overrideDeadlineExpired = in.readInt() == 1;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(jobId);
+        dest.writePersistableBundle(extras);
+        dest.writeStrongBinder(callback);
+        dest.writeInt(overrideDeadlineExpired ? 1 : 0);
+    }
+
+    public static final Creator<JobParameters> CREATOR = new Creator<JobParameters>() {
+        @Override
+        public JobParameters createFromParcel(Parcel in) {
+            return new JobParameters(in);
+        }
+
+        @Override
+        public JobParameters[] newArray(int size) {
+            return new JobParameters[size];
+        }
+    };
+}
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
new file mode 100644
index 0000000..89efeb2
--- /dev/null
+++ b/core/java/android/app/job/JobScheduler.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.job;
+
+import java.util.List;
+
+import android.content.Context;
+
+/**
+ * This is an API for scheduling various types of jobs against the framework that will be executed
+ * in your application's own process.
+ * <p>
+ * See {@link android.app.job.JobInfo} for more description of the types of jobs that can be run
+ * and how to construct them. You will construct these JobInfo objects and pass them to the
+ * JobScheduler with {@link #schedule(JobInfo)}. When the criteria declared are met, the
+ * system will execute this job on your application's {@link android.app.job.JobService}.
+ * You identify which JobService is meant to execute the logic for your job when you create the
+ * JobInfo with
+ * {@link android.app.job.JobInfo.Builder#JobInfo.Builder(int,android.content.ComponentName)}.
+ * </p>
+ * <p>
+ * The framework will be intelligent about when you receive your callbacks, and attempt to batch
+ * and defer them as much as possible. Typically if you don't specify a deadline on your job, it
+ * can be run at any moment depending on the current state of the JobScheduler's internal queue,
+ * however it might be deferred as long as until the next time the device is connected to a power
+ * source.
+ * </p>
+ * <p>You do not
+ * instantiate this class directly; instead, retrieve it through
+ * {@link android.content.Context#getSystemService
+ * Context.getSystemService(Context.JOB_SCHEDULER_SERVICE)}.
+ */
+public abstract class JobScheduler {
+    /**
+     * Returned from {@link #schedule(JobInfo)} when an invalid parameter was supplied. This can occur
+     * if the run-time for your job is too short, or perhaps the system can't resolve the
+     * requisite {@link JobService} in your package.
+     */
+    public static final int RESULT_FAILURE = 0;
+    /**
+     * Returned from {@link #schedule(JobInfo)} if this application has made too many requests for
+     * work over too short a time.
+     */
+    // TODO: Determine if this is necessary.
+    public static final int RESULT_SUCCESS = 1;
+
+    /**
+     * @param job The job you wish scheduled. See
+     * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
+     * you can schedule.
+     * @return If >0, this int returns the jobId of the successfully scheduled job.
+     * Otherwise you have to compare the return value to the error codes defined in this class.
+     */
+    public abstract int schedule(JobInfo job);
+
+    /**
+     * Cancel a job that is pending in the JobScheduler.
+     * @param jobId unique identifier for this job. Obtain this value from the jobs returned by
+     * {@link #getAllPendingJobs()}.
+     * @return
+     */
+    public abstract void cancel(int jobId);
+
+    /**
+     * Cancel all jobs that have been registered with the JobScheduler by this package.
+     */
+    public abstract void cancelAll();
+
+    /**
+     * @return a list of all the jobs registered by this package that have not yet been executed.
+     */
+    public abstract List<JobInfo> getAllPendingJobs();
+
+}
diff --git a/core/java/android/app/job/JobService.java b/core/java/android/app/job/JobService.java
new file mode 100644
index 0000000..940a530
--- /dev/null
+++ b/core/java/android/app/job/JobService.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.job;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * <p>Entry point for the callback from the {@link android.app.job.JobScheduler}.</p>
+ * <p>This is the base class that handles asynchronous requests that were previously scheduled. You
+ * are responsible for overriding {@link JobService#onStartJob(JobParameters)}, which is where
+ * you will implement your job logic.</p>
+ * <p>This service executes each incoming job on a {@link android.os.Handler} running on your
+ * application's main thread. This means that you <b>must</b> offload your execution logic to
+ * another thread/handler/{@link android.os.AsyncTask} of your choosing. Not doing so will result
+ * in blocking any future callbacks from the JobManager - specifically
+ * {@link #onStopJob(android.app.job.JobParameters)}, which is meant to inform you that the
+ * scheduling requirements are no longer being met.</p>
+ */
+public abstract class JobService extends Service {
+    private static final String TAG = "JobService";
+
+    /**
+     * Job services must be protected with this permission:
+     *
+     * <pre class="prettyprint">
+     *     <service android:name="MyJobService"
+     *              android:permission="android.permission.BIND_JOB_SERVICE" >
+     *         ...
+     *     </service>
+     * </pre>
+     *
+     * <p>If a job service is declared in the manifest but not protected with this
+     * permission, that service will be ignored by the OS.
+     */
+    public static final String PERMISSION_BIND =
+            "android.permission.BIND_JOB_SERVICE";
+
+    /**
+     * Identifier for a message that will result in a call to
+     * {@link #onStartJob(android.app.job.JobParameters)}.
+     */
+    private final int MSG_EXECUTE_JOB = 0;
+    /**
+     * Message that will result in a call to {@link #onStopJob(android.app.job.JobParameters)}.
+     */
+    private final int MSG_STOP_JOB = 1;
+    /**
+     * Message that the client has completed execution of this job.
+     */
+    private final int MSG_JOB_FINISHED = 2;
+
+    /** Lock object for {@link #mHandler}. */
+    private final Object mHandlerLock = new Object();
+
+    /**
+     * Handler we post jobs to. Responsible for calling into the client logic, and handling the
+     * callback to the system.
+     */
+    @GuardedBy("mHandlerLock")
+    JobHandler mHandler;
+
+    /** Binder for this service. */
+    IJobService mBinder = new IJobService.Stub() {
+        @Override
+        public void startJob(JobParameters jobParams) {
+            ensureHandler();
+            Message m = Message.obtain(mHandler, MSG_EXECUTE_JOB, jobParams);
+            m.sendToTarget();
+        }
+        @Override
+        public void stopJob(JobParameters jobParams) {
+            ensureHandler();
+            Message m = Message.obtain(mHandler, MSG_STOP_JOB, jobParams);
+            m.sendToTarget();
+        }
+    };
+
+    /** @hide */
+    void ensureHandler() {
+        synchronized (mHandlerLock) {
+            if (mHandler == null) {
+                mHandler = new JobHandler(getMainLooper());
+            }
+        }
+    }
+
+    /**
+     * Runs on application's main thread - callbacks are meant to offboard work to some other
+     * (app-specified) mechanism.
+     * @hide
+     */
+    class JobHandler extends Handler {
+        JobHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            final JobParameters params = (JobParameters) msg.obj;
+            switch (msg.what) {
+                case MSG_EXECUTE_JOB:
+                    try {
+                        boolean workOngoing = JobService.this.onStartJob(params);
+                        ackStartMessage(params, workOngoing);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Error while executing job: " + params.getJobId());
+                        throw new RuntimeException(e);
+                    }
+                    break;
+                case MSG_STOP_JOB:
+                    try {
+                        boolean ret = JobService.this.onStopJob(params);
+                        ackStopMessage(params, ret);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Application unable to handle onStopJob.", e);
+                        throw new RuntimeException(e);
+                    }
+                    break;
+                case MSG_JOB_FINISHED:
+                    final boolean needsReschedule = (msg.arg2 == 1);
+                    IJobCallback callback = params.getCallback();
+                    if (callback != null) {
+                        try {
+                            callback.jobFinished(params.getJobId(), needsReschedule);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Error reporting job finish to system: binder has gone" +
+                                    "away.");
+                        }
+                    } else {
+                        Log.e(TAG, "finishJob() called for a nonexistent job id.");
+                    }
+                    break;
+                default:
+                    Log.e(TAG, "Unrecognised message received.");
+                    break;
+            }
+        }
+
+        private void ackStartMessage(JobParameters params, boolean workOngoing) {
+            final IJobCallback callback = params.getCallback();
+            final int jobId = params.getJobId();
+            if (callback != null) {
+                try {
+                     callback.acknowledgeStartMessage(jobId, workOngoing);
+                } catch(RemoteException e) {
+                    Log.e(TAG, "System unreachable for starting job.");
+                }
+            } else {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "Attempting to ack a job that has already been processed.");
+                }
+            }
+        }
+
+        private void ackStopMessage(JobParameters params, boolean reschedule) {
+            final IJobCallback callback = params.getCallback();
+            final int jobId = params.getJobId();
+            if (callback != null) {
+                try {
+                    callback.acknowledgeStopMessage(jobId, reschedule);
+                } catch(RemoteException e) {
+                    Log.e(TAG, "System unreachable for stopping job.");
+                }
+            } else {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "Attempting to ack a job that has already been processed.");
+                }
+            }
+        }
+    }
+
+    /** @hide */
+    public final IBinder onBind(Intent intent) {
+        return mBinder.asBinder();
+    }
+
+    /**
+     * Override this method with the callback logic for your job. Any such logic needs to be
+     * performed on a separate thread, as this function is executed on your application's main
+     * thread.
+     *
+     * @param params Parameters specifying info about this job, including the extras bundle you
+     *               optionally provided at job-creation time.
+     * @return True if your service needs to process the work (on a separate thread). False if
+     * there's no more work to be done for this job.
+     */
+    public abstract boolean onStartJob(JobParameters params);
+
+    /**
+     * This method is called if the system has determined that you must stop execution of your job
+     * even before you've had a chance to call {@link #jobFinished(JobParameters, boolean)}.
+     *
+     * <p>This will happen if the requirements specified at schedule time are no longer met. For
+     * example you may have requested WiFi with
+     * {@link android.app.job.JobInfo.Builder#setRequiredNetworkType(int)}, yet while your
+     * job was executing the user toggled WiFi. Another example is if you had specified
+     * {@link android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)}, and the phone left its
+     * idle maintenance window. You are solely responsible for the behaviour of your application
+     * upon receipt of this message; your app will likely start to misbehave if you ignore it. One
+     * immediate repercussion is that the system will cease holding a wakelock for you.</p>
+     *
+     * @param params Parameters specifying info about this job.
+     * @return True to indicate to the JobManager whether you'd like to reschedule this job based
+     * on the retry criteria provided at job creation-time. False to drop the job. Regardless of
+     * the value returned, your job must stop executing.
+     */
+    public abstract boolean onStopJob(JobParameters params);
+
+    /**
+     * Callback to inform the JobManager you've finished executing. This can be called from any
+     * thread, as it will ultimately be run on your application's main thread. When the system
+     * receives this message it will release the wakelock being held.
+     * <p>
+     *     You can specify post-execution behaviour to the scheduler here with
+     *     <code>needsReschedule </code>. This will apply a back-off timer to your job based on
+     *     the default, or what was set with
+     *     {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}. The original
+     *     requirements are always honoured even for a backed-off job. Note that a job running in
+     *     idle mode will not be backed-off. Instead what will happen is the job will be re-added
+     *     to the queue and re-executed within a future idle maintenance window.
+     * </p>
+     *
+     * @param params Parameters specifying system-provided info about this job, this was given to
+     *               your application in {@link #onStartJob(JobParameters)}.
+     * @param needsReschedule True if this job should be rescheduled according to the back-off
+     *                        criteria specified at schedule-time. False otherwise.
+     */
+    public final void jobFinished(JobParameters params, boolean needsReschedule) {
+        ensureHandler();
+        Message m = Message.obtain(mHandler, MSG_JOB_FINISHED, params);
+        m.arg2 = needsReschedule ? 1 : 0;
+        m.sendToTarget();
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/app/trust/ITrustListener.aidl b/core/java/android/app/trust/ITrustListener.aidl
new file mode 100644
index 0000000..d80f58c
--- /dev/null
+++ b/core/java/android/app/trust/ITrustListener.aidl
@@ -0,0 +1,27 @@
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+package android.app.trust;
+
+/**
+ * Private API to be notified about trust changes.
+ *
+ * {@hide}
+ */
+oneway interface ITrustListener {
+    void onTrustChanged(boolean enabled, int userId, boolean initiatedByUser);
+    void onTrustManagedChanged(boolean managed, int userId);
+}
\ No newline at end of file
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
new file mode 100644
index 0000000..6fbf87d
--- /dev/null
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -0,0 +1,32 @@
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+package android.app.trust;
+
+import android.app.trust.ITrustListener;
+
+/**
+ * System private API to comunicate with trust service.
+ *
+ * {@hide}
+ */
+interface ITrustManager {
+    void reportUnlockAttempt(boolean successful, int userId);
+    void reportEnabledTrustAgentsChanged(int userId);
+    void reportRequireCredentialEntry(int userId);
+    void registerTrustListener(in ITrustListener trustListener);
+    void unregisterTrustListener(in ITrustListener trustListener);
+}
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
new file mode 100644
index 0000000..3d262b1
--- /dev/null
+++ b/core/java/android/app/trust/TrustManager.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.trust;
+
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
+
+/**
+ * See {@link com.android.server.trust.TrustManagerService}
+ * @hide
+ */
+public class TrustManager {
+
+    private static final int MSG_TRUST_CHANGED = 1;
+    private static final int MSG_TRUST_MANAGED_CHANGED = 2;
+
+    private static final String TAG = "TrustManager";
+    private static final String DATA_INITIATED_BY_USER = "initiatedByUser";
+
+    private final ITrustManager mService;
+    private final ArrayMap<TrustListener, ITrustListener> mTrustListeners;
+
+    public TrustManager(IBinder b) {
+        mService = ITrustManager.Stub.asInterface(b);
+        mTrustListeners = new ArrayMap<TrustListener, ITrustListener>();
+    }
+
+    /**
+     * Reports that user {@param userId} has tried to unlock the device.
+     *
+     * @param successful if true, the unlock attempt was successful.
+     *
+     * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
+     */
+    public void reportUnlockAttempt(boolean successful, int userId) {
+        try {
+            mService.reportUnlockAttempt(successful, userId);
+        } catch (RemoteException e) {
+            onError(e);
+        }
+    }
+
+    /**
+     * Reports that the list of enabled trust agents changed for user {@param userId}.
+     *
+     * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
+     */
+    public void reportEnabledTrustAgentsChanged(int userId) {
+        try {
+            mService.reportEnabledTrustAgentsChanged(userId);
+        } catch (RemoteException e) {
+            onError(e);
+        }
+    }
+
+    /**
+     * Reports that trust is disabled until credentials have been entered for user {@param userId}.
+     *
+     * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
+     *
+     * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
+     */
+    public void reportRequireCredentialEntry(int userId) {
+        try {
+            mService.reportRequireCredentialEntry(userId);
+        } catch (RemoteException e) {
+            onError(e);
+        }
+    }
+
+    /**
+     * Registers a listener for trust events.
+     *
+     * Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission.
+     */
+    public void registerTrustListener(final TrustListener trustListener) {
+        try {
+            ITrustListener.Stub iTrustListener = new ITrustListener.Stub() {
+                @Override
+                public void onTrustChanged(boolean enabled, int userId, boolean initiatedByUser) {
+                    Message m = mHandler.obtainMessage(MSG_TRUST_CHANGED, (enabled ? 1 : 0), userId,
+                            trustListener);
+                    if (initiatedByUser) {
+                        m.getData().putBoolean(DATA_INITIATED_BY_USER, initiatedByUser);
+                    }
+                    m.sendToTarget();
+                }
+
+                @Override
+                public void onTrustManagedChanged(boolean managed, int userId) {
+                    mHandler.obtainMessage(MSG_TRUST_MANAGED_CHANGED, (managed ? 1 : 0), userId,
+                            trustListener).sendToTarget();
+                }
+            };
+            mService.registerTrustListener(iTrustListener);
+            mTrustListeners.put(trustListener, iTrustListener);
+        } catch (RemoteException e) {
+            onError(e);
+        }
+    }
+
+    /**
+     * Unregisters a listener for trust events.
+     *
+     * Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission.
+     */
+    public void unregisterTrustListener(final TrustListener trustListener) {
+        ITrustListener iTrustListener = mTrustListeners.remove(trustListener);
+        if (iTrustListener != null) {
+            try {
+                mService.unregisterTrustListener(iTrustListener);
+            } catch (RemoteException e) {
+                onError(e);
+            }
+        }
+    }
+
+    private void onError(Exception e) {
+        Log.e(TAG, "Error while calling TrustManagerService", e);
+    }
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+        @Override
+        public void handleMessage(Message msg) {
+            switch(msg.what) {
+                case MSG_TRUST_CHANGED:
+                    boolean initiatedByUser = msg.peekData() != null &&
+                            msg.peekData().getBoolean(DATA_INITIATED_BY_USER);
+                    ((TrustListener)msg.obj).onTrustChanged(
+                            msg.arg1 != 0, msg.arg2, initiatedByUser);
+
+                    break;
+                case MSG_TRUST_MANAGED_CHANGED:
+                    ((TrustListener)msg.obj).onTrustManagedChanged(msg.arg1 != 0, msg.arg2);
+            }
+        }
+    };
+
+    public interface TrustListener {
+
+        /**
+         * Reports that the trust state has changed.
+         * @param enabled if true, the system believes the environment to be trusted.
+         * @param userId the user, for which the trust changed.
+         * @param initiatedByUser indicates that the user has explicitly initiated an action that
+         *                        proves the user is about to use the device.
+         */
+        void onTrustChanged(boolean enabled, int userId, boolean initiatedByUser);
+
+        /**
+         * Reports that whether trust is managed has changed
+         * @param enabled if true, at least one trust agent is managing trust.
+         * @param userId the user, for which the state changed.
+         */
+        void onTrustManagedChanged(boolean enabled, int userId);
+    }
+}
diff --git a/core/java/android/app/usage/ConfigurationStats.java b/core/java/android/app/usage/ConfigurationStats.java
new file mode 100644
index 0000000..080216c
--- /dev/null
+++ b/core/java/android/app/usage/ConfigurationStats.java
@@ -0,0 +1,161 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package android.app.usage;
+
+import android.content.res.Configuration;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents the usage statistics of a device {@link android.content.res.Configuration} for a
+ * specific time range.
+ */
+public final class ConfigurationStats implements Parcelable {
+
+    /**
+     * {@hide}
+     */
+    public Configuration mConfiguration;
+
+    /**
+     * {@hide}
+     */
+    public long mBeginTimeStamp;
+
+    /**
+     * {@hide}
+     */
+    public long mEndTimeStamp;
+
+    /**
+     * {@hide}
+     */
+    public long mLastTimeActive;
+
+    /**
+     * {@hide}
+     */
+    public long mTotalTimeActive;
+
+    /**
+     * {@hide}
+     */
+    public int mActivationCount;
+
+    /**
+     * {@hide}
+     */
+    public ConfigurationStats() {
+    }
+
+    public ConfigurationStats(ConfigurationStats stats) {
+        mConfiguration = stats.mConfiguration;
+        mBeginTimeStamp = stats.mBeginTimeStamp;
+        mEndTimeStamp = stats.mEndTimeStamp;
+        mLastTimeActive = stats.mLastTimeActive;
+        mTotalTimeActive = stats.mTotalTimeActive;
+        mActivationCount = stats.mActivationCount;
+    }
+
+    public Configuration getConfiguration() {
+        return mConfiguration;
+    }
+
+    /**
+     * Get the beginning of the time range this {@link ConfigurationStats} represents,
+     * measured in milliseconds since the epoch.
+     * <p/>
+     * See {@link System#currentTimeMillis()}.
+     */
+    public long getFirstTimeStamp() {
+        return mBeginTimeStamp;
+    }
+
+    /**
+     * Get the end of the time range this {@link ConfigurationStats} represents,
+     * measured in milliseconds since the epoch.
+     * <p/>
+     * See {@link System#currentTimeMillis()}.
+     */
+    public long getLastTimeStamp() {
+        return mEndTimeStamp;
+    }
+
+    /**
+     * Get the last time this configuration was active, measured in milliseconds since the epoch.
+     * <p/>
+     * See {@link System#currentTimeMillis()}.
+     */
+    public long getLastTimeActive() {
+        return mLastTimeActive;
+    }
+
+    /**
+     * Get the total time this configuration was active, measured in milliseconds.
+     */
+    public long getTotalTimeActive() {
+        return mTotalTimeActive;
+    }
+
+    /**
+     * Get the number of times this configuration was active.
+     */
+    public int getActivationCount() {
+        return mActivationCount;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        if (mConfiguration != null) {
+            dest.writeInt(1);
+            mConfiguration.writeToParcel(dest, flags);
+        } else {
+            dest.writeInt(0);
+        }
+
+        dest.writeLong(mBeginTimeStamp);
+        dest.writeLong(mEndTimeStamp);
+        dest.writeLong(mLastTimeActive);
+        dest.writeLong(mTotalTimeActive);
+        dest.writeInt(mActivationCount);
+    }
+
+    public static final Creator<ConfigurationStats> CREATOR = new Creator<ConfigurationStats>() {
+        @Override
+        public ConfigurationStats createFromParcel(Parcel source) {
+            ConfigurationStats stats = new ConfigurationStats();
+            if (source.readInt() != 0) {
+                stats.mConfiguration = Configuration.CREATOR.createFromParcel(source);
+            }
+            stats.mBeginTimeStamp = source.readLong();
+            stats.mEndTimeStamp = source.readLong();
+            stats.mLastTimeActive = source.readLong();
+            stats.mTotalTimeActive = source.readLong();
+            stats.mActivationCount = source.readInt();
+            return stats;
+        }
+
+        @Override
+        public ConfigurationStats[] newArray(int size) {
+            return new ConfigurationStats[size];
+        }
+    };
+}
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
new file mode 100644
index 0000000..4ed1489
--- /dev/null
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.usage;
+
+import android.app.usage.UsageEvents;
+import android.content.pm.ParceledListSlice;
+
+/**
+ * System private API for talking with the UsageStatsManagerService.
+ *
+ * {@hide}
+ */
+interface IUsageStatsManager {
+    ParceledListSlice queryUsageStats(int bucketType, long beginTime, long endTime,
+            String callingPackage);
+    ParceledListSlice queryConfigurationStats(int bucketType, long beginTime, long endTime,
+            String callingPackage);
+    UsageEvents queryEvents(long beginTime, long endTime, String callingPackage);
+}
diff --git a/core/java/android/app/usage/PackageUsageStats.aidl b/core/java/android/app/usage/PackageUsageStats.aidl
new file mode 100644
index 0000000..5293098
--- /dev/null
+++ b/core/java/android/app/usage/PackageUsageStats.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.usage;
+
+parcelable PackageUsageStats;
diff --git a/core/java/android/app/usage/TimeSparseArray.java b/core/java/android/app/usage/TimeSparseArray.java
new file mode 100644
index 0000000..7974fa7
--- /dev/null
+++ b/core/java/android/app/usage/TimeSparseArray.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package android.app.usage;
+
+import android.util.LongSparseArray;
+
+/**
+ * An array that indexes by a long timestamp, representing milliseconds since the epoch.
+ *
+ * {@hide}
+ */
+public class TimeSparseArray<E> extends LongSparseArray<E> {
+    public TimeSparseArray() {
+        super();
+    }
+
+    public TimeSparseArray(int initialCapacity) {
+        super(initialCapacity);
+    }
+
+    /**
+     * Finds the index of the first element whose timestamp is greater or equal to
+     * the given time.
+     *
+     * @param time The timestamp for which to search the array.
+     * @return The index of the matched element, or -1 if no such match exists.
+     */
+    public int closestIndexOnOrAfter(long time) {
+        // This is essentially a binary search, except that if no match is found
+        // the closest index is returned.
+        final int size = size();
+        int lo = 0;
+        int hi = size - 1;
+        int mid = -1;
+        long key = -1;
+        while (lo <= hi) {
+            mid = lo + ((hi - lo) / 2);
+            key = keyAt(mid);
+
+            if (time > key) {
+                lo = mid + 1;
+            } else if (time < key) {
+                hi = mid - 1;
+            } else {
+                return mid;
+            }
+        }
+
+        if (time < key) {
+            return mid;
+        } else if (time > key && lo < size) {
+            return lo;
+        } else {
+            return -1;
+        }
+    }
+
+    /**
+     * Finds the index of the first element whose timestamp is less than or equal to
+     * the given time.
+     *
+     * @param time The timestamp for which to search the array.
+     * @return The index of the matched element, or -1 if no such match exists.
+     */
+    public int closestIndexOnOrBefore(long time) {
+        final int index = closestIndexOnOrAfter(time);
+        if (index < 0) {
+            // Everything is larger, so we use the last element, or -1 if the list is empty.
+            return size() - 1;
+        }
+
+        if (keyAt(index) == time) {
+            return index;
+        }
+        return index - 1;
+    }
+}
diff --git a/core/java/android/app/usage/UsageEvents.aidl b/core/java/android/app/usage/UsageEvents.aidl
new file mode 100644
index 0000000..f1bceba
--- /dev/null
+++ b/core/java/android/app/usage/UsageEvents.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.usage;
+
+parcelable UsageEvents;
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
new file mode 100644
index 0000000..1a947ec
--- /dev/null
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -0,0 +1,379 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package android.app.usage;
+
+import android.content.ComponentName;
+import android.content.res.Configuration;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A result returned from {@link android.app.usage.UsageStatsManager#queryEvents(long, long)}
+ * from which to read {@link android.app.usage.UsageEvents.Event} objects.
+ */
+public final class UsageEvents implements Parcelable {
+
+    /**
+     * An event representing a state change for a component.
+     */
+    public static final class Event {
+
+        /**
+         * No event type.
+         */
+        public static final int NONE = 0;
+
+        /**
+         * An event type denoting that a component moved to the foreground.
+         */
+        public static final int MOVE_TO_FOREGROUND = 1;
+
+        /**
+         * An event type denoting that a component moved to the background.
+         */
+        public static final int MOVE_TO_BACKGROUND = 2;
+
+        /**
+         * An event type denoting that a component was in the foreground when the stats
+         * rolled-over. This is effectively treated as a {@link #MOVE_TO_BACKGROUND}.
+         * {@hide}
+         */
+        public static final int END_OF_DAY = 3;
+
+        /**
+         * An event type denoting that a component was in the foreground the previous day.
+         * This is effectively treated as a {@link #MOVE_TO_FOREGROUND}.
+         * {@hide}
+         */
+        public static final int CONTINUE_PREVIOUS_DAY = 4;
+
+        /**
+         * An event type denoting that the device configuration has changed.
+         */
+        public static final int CONFIGURATION_CHANGE = 5;
+
+        /**
+         * {@hide}
+         */
+        public String mPackage;
+
+        /**
+         * {@hide}
+         */
+        public String mClass;
+
+        /**
+         * {@hide}
+         */
+        public long mTimeStamp;
+
+        /**
+         * {@hide}
+         */
+        public int mEventType;
+
+        /**
+         * Only present for {@link #CONFIGURATION_CHANGE} event types.
+         * {@hide}
+         */
+        public Configuration mConfiguration;
+
+        /**
+         * TODO(adamlesinski): Removed before release.
+         * {@hide}
+         */
+        public ComponentName getComponent() {
+            return new ComponentName(mPackage, mClass);
+        }
+
+        /**
+         * The package name of the source of this event.
+         */
+        public String getPackageName() {
+            return mPackage;
+        }
+
+        /**
+         * The class name of the source of this event. This may be null for
+         * certain events.
+         */
+        public String getClassName() {
+            return mClass;
+        }
+
+        /**
+         * The time at which this event occurred, measured in milliseconds since the epoch.
+         * <p/>
+         * See {@link System#currentTimeMillis()}.
+         */
+        public long getTimeStamp() {
+            return mTimeStamp;
+        }
+
+        /**
+         * The event type.
+         *
+         * See {@link #MOVE_TO_BACKGROUND}
+         * See {@link #MOVE_TO_FOREGROUND}
+         */
+        public int getEventType() {
+            return mEventType;
+        }
+
+        /**
+         * Returns a {@link Configuration} for this event if the event is of type
+         * {@link #CONFIGURATION_CHANGE}, otherwise it returns null.
+         */
+        public Configuration getConfiguration() {
+            return mConfiguration;
+        }
+    }
+
+    // Only used when creating the resulting events. Not used for reading/unparceling.
+    private List<Event> mEventsToWrite = null;
+
+    // Only used for reading/unparceling events.
+    private Parcel mParcel = null;
+    private final int mEventCount;
+
+    private int mIndex = 0;
+
+    /*
+     * In order to save space, since ComponentNames will be duplicated everywhere,
+     * we use a map and index into it.
+     */
+    private String[] mStringPool;
+
+    /**
+     * Construct the iterator from a parcel.
+     * {@hide}
+     */
+    public UsageEvents(Parcel in) {
+        mEventCount = in.readInt();
+        mIndex = in.readInt();
+        if (mEventCount > 0) {
+            mStringPool = in.createStringArray();
+
+            final int listByteLength = in.readInt();
+            final int positionInParcel = in.readInt();
+            mParcel = Parcel.obtain();
+            mParcel.setDataPosition(0);
+            mParcel.appendFrom(in, in.dataPosition(), listByteLength);
+            mParcel.setDataSize(mParcel.dataPosition());
+            mParcel.setDataPosition(positionInParcel);
+        }
+    }
+
+    /**
+     * Create an empty iterator.
+     * {@hide}
+     */
+    UsageEvents() {
+        mEventCount = 0;
+    }
+
+    /**
+     * Construct the iterator in preparation for writing it to a parcel.
+     * {@hide}
+     */
+    public UsageEvents(List<Event> events, String[] stringPool) {
+        mStringPool = stringPool;
+        mEventCount = events.size();
+        mEventsToWrite = events;
+    }
+
+    /**
+     * Returns whether or not there are more events to read using
+     * {@link #getNextEvent(android.app.usage.UsageEvents.Event)}.
+     *
+     * @return true if there are more events, false otherwise.
+     */
+    public boolean hasNextEvent() {
+        return mIndex < mEventCount;
+    }
+
+    /**
+     * Retrieve the next {@link android.app.usage.UsageEvents.Event} from the collection and put the
+     * resulting data into {@code eventOut}.
+     *
+     * @param eventOut The {@link android.app.usage.UsageEvents.Event} object that will receive the
+     *                 next event data.
+     * @return true if an event was available, false if there are no more events.
+     */
+    public boolean getNextEvent(Event eventOut) {
+        if (mIndex >= mEventCount) {
+            return false;
+        }
+
+        readEventFromParcel(mParcel, eventOut);
+
+        mIndex++;
+        if (mIndex >= mEventCount) {
+            mParcel.recycle();
+            mParcel = null;
+        }
+        return true;
+    }
+
+    /**
+     * Resets the collection so that it can be iterated over from the beginning.
+     */
+    public void resetToStart() {
+        mIndex = 0;
+        if (mParcel != null) {
+            mParcel.setDataPosition(0);
+        }
+    }
+
+    private int findStringIndex(String str) {
+        final int index = Arrays.binarySearch(mStringPool, str);
+        if (index < 0) {
+            throw new IllegalStateException("String '" + str + "' is not in the string pool");
+        }
+        return index;
+    }
+
+    /**
+     * Writes a single event to the parcel. Modify this when updating {@link Event}.
+     */
+    private void writeEventToParcel(Event event, Parcel p, int flags) {
+        final int packageIndex;
+        if (event.mPackage != null) {
+            packageIndex = findStringIndex(event.mPackage);
+        } else {
+            packageIndex = -1;
+        }
+
+        final int classIndex;
+        if (event.mClass != null) {
+            classIndex = findStringIndex(event.mClass);
+        } else {
+            classIndex = -1;
+        }
+        p.writeInt(packageIndex);
+        p.writeInt(classIndex);
+        p.writeInt(event.mEventType);
+        p.writeLong(event.mTimeStamp);
+
+        if (event.mEventType == Event.CONFIGURATION_CHANGE) {
+            event.mConfiguration.writeToParcel(p, flags);
+        }
+    }
+
+    /**
+     * Reads a single event from the parcel. Modify this when updating {@link Event}.
+     */
+    private void readEventFromParcel(Parcel p, Event eventOut) {
+        final int packageIndex = p.readInt();
+        if (packageIndex >= 0) {
+            eventOut.mPackage = mStringPool[packageIndex];
+        } else {
+            eventOut.mPackage = null;
+        }
+
+        final int classIndex = p.readInt();
+        if (classIndex >= 0) {
+            eventOut.mClass = mStringPool[classIndex];
+        } else {
+            eventOut.mClass = null;
+        }
+        eventOut.mEventType = p.readInt();
+        eventOut.mTimeStamp = p.readLong();
+
+        // Extract the configuration for configuration change events.
+        if (eventOut.mEventType == Event.CONFIGURATION_CHANGE) {
+            eventOut.mConfiguration = Configuration.CREATOR.createFromParcel(p);
+        } else {
+            eventOut.mConfiguration = null;
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mEventCount);
+        dest.writeInt(mIndex);
+        if (mEventCount > 0) {
+            dest.writeStringArray(mStringPool);
+
+            if (mEventsToWrite != null) {
+                // Write out the events
+                Parcel p = Parcel.obtain();
+                try {
+                    p.setDataPosition(0);
+                    for (int i = 0; i < mEventCount; i++) {
+                        final Event event = mEventsToWrite.get(i);
+                        writeEventToParcel(event, p, flags);
+                    }
+
+                    final int listByteLength = p.dataPosition();
+
+                    // Write the total length of the data.
+                    dest.writeInt(listByteLength);
+
+                    // Write our current position into the data.
+                    dest.writeInt(0);
+
+                    // Write the data.
+                    dest.appendFrom(p, 0, listByteLength);
+                } finally {
+                    p.recycle();
+                }
+
+            } else if (mParcel != null) {
+                // Write the total length of the data.
+                dest.writeInt(mParcel.dataSize());
+
+                // Write out current position into the data.
+                dest.writeInt(mParcel.dataPosition());
+
+                // Write the data.
+                dest.appendFrom(mParcel, 0, mParcel.dataSize());
+            } else {
+                throw new IllegalStateException(
+                        "Either mParcel or mEventsToWrite must not be null");
+            }
+        }
+    }
+
+    public static final Creator<UsageEvents> CREATOR = new Creator<UsageEvents>() {
+        @Override
+        public UsageEvents createFromParcel(Parcel source) {
+            return new UsageEvents(source);
+        }
+
+        @Override
+        public UsageEvents[] newArray(int size) {
+            return new UsageEvents[size];
+        }
+    };
+
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+        if (mParcel != null) {
+            mParcel.recycle();
+            mParcel = null;
+        }
+    }
+}
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
new file mode 100644
index 0000000..abfc435
--- /dev/null
+++ b/core/java/android/app/usage/UsageStats.java
@@ -0,0 +1,177 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package android.app.usage;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Contains usage statistics for an app package for a specific
+ * time range.
+ */
+public final class UsageStats implements Parcelable {
+
+    /**
+     * {@hide}
+     */
+    public String mPackageName;
+
+    /**
+     * {@hide}
+     */
+    public long mBeginTimeStamp;
+
+    /**
+     * {@hide}
+     */
+    public long mEndTimeStamp;
+
+    /**
+     * {@hide}
+     */
+    public long mLastTimeUsed;
+
+    /**
+     * {@hide}
+     */
+    public long mTotalTimeInForeground;
+
+    /**
+     * {@hide}
+     */
+    public int mLaunchCount;
+
+    /**
+     * {@hide}
+     */
+    public int mLastEvent;
+
+    /**
+     * {@hide}
+     */
+    public UsageStats() {
+    }
+
+    public UsageStats(UsageStats stats) {
+        mPackageName = stats.mPackageName;
+        mBeginTimeStamp = stats.mBeginTimeStamp;
+        mEndTimeStamp = stats.mEndTimeStamp;
+        mLastTimeUsed = stats.mLastTimeUsed;
+        mTotalTimeInForeground = stats.mTotalTimeInForeground;
+        mLaunchCount = stats.mLaunchCount;
+        mLastEvent = stats.mLastEvent;
+    }
+
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * Get the beginning of the time range this {@link android.app.usage.UsageStats} represents,
+     * measured in milliseconds since the epoch.
+     * <p/>
+     * See {@link System#currentTimeMillis()}.
+     */
+    public long getFirstTimeStamp() {
+        return mBeginTimeStamp;
+    }
+
+    /**
+     * Get the end of the time range this {@link android.app.usage.UsageStats} represents,
+     * measured in milliseconds since the epoch.
+     * <p/>
+     * See {@link System#currentTimeMillis()}.
+     */
+    public long getLastTimeStamp() {
+        return mEndTimeStamp;
+    }
+
+    /**
+     * Get the last time this package was used, measured in milliseconds since the epoch.
+     * <p/>
+     * See {@link System#currentTimeMillis()}.
+     */
+    public long getLastTimeUsed() {
+        return mLastTimeUsed;
+    }
+
+    /**
+     * Get the total time this package spent in the foreground, measured in milliseconds.
+     */
+    public long getTotalTimeInForeground() {
+        return mTotalTimeInForeground;
+    }
+
+    /**
+     * Add the statistics from the right {@link UsageStats} to the left. The package name for
+     * both {@link UsageStats} objects must be the same.
+     * @param right The {@link UsageStats} object to merge into this one.
+     * @throws java.lang.IllegalArgumentException if the package names of the two
+     *         {@link UsageStats} objects are different.
+     */
+    public void add(UsageStats right) {
+        if (!mPackageName.equals(right.mPackageName)) {
+            throw new IllegalArgumentException("Can't merge UsageStats for package '" +
+                    mPackageName + "' with UsageStats for package '" + right.mPackageName + "'.");
+        }
+
+        if (right.mEndTimeStamp > mEndTimeStamp) {
+            mLastEvent = right.mLastEvent;
+            mEndTimeStamp = right.mEndTimeStamp;
+            mLastTimeUsed = right.mLastTimeUsed;
+        }
+        mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp);
+        mTotalTimeInForeground += right.mTotalTimeInForeground;
+        mLaunchCount += right.mLaunchCount;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mPackageName);
+        dest.writeLong(mBeginTimeStamp);
+        dest.writeLong(mEndTimeStamp);
+        dest.writeLong(mLastTimeUsed);
+        dest.writeLong(mTotalTimeInForeground);
+        dest.writeInt(mLaunchCount);
+        dest.writeInt(mLastEvent);
+    }
+
+    public static final Creator<UsageStats> CREATOR = new Creator<UsageStats>() {
+        @Override
+        public UsageStats createFromParcel(Parcel in) {
+            UsageStats stats = new UsageStats();
+            stats.mPackageName = in.readString();
+            stats.mBeginTimeStamp = in.readLong();
+            stats.mEndTimeStamp = in.readLong();
+            stats.mLastTimeUsed = in.readLong();
+            stats.mTotalTimeInForeground = in.readLong();
+            stats.mLaunchCount = in.readInt();
+            stats.mLastEvent = in.readInt();
+            return stats;
+        }
+
+        @Override
+        public UsageStats[] newArray(int size) {
+            return new UsageStats[size];
+        }
+    };
+}
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
new file mode 100644
index 0000000..bc6099a
--- /dev/null
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -0,0 +1,220 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package android.app.usage;
+
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides access to device usage history and statistics. Usage data is aggregated into
+ * time intervals: days, weeks, months, and years.
+ * <p />
+ * When requesting usage data since a particular time, the request might look something like this:
+ * <pre>
+ * PAST                   REQUEST_TIME                    TODAY                   FUTURE
+ * ————————————————————————————||———————————————————————————¦-----------------------|
+ *                        YEAR ||                           ¦                       |
+ * ————————————————————————————||———————————————————————————¦-----------------------|
+ *  MONTH            |         ||                MONTH      ¦                       |
+ * ——————————————————|—————————||———————————————————————————¦-----------------------|
+ *   |      WEEK     |     WEEK||    |     WEEK     |     WE¦EK     |      WEEK     |
+ * ————————————————————————————||———————————————————|———————¦-----------------------|
+ *                             ||           |DAY|DAY|DAY|DAY¦DAY|DAY|DAY|DAY|DAY|DAY|
+ * ————————————————————————————||———————————————————————————¦-----------------------|
+ * </pre>
+ * A request for data in the middle of a time interval will include that interval.
+ * <p/>
+ * <b>NOTE:</b> This API requires the permission android.permission.PACKAGE_USAGE_STATS, which
+ * is a system-level permission and will not be granted to third-party apps. However, declaring
+ * the permission implies intention to use the API and the user of the device can grant permission
+ * through the Settings application.
+ */
+public final class UsageStatsManager {
+
+    /**
+     * An interval type that spans a day. See {@link #queryUsageStats(int, long, long)}.
+     */
+    public static final int INTERVAL_DAILY = 0;
+
+    /**
+     * An interval type that spans a week. See {@link #queryUsageStats(int, long, long)}.
+     */
+    public static final int INTERVAL_WEEKLY = 1;
+
+    /**
+     * An interval type that spans a month. See {@link #queryUsageStats(int, long, long)}.
+     */
+    public static final int INTERVAL_MONTHLY = 2;
+
+    /**
+     * An interval type that spans a year. See {@link #queryUsageStats(int, long, long)}.
+     */
+    public static final int INTERVAL_YEARLY = 3;
+
+    /**
+     * An interval type that will use the best fit interval for the given time range.
+     * See {@link #queryUsageStats(int, long, long)}.
+     */
+    public static final int INTERVAL_BEST = 4;
+
+    /**
+     * The number of available intervals. Does not include {@link #INTERVAL_BEST}, since it
+     * is a pseudo interval (it actually selects a real interval).
+     * {@hide}
+     */
+    public static final int INTERVAL_COUNT = 4;
+
+    private static final UsageEvents sEmptyResults = new UsageEvents();
+
+    private final Context mContext;
+    private final IUsageStatsManager mService;
+
+    /**
+     * {@hide}
+     */
+    public UsageStatsManager(Context context, IUsageStatsManager service) {
+        mContext = context;
+        mService = service;
+    }
+
+    /**
+     * Gets application usage stats for the given time range, aggregated by the specified interval.
+     * <p>The returned list will contain a {@link UsageStats} object for each package that
+     * has data for an interval that is a subset of the time range given. To illustrate:</p>
+     * <pre>
+     * intervalType = INTERVAL_YEARLY
+     * beginTime = 2013
+     * endTime = 2015 (exclusive)
+     *
+     * Results:
+     * 2013 - com.example.alpha
+     * 2013 - com.example.beta
+     * 2014 - com.example.alpha
+     * 2014 - com.example.beta
+     * 2014 - com.example.charlie
+     * </pre>
+     *
+     * @param intervalType The time interval by which the stats are aggregated.
+     * @param beginTime The inclusive beginning of the range of stats to include in the results.
+     * @param endTime The exclusive end of the range of stats to include in the results.
+     * @return A list of {@link UsageStats} or null if none are available.
+     *
+     * @see #INTERVAL_DAILY
+     * @see #INTERVAL_WEEKLY
+     * @see #INTERVAL_MONTHLY
+     * @see #INTERVAL_YEARLY
+     * @see #INTERVAL_BEST
+     */
+    public List<UsageStats> queryUsageStats(int intervalType, long beginTime, long endTime) {
+        try {
+            @SuppressWarnings("unchecked")
+            ParceledListSlice<UsageStats> slice = mService.queryUsageStats(intervalType, beginTime,
+                    endTime, mContext.getOpPackageName());
+            if (slice != null) {
+                return slice.getList();
+            }
+        } catch (RemoteException e) {
+            // fallthrough and return null.
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * Gets the hardware configurations the device was in for the given time range, aggregated by
+     * the specified interval. The results are ordered as in
+     * {@link #queryUsageStats(int, long, long)}.
+     *
+     * @param intervalType The time interval by which the stats are aggregated.
+     * @param beginTime The inclusive beginning of the range of stats to include in the results.
+     * @param endTime The exclusive end of the range of stats to include in the results.
+     * @return A list of {@link ConfigurationStats} or null if none are available.
+     */
+    public List<ConfigurationStats> queryConfigurations(int intervalType, long beginTime,
+            long endTime) {
+        try {
+            @SuppressWarnings("unchecked")
+            ParceledListSlice<ConfigurationStats> slice = mService.queryConfigurationStats(
+                    intervalType, beginTime, endTime, mContext.getOpPackageName());
+            if (slice != null) {
+                return slice.getList();
+            }
+        } catch (RemoteException e) {
+            // fallthrough and return the empty list.
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * Query for events in the given time range. Events are only kept by the system for a few
+     * days.
+     * <p />
+     * <b>NOTE:</b> The last few minutes of the event log will be truncated to prevent abuse
+     * by applications.
+     *
+     * @param beginTime The inclusive beginning of the range of events to include in the results.
+     * @param endTime The exclusive end of the range of events to include in the results.
+     * @return A {@link UsageEvents}.
+     */
+    public UsageEvents queryEvents(long beginTime, long endTime) {
+        try {
+            UsageEvents iter = mService.queryEvents(beginTime, endTime,
+                    mContext.getOpPackageName());
+            if (iter != null) {
+                return iter;
+            }
+        } catch (RemoteException e) {
+            // fallthrough and return null
+        }
+        return sEmptyResults;
+    }
+
+    /**
+     * A convenience method that queries for all stats in the given range (using the best interval
+     * for that range), merges the resulting data, and keys it by package name.
+     * See {@link #queryUsageStats(int, long, long)}.
+     *
+     * @param beginTime The inclusive beginning of the range of stats to include in the results.
+     * @param endTime The exclusive end of the range of stats to include in the results.
+     * @return A {@link java.util.Map} keyed by package name, or null if no stats are
+     *         available.
+     */
+    public Map<String, UsageStats> queryAndAggregateUsageStats(long beginTime, long endTime) {
+        List<UsageStats> stats = queryUsageStats(INTERVAL_BEST, beginTime, endTime);
+        if (stats.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        ArrayMap<String, UsageStats> aggregatedStats = new ArrayMap<>();
+        final int statCount = stats.size();
+        for (int i = 0; i < statCount; i++) {
+            UsageStats newStat = stats.get(i);
+            UsageStats existingStat = aggregatedStats.get(newStat.getPackageName());
+            if (existingStat == null) {
+                aggregatedStats.put(newStat.mPackageName, newStat);
+            } else {
+                existingStat.add(newStat);
+            }
+        }
+        return aggregatedStats;
+    }
+}
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
new file mode 100644
index 0000000..083a48a
--- /dev/null
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package android.app.usage;
+
+import android.content.ComponentName;
+import android.content.res.Configuration;
+
+/**
+ * UsageStatsManager local system service interface.
+ *
+ * {@hide} Only for use within the system server.
+ */
+public abstract class UsageStatsManagerInternal {
+
+    /**
+     * Reports an event to the UsageStatsManager.
+     *
+     * @param component The component for which this event occurred.
+     * @param userId The user id to which the component belongs to.
+     * @param eventType The event that occurred. Valid values can be found at
+     * {@link UsageEvents}
+     */
+    public abstract void reportEvent(ComponentName component, int userId, int eventType);
+
+    /**
+     * Reports a configuration change to the UsageStatsManager.
+     *
+     * @param config The new device configuration.
+     */
+    public abstract void reportConfigurationChange(Configuration config, int userId);
+
+    /**
+     * Prepares the UsageStatsService for shutdown.
+     */
+    public abstract void prepareShutdown();
+}
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index f104d71..24c6793 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -19,9 +19,14 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 
-import android.app.ActivityThread;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
 import android.content.Context;
+import android.content.IntentSender;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -29,9 +34,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.UserHandle;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.util.TypedValue;
 import android.widget.RemoteViews;
 import android.widget.RemoteViews.OnClickHandler;
@@ -55,7 +58,6 @@
     private DisplayMetrics mDisplayMetrics;
 
     Context mContext;
-    String mPackageName;
     Handler mHandler;
     int mHostId;
     Callbacks mCallbacks = new Callbacks();
@@ -63,32 +65,30 @@
     private OnClickHandler mOnClickHandler;
 
     class Callbacks extends IAppWidgetHost.Stub {
-        public void updateAppWidget(int appWidgetId, RemoteViews views, int userId) {
+        public void updateAppWidget(int appWidgetId, RemoteViews views) {
             if (isLocalBinder() && views != null) {
                 views = views.clone();
-                views.setUser(new UserHandle(userId));
             }
-            Message msg = mHandler.obtainMessage(HANDLE_UPDATE, appWidgetId, userId, views);
+            Message msg = mHandler.obtainMessage(HANDLE_UPDATE, appWidgetId, 0, views);
             msg.sendToTarget();
         }
 
-        public void providerChanged(int appWidgetId, AppWidgetProviderInfo info, int userId) {
+        public void providerChanged(int appWidgetId, AppWidgetProviderInfo info) {
             if (isLocalBinder() && info != null) {
                 info = info.clone();
             }
             Message msg = mHandler.obtainMessage(HANDLE_PROVIDER_CHANGED,
-                    appWidgetId, userId, info);
+                    appWidgetId, 0, info);
             msg.sendToTarget();
         }
 
-        public void providersChanged(int userId) {
-            Message msg = mHandler.obtainMessage(HANDLE_PROVIDERS_CHANGED, userId, 0);
-            msg.sendToTarget();
+        public void providersChanged() {
+            mHandler.obtainMessage(HANDLE_PROVIDERS_CHANGED).sendToTarget();
         }
 
-        public void viewDataChanged(int appWidgetId, int viewId, int userId) {
+        public void viewDataChanged(int appWidgetId, int viewId) {
             Message msg = mHandler.obtainMessage(HANDLE_VIEW_DATA_CHANGED,
-                    appWidgetId, viewId, userId);
+                    appWidgetId, viewId);
             msg.sendToTarget();
         }
     }
@@ -101,7 +101,7 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case HANDLE_UPDATE: {
-                    updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj, msg.arg2);
+                    updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj);
                     break;
                 }
                 case HANDLE_PROVIDER_CHANGED: {
@@ -113,7 +113,7 @@
                     break;
                 }
                 case HANDLE_VIEW_DATA_CHANGED: {
-                    viewDataChanged(msg.arg1, msg.arg2, (Integer) msg.obj);
+                    viewDataChanged(msg.arg1, msg.arg2);
                     break;
                 }
             }
@@ -153,25 +153,17 @@
     public void startListening() {
         int[] updatedIds;
         ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>();
-
-        final int userId = mContext.getUserId();
         try {
-            if (mPackageName == null) {
-                mPackageName = mContext.getPackageName();
-            }
-            updatedIds = sService.startListening(
-                    mCallbacks, mPackageName, mHostId, updatedViews, userId);
+            updatedIds = sService.startListening(mCallbacks, mContext.getOpPackageName(), mHostId,
+                    updatedViews);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
 
         final int N = updatedIds.length;
-        for (int i=0; i<N; i++) {
-            if (updatedViews.get(i) != null) {
-                updatedViews.get(i).setUser(new UserHandle(userId));
-            }
-            updateAppWidgetView(updatedIds[i], updatedViews.get(i), userId);
+        for (int i = 0; i < N; i++) {
+            updateAppWidgetView(updatedIds[i], updatedViews.get(i));
         }
     }
 
@@ -181,7 +173,7 @@
      */
     public void stopListening() {
         try {
-            sService.stopListening(mHostId, mContext.getUserId());
+            sService.stopListening(mContext.getOpPackageName(), mHostId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -199,10 +191,7 @@
      */
     public int allocateAppWidgetId() {
         try {
-            if (mPackageName == null) {
-                mPackageName = mContext.getPackageName();
-            }
-            return sService.allocateAppWidgetId(mPackageName, mHostId, mContext.getUserId());
+            return sService.allocateAppWidgetId(mContext.getOpPackageName(), mHostId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -210,18 +199,37 @@
     }
 
     /**
-     * Get a appWidgetId for a host in the given package.
+     * Starts an app widget provider configure activity for result on behalf of the caller.
+     * Use this method if the provider is in another profile as you are not allowed to start
+     * an activity in another profile. You can optionally provide a request code that is
+     * returned in {@link Activity#onActivityResult(int, int, android.content.Intent)} and
+     * an options bundle to be passed to the started activity.
+     * <p>
+     * Note that the provided app widget has to be bound for this method to work.
+     * </p>
      *
-     * @return a appWidgetId
-     * @hide
+     * @param activity The activity from which to start the configure one.
+     * @param appWidgetId The bound app widget whose provider's config activity to start.
+     * @param requestCode Optional request code retuned with the result.
+     * @param intentFlags Optional intent flags.
+     *
+     * @throws android.content.ActivityNotFoundException If the activity is not found.
+     *
+     * @see AppWidgetProviderInfo#getProfile()
      */
-    public static int allocateAppWidgetIdForPackage(int hostId, int userId, String packageName) {
-        checkCallerIsSystem();
+    public final void startAppWidgetConfigureActivityForResult(@NonNull Activity activity,
+            int appWidgetId, int intentFlags, int requestCode, @Nullable Bundle options) {
         try {
-            if (sService == null) {
-                bindService();
+            IntentSender intentSender = sService.createAppWidgetConfigIntentSender(
+                    mContext.getOpPackageName(), appWidgetId, intentFlags);
+            if (intentSender != null) {
+                activity.startIntentSenderForResult(intentSender, requestCode, null, 0, 0, 0,
+                        options);
+            } else {
+                throw new ActivityNotFoundException();
             }
-            return sService.allocateAppWidgetId(packageName, hostId, userId);
+        } catch (IntentSender.SendIntentException e) {
+            throw new ActivityNotFoundException();
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
@@ -237,20 +245,12 @@
             if (sService == null) {
                 bindService();
             }
-            return sService.getAppWidgetIdsForHost(mHostId, mContext.getUserId());
+            return sService.getAppWidgetIdsForHost(mContext.getOpPackageName(), mHostId);
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
     }
 
-    private static void checkCallerIsSystem() {
-        int uid = Process.myUid();
-        if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) {
-            return;
-        }
-        throw new SecurityException("Disallowed call for uid " + uid);
-    }
-
     private boolean isLocalBinder() {
         return Process.myPid() == Binder.getCallingPid();
     }
@@ -262,7 +262,7 @@
         synchronized (mViews) {
             mViews.remove(appWidgetId);
             try {
-                sService.deleteAppWidgetId(appWidgetId, mContext.getUserId());
+                sService.deleteAppWidgetId(mContext.getOpPackageName(), appWidgetId);
             }
             catch (RemoteException e) {
                 throw new RuntimeException("system server dead?", e);
@@ -271,22 +271,6 @@
     }
 
     /**
-     * Stop listening to changes for this AppWidget.
-     * @hide
-     */
-    public static void deleteAppWidgetIdForSystem(int appWidgetId, int userId) {
-        checkCallerIsSystem();
-        try {
-            if (sService == null) {
-                bindService();
-            }
-            sService.deleteAppWidgetId(appWidgetId, userId);
-        } catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
-    }
-
-    /**
      * Remove all records about this host from the AppWidget manager.
      * <ul>
      *   <li>Call this when initializing your database, as it might be because of a data wipe.</li>
@@ -296,7 +280,7 @@
      */
     public void deleteHost() {
         try {
-            sService.deleteHost(mHostId, mContext.getUserId());
+            sService.deleteHost(mContext.getOpPackageName(), mHostId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -312,16 +296,8 @@
      * </ul>
      */
     public static void deleteAllHosts() {
-        deleteAllHosts(UserHandle.myUserId());
-    }
-
-    /**
-     * Private method containing a userId
-     * @hide
-     */
-    public static void deleteAllHosts(int userId) {
         try {
-            sService.deleteAllHosts(userId);
+            sService.deleteAllHosts();
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -334,9 +310,7 @@
      */
     public final AppWidgetHostView createView(Context context, int appWidgetId,
             AppWidgetProviderInfo appWidget) {
-        final int userId = mContext.getUserId();
         AppWidgetHostView view = onCreateView(mContext, appWidgetId, appWidget);
-        view.setUserId(userId);
         view.setOnClickHandler(mOnClickHandler);
         view.setAppWidget(appWidgetId, appWidget);
         synchronized (mViews) {
@@ -344,10 +318,7 @@
         }
         RemoteViews views;
         try {
-            views = sService.getAppWidgetViews(appWidgetId, userId);
-            if (views != null) {
-                views.setUser(new UserHandle(mContext.getUserId()));
-            }
+            views = sService.getAppWidgetViews(mContext.getOpPackageName(), appWidgetId);
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
@@ -399,7 +370,7 @@
         // Does nothing
     }
 
-    void updateAppWidgetView(int appWidgetId, RemoteViews views, int userId) {
+    void updateAppWidgetView(int appWidgetId, RemoteViews views) {
         AppWidgetHostView v;
         synchronized (mViews) {
             v = mViews.get(appWidgetId);
@@ -409,7 +380,7 @@
         }
     }
 
-    void viewDataChanged(int appWidgetId, int viewId, int userId) {
+    void viewDataChanged(int appWidgetId, int viewId) {
         AppWidgetHostView v;
         synchronized (mViews) {
             v = mViews.get(appWidgetId);
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 700bba8..1ff476e 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -87,7 +87,6 @@
     Bitmap mOld;
     Paint mOldPaint = new Paint();
     private OnClickHandler mOnClickHandler;
-    private UserHandle mUser;
 
     /**
      * Create a host view.  Uses default fade animations.
@@ -115,17 +114,11 @@
     public AppWidgetHostView(Context context, int animationIn, int animationOut) {
         super(context);
         mContext = context;
-        mUser = Process.myUserHandle();
         // We want to segregate the view ids within AppWidgets to prevent
         // problems when those ids collide with view ids in the AppWidgetHost.
         setIsRootNamespace(true);
     }
 
-    /** @hide */
-    public void setUserId(int userId) {
-        mUser = new UserHandle(userId);
-    }
-
     /**
      * Pass the given handler to RemoteViews when updating this widget. Unless this
      * is done immediatly after construction, a call to {@link #updateAppWidget(RemoteViews)}
@@ -380,7 +373,7 @@
         } else {
             // Prepare a local reference to the remote Context so we're ready to
             // inflate any requested LayoutParams.
-            mRemoteContext = getRemoteContext(remoteViews);
+            mRemoteContext = getRemoteContext();
             int layoutId = remoteViews.getLayoutId();
 
             // If our stale view has been prepared to match active, and the new
@@ -466,17 +459,14 @@
      * Build a {@link Context} cloned into another package name, usually for the
      * purposes of reading remote resources.
      */
-    private Context getRemoteContext(RemoteViews views) {
-        // Bail if missing package name
-        final String packageName = views.getPackage();
-        if (packageName == null) return mContext;
-
+    private Context getRemoteContext() {
         try {
             // Return if cloned successfully, otherwise default
-            return mContext.createPackageContextAsUser(packageName, Context.CONTEXT_RESTRICTED,
-                    mUser);
+            return mContext.createApplicationContext(
+                    mInfo.providerInfo.applicationInfo,
+                    Context.CONTEXT_RESTRICTED);
         } catch (NameNotFoundException e) {
-            Log.e(TAG, "Package name " + packageName + " not found");
+            Log.e(TAG, "Package name " +  mInfo.providerInfo.packageName + " not found");
             return mContext;
         }
     }
@@ -548,8 +538,7 @@
 
         try {
             if (mInfo != null) {
-                Context theirContext = mContext.createPackageContextAsUser(
-                        mInfo.provider.getPackageName(), Context.CONTEXT_RESTRICTED, mUser);
+                Context theirContext = getRemoteContext();
                 mRemoteContext = theirContext;
                 LayoutInflater inflater = (LayoutInflater)
                         theirContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -572,8 +561,6 @@
             } else {
                 Log.w(TAG, "can't inflate defaultView because mInfo is missing");
             }
-        } catch (PackageManager.NameNotFoundException e) {
-            exception = e;
         } catch (RuntimeException e) {
             exception = e;
         }
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index d1c7bec..00248cc 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -16,14 +16,14 @@
 
 package android.appwidget;
 
-import android.app.ActivityManagerNative;
+import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.Process;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
@@ -31,9 +31,8 @@
 
 import com.android.internal.appwidget.IAppWidgetService;
 
-import java.lang.ref.WeakReference;
+import java.util.Collections;
 import java.util.List;
-import java.util.WeakHashMap;
 
 /**
  * Updates AppWidget state; gets information about installed AppWidget providers and other
@@ -46,7 +45,6 @@
  * </div>
  */
 public class AppWidgetManager {
-    static final String TAG = "AppWidgetManager";
 
     /**
      * Activity action to launch from your {@link AppWidgetHost} activity when you want to
@@ -73,9 +71,9 @@
      * <p>
      * When you receive the result from the AppWidget pick activity, if the resultCode is
      * {@link android.app.Activity#RESULT_OK}, an AppWidget has been selected.  You should then
-     * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its configuration
-     * activity.  If {@link android.app.Activity#RESULT_CANCELED} is returned, you should delete
-     * the appWidgetId.
+     * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its
+     * configuration activity.  If {@link android.app.Activity#RESULT_CANCELED} is returned, you
+     * should delete the appWidgetId.
      *
      * @see #ACTION_APPWIDGET_CONFIGURE
      */
@@ -104,6 +102,12 @@
      *     <td>The BroadcastReceiver that will be the AppWidget provider for this AppWidget.
      *     </td>
      *  </tr>
+     *  <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_PROVIDER_PROFILE}</td>
+     *     <td>An optional handle to a user profile under which runs the provider
+     *     for this AppWidget.
+     *     </td>
+     *  </tr>
      * </table>
      *
      * <p>
@@ -120,8 +124,7 @@
      * {@link android.app.Activity#RESULT_OK}, the AppWidget has been bound.  You should then
      * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its
      * configuration activity.  If {@link android.app.Activity#RESULT_CANCELED} is returned, you
-     * should delete
-     * the appWidgetId.
+     * should delete the appWidgetId.
      *
      * @see #ACTION_APPWIDGET_CONFIGURE
      *
@@ -131,7 +134,8 @@
     /**
      * Sent when it is time to configure your AppWidget while it is being added to a host.
      * This action is not sent as a broadcast to the AppWidget provider, but as a startActivity
-     * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo meta-data}.
+     * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo
+     * meta-data}.
      *
      * <p>
      * The intent will contain the following extras:
@@ -146,7 +150,8 @@
      * {@link android.app.Activity#setResult Activity.setResult()}, the AppWidget will be added,
      * and you will receive an {@link #ACTION_APPWIDGET_UPDATE} broadcast for this AppWidget.
      * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add
-     * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED} broadcast.
+     * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED}
+     * broadcast.
      */
     public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE";
 
@@ -182,13 +187,16 @@
      * A bundle extra that hints to the AppWidgetProvider the category of host that owns this
      * this widget. Can have the value {@link
      * AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN} or {@link
-     * AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD}.
+     * AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD} or {@link
+     * AppWidgetProviderInfo#WIDGET_CATEGORY_SEARCHBOX}.
      */
     public static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
 
     /**
      * An intent extra which points to a bundle of extra information for a particular widget id.
-     * In particular this bundle can contain EXTRA_APPWIDGET_WIDTH and EXTRA_APPWIDGET_HEIGHT.
+     * In particular this bundle can contain {@link #OPTION_APPWIDGET_MIN_WIDTH},
+     * {@link #OPTION_APPWIDGET_MIN_HEIGHT}, {@link #OPTION_APPWIDGET_MAX_WIDTH},
+     * {@link #OPTION_APPWIDGET_MAX_HEIGHT}.
      */
     public static final String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions";
 
@@ -203,11 +211,19 @@
     /**
      * An intent extra that contains the component name of a AppWidget provider.
      * <p>
-     * The value will be an ComponentName.
+     * The value will be an {@link android.content.ComponentName}.
      */
     public static final String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider";
 
     /**
+     * An intent extra that contains the user handle of the profile under
+     * which an AppWidget provider is registered.
+     * <p>
+     * The value will be a {@link android.os.UserHandle}.
+     */
+    public static final String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile";
+
+    /**
      * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
      * {@link AppWidgetProviderInfo} objects to mix in to the list of AppWidgets that are
      * installed.  (This is how the launcher shows the search widget).
@@ -215,6 +231,12 @@
     public static final String EXTRA_CUSTOM_INFO = "customInfo";
 
     /**
+     * An intent extra attached to the {@link #ACTION_APPWIDGET_HOST_RESTORED} broadcast,
+     * indicating the integer ID of the host whose widgets have just been restored.
+     */
+    public static final String EXTRA_HOST_ID = "hostId";
+
+    /**
      * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
      * {@link android.os.Bundle} objects to mix in to the list of AppWidgets that are
      * installed.  It will be added to the extras object on the {@link android.content.Intent}
@@ -289,12 +311,12 @@
     public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
 
     /**
-     * Sent when an instance of an AppWidget is removed from the last host.
+     * Sent when the last AppWidget of this provider is removed from the last host.
      *
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
      *
-     * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
+     * @see AppWidgetProvider#onEnabled AppWidgetProvider.onDisabled(Context context)
      */
     public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
 
@@ -311,52 +333,122 @@
     public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
 
     /**
+     * Sent to an {@link AppWidgetProvider} after AppWidget state related to that provider has
+     * been restored from backup. The intent contains information about how to translate AppWidget
+     * ids from the restored data to their new equivalents.
+     *
+     * <p>The intent will contain the following extras:
+     *
+     * <table>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td>
+     *     <td>The set of appWidgetIds represented in a restored backup that have been successfully
+     *     incorporated into the current environment.  This may be all of the AppWidgets known
+     *     to this application, or just a subset.  Each entry in this array of appWidgetIds has
+     *     a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td>
+     *  </tr>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_IDS}</td>
+     *     <td>The set of appWidgetIds now valid for this application.  The app should look at
+     *     its restored widget configuration and translate each appWidgetId in the
+     *     {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding
+     *     index within this array.</td>
+     *  </tr>
+     * </table>
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system.
+     *
+     * @see #ACTION_APPWIDGET_HOST_RESTORED
+     */
+    public static final String ACTION_APPWIDGET_RESTORED
+            = "android.appwidget.action.APPWIDGET_RESTORED";
+
+    /**
+     * Sent to widget hosts after AppWidget state related to the host has been restored from
+     * backup. The intent contains information about how to translate AppWidget ids from the
+     * restored data to their new equivalents.  If an application maintains multiple separate
+     * widget host instances, it will receive this broadcast separately for each one.
+     *
+     * <p>The intent will contain the following extras:
+     *
+     * <table>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td>
+     *     <td>The set of appWidgetIds represented in a restored backup that have been successfully
+     *     incorporated into the current environment.  This may be all of the AppWidgets known
+     *     to this application, or just a subset.  Each entry in this array of appWidgetIds has
+     *     a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td>
+     *  </tr>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_IDS}</td>
+     *     <td>The set of appWidgetIds now valid for this application.  The app should look at
+     *     its restored widget configuration and translate each appWidgetId in the
+     *     {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding
+     *     index within this array.</td>
+     *  </tr>
+     *  <tr>
+     *     <td>{@link #EXTRA_HOST_ID}</td>
+     *     <td>The integer ID of the widget host instance whose state has just been restored.</td>
+     *  </tr>
+     * </table>
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system.
+     *
+     * @see #ACTION_APPWIDGET_RESTORED
+     */
+    public static final String ACTION_APPWIDGET_HOST_RESTORED
+            = "android.appwidget.action.APPWIDGET_HOST_RESTORED";
+
+    /**
+     * An intent extra that contains multiple appWidgetIds.  These are id values as
+     * they were provided to the application during a recent restore from backup.  It is
+     * attached to the {@link #ACTION_APPWIDGET_RESTORED} broadcast intent.
+     *
+     * <p>
+     * The value will be an int array that can be retrieved like this:
+     * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS}
+     */
+    public static final String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
+
+    /**
      * Field for the manifest meta-data tag.
      *
      * @see AppWidgetProviderInfo
      */
     public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
 
-    static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache =
-        new WeakHashMap<Context, WeakReference<AppWidgetManager>>();
-    static IAppWidgetService sService;
+    private final String mPackageName;
 
-    Context mContext;
+    private final IAppWidgetService mService;
 
-    private DisplayMetrics mDisplayMetrics;
+    private final DisplayMetrics mDisplayMetrics;
 
     /**
      * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context
      * Context} object.
      */
     public static AppWidgetManager getInstance(Context context) {
-        synchronized (sManagerCache) {
-            if (sService == null) {
-                IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
-                sService = IAppWidgetService.Stub.asInterface(b);
-            }
-
-            WeakReference<AppWidgetManager> ref = sManagerCache.get(context);
-            AppWidgetManager result = null;
-            if (ref != null) {
-                result = ref.get();
-            }
-            if (result == null) {
-                result = new AppWidgetManager(context);
-                sManagerCache.put(context, new WeakReference<AppWidgetManager>(result));
-            }
-            return result;
-        }
+        return (AppWidgetManager) context.getSystemService(Context.APPWIDGET_SERVICE);
     }
 
-    private AppWidgetManager(Context context) {
-        mContext = context;
+    /**
+     * Creates a new instance.
+     *
+     * @param context The current context in which to operate.
+     * @param service The backing system service.
+     * @hide
+     */
+    public AppWidgetManager(Context context, IAppWidgetService service) {
+        mPackageName = context.getOpPackageName();
+        mService = service;
         mDisplayMetrics = context.getResources().getDisplayMetrics();
     }
 
     /**
      * Set the RemoteViews to use for the specified appWidgetIds.
-     *
+     * <p>
      * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
      * contain a complete representation of the widget. For performing partial widget updates, see
      * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}.
@@ -370,12 +462,15 @@
      * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
      * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.
      *
-     * @param appWidgetIds     The AppWidget instances for which to set the RemoteViews.
-     * @param views         The RemoteViews object to show.
+     * @param appWidgetIds The AppWidget instances for which to set the RemoteViews.
+     * @param views The RemoteViews object to show.
      */
     public void updateAppWidget(int[] appWidgetIds, RemoteViews views) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.updateAppWidgetIds(appWidgetIds, views, mContext.getUserId());
+            mService.updateAppWidgetIds(mPackageName, appWidgetIds, views);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -384,18 +479,21 @@
 
     /**
      * Update the extras for a given widget instance.
-     *
+     * <p>
      * The extras can be used to embed additional information about this widget to be accessed
      * by the associated widget's AppWidgetProvider.
      *
      * @see #getAppWidgetOptions(int)
      *
-     * @param appWidgetId    The AppWidget instances for which to set the RemoteViews.
-     * @param options         The options to associate with this widget
+     * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
+     * @param options The options to associate with this widget
      */
     public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.updateAppWidgetOptions(appWidgetId, options, mContext.getUserId());
+            mService.updateAppWidgetOptions(mPackageName, appWidgetId, options);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -404,18 +502,21 @@
 
     /**
      * Get the extras associated with a given widget instance.
-     *
+     * <p>
      * The extras can be used to embed additional information about this widget to be accessed
      * by the associated widget's AppWidgetProvider.
      *
      * @see #updateAppWidgetOptions(int, Bundle)
      *
-     * @param appWidgetId     The AppWidget instances for which to set the RemoteViews.
-     * @return                The options associated with the given widget instance.
+     * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
+     * @return The options associated with the given widget instance.
      */
     public Bundle getAppWidgetOptions(int appWidgetId) {
+        if (mService == null) {
+            return Bundle.EMPTY;
+        }
         try {
-            return sService.getAppWidgetOptions(appWidgetId, mContext.getUserId());
+            return mService.getAppWidgetOptions(mPackageName, appWidgetId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -424,7 +525,7 @@
 
     /**
      * Set the RemoteViews to use for the specified appWidgetId.
-     *
+     * <p>
      * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
      * contain a complete representation of the widget. For performing partial widget updates, see
      * {@link #partiallyUpdateAppWidget(int, RemoteViews)}.
@@ -442,12 +543,15 @@
      * @param views         The RemoteViews object to show.
      */
     public void updateAppWidget(int appWidgetId, RemoteViews views) {
+        if (mService == null) {
+            return;
+        }
         updateAppWidget(new int[] { appWidgetId }, views);
     }
 
     /**
      * Perform an incremental update or command on the widget(s) specified by appWidgetIds.
-     *
+     * <p>
      * This update  differs from {@link #updateAppWidget(int[], RemoteViews)} in that the
      * RemoteViews object which is passed is understood to be an incomplete representation of the
      * widget, and hence does not replace the cached representation of the widget. As of API
@@ -470,8 +574,11 @@
      * @param views            The RemoteViews object containing the incremental update / command.
      */
     public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.partiallyUpdateAppWidgetIds(appWidgetIds, views, mContext.getUserId());
+            mService.partiallyUpdateAppWidgetIds(mPackageName, appWidgetIds, views);
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
@@ -479,7 +586,7 @@
 
     /**
      * Perform an incremental update or command on the widget specified by appWidgetId.
-     *
+     * <p>
      * This update  differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews
      * object which is passed is understood to be an incomplete representation of the widget, and
      * hence is not cached by the AppWidgetService. Note that because these updates are not cached,
@@ -502,6 +609,9 @@
      * @param views            The RemoteViews object containing the incremental update / command.
      */
     public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) {
+        if (mService == null) {
+            return;
+        }
         partiallyUpdateAppWidget(new int[] { appWidgetId }, views);
     }
 
@@ -519,8 +629,11 @@
      * @param views         The RemoteViews object to show.
      */
     public void updateAppWidget(ComponentName provider, RemoteViews views) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.updateAppWidgetProvider(provider, views, mContext.getUserId());
+            mService.updateAppWidgetProvider(provider, views);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -535,8 +648,11 @@
      * @param viewId        The collection view id.
      */
     public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.notifyAppWidgetViewDataChanged(appWidgetIds, viewId, mContext.getUserId());
+            mService.notifyAppWidgetViewDataChanged(mPackageName, appWidgetIds, viewId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -551,37 +667,100 @@
      * @param viewId       The collection view id.
      */
     public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) {
+        if (mService == null) {
+            return;
+        }
         notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId);
     }
 
     /**
+     * Gets the AppWidget providers for the given user profile. User profile can only
+     * be the current user or a profile of the current user. For example, the current
+     * user may have a corporate profile. In this case the parent user profile has a
+     * child profile, the corporate one.
+     *
+     * @param profile The profile for which to get providers. Passing null is equivaled
+     *         to passing only the current user handle.
+     * @return The intalled providers.
+     *
+     * @see android.os.Process#myUserHandle()
+     * @see android.os.UserManager#getUserProfiles()
+     */
+    public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(@Nullable UserHandle profile) {
+        if (mService == null) {
+            return Collections.emptyList();
+        }
+        return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
+                profile);
+    }
+
+    /**
      * Return a list of the AppWidget providers that are currently installed.
      */
     public List<AppWidgetProviderInfo> getInstalledProviders() {
-        return getInstalledProviders(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
+        if (mService == null) {
+            return Collections.emptyList();
+        }
+        return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
+                null);
     }
 
     /**
-     * Return a list of the AppWidget providers that are currently installed.
+     * Gets the AppWidget providers for the current user.
      *
      * @param categoryFilter Will only return providers which register as any of the specified
      *        specified categories. See {@link AppWidgetProviderInfo#widgetCategory}.
+     * @return The intalled providers.
+     *
+     * @see android.os.Process#myUserHandle()
+     * @see android.os.UserManager#getUserProfiles()
+     *
      * @hide
      */
     public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) {
+        if (mService == null) {
+            return Collections.emptyList();
+        }
+        return getInstalledProvidersForProfile(categoryFilter, null);
+    }
+
+    /**
+     * Gets the AppWidget providers for the given user profile. User profile can only
+     * be the current user or a profile of the current user. For example, the current
+     * user may have a corporate profile. In this case the parent user profile has a
+     * child profile, the corporate one.
+     *
+     * @param categoryFilter Will only return providers which register as any of the specified
+     *        specified categories. See {@link AppWidgetProviderInfo#widgetCategory}.
+     * @param profile A profile of the current user which to be queried. The user
+     *        is itself also a profile. If null, the providers only for the current user
+     *        are returned.
+     * @return The intalled providers.
+     *
+     * @see android.os.Process#myUserHandle()
+     * @see android.os.UserManager#getUserProfiles()
+     *
+     * @hide
+     */
+    public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter,
+            UserHandle profile) {
+        if (mService == null) {
+            return Collections.emptyList();
+        }
+
+        if (profile == null) {
+            profile = Process.myUserHandle();
+        }
+
         try {
-            List<AppWidgetProviderInfo> providers = sService.getInstalledProviders(categoryFilter,
-                    mContext.getUserId());
+            List<AppWidgetProviderInfo> providers = mService.getInstalledProvidersForProfile(
+                    categoryFilter, profile.getIdentifier());
+            if (providers == null) {
+                return Collections.emptyList();
+            }
             for (AppWidgetProviderInfo info : providers) {
                 // Converting complex to dp.
-                info.minWidth =
-                        TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
-                info.minHeight =
-                        TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
-                info.minResizeWidth =
-                    TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics);
-                info.minResizeHeight =
-                    TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics);
+                convertSizesToPixels(info);
             }
             return providers;
         }
@@ -597,19 +776,14 @@
      * you don't have access to that appWidgetId, null is returned.
      */
     public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
+        if (mService == null) {
+            return null;
+        }
         try {
-            AppWidgetProviderInfo info = sService.getAppWidgetInfo(appWidgetId,
-                    mContext.getUserId());
+            AppWidgetProviderInfo info = mService.getAppWidgetInfo(mPackageName, appWidgetId);
             if (info != null) {
                 // Converting complex to dp.
-                info.minWidth =
-                        TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
-                info.minHeight =
-                        TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
-                info.minResizeWidth =
-                    TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics);
-                info.minResizeHeight =
-                    TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics);
+                convertSizesToPixels(info);
             }
             return info;
         }
@@ -631,12 +805,10 @@
      * @hide
      */
     public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
-        try {
-            sService.bindAppWidgetId(appWidgetId, provider, null, mContext.getUserId());
+        if (mService == null) {
+            return;
         }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
+        bindAppWidgetId(appWidgetId, provider, null);
     }
 
     /**
@@ -655,12 +827,10 @@
      * @hide
      */
     public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
-        try {
-            sService.bindAppWidgetId(appWidgetId, provider, options, mContext.getUserId());
+        if (mService == null) {
+            return;
         }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
+        bindAppWidgetIdIfAllowed(appWidgetId, Process.myUserHandle(), provider, options);
     }
 
     /**
@@ -671,22 +841,16 @@
      *         method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
      *         bind
      *
-     * @param appWidgetId     The AppWidget instance for which to set the RemoteViews.
+     * @param appWidgetId   The AppWidget id under which to bind the provider.
      * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
      *                      provider for this AppWidget.
      * @return true if this component has permission to bind the AppWidget
      */
     public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) {
-        if (mContext == null) {
+        if (mService == null) {
             return false;
         }
-        try {
-            return sService.bindAppWidgetIdIfAllowed(
-                    mContext.getPackageName(), appWidgetId, provider, null, mContext.getUserId());
-        }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
+        return bindAppWidgetIdIfAllowed(appWidgetId, UserHandle.myUserId(), provider, null);
     }
 
     /**
@@ -697,7 +861,7 @@
      *         method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
      *         bind
      *
-     * @param appWidgetId     The AppWidget instance for which to set the RemoteViews.
+     * @param appWidgetId The AppWidget id under which to bind the provider.
      * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
      *                      provider for this AppWidget.
      * @param options       Bundle containing options for the AppWidget. See also
@@ -707,12 +871,52 @@
      */
     public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider,
             Bundle options) {
-        if (mContext == null) {
+        if (mService == null) {
+            return false;
+        }
+        return bindAppWidgetIdIfAllowed(appWidgetId, UserHandle.myUserId(), provider, options);
+    }
+
+    /**
+     * Set the provider for a given appWidgetId if the caller has a permission.
+     * <p>
+     * <strong>Note:</strong> You need the {@link android.Manifest.permission#BIND_APPWIDGET}
+     * permission or the user must have enabled binding widgets always for your component.
+     * Should be used by apps that host widgets. If this method returns false, call {@link
+     * #ACTION_APPWIDGET_BIND} to request permission to bind.
+     * </p>
+     *
+     * @param appWidgetId The AppWidget id under which to bind the provider.
+     * @param user The user id in which the provider resides.
+     * @param provider The component name of the provider.
+     * @param options An optional Bundle containing options for the AppWidget.
+     *
+     * @return true if this component has permission to bind the AppWidget
+     */
+    public boolean bindAppWidgetIdIfAllowed(int appWidgetId, UserHandle user,
+            ComponentName provider, Bundle options) {
+        if (mService == null) {
+            return false;
+        }
+        return bindAppWidgetIdIfAllowed(appWidgetId, user.getIdentifier(), provider, options);
+    }
+
+    /**
+     * Query if a given package was granted permission by the user to bind app widgets
+     *
+     * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
+     *
+     * @param packageName The package for which the permission is being queried
+     * @param userId The user id of the user under which the package runs.
+     * @return true if the package was granted permission by the user to bind app widgets
+     * @hide
+     */
+    public boolean hasBindAppWidgetPermission(String packageName, int userId) {
+        if (mService == null) {
             return false;
         }
         try {
-            return sService.bindAppWidgetIdIfAllowed(mContext.getPackageName(), appWidgetId,
-                    provider, options, mContext.getUserId());
+            return mService.hasBindAppWidgetPermission(packageName, userId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -729,8 +933,11 @@
      * @hide
      */
     public boolean hasBindAppWidgetPermission(String packageName) {
+        if (mService == null) {
+            return false;
+        }
         try {
-            return sService.hasBindAppWidgetPermission(packageName, mContext.getUserId());
+            return mService.hasBindAppWidgetPermission(packageName, UserHandle.myUserId());
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -742,13 +949,35 @@
      *
      * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
      *
-     * @param provider        The package whose permission is being changed
-     * @param permission      Whether to give the package permission to bind widgets
+     * @param packageName The package whose permission is being changed
+     * @param permission Whether to give the package permission to bind widgets
+     *
      * @hide
      */
     public void setBindAppWidgetPermission(String packageName, boolean permission) {
+        if (mService == null) {
+            return;
+        }
+        setBindAppWidgetPermission(packageName, UserHandle.myUserId(), permission);
+    }
+
+    /**
+     * Changes any user-granted permission for the given package to bind app widgets
+     *
+     * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
+     *
+     * @param packageName The package whose permission is being changed
+     * @param userId The user under which the package is running.
+     * @param permission Whether to give the package permission to bind widgets
+     *
+     * @hide
+     */
+    public void setBindAppWidgetPermission(String packageName, int userId, boolean permission) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.setBindAppWidgetPermission(packageName, permission, mContext.getUserId());
+            mService.setBindAppWidgetPermission(packageName, userId, permission);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -761,18 +990,20 @@
      * The appWidgetId specified must already be bound to the calling AppWidgetHost via
      * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
      *
+     * @param packageName   The package from which the binding is requested.
      * @param appWidgetId   The AppWidget instance for which to bind the RemoteViewsService.
      * @param intent        The intent of the service which will be providing the data to the
      *                      RemoteViewsAdapter.
      * @param connection    The callback interface to be notified when a connection is made or lost.
-     * @param userHandle    The user to bind to.
      * @hide
      */
-    public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection,
-            UserHandle userHandle) {
+    public void bindRemoteViewsService(String packageName, int appWidgetId, Intent intent,
+            IBinder connection) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.bindRemoteViewsService(appWidgetId, intent, connection,
-                    userHandle.getIdentifier());
+            mService.bindRemoteViewsService(packageName, appWidgetId, intent, connection);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -785,15 +1016,18 @@
      * The appWidgetId specified muse already be bound to the calling AppWidgetHost via
      * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
      *
+     * @param packageName   The package from which the binding is requested.
      * @param appWidgetId   The AppWidget instance for which to bind the RemoteViewsService.
      * @param intent        The intent of the service which will be providing the data to the
      *                      RemoteViewsAdapter.
-     * @param userHandle    The user to unbind from.
      * @hide
      */
-    public void unbindRemoteViewsService(int appWidgetId, Intent intent, UserHandle userHandle) {
+    public void unbindRemoteViewsService(String packageName, int appWidgetId, Intent intent) {
+        if (mService == null) {
+            return;
+        }
         try {
-            sService.unbindRemoteViewsService(appWidgetId, intent, userHandle.getIdentifier());
+            mService.unbindRemoteViewsService(packageName, appWidgetId, intent);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -808,12 +1042,40 @@
      *            AppWidget provider to find appWidgetIds for.
      */
     public int[] getAppWidgetIds(ComponentName provider) {
+        if (mService == null) {
+            return new int[0];
+        }
         try {
-            return sService.getAppWidgetIds(provider, mContext.getUserId());
+            return mService.getAppWidgetIds(provider);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
     }
-}
 
+    private boolean bindAppWidgetIdIfAllowed(int appWidgetId, int profileId,
+            ComponentName provider, Bundle options) {
+        if (mService == null) {
+            return false;
+        }
+        try {
+            return mService.bindAppWidgetId(mPackageName, appWidgetId,
+                    profileId, provider, options);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    private void convertSizesToPixels(AppWidgetProviderInfo info) {
+        // Converting complex to dp.
+        info.minWidth = TypedValue.complexToDimensionPixelSize(info.minWidth,
+                mDisplayMetrics);
+        info.minHeight = TypedValue.complexToDimensionPixelSize(info.minHeight,
+                mDisplayMetrics);
+        info.minResizeWidth = TypedValue.complexToDimensionPixelSize(info.minResizeWidth,
+                mDisplayMetrics);
+        info.minResizeHeight = TypedValue.complexToDimensionPixelSize(info.minResizeHeight,
+                mDisplayMetrics);
+    }
+}
diff --git a/core/java/android/appwidget/AppWidgetProvider.java b/core/java/android/appwidget/AppWidgetProvider.java
index edf142b..ab91edf 100644
--- a/core/java/android/appwidget/AppWidgetProvider.java
+++ b/core/java/android/appwidget/AppWidgetProvider.java
@@ -66,15 +66,13 @@
                     this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
                 }
             }
-        }
-        else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
+        } else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
             Bundle extras = intent.getExtras();
             if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
                 final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
                 this.onDeleted(context, new int[] { appWidgetId });
             }
-        }
-        else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
+        } else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
             Bundle extras = intent.getExtras();
             if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
                     && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)) {
@@ -83,19 +81,28 @@
                 this.onAppWidgetOptionsChanged(context, AppWidgetManager.getInstance(context),
                         appWidgetId, widgetExtras);
             }
-        }
-        else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
+        } else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
             this.onEnabled(context);
-        }
-        else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
+        } else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
             this.onDisabled(context);
+        } else if (AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)) {
+            Bundle extras = intent.getExtras();
+            if (extras != null) {
+                int[] oldIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
+                int[] newIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
+                if (oldIds != null && oldIds.length > 0) {
+                    this.onRestored(context, oldIds, newIds);
+                    this.onUpdate(context, AppWidgetManager.getInstance(context), newIds);
+                }
+            }
         }
     }
     // END_INCLUDE(onReceive)
 
     /**
-     * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_UPDATE} broadcast when
-     * this AppWidget provider is being asked to provide {@link android.widget.RemoteViews RemoteViews}
+     * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_UPDATE} and
+     * {@link AppWidgetManager#ACTION_APPWIDGET_RESTORED} broadcasts when this AppWidget
+     * provider is being asked to provide {@link android.widget.RemoteViews RemoteViews}
      * for a set of AppWidgets.  Override this method to implement your own AppWidget functionality.
      *
      * {@more}
@@ -123,8 +130,8 @@
      *                  running.
      * @param appWidgetManager A {@link AppWidgetManager} object you can call {@link
      *                  AppWidgetManager#updateAppWidget} on.
-     * @param appWidgetId The appWidgetId of the widget who's size changed.
-     * @param newOptions The appWidgetId of the widget who's size changed.
+     * @param appWidgetId The appWidgetId of the widget whose size changed.
+     * @param newOptions The appWidgetId of the widget whose size changed.
      *
      * @see AppWidgetManager#ACTION_APPWIDGET_OPTIONS_CHANGED
      */
@@ -181,4 +188,24 @@
      */
     public void onDisabled(Context context) {
     }
+
+    /**
+     * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_RESTORED} broadcast
+     * when instances of this AppWidget provider have been restored from backup.  If your
+     * provider maintains any persistent data about its widget instances, override this method
+     * to remap the old AppWidgetIds to the new values and update any other app state that may
+     * be relevant.
+     *
+     * <p>This callback will be followed immediately by a call to {@link #onUpdate} so your
+     * provider can immediately generate new RemoteViews suitable for its newly-restored set
+     * of instances.
+     *
+     * {@more}
+     *
+     * @param context
+     * @param oldWidgetIds
+     * @param newWidgetIds
+     */
+    public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
+    }
 }
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 7b8b286..b4d79b4 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -16,9 +16,16 @@
 
 package android.appwidget;
 
+import android.annotation.NonNull;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.content.ComponentName;
+import android.os.UserHandle;
 
 /**
  * Describes the meta data for an installed AppWidget provider.  The fields in this class
@@ -54,6 +61,11 @@
     public static final int WIDGET_CATEGORY_KEYGUARD = 2;
 
     /**
+     * Indicates that the widget can be displayed within a space reserved for the search box.
+     */
+    public static final int WIDGET_CATEGORY_SEARCHBOX = 4;
+
+    /**
      * Identity of this AppWidget component.  This component should be a {@link
      * android.content.BroadcastReceiver}, and it will be sent the AppWidget intents
      * {@link android.appwidget as described in the AppWidget package documentation}.
@@ -140,16 +152,15 @@
     public ComponentName configure;
 
     /**
-     * The label to display to the user in the AppWidget picker.  If not supplied in the
-     * xml, the application label will be used.
+     * The label to display to the user in the AppWidget picker.
      *
-     * <p>This field corresponds to the <code>android:label</code> attribute in
-     * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
+     * @deprecated Use {@link #loadLabel(android.content.pm.PackageManager)}.
      */
+    @Deprecated
     public String label;
 
     /**
-     * The icon to display for this AppWidget in the AppWidget picker.  If not supplied in the
+     * The icon to display for this AppWidget in the AppWidget picker. If not supplied in the
      * xml, the application icon will be used.
      *
      * <p>This field corresponds to the <code>android:icon</code> attribute in
@@ -172,7 +183,7 @@
      * <p>This field corresponds to the <code>android:previewImage</code> attribute in
      * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
      */
-	public int previewImage;
+    public int previewImage;
 
     /**
      * The rules by which a widget can be resized. See {@link #RESIZE_NONE},
@@ -195,12 +206,17 @@
      */
     public int widgetCategory;
 
+    /** @hide */
+    public ActivityInfo providerInfo;
+
     public AppWidgetProviderInfo() {
+
     }
 
     /**
      * Unflatten the AppWidgetProviderInfo from a parcel.
      */
+    @SuppressWarnings("deprecation")
     public AppWidgetProviderInfo(Parcel in) {
         if (0 != in.readInt()) {
             this.provider = new ComponentName(in);
@@ -221,8 +237,74 @@
         this.autoAdvanceViewId = in.readInt();
         this.resizeMode = in.readInt();
         this.widgetCategory = in.readInt();
+        this.providerInfo = in.readParcelable(null);
     }
 
+    /**
+     * Loads the localized label to display to the user in the AppWidget picker.
+     *
+     * @param packageManager Package manager instance for loading resources.
+     * @return The label for the current locale.
+     */
+    public final String loadLabel(PackageManager packageManager) {
+        CharSequence label = providerInfo.loadLabel(packageManager);
+        if (label != null) {
+            return label.toString().trim();
+        }
+        return null;
+    }
+
+    /**
+     * Loads the icon to display for this AppWidget in the AppWidget picker. If not
+     * supplied in the xml, the application icon will be used. A client can optionally
+     * provide a desired density such as {@link android.util.DisplayMetrics#DENSITY_LOW}
+     * {@link android.util.DisplayMetrics#DENSITY_MEDIUM}, etc. If no density is
+     * provided, the density of the current display will be used.
+     * <p>
+     * The loaded icon corresponds to the <code>android:icon</code> attribute in
+     * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
+     * </p>
+     *
+     * @param context Context for accessing resources.
+     * @param density The optional desired density as per
+     *         {@link android.util.DisplayMetrics#densityDpi}.
+     * @return The provider icon.
+     */
+    public final Drawable loadIcon(@NonNull Context context, int density) {
+        return loadDrawable(context, density, providerInfo.getIconResource(), true);
+    }
+
+    /**
+     * Loads a preview of what the AppWidget will look like after it's configured.
+     * A client can optionally provide a desired density such as
+     * {@link android.util.DisplayMetrics#DENSITY_LOW}
+     * {@link android.util.DisplayMetrics#DENSITY_MEDIUM}, etc. If no density is
+     * provided, the density of the current display will be used.
+     * <p>
+     * The loaded image corresponds to the <code>android:previewImage</code> attribute
+     * in the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
+     * </p>
+     *
+     * @param context Context for accessing resources.
+     * @param density The optional desired density as per
+     *         {@link android.util.DisplayMetrics#densityDpi}.
+     * @return The widget preview image or null if preview image is not available.
+     */
+    public final Drawable loadPreviewImage(@NonNull Context context, int density) {
+        return loadDrawable(context, density, previewImage, false);
+    }
+
+    /**
+     * Gets the user profile in which the provider resides.
+     *
+     * @return The hosting user profile.
+     */
+    public final UserHandle getProfile() {
+        return new UserHandle(UserHandle.getUserId(providerInfo.applicationInfo.uid));
+    }
+
+    @Override
+    @SuppressWarnings("deprecation")
     public void writeToParcel(android.os.Parcel out, int flags) {
         if (this.provider != null) {
             out.writeInt(1);
@@ -249,9 +331,11 @@
         out.writeInt(this.autoAdvanceViewId);
         out.writeInt(this.resizeMode);
         out.writeInt(this.widgetCategory);
+        out.writeParcelable(this.providerInfo, flags);
     }
 
     @Override
+    @SuppressWarnings("deprecation")
     public AppWidgetProviderInfo clone() {
         AppWidgetProviderInfo that = new AppWidgetProviderInfo();
         that.provider = this.provider == null ? null : this.provider.clone();
@@ -268,7 +352,8 @@
         that.previewImage = this.previewImage;
         that.autoAdvanceViewId = this.autoAdvanceViewId;
         that.resizeMode = this.resizeMode;
-        that.widgetCategory  = this.widgetCategory;
+        that.widgetCategory = this.widgetCategory;
+        that.providerInfo = this.providerInfo;
         return that;
     }
 
@@ -276,6 +361,23 @@
         return 0;
     }
 
+    private Drawable loadDrawable(Context context, int density, int resourceId,
+            boolean loadDefaultIcon) {
+        try {
+            Resources resources = context.getPackageManager().getResourcesForApplication(
+                    providerInfo.applicationInfo);
+            if (resourceId > 0) {
+                if (density <= 0) {
+                    density = context.getResources().getDisplayMetrics().densityDpi;
+                }
+                return resources.getDrawableForDensity(resourceId, density);
+            }
+        } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
+            /* ignore */
+        }
+        return loadDefaultIcon ? providerInfo.loadIcon(context.getPackageManager()) : null;
+    }
+
     /**
      * Parcelable.Creator that instantiates AppWidgetProviderInfo objects
      */
@@ -294,6 +396,6 @@
     };
 
     public String toString() {
-        return "AppWidgetProviderInfo(provider=" + this.provider + ")";
+        return "AppWidgetProviderInfo(" + getProfile() + '/' + provider + ')';
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 6f929f2..5175490 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -90,6 +90,11 @@
     public static final String ACTION_PLAYING_STATE_CHANGED =
         "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
 
+    /** @hide */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_AVRCP_CONNECTION_STATE_CHANGED =
+        "android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED";
+
     /**
      * A2DP sink device is streaming music. This state can be one of
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
@@ -162,7 +167,8 @@
         Intent intent = new Intent(IBluetoothA2dp.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
-        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
new file mode 100644
index 0000000..2e27345
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides the public APIs to control the Bluetooth A2DP Sink
+ * profile.
+ *
+ *<p>BluetoothA2dpSink is a proxy object for controlling the Bluetooth A2DP Sink
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothA2dpSink proxy object.
+ *
+ * @hide
+ */
+public final class BluetoothA2dpSink implements BluetoothProfile {
+    private static final String TAG = "BluetoothA2dpSink";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false;
+
+    /**
+     * Intent used to broadcast the change in connection state of the A2DP Sink
+     * profile.
+     *
+     * <p>This intent will have 3 extras:
+     * <ul>
+     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * </ul>
+     *
+     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+     * receive.
+     */
+    public static final String ACTION_CONNECTION_STATE_CHANGED =
+        "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";
+
+    /**
+     * Intent used to broadcast the change in the Playing state of the A2DP Sink
+     * profile.
+     *
+     * <p>This intent will have 3 extras:
+     * <ul>
+     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
+     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * </ul>
+     *
+     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+     * {@link #STATE_PLAYING}, {@link #STATE_NOT_PLAYING},
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+     * receive.
+     */
+    public static final String ACTION_PLAYING_STATE_CHANGED =
+        "android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED";
+
+    /**
+     * A2DP sink device is streaming music. This state can be one of
+     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
+     * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
+     */
+    public static final int STATE_PLAYING   =  10;
+
+    /**
+     * A2DP sink device is NOT streaming music. This state can be one of
+     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
+     * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
+     */
+    public static final int STATE_NOT_PLAYING   =  11;
+
+    /**
+     * Intent used to broadcast the change in the Playing state of the A2DP Sink
+     * profile.
+     *
+     * <p>This intent will have 3 extras:
+     * <ul>
+     *   <li> {@link #EXTRA_AUDIO_CONFIG} - The audio configuration for the remote device. </li>
+     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * </ul>
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+     * receive.
+     */
+    public static final String ACTION_AUDIO_CONFIG_CHANGED =
+        "android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED";
+
+    /**
+     * Extra for the {@link #ACTION_AUDIO_CONFIG_CHANGED} intent.
+     *
+     * This extra represents the current audio configuration of the A2DP source device.
+     * {@see BluetoothAudioConfig}
+     */
+    public static final String EXTRA_AUDIO_CONFIG
+            = "android.bluetooth.a2dp-sink.profile.extra.AUDIO_CONFIG";
+
+    private Context mContext;
+    private ServiceListener mServiceListener;
+    private IBluetoothA2dpSink mService;
+    private BluetoothAdapter mAdapter;
+
+    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    if (!up) {
+                        if (VDBG) Log.d(TAG,"Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (VDBG) Log.d(TAG,"Binding service...");
+                                    doBind();
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    }
+                }
+        };
+    /**
+     * Create a BluetoothA2dp proxy object for interacting with the local
+     * Bluetooth A2DP service.
+     *
+     */
+    /*package*/ BluetoothA2dpSink(Context context, ServiceListener l) {
+        mContext = context;
+        mServiceListener = l;
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothA2dpSink.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
+            Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
+            return false;
+        }
+        return true;
+    }
+
+    /*package*/ void close() {
+        mServiceListener = null;
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (Exception e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        synchronized (mConnection) {
+            if (mService != null) {
+                try {
+                    mService = null;
+                    mContext.unbindService(mConnection);
+                } catch (Exception re) {
+                    Log.e(TAG,"",re);
+                }
+            }
+        }
+    }
+
+    public void finalize() {
+        close();
+    }
+    /**
+     * Initiate connection to a profile of the remote bluetooth device.
+     *
+     * <p> Currently, the system supports only 1 connection to the
+     * A2DP profile. The API will automatically disconnect connected
+     * devices before connecting.
+     *
+     * <p> This API returns false in scenarios like the profile on the
+     * device is already connected or Bluetooth is not turned on.
+     * When this API returns true, it is guaranteed that
+     * connection state intent for the profile will be broadcasted with
+     * the state. Users can get the connection state of the profile
+     * from this intent.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
+     * @hide
+     */
+    public boolean connect(BluetoothDevice device) {
+        if (DBG) log("connect(" + device + ")");
+        if (mService != null && isEnabled() &&
+            isValidDevice(device)) {
+            try {
+                return mService.connect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Initiate disconnection from a profile
+     *
+     * <p> This API will return false in scenarios like the profile on the
+     * Bluetooth device is not in connected state etc. When this API returns,
+     * true, it is guaranteed that the connection state change
+     * intent will be broadcasted with the state. Users can get the
+     * disconnection state of the profile from this intent.
+     *
+     * <p> If the disconnection is initiated by a remote device, the state
+     * will transition from {@link #STATE_CONNECTED} to
+     * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
+     * host (local) device the state will transition from
+     * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
+     * state {@link #STATE_DISCONNECTED}. The transition to
+     * {@link #STATE_DISCONNECTING} can be used to distinguish between the
+     * two scenarios.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
+     * @hide
+     */
+    public boolean disconnect(BluetoothDevice device) {
+        if (DBG) log("disconnect(" + device + ")");
+        if (mService != null && isEnabled() &&
+            isValidDevice(device)) {
+            try {
+                return mService.disconnect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List<BluetoothDevice> getConnectedDevices() {
+        if (VDBG) log("getConnectedDevices()");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getConnectedDevices();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return new ArrayList<BluetoothDevice>();
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        if (VDBG) log("getDevicesMatchingStates()");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getDevicesMatchingConnectionStates(states);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return new ArrayList<BluetoothDevice>();
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getConnectionState(BluetoothDevice device) {
+        if (VDBG) log("getState(" + device + ")");
+        if (mService != null && isEnabled()
+            && isValidDevice(device)) {
+            try {
+                return mService.getConnectionState(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return BluetoothProfile.STATE_DISCONNECTED;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return BluetoothProfile.STATE_DISCONNECTED;
+    }
+
+    /**
+     * Get the current audio configuration for the A2DP source device,
+     * or null if the device has no audio configuration
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param device Remote bluetooth device.
+     * @return audio configuration for the device, or null
+     *
+     * {@see BluetoothAudioConfig}
+     */
+          public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
+        if (VDBG) log("getAudioConfig(" + device + ")");
+        if (mService != null && isEnabled()
+            && isValidDevice(device)) {
+            try {
+                return mService.getAudioConfig(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return null;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return null;
+    }
+
+    /**
+     * Helper for converting a state to a string.
+     *
+     * For debug use only - strings are not internationalized.
+     * @hide
+     */
+    public static String stateToString(int state) {
+        switch (state) {
+        case STATE_DISCONNECTED:
+            return "disconnected";
+        case STATE_CONNECTING:
+            return "connecting";
+        case STATE_CONNECTED:
+            return "connected";
+        case STATE_DISCONNECTING:
+            return "disconnecting";
+        case STATE_PLAYING:
+            return "playing";
+        case STATE_NOT_PLAYING:
+          return "not playing";
+        default:
+            return "<unknown state " + state + ">";
+        }
+    }
+
+    private final ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "Proxy object connected");
+            mService = IBluetoothA2dpSink.Stub.asInterface(service);
+
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.A2DP_SINK,
+                        BluetoothA2dpSink.this);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) Log.d(TAG, "Proxy object disconnected");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP_SINK);
+            }
+        }
+    };
+
+    private boolean isEnabled() {
+       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
+       return false;
+    }
+
+    private boolean isValidDevice(BluetoothDevice device) {
+       if (device == null) return false;
+
+       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+       return false;
+    }
+
+    private static void log(String msg) {
+      Log.d(TAG, msg);
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.aidl b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.aidl
new file mode 100644
index 0000000..60cbf9f
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+parcelable BluetoothActivityEnergyInfo;
diff --git a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
new file mode 100644
index 0000000..ce87329
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Record of energy and activity information from controller and
+ * underlying bt stack state.Timestamp the record with system
+ * time
+ * @hide
+ */
+public final class BluetoothActivityEnergyInfo implements Parcelable {
+    private final int mBluetoothStackState;
+    private final int mControllerTxTimeMs;
+    private final int mControllerRxTimeMs;
+    private final int mControllerIdleTimeMs;
+    private final int mControllerEnergyUsed;
+    private final long timestamp;
+
+    public static final int BT_STACK_STATE_INVALID = 0;
+    public static final int BT_STACK_STATE_STATE_ACTIVE = 1;
+    public static final int BT_STACK_STATE_STATE_SCANNING = 2;
+    public static final int BT_STACK_STATE_STATE_IDLE = 3;
+
+    public BluetoothActivityEnergyInfo(int stackState, int txTime, int rxTime,
+            int idleTime, int energyUsed) {
+        mBluetoothStackState = stackState;
+        mControllerTxTimeMs = txTime;
+        mControllerRxTimeMs = rxTime;
+        mControllerIdleTimeMs = idleTime;
+        mControllerEnergyUsed = energyUsed;
+        timestamp = System.currentTimeMillis();
+    }
+
+    @Override
+    public String toString() {
+        return "BluetoothActivityEnergyInfo{"
+            + " timestamp=" + timestamp
+            + " mBluetoothStackState=" + mBluetoothStackState
+            + " mControllerTxTimeMs=" + mControllerTxTimeMs
+            + " mControllerRxTimeMs=" + mControllerRxTimeMs
+            + " mControllerIdleTimeMs=" + mControllerIdleTimeMs
+            + " mControllerEnergyUsed=" + mControllerEnergyUsed
+            + " }";
+    }
+
+    public static final Parcelable.Creator<BluetoothActivityEnergyInfo> CREATOR =
+            new Parcelable.Creator<BluetoothActivityEnergyInfo>() {
+        public BluetoothActivityEnergyInfo createFromParcel(Parcel in) {
+            int stackState = in.readInt();
+            int txTime = in.readInt();
+            int rxTime = in.readInt();
+            int idleTime = in.readInt();
+            int energyUsed = in.readInt();
+            return new BluetoothActivityEnergyInfo(stackState, txTime, rxTime,
+                    idleTime, energyUsed);
+        }
+        public BluetoothActivityEnergyInfo[] newArray(int size) {
+            return new BluetoothActivityEnergyInfo[size];
+        }
+    };
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mBluetoothStackState);
+        out.writeInt(mControllerTxTimeMs);
+        out.writeInt(mControllerRxTimeMs);
+        out.writeInt(mControllerIdleTimeMs);
+        out.writeInt(mControllerEnergyUsed);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * @return bt stack reported state
+     */
+    public int getBluetoothStackState() {
+        return mBluetoothStackState;
+    }
+
+    /**
+     * @return tx time in ms
+     */
+    public int getControllerTxTimeMillis() {
+        return mControllerTxTimeMs;
+    }
+
+    /**
+     * @return rx time in ms
+     */
+    public int getControllerRxTimeMillis() {
+        return mControllerRxTimeMs;
+    }
+
+    /**
+     * @return idle time in ms
+     */
+    public int getControllerIdleTimeMillis() {
+        return mControllerIdleTimeMs;
+    }
+
+    /**
+     * product of current(mA), voltage(V) and time(ms)
+     * @return energy used
+     */
+    public int getControllerEnergyUsed() {
+        return mControllerEnergyUsed;
+    }
+    /**
+     * @return timestamp(wall clock) of record creation
+     */
+    public long getTimeStamp() {
+        return timestamp;
+    }
+
+    /**
+     * @return if the record is valid
+     */
+    public boolean isValid() {
+        return ((getControllerTxTimeMillis() !=0) ||
+                (getControllerRxTimeMillis() !=0) ||
+                (getControllerIdleTimeMillis() !=0));
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 646be06..f0b609a 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-2014 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,12 +18,17 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.bluetooth.le.BluetoothLeAdvertiser;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
 import android.content.Context;
-import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Message;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -37,9 +42,9 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Random;
 import java.util.Set;
 import java.util.UUID;
 
@@ -216,22 +221,6 @@
             "android.bluetooth.adapter.action.SCAN_MODE_CHANGED";
 
     /**
-     * Broadcast Action: Indicate BLE Advertising is started.
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_BLUETOOTH_ADVERTISING_STARTED =
-            "android.bluetooth.adapter.action.ADVERTISING_STARTED";
-
-    /**
-     * Broadcast Action: Indicated BLE Advertising is stopped.
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_BLUETOOTH_ADVERTISING_STOPPED =
-            "android.bluetooth.adapter.action.ADVERTISING_STOPPED";
-
-    /**
      * Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED}
      * intents to request the current scan mode. Possible values are:
      * {@link #SCAN_MODE_NONE},
@@ -367,43 +356,31 @@
     /** The profile is in disconnecting state */
     public static final int STATE_DISCONNECTING = 3;
 
-    /** States for Bluetooth LE advertising */
-    /** @hide */
-    public static final int STATE_ADVERTISE_STARTING = 0;
-    /** @hide */
-    public static final int STATE_ADVERTISE_STARTED = 1;
-    /** @hide */
-    public static final int STATE_ADVERTISE_STOPPING = 2;
-    /** @hide */
-    public static final int STATE_ADVERTISE_STOPPED = 3;
-    /**
-     * Force stopping advertising without callback in case the advertising app dies.
-     * @hide
-     */
-    public static final int STATE_ADVERTISE_FORCE_STOPPING = 4;
-
     /** @hide */
     public static final String BLUETOOTH_MANAGER_SERVICE = "bluetooth_manager";
 
-    /** @hide */
-    public static final int ADVERTISE_CALLBACK_SUCCESS = 0;
-
     private static final int ADDRESS_LENGTH = 17;
 
+    private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30;
+    /** @hide */
+    public static final int ACTIVITY_ENERGY_INFO_CACHED = 0;
+    /** @hide */
+    public static final int ACTIVITY_ENERGY_INFO_REFRESHED = 1;
+
     /**
      * Lazily initialized singleton. Guaranteed final after first object
      * constructed.
      */
     private static BluetoothAdapter sAdapter;
 
+    private static BluetoothLeScanner sBluetoothLeScanner;
+    private static BluetoothLeAdvertiser sBluetoothLeAdvertiser;
+
     private final IBluetoothManager mManagerService;
     private IBluetooth mService;
 
-    private final Map<LeScanCallback, GattCallbackWrapper> mLeScanClients;
-    private BluetoothAdvScanData mBluetoothAdvScanData = null;
-    private GattCallbackWrapper mAdvertisingGattCallback;
-    private final Handler mHandler;  // Handler to post the advertise callback to run on main thread.
     private final Object mLock = new Object();
+    private final Map<LeScanCallback, ScanCallback> mLeScanClients;
 
     /**
      * Get a handle to the default local Bluetooth adapter.
@@ -438,8 +415,7 @@
             mService = managerService.registerAdapter(mManagerCallback);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         mManagerService = managerService;
-        mLeScanClients = new HashMap<LeScanCallback, GattCallbackWrapper>();
-        mHandler = new Handler(Looper.getMainLooper());
+        mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
     }
 
     /**
@@ -478,126 +454,40 @@
     }
 
     /**
-     * Returns a {@link BluetoothAdvScanData} object representing advertising data.
-     * Data will be reset when bluetooth service is turned off.
-     * @hide
+     * Returns a {@link BluetoothLeAdvertiser} object for Bluetooth LE Advertising operations, or
+     * null if Bluetooth LE Advertising is not support on this device.
+     * <p>
+     * Use {@link #isMultipleAdvertisementSupported()} to check whether LE Advertising is supported
+     * on this device before calling this method.
      */
-    public BluetoothAdvScanData getAdvScanData() {
-      try {
-          IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
-          if (iGatt == null) {
-              // BLE is not supported
-              Log.e(TAG, "failed to start, iGatt null");
-              return null;
-          }
-          if (mBluetoothAdvScanData == null) {
-              mBluetoothAdvScanData = new BluetoothAdvScanData(iGatt, BluetoothAdvScanData.AD);
-          }
-          return mBluetoothAdvScanData;
-      } catch (RemoteException e) {
-          Log.e(TAG, "failed to get advScanData, error: " + e);
-          return null;
-      }
-    }
-
-    /**
-     * Interface for BLE advertising callback.
-     *
-     * @hide
-     */
-    public interface AdvertiseCallback {
-        /**
-         * Callback when advertise starts.
-         * @param status - {@link #ADVERTISE_CALLBACK_SUCCESS} for success, others for failure.
-         */
-        void onAdvertiseStart(int status);
-        /**
-         * Callback when advertise stops.
-         * @param status - {@link #ADVERTISE_CALLBACK_SUCCESS} for success, others for failure.
-         */
-        void onAdvertiseStop(int status);
-    }
-
-    /**
-     * Start BLE advertising using current {@link BluetoothAdvScanData}.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}
-     *
-     * @param callback - {@link AdvertiseCallback}
-     * @return true if BLE advertising succeeds, false otherwise.
-     * @hide
-     */
-    public boolean startAdvertising(final AdvertiseCallback callback) {
-        if (getState() != STATE_ON) return false;
-        try {
-            IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
-            if (iGatt == null) {
-                // BLE is not supported.
-                return false;
-            }
-            // Restart/reset advertising packets if advertising is in progress.
-            if (isAdvertising()) {
-                // Invalid advertising callback.
-                if (mAdvertisingGattCallback == null || mAdvertisingGattCallback.mLeHandle == -1) {
-                    Log.e(TAG, "failed to restart advertising, invalid callback");
-                    return false;
-                }
-                iGatt.startAdvertising(mAdvertisingGattCallback.mLeHandle);
-                // Run the callback from main thread.
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        // callback with status success.
-                        callback.onAdvertiseStart(ADVERTISE_CALLBACK_SUCCESS);
-                    }
-                });
-                return true;
-            }
-            UUID uuid = UUID.randomUUID();
-            GattCallbackWrapper wrapper =
-                new GattCallbackWrapper(this, null, null, callback);
-            iGatt.registerClient(new ParcelUuid(uuid), wrapper);
-            if (!wrapper.advertiseStarted()) {
-                return false;
-            }
-            synchronized (mLock) {
-                mAdvertisingGattCallback = wrapper;
-            }
-            return true;
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
+    public BluetoothLeAdvertiser getBluetoothLeAdvertiser() {
+        if (getState() != STATE_ON) {
+            return null;
         }
+        if (!isMultipleAdvertisementSupported()) {
+            return null;
+        }
+        synchronized(mLock) {
+            if (sBluetoothLeAdvertiser == null) {
+                sBluetoothLeAdvertiser = new BluetoothLeAdvertiser(mManagerService);
+            }
+        }
+        return sBluetoothLeAdvertiser;
     }
 
     /**
-     * Stop BLE advertising. The callback has to be the same one used for start advertising.
-     *
-     * @param callback - {@link AdvertiseCallback}
-     * @return true if BLE advertising stops, false otherwise.
-     * @hide
+     * Returns a {@link BluetoothLeScanner} object for Bluetooth LE scan operations.
      */
-    public boolean stopAdvertising(AdvertiseCallback callback) {
-        try {
-            IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
-            if (iGatt == null) {
-                // BLE is not supported
-                return false;
-            }
-            if (mAdvertisingGattCallback == null) {
-                // no callback.
-                return false;
-            }
-            // Make sure same callback is used for start and stop advertising.
-            if (callback != mAdvertisingGattCallback.mAdvertiseCallback) {
-                Log.e(TAG, "must use the same callback for star/stop advertising");
-                return false;
-            }
-            mAdvertisingGattCallback.stopAdvertising();
-            return true;
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
+    public BluetoothLeScanner getBluetoothLeScanner() {
+        if (getState() != STATE_ON) {
+            return null;
         }
+        synchronized(mLock) {
+            if (sBluetoothLeScanner == null) {
+                sBluetoothLeScanner = new BluetoothLeScanner(mManagerService);
+            }
+        }
+        return sBluetoothLeScanner;
     }
 
     /**
@@ -1012,23 +902,88 @@
     }
 
     /**
-     * Returns whether BLE is currently advertising.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
+     * Return true if the multi advertisement is supported by the chipset
      *
-     * @hide
+     * @return true if Multiple Advertisement feature is supported
      */
-    public boolean isAdvertising() {
+    public boolean isMultipleAdvertisementSupported() {
         if (getState() != STATE_ON) return false;
         try {
-            IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
-            return iGatt.isAdvertising();
+            return mService.isMultiAdvertisementSupported();
         } catch (RemoteException e) {
-            Log.e(TAG, "", e);
+            Log.e(TAG, "failed to get isMultipleAdvertisementSupported, error: ", e);
         }
         return false;
     }
 
     /**
+     * Return true if offloaded filters are supported
+     *
+     * @return true if chipset supports on-chip filtering
+     */
+    public boolean isOffloadedFilteringSupported() {
+        if (getState() != STATE_ON) return false;
+        try {
+            return mService.isOffloadedFilteringSupported();
+        } catch (RemoteException e) {
+            Log.e(TAG, "failed to get isOffloadedFilteringSupported, error: ", e);
+        }
+        return false;
+    }
+
+    /**
+     * Return true if offloaded scan batching is supported
+     *
+     * @return true if chipset supports on-chip scan batching
+     */
+    public boolean isOffloadedScanBatchingSupported() {
+        if (getState() != STATE_ON) return false;
+        try {
+            return mService.isOffloadedScanBatchingSupported();
+        } catch (RemoteException e) {
+            Log.e(TAG, "failed to get isOffloadedScanBatchingSupported, error: ", e);
+        }
+        return false;
+    }
+
+    /**
+     * Return the record of {@link BluetoothActivityEnergyInfo} object that
+     * has the activity and energy info. This can be used to ascertain what
+     * the controller has been up to, since the last sample.
+     * @param updateType Type of info, cached vs refreshed.
+     *
+     * @return a record with {@link BluetoothActivityEnergyInfo} or null if
+     * report is unavailable or unsupported
+     * @hide
+     */
+    public BluetoothActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
+        if (getState() != STATE_ON) return null;
+        try {
+            BluetoothActivityEnergyInfo record;
+            if (!mService.isActivityAndEnergyReportingSupported()) {
+                return null;
+            }
+            synchronized(this) {
+                if (updateType == ACTIVITY_ENERGY_INFO_REFRESHED) {
+                    mService.getActivityEnergyInfoFromController();
+                    wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS);
+                }
+                record = mService.reportActivityInfo();
+                if (record.isValid()) {
+                    return record;
+                } else {
+                    return null;
+                }
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "getControllerActivityEnergyInfoCallback wait interrupted: " + e);
+        } catch (RemoteException e) {
+            Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e);
+        }
+        return null;
+    }
+
+    /**
      * Return the set of {@link BluetoothDevice} objects that are bonded
      * (paired) to the local adapter.
      * <p>If Bluetooth state is not {@link #STATE_ON}, this API
@@ -1363,6 +1318,12 @@
         } else if (profile == BluetoothProfile.A2DP) {
             BluetoothA2dp a2dp = new BluetoothA2dp(context, listener);
             return true;
+        } else if (profile == BluetoothProfile.A2DP_SINK) {
+            BluetoothA2dpSink a2dpSink = new BluetoothA2dpSink(context, listener);
+            return true;
+        } else if (profile == BluetoothProfile.AVRCP_CONTROLLER) {
+            BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener);
+            return true;
         } else if (profile == BluetoothProfile.INPUT_DEVICE) {
             BluetoothInputDevice iDev = new BluetoothInputDevice(context, listener);
             return true;
@@ -1375,6 +1336,9 @@
         } else if (profile == BluetoothProfile.MAP) {
             BluetoothMap map = new BluetoothMap(context, listener);
             return true;
+        } else if (profile == BluetoothProfile.HEADSET_CLIENT) {
+            BluetoothHeadsetClient headsetClient = new BluetoothHeadsetClient(context, listener);
+            return true;
         } else {
             return false;
         }
@@ -1403,6 +1367,14 @@
                 BluetoothA2dp a2dp = (BluetoothA2dp)proxy;
                 a2dp.close();
                 break;
+            case BluetoothProfile.A2DP_SINK:
+                BluetoothA2dpSink a2dpSink = (BluetoothA2dpSink)proxy;
+                a2dpSink.close();
+                break;
+            case BluetoothProfile.AVRCP_CONTROLLER:
+                BluetoothAvrcpController avrcp = (BluetoothAvrcpController)proxy;
+                avrcp.close();
+                break;
             case BluetoothProfile.INPUT_DEVICE:
                 BluetoothInputDevice iDev = (BluetoothInputDevice)proxy;
                 iDev.close();
@@ -1427,6 +1399,10 @@
                 BluetoothMap map = (BluetoothMap)proxy;
                 map.close();
                 break;
+            case BluetoothProfile.HEADSET_CLIENT:
+                BluetoothHeadsetClient headsetClient = (BluetoothHeadsetClient)proxy;
+                headsetClient.close();
+                break;
         }
     }
 
@@ -1452,8 +1428,9 @@
                 if (VDBG) Log.d(TAG, "onBluetoothServiceDown: " + mService);
                 synchronized (mManagerCallback) {
                     mService = null;
-                    // Reset bluetooth adv scan data when Gatt service is down.
-                    mBluetoothAdvScanData = null;
+                    mLeScanClients.clear();
+                    if (sBluetoothLeAdvertiser != null) sBluetoothLeAdvertiser.cleanup();
+                    if (sBluetoothLeScanner != null) sBluetoothLeScanner.cleanup();
                     for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){
                         try {
                             if (cb != null) {
@@ -1651,7 +1628,10 @@
      *
      * @param callback the callback LE scan results are delivered
      * @return true, if the scan was started successfully
+     * @deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)}
+     *             instead.
      */
+    @Deprecated
     public boolean startLeScan(LeScanCallback callback) {
         return startLeScan(null, callback);
     }
@@ -1668,14 +1648,21 @@
      * @param serviceUuids Array of services to look for
      * @param callback the callback LE scan results are delivered
      * @return true, if the scan was started successfully
+     * @deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)}
+     *             instead.
      */
-    public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) {
+    @Deprecated
+    public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) {
         if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);
-
         if (callback == null) {
             if (DBG) Log.e(TAG, "startLeScan: null callback");
             return false;
         }
+        BluetoothLeScanner scanner = getBluetoothLeScanner();
+        if (scanner == null) {
+            if (DBG) Log.e(TAG, "startLeScan: cannot get BluetoothLeScanner");
+            return false;
+        }
 
         synchronized(mLeScanClients) {
             if (mLeScanClients.containsKey(callback)) {
@@ -1690,13 +1677,50 @@
                     return false;
                 }
 
-                UUID uuid = UUID.randomUUID();
-                GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids);
-                iGatt.registerClient(new ParcelUuid(uuid), wrapper);
-                if (wrapper.scanStarted()) {
-                    mLeScanClients.put(callback, wrapper);
-                    return true;
+                ScanCallback scanCallback = new ScanCallback() {
+                    @Override
+                    public void onScanResult(int callbackType, ScanResult result) {
+                        if (callbackType != ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
+                            // Should not happen.
+                            Log.e(TAG, "LE Scan has already started");
+                            return;
+                        }
+                        ScanRecord scanRecord = result.getScanRecord();
+                        if (scanRecord == null) {
+                            return;
+                        }
+                        if (serviceUuids != null) {
+                            List<ParcelUuid> uuids = new ArrayList<ParcelUuid>();
+                            for (UUID uuid : serviceUuids) {
+                                uuids.add(new ParcelUuid(uuid));
+                            }
+                            List<ParcelUuid> scanServiceUuids = scanRecord.getServiceUuids();
+                            if (scanServiceUuids == null || !scanServiceUuids.containsAll(uuids)) {
+                                if (DBG) Log.d(TAG, "uuids does not match");
+                                return;
+                            }
+                        }
+                        callback.onLeScan(result.getDevice(), result.getRssi(),
+                                scanRecord.getBytes());
+                    }
+                };
+                ScanSettings settings = new ScanSettings.Builder()
+                    .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
+                    .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
+
+                List<ScanFilter> filters = new ArrayList<ScanFilter>();
+                if (serviceUuids != null && serviceUuids.length > 0) {
+                    // Note scan filter does not support matching an UUID array so we put one
+                    // UUID to hardware and match the whole array in callback.
+                    ScanFilter filter = new ScanFilter.Builder().setServiceUuid(
+                            new ParcelUuid(serviceUuids[0])).build();
+                    filters.add(filter);
                 }
+                scanner.startScan(filters, settings, scanCallback);
+
+                mLeScanClients.put(callback, scanCallback);
+                return true;
+
             } catch (RemoteException e) {
                 Log.e(TAG,"",e);
             }
@@ -1711,328 +1735,22 @@
      *
      * @param callback used to identify which scan to stop
      *        must be the same handle used to start the scan
+     * @deprecated Use {@link BluetoothLeScanner#stopScan(ScanCallback)} instead.
      */
+    @Deprecated
     public void stopLeScan(LeScanCallback callback) {
         if (DBG) Log.d(TAG, "stopLeScan()");
-        GattCallbackWrapper wrapper;
-        synchronized(mLeScanClients) {
-            wrapper = mLeScanClients.remove(callback);
-            if (wrapper == null) return;
+        BluetoothLeScanner scanner = getBluetoothLeScanner();
+        if (scanner == null) {
+            return;
         }
-        wrapper.stopLeScan();
-    }
-
-    /**
-     * Bluetooth GATT interface callbacks
-     */
-    private static class GattCallbackWrapper extends IBluetoothGattCallback.Stub {
-        private static final int LE_CALLBACK_REG_TIMEOUT = 2000;
-        private static final int LE_CALLBACK_REG_WAIT_COUNT = 5;
-
-        private final AdvertiseCallback mAdvertiseCallback;
-        private final LeScanCallback mLeScanCb;
-
-        // mLeHandle 0: not registered
-        //           -1: scan stopped
-        //           >0: registered and scan started
-        private int mLeHandle;
-        private final UUID[] mScanFilter;
-        private WeakReference<BluetoothAdapter> mBluetoothAdapter;
-
-        public GattCallbackWrapper(BluetoothAdapter bluetoothAdapter,
-                                   LeScanCallback leScanCb, UUID[] uuid) {
-            mBluetoothAdapter = new WeakReference<BluetoothAdapter>(bluetoothAdapter);
-            mLeScanCb = leScanCb;
-            mScanFilter = uuid;
-            mLeHandle = 0;
-            mAdvertiseCallback = null;
-        }
-
-        public GattCallbackWrapper(BluetoothAdapter bluetoothAdapter, LeScanCallback leScanCb,
-            UUID[] uuid, AdvertiseCallback callback) {
-          mBluetoothAdapter = new WeakReference<BluetoothAdapter>(bluetoothAdapter);
-          mLeScanCb = leScanCb;
-          mScanFilter = uuid;
-          mLeHandle = 0;
-          mAdvertiseCallback = callback;
-        }
-
-        public boolean scanStarted() {
-            return waitForRegisteration(LE_CALLBACK_REG_WAIT_COUNT);
-        }
-
-        public boolean advertiseStarted() {
-            // Wait for registeration callback.
-            return waitForRegisteration(1);
-        }
-
-        private boolean waitForRegisteration(int maxWaitCount) {
-            boolean started = false;
-            synchronized(this) {
-                if (mLeHandle == -1) return false;
-                int count = 0;
-                // wait for callback registration and LE scan to start
-                while (mLeHandle == 0 && count < maxWaitCount) {
-                    try {
-                        wait(LE_CALLBACK_REG_TIMEOUT);
-                    } catch (InterruptedException e) {
-                        Log.e(TAG, "Callback reg wait interrupted: " + e);
-                    }
-                    count++;
-                }
-                started = (mLeHandle > 0);
+        synchronized (mLeScanClients) {
+            ScanCallback scanCallback = mLeScanClients.remove(callback);
+            if (scanCallback == null) {
+                if (DBG) Log.d(TAG, "scan not started yet");
+                return;
             }
-            return started;
-        }
-
-        public void stopAdvertising() {
-            synchronized (this) {
-                if (mLeHandle <= 0) {
-                    Log.e(TAG, "Error state, mLeHandle: " + mLeHandle);
-                    return;
-                }
-                BluetoothAdapter adapter = mBluetoothAdapter.get();
-                if (adapter != null) {
-                    try {
-                        IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt();
-                        iGatt.stopAdvertising();
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Failed to stop advertising" + e);
-                    }
-                } else {
-                    Log.e(TAG, "stopAdvertising, BluetoothAdapter is null");
-                }
-                notifyAll();
-            }
-        }
-
-        public void stopLeScan() {
-            synchronized(this) {
-                if (mLeHandle <= 0) {
-                    Log.e(TAG, "Error state, mLeHandle: " + mLeHandle);
-                    return;
-                }
-                BluetoothAdapter adapter = mBluetoothAdapter.get();
-                if (adapter != null) {
-                    try {
-                        IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt();
-                        iGatt.stopScan(mLeHandle, false);
-                        iGatt.unregisterClient(mLeHandle);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Failed to stop scan and unregister" + e);
-                    }
-                } else {
-                    Log.e(TAG, "stopLeScan, BluetoothAdapter is null");
-                }
-                mLeHandle = -1;
-                notifyAll();
-            }
-        }
-
-        /**
-         * Application interface registered - app is ready to go
-         */
-        public void onClientRegistered(int status, int clientIf) {
-            if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status +
-                           " clientIf=" + clientIf);
-            synchronized(this) {
-                if (mLeHandle == -1) {
-                    if (DBG) Log.d(TAG, "onClientRegistered LE scan canceled");
-                }
-
-                if (status == BluetoothGatt.GATT_SUCCESS) {
-                    mLeHandle = clientIf;
-                    IBluetoothGatt iGatt = null;
-                    try {
-                        BluetoothAdapter adapter = mBluetoothAdapter.get();
-                        if (adapter != null) {
-                            iGatt = adapter.getBluetoothManager().getBluetoothGatt();
-                            if (mAdvertiseCallback != null) {
-                                iGatt.startAdvertising(mLeHandle);
-                            } else {
-                              if (mScanFilter == null) {
-                                  iGatt.startScan(mLeHandle, false);
-                              } else {
-                                  ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length];
-                                  for(int i = 0; i != uuids.length; ++i) {
-                                      uuids[i] = new ParcelUuid(mScanFilter[i]);
-                                  }
-                                  iGatt.startScanWithUuids(mLeHandle, false, uuids);
-                              }
-                            }
-                        } else {
-                            Log.e(TAG, "onClientRegistered, BluetoothAdapter null");
-                            mLeHandle = -1;
-                        }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "fail to start le scan: " + e);
-                        mLeHandle = -1;
-                    }
-                    if (mLeHandle == -1) {
-                        // registration succeeded but start scan or advertise failed
-                        if (iGatt != null) {
-                            try {
-                                iGatt.unregisterClient(mLeHandle);
-                            } catch (RemoteException e) {
-                                Log.e(TAG, "fail to unregister callback: " + mLeHandle +
-                                      " error: " + e);
-                            }
-                        }
-                    }
-                } else {
-                    // registration failed
-                    mLeHandle = -1;
-                }
-                notifyAll();
-            }
-        }
-
-        public void onClientConnectionState(int status, int clientIf,
-                                            boolean connected, String address) {
-            // no op
-        }
-
-        /**
-         * Callback reporting an LE scan result.
-         * @hide
-         */
-        public void onScanResult(String address, int rssi, byte[] advData) {
-            if (VDBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
-
-            // Check null in case the scan has been stopped
-            synchronized(this) {
-                if (mLeHandle <= 0) return;
-            }
-            try {
-                BluetoothAdapter adapter = mBluetoothAdapter.get();
-                if (adapter == null) {
-                    Log.d(TAG, "onScanResult, BluetoothAdapter null");
-                    return;
-                }
-                mLeScanCb.onLeScan(adapter.getRemoteDevice(address), rssi, advData);
-            } catch (Exception ex) {
-                Log.w(TAG, "Unhandled exception: " + ex);
-            }
-        }
-
-        public void onGetService(String address, int srvcType,
-                                 int srvcInstId, ParcelUuid srvcUuid) {
-            // no op
-        }
-
-        public void onGetIncludedService(String address, int srvcType,
-                                         int srvcInstId, ParcelUuid srvcUuid,
-                                         int inclSrvcType, int inclSrvcInstId,
-                                         ParcelUuid inclSrvcUuid) {
-            // no op
-        }
-
-        public void onGetCharacteristic(String address, int srvcType,
-                                        int srvcInstId, ParcelUuid srvcUuid,
-                                        int charInstId, ParcelUuid charUuid,
-                                        int charProps) {
-            // no op
-        }
-
-        public void onGetDescriptor(String address, int srvcType,
-                                    int srvcInstId, ParcelUuid srvcUuid,
-                                    int charInstId, ParcelUuid charUuid,
-                                    int descInstId, ParcelUuid descUuid) {
-            // no op
-        }
-
-        public void onSearchComplete(String address, int status) {
-            // no op
-        }
-
-        public void onCharacteristicRead(String address, int status, int srvcType,
-                                         int srvcInstId, ParcelUuid srvcUuid,
-                                         int charInstId, ParcelUuid charUuid, byte[] value) {
-            // no op
-        }
-
-        public void onCharacteristicWrite(String address, int status, int srvcType,
-                                          int srvcInstId, ParcelUuid srvcUuid,
-                                          int charInstId, ParcelUuid charUuid) {
-            // no op
-        }
-
-        public void onNotify(String address, int srvcType,
-                             int srvcInstId, ParcelUuid srvcUuid,
-                             int charInstId, ParcelUuid charUuid,
-                             byte[] value) {
-            // no op
-        }
-
-        public void onDescriptorRead(String address, int status, int srvcType,
-                                     int srvcInstId, ParcelUuid srvcUuid,
-                                     int charInstId, ParcelUuid charUuid,
-                                     int descInstId, ParcelUuid descrUuid, byte[] value) {
-            // no op
-        }
-
-        public void onDescriptorWrite(String address, int status, int srvcType,
-                                      int srvcInstId, ParcelUuid srvcUuid,
-                                      int charInstId, ParcelUuid charUuid,
-                                      int descInstId, ParcelUuid descrUuid) {
-            // no op
-        }
-
-        public void onExecuteWrite(String address, int status) {
-            // no op
-        }
-
-        public void onReadRemoteRssi(String address, int rssi, int status) {
-            // no op
-        }
-
-        public void onAdvertiseStateChange(int advertiseState, int status) {
-            Log.d(TAG, "on advertise call back, state: " + advertiseState + " status: " + status);
-            if (advertiseState == STATE_ADVERTISE_STARTED) {
-                if (status == ADVERTISE_CALLBACK_SUCCESS) {
-                    mAdvertiseCallback.onAdvertiseStart(status);
-                } else {
-                    // If status is unsuccessful and advertise state is started, it means stop
-                    // advertising fails.
-                    mAdvertiseCallback.onAdvertiseStop(status);
-                }
-            } else {
-                synchronized (this) {
-                    if (status == ADVERTISE_CALLBACK_SUCCESS) {
-                        BluetoothAdapter adapter = mBluetoothAdapter.get();
-                        if (adapter != null) {
-                            try {
-                                IBluetoothGatt iGatt =
-                                        adapter.getBluetoothManager().getBluetoothGatt();
-                                Log.d(TAG, "unregistering client " + mLeHandle);
-                                iGatt.unregisterClient(mLeHandle);
-                                // Reset advertise app handle.
-                                mLeHandle = -1;
-                                adapter.mAdvertisingGattCallback = null;
-                            } catch (RemoteException e) {
-                                Log.e(TAG, "Failed to unregister client" + e);
-                            }
-                        } else {
-                            Log.e(TAG, "cannot unregister client, BluetoothAdapter is null");
-                        }
-                    }
-                }
-                if (status == ADVERTISE_CALLBACK_SUCCESS) {
-                    mAdvertiseCallback.onAdvertiseStop(status);
-                } else{
-                    // If status is unsuccesful and advertise state is stopped, it means start
-                    // advertising fails.
-                    mAdvertiseCallback.onAdvertiseStart(status);
-                }
-            }
-        }
-
-        /**
-         * Callback reporting LE ATT MTU.
-         * @hide
-         */
-        public void onConfigureMTU(String address, int mtu, int status) {
-            // no op
+            scanner.stopScan(scanCallback);
         }
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothAdvScanData.java b/core/java/android/bluetooth/BluetoothAdvScanData.java
deleted file mode 100644
index df2c256..0000000
--- a/core/java/android/bluetooth/BluetoothAdvScanData.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.Collections;
-import java.util.List;
-
-
-/**
- * This class provides the public APIs to set advertising and scan response data when BLE device
- * operates in peripheral mode. <br>
- * The exact format is defined in Bluetooth 4.0 specification, Volume 3, Part C, Section 11
- * @hide
- */
-public final class BluetoothAdvScanData {
-
-  /**
-   * Available data types of {@link BluetoothAdvScanData}.
-   */
-  public static final int AD = 0;  // Advertising Data
-  public static final int SCAN_RESPONSE = 1;  // Scan Response
-  public static final int EIR = 2;  // Extended Inquiry Response
-
-  private static final String TAG = "BluetoothAdvScanData";
-
-  /**
-   * Data type of BluetoothAdvScanData.
-   */
-  private final int mDataType;
-  /**
-   * Bluetooth Gatt Service.
-   */
-  private IBluetoothGatt mBluetoothGatt;
-
-  /**
-   * @param mBluetoothGatt
-   * @param dataType
-   */
-  public BluetoothAdvScanData(IBluetoothGatt mBluetoothGatt, int dataType) {
-    this.mBluetoothGatt = mBluetoothGatt;
-    this.mDataType = dataType;
-  }
-
-  /**
-   * @return advertising data type.
-   */
-  public int getDataType() {
-    return mDataType;
-  }
-
-  /**
-   * Set manufactureCode and manufactureData.
-   * Returns true if manufacturer data is set, false if there is no enough room to set
-   * manufacturer data or the data is already set.
-   * @param manufacturerCode - unique identifier for the manufacturer
-   * @param manufacturerData - data associated with the specific manufacturer.
-   */
-  public boolean setManufacturerData(int manufacturerCode, byte[] manufacturerData) {
-    if (mDataType != AD) return false;
-    try {
-      return mBluetoothGatt.setAdvManufacturerCodeAndData(manufacturerCode, manufacturerData);
-    } catch (RemoteException e) {
-      Log.e(TAG, "Unable to set manufacturer id and data.", e);
-      return false;
-    }
-  }
-
-  /**
-   * Set service data.  Note the service data can only be set when the data type is {@code AD};
-   * @param serviceData
-   */
-  public boolean setServiceData(byte[] serviceData) {
-
-    if (mDataType != AD) return false;
-    if (serviceData == null) return false;
-    try {
-      return mBluetoothGatt.setAdvServiceData(serviceData);
-    } catch (RemoteException e) {
-      Log.e(TAG, "Unable to set service data.", e);
-      return false;
-    }
-  }
-
-  /**
-   * Returns an immutable list of service uuids that will be advertised.
-   */
-  public List<ParcelUuid> getServiceUuids() {
-    try {
-      return Collections.unmodifiableList(mBluetoothGatt.getAdvServiceUuids());
-    } catch (RemoteException e) {
-      Log.e(TAG, "Unable to get service uuids.", e);
-      return null;
-    }
-  }
-
-  /**
-   * Returns manufacturer data.
-   */
-  public byte[] getManufacturerData() {
-    if (mBluetoothGatt == null) return null;
-    try {
-      return mBluetoothGatt.getAdvManufacturerData();
-    } catch (RemoteException e) {
-      Log.e(TAG, "Unable to get manufacturer data.", e);
-      return null;
-    }
-  }
-
-  /**
-   * Returns service data.
-   */
-  public byte[] getServiceData() {
-    if (mBluetoothGatt == null) return null;
-    try {
-      return mBluetoothGatt.getAdvServiceData();
-    } catch (RemoteException e) {
-      Log.e(TAG, "Unable to get service data.", e);
-      return null;
-    }
-  }
-
-  /**
-   * Remove manufacturer data based on given manufacturer code.
-   * @param manufacturerCode
-   */
-  public void removeManufacturerCodeAndData(int manufacturerCode) {
-    if (mBluetoothGatt != null) {
-      try {
-        mBluetoothGatt.removeAdvManufacturerCodeAndData(manufacturerCode);
-      } catch (RemoteException e) {
-        Log.e(TAG, "Unable to remove manufacturer : " + manufacturerCode, e);
-      }
-    }
-  }
-}
diff --git a/core/java/android/bluetooth/BluetoothAudioConfig.aidl b/core/java/android/bluetooth/BluetoothAudioConfig.aidl
new file mode 100644
index 0000000..63be5cf
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothAudioConfig.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+parcelable BluetoothAudioConfig;
diff --git a/core/java/android/bluetooth/BluetoothAudioConfig.java b/core/java/android/bluetooth/BluetoothAudioConfig.java
new file mode 100644
index 0000000..03176b9
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothAudioConfig.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents the audio configuration for a Bluetooth A2DP source device.
+ *
+ * {@see BluetoothA2dpSink}
+ *
+ * {@hide}
+ */
+public final class BluetoothAudioConfig implements Parcelable {
+
+    private final int mSampleRate;
+    private final int mChannelConfig;
+    private final int mAudioFormat;
+
+    public BluetoothAudioConfig(int sampleRate, int channelConfig, int audioFormat) {
+        mSampleRate = sampleRate;
+        mChannelConfig = channelConfig;
+        mAudioFormat = audioFormat;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof BluetoothAudioConfig) {
+            BluetoothAudioConfig bac = (BluetoothAudioConfig)o;
+            return (bac.mSampleRate == mSampleRate &&
+                    bac.mChannelConfig == mChannelConfig &&
+                    bac.mAudioFormat == mAudioFormat);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return mSampleRate | (mChannelConfig << 24) | (mAudioFormat << 28);
+    }
+
+    @Override
+    public String toString() {
+        return "{mSampleRate:" + mSampleRate + ",mChannelConfig:" + mChannelConfig
+                + ",mAudioFormat:" + mAudioFormat + "}";
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<BluetoothAudioConfig> CREATOR =
+            new Parcelable.Creator<BluetoothAudioConfig>() {
+        public BluetoothAudioConfig createFromParcel(Parcel in) {
+            int sampleRate = in.readInt();
+            int channelConfig = in.readInt();
+            int audioFormat = in.readInt();
+            return new BluetoothAudioConfig(sampleRate, channelConfig, audioFormat);
+        }
+        public BluetoothAudioConfig[] newArray(int size) {
+            return new BluetoothAudioConfig[size];
+        }
+    };
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mSampleRate);
+        out.writeInt(mChannelConfig);
+        out.writeInt(mAudioFormat);
+    }
+
+    /**
+     * Returns the sample rate in samples per second
+     * @return sample rate
+     */
+    public int getSampleRate() {
+        return mSampleRate;
+    }
+
+    /**
+     * Returns the channel configuration (either {@link android.media.AudioFormat#CHANNEL_IN_MONO}
+     * or {@link android.media.AudioFormat#CHANNEL_IN_STEREO})
+     * @return channel configuration
+     */
+    public int getChannelConfig() {
+        return mChannelConfig;
+    }
+
+    /**
+     * Returns the channel audio format (either {@link android.media.AudioFormat#ENCODING_PCM_16BIT}
+     * or {@link android.media.AudioFormat#ENCODING_PCM_8BIT}
+     * @return audio format
+     */
+    public int getAudioFormat() {
+        return mAudioFormat;
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothAvrcp.java b/core/java/android/bluetooth/BluetoothAvrcp.java
new file mode 100644
index 0000000..44fe1b7
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothAvrcp.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+/**
+ * This class contains constants for Bluetooth AVRCP profile.
+ *
+ * {@hide}
+ */
+public final class BluetoothAvrcp {
+
+    /*
+     * State flags for Passthrough commands
+    */
+    public static final int PASSTHROUGH_STATE_PRESS    = 0;
+    public static final int PASSTHROUGH_STATE_RELEASE  = 1;
+
+    /*
+     * Operation IDs for Passthrough commands
+    */
+    public static final int PASSTHROUGH_ID_SELECT      = 0x00;    /* select */
+    public static final int PASSTHROUGH_ID_UP          = 0x01;    /* up */
+    public static final int PASSTHROUGH_ID_DOWN        = 0x02;    /* down */
+    public static final int PASSTHROUGH_ID_LEFT        = 0x03;    /* left */
+    public static final int PASSTHROUGH_ID_RIGHT       = 0x04;    /* right */
+    public static final int PASSTHROUGH_ID_RIGHT_UP    = 0x05;    /* right-up */
+    public static final int PASSTHROUGH_ID_RIGHT_DOWN  = 0x06;    /* right-down */
+    public static final int PASSTHROUGH_ID_LEFT_UP     = 0x07;    /* left-up */
+    public static final int PASSTHROUGH_ID_LEFT_DOWN   = 0x08;    /* left-down */
+    public static final int PASSTHROUGH_ID_ROOT_MENU   = 0x09;    /* root menu */
+    public static final int PASSTHROUGH_ID_SETUP_MENU  = 0x0A;    /* setup menu */
+    public static final int PASSTHROUGH_ID_CONT_MENU   = 0x0B;    /* contents menu */
+    public static final int PASSTHROUGH_ID_FAV_MENU    = 0x0C;    /* favorite menu */
+    public static final int PASSTHROUGH_ID_EXIT        = 0x0D;    /* exit */
+    public static final int PASSTHROUGH_ID_0           = 0x20;    /* 0 */
+    public static final int PASSTHROUGH_ID_1           = 0x21;    /* 1 */
+    public static final int PASSTHROUGH_ID_2           = 0x22;    /* 2 */
+    public static final int PASSTHROUGH_ID_3           = 0x23;    /* 3 */
+    public static final int PASSTHROUGH_ID_4           = 0x24;    /* 4 */
+    public static final int PASSTHROUGH_ID_5           = 0x25;    /* 5 */
+    public static final int PASSTHROUGH_ID_6           = 0x26;    /* 6 */
+    public static final int PASSTHROUGH_ID_7           = 0x27;    /* 7 */
+    public static final int PASSTHROUGH_ID_8           = 0x28;    /* 8 */
+    public static final int PASSTHROUGH_ID_9           = 0x29;    /* 9 */
+    public static final int PASSTHROUGH_ID_DOT         = 0x2A;    /* dot */
+    public static final int PASSTHROUGH_ID_ENTER       = 0x2B;    /* enter */
+    public static final int PASSTHROUGH_ID_CLEAR       = 0x2C;    /* clear */
+    public static final int PASSTHROUGH_ID_CHAN_UP     = 0x30;    /* channel up */
+    public static final int PASSTHROUGH_ID_CHAN_DOWN   = 0x31;    /* channel down */
+    public static final int PASSTHROUGH_ID_PREV_CHAN   = 0x32;    /* previous channel */
+    public static final int PASSTHROUGH_ID_SOUND_SEL   = 0x33;    /* sound select */
+    public static final int PASSTHROUGH_ID_INPUT_SEL   = 0x34;    /* input select */
+    public static final int PASSTHROUGH_ID_DISP_INFO   = 0x35;    /* display information */
+    public static final int PASSTHROUGH_ID_HELP        = 0x36;    /* help */
+    public static final int PASSTHROUGH_ID_PAGE_UP     = 0x37;    /* page up */
+    public static final int PASSTHROUGH_ID_PAGE_DOWN   = 0x38;    /* page down */
+    public static final int PASSTHROUGH_ID_POWER       = 0x40;    /* power */
+    public static final int PASSTHROUGH_ID_VOL_UP      = 0x41;    /* volume up */
+    public static final int PASSTHROUGH_ID_VOL_DOWN    = 0x42;    /* volume down */
+    public static final int PASSTHROUGH_ID_MUTE        = 0x43;    /* mute */
+    public static final int PASSTHROUGH_ID_PLAY        = 0x44;    /* play */
+    public static final int PASSTHROUGH_ID_STOP        = 0x45;    /* stop */
+    public static final int PASSTHROUGH_ID_PAUSE       = 0x46;    /* pause */
+    public static final int PASSTHROUGH_ID_RECORD      = 0x47;    /* record */
+    public static final int PASSTHROUGH_ID_REWIND      = 0x48;    /* rewind */
+    public static final int PASSTHROUGH_ID_FAST_FOR    = 0x49;    /* fast forward */
+    public static final int PASSTHROUGH_ID_EJECT       = 0x4A;    /* eject */
+    public static final int PASSTHROUGH_ID_FORWARD     = 0x4B;    /* forward */
+    public static final int PASSTHROUGH_ID_BACKWARD    = 0x4C;    /* backward */
+    public static final int PASSTHROUGH_ID_ANGLE       = 0x50;    /* angle */
+    public static final int PASSTHROUGH_ID_SUBPICT     = 0x51;    /* subpicture */
+    public static final int PASSTHROUGH_ID_F1          = 0x71;    /* F1 */
+    public static final int PASSTHROUGH_ID_F2          = 0x72;    /* F2 */
+    public static final int PASSTHROUGH_ID_F3          = 0x73;    /* F3 */
+    public static final int PASSTHROUGH_ID_F4          = 0x74;    /* F4 */
+    public static final int PASSTHROUGH_ID_F5          = 0x75;    /* F5 */
+    public static final int PASSTHROUGH_ID_VENDOR      = 0x7E;    /* vendor unique */
+    public static final int PASSTHROUGH_KEYPRESSED_RELEASE = 0x80;
+}
diff --git a/core/java/android/bluetooth/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
new file mode 100644
index 0000000..b53a8fc
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothAvrcpController.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides the public APIs to control the Bluetooth AVRCP Controller
+ * profile.
+ *
+ *<p>BluetoothAvrcpController is a proxy object for controlling the Bluetooth AVRCP
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothAvrcpController proxy object.
+ *
+ * {@hide}
+ */
+public final class BluetoothAvrcpController implements BluetoothProfile {
+    private static final String TAG = "BluetoothAvrcpController";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false;
+
+    /**
+     * Intent used to broadcast the change in connection state of the AVRCP Controller
+     * profile.
+     *
+     * <p>This intent will have 3 extras:
+     * <ul>
+     *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+     *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * </ul>
+     *
+     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+     * receive.
+     */
+    public static final String ACTION_CONNECTION_STATE_CHANGED =
+        "android.bluetooth.acrcp-controller.profile.action.CONNECTION_STATE_CHANGED";
+
+    private Context mContext;
+    private ServiceListener mServiceListener;
+    private IBluetoothAvrcpController mService;
+    private BluetoothAdapter mAdapter;
+
+    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    if (!up) {
+                        if (VDBG) Log.d(TAG,"Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (VDBG) Log.d(TAG,"Binding service...");
+                                    doBind();
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    }
+                }
+        };
+
+    /**
+     * Create a BluetoothAvrcpController proxy object for interacting with the local
+     * Bluetooth AVRCP service.
+     *
+     */
+    /*package*/ BluetoothAvrcpController(Context context, ServiceListener l) {
+        mContext = context;
+        mServiceListener = l;
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothAvrcpController.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
+            Log.e(TAG, "Could not bind to Bluetooth AVRCP Controller Service with " + intent);
+            return false;
+        }
+        return true;
+    }
+
+    /*package*/ void close() {
+        mServiceListener = null;
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (Exception e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        synchronized (mConnection) {
+            if (mService != null) {
+                try {
+                    mService = null;
+                    mContext.unbindService(mConnection);
+                } catch (Exception re) {
+                    Log.e(TAG,"",re);
+                }
+            }
+        }
+    }
+
+    public void finalize() {
+        close();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List<BluetoothDevice> getConnectedDevices() {
+        if (VDBG) log("getConnectedDevices()");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getConnectedDevices();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return new ArrayList<BluetoothDevice>();
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        if (VDBG) log("getDevicesMatchingStates()");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getDevicesMatchingConnectionStates(states);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return new ArrayList<BluetoothDevice>();
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getConnectionState(BluetoothDevice device) {
+        if (VDBG) log("getState(" + device + ")");
+        if (mService != null && isEnabled()
+            && isValidDevice(device)) {
+            try {
+                return mService.getConnectionState(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return BluetoothProfile.STATE_DISCONNECTED;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return BluetoothProfile.STATE_DISCONNECTED;
+    }
+
+    public void sendPassThroughCmd(BluetoothDevice device, int keyCode, int keyState) {
+        if (DBG) Log.d(TAG, "sendPassThroughCmd");
+        if (mService != null && isEnabled()) {
+            try {
+                mService.sendPassThroughCmd(device, keyCode, keyState);
+                return;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error talking to BT service in sendPassThroughCmd()", e);
+                return;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+    }
+
+    private final ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "Proxy object connected");
+            mService = IBluetoothAvrcpController.Stub.asInterface(service);
+
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.AVRCP_CONTROLLER,
+                        BluetoothAvrcpController.this);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) Log.d(TAG, "Proxy object disconnected");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.AVRCP_CONTROLLER);
+            }
+        }
+    };
+
+    private boolean isEnabled() {
+       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
+       return false;
+    }
+
+    private boolean isValidDevice(BluetoothDevice device) {
+       if (device == null) return false;
+
+       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+       return false;
+    }
+
+    private static void log(String msg) {
+      Log.d(TAG, msg);
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index d789a944..5e50b69 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -19,12 +19,10 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.io.IOException;
@@ -308,6 +306,11 @@
     public static final String ACTION_UUID =
             "android.bluetooth.device.action.UUID";
 
+    /** @hide */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_MAS_INSTANCE =
+            "android.bluetooth.device.action.MAS_INSTANCE";
+
     /**
      * Broadcast Action: Indicates a failure to retrieve the name of a remote
      * device.
@@ -515,6 +518,49 @@
     public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
 
     /**
+     * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
+     * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
+     * @hide
+     */
+    public static final int ACCESS_UNKNOWN = 0;
+
+    /**
+     * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
+     * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
+     * @hide
+     */
+    public static final int ACCESS_ALLOWED = 1;
+
+    /**
+     * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
+     * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
+     * @hide
+     */
+    public static final int ACCESS_REJECTED = 2;
+
+     /**
+      * No preferrence of physical transport for GATT connections to remote dual-mode devices
+      * @hide
+      */
+    public static final int TRANSPORT_AUTO = 0;
+
+    /**
+     * Prefer BR/EDR transport for GATT connections to remote dual-mode devices
+     * @hide
+     */
+    public static final int TRANSPORT_BREDR = 1;
+
+    /**
+     * Prefer LE transport for GATT connections to remote dual-mode devices
+     * @hide
+     */
+    public static final int TRANSPORT_LE = 2;
+
+    /** @hide */
+    public static final String EXTRA_MAS_INSTANCE =
+        "android.bluetooth.device.extra.MAS_INSTANCE";
+
+    /**
      * Lazy initialization. Guaranteed final after first object constructed, or
      * getService() called.
      * TODO: Unify implementation of sService amongst BluetoothFoo API's
@@ -735,7 +781,38 @@
             return false;
         }
         try {
-            return sService.createBond(this);
+            return sService.createBond(this, TRANSPORT_AUTO);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return false;
+    }
+
+    /**
+     * Start the bonding (pairing) process with the remote device using the
+     * specified transport.
+     *
+     * <p>This is an asynchronous call, it will return immediately. Register
+     * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
+     * the bonding process completes, and its result.
+     * <p>Android system services will handle the necessary user interactions
+     * to confirm and complete the bonding process.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
+     *
+     * @param transport The transport to use for the pairing procedure.
+     * @return false on immediate error, true if bonding will begin
+     * @throws IllegalArgumentException if an invalid transport was specified
+     * @hide
+     */
+    public boolean createBond(int transport) {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
+            return false;
+        }
+        if (TRANSPORT_AUTO > transport || transport > TRANSPORT_LE)
+        {
+            throw new IllegalArgumentException(transport + " is not a valid Bluetooth transport");
+        }
+        try {
+            return sService.createBond(this, transport);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -857,6 +934,26 @@
     }
 
     /**
+     * Returns whether there is an open connection to this device.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
+     *
+     * @return True if there is at least one open connection to this device.
+     * @hide
+     */
+    public boolean isConnected() {
+        if (sService == null) {
+            // BT is not enabled, we cannot be connected.
+            return false;
+        }
+        try {
+            return sService.isConnected(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+            return false;
+        }
+    }
+
+    /**
      * Get the Bluetooth class of the remote device.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
      *
@@ -876,39 +973,6 @@
     }
 
     /**
-     * Get trust state of a remote device.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
-     * @hide
-     */
-    public boolean getTrustState() {
-        //TODO(BT)
-        /*
-        try {
-            return sService.getTrustState(this);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }*/
-        return false;
-    }
-
-    /**
-     * Set trust state for a remote device.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
-     * @param value the trust state value (true or false)
-     * @hide
-     */
-    public boolean setTrust(boolean value) {
-        //TODO(BT)
-        /*
-        try {
-            return sService.setTrust(this, value);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        }*/
-        return false;
-    }
-
-    /**
      * Returns the supported features (UUIDs) of the remote device.
      *
      * <p>This method does not start a service discovery procedure to retrieve the UUIDs
@@ -947,12 +1011,29 @@
       *               was started.
       */
      public boolean fetchUuidsWithSdp() {
+        IBluetooth service = sService;
+        if (service == null) {
+            Log.e(TAG, "BT not enabled. Cannot fetchUuidsWithSdp");
+            return false;
+        }
         try {
-            return sService.fetchRemoteUuids(this);
+            return service.fetchRemoteUuids(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
             return false;
     }
 
+     /** @hide */
+     public boolean fetchMasInstances() {
+         if (sService == null) {
+             Log.e(TAG, "BT not enabled. Cannot query remote device for MAS instances");
+             return false;
+         }
+         try {
+             return sService.fetchRemoteMasInstances(this);
+         } catch (RemoteException e) {Log.e(TAG, "", e);}
+         return false;
+     }
+
     /** @hide */
     public int getServiceChannel(ParcelUuid uuid) {
         //TODO(BT)
@@ -1042,6 +1123,82 @@
     }
 
     /**
+     * Requires {@link android.Manifest.permission#BLUETOOTH}.
+     * @return Whether the phonebook access is allowed to this device. Can be
+     *         {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
+     * @hide
+     */
+    public int getPhonebookAccessPermission() {
+        if (sService == null) {
+            return ACCESS_UNKNOWN;
+        }
+        try {
+            return sService.getPhonebookAccessPermission(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
+        return ACCESS_UNKNOWN;
+    }
+
+    /**
+     * Sets whether the phonebook access is allowed to this device.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
+     * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or
+     *              {@link #ACCESS_REJECTED}.
+     * @return Whether the value has been successfully set.
+     * @hide
+     */
+    public boolean setPhonebookAccessPermission(int value) {
+        if (sService == null) {
+            return false;
+        }
+        try {
+            return sService.setPhonebookAccessPermission(this, value);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
+        return false;
+    }
+
+    /**
+     * Requires {@link android.Manifest.permission#BLUETOOTH}.
+     * @return Whether the message access is allowed to this device. Can be
+     *         {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
+     * @hide
+     */
+    public int getMessageAccessPermission() {
+        if (sService == null) {
+            return ACCESS_UNKNOWN;
+        }
+        try {
+            return sService.getMessageAccessPermission(this);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
+        return ACCESS_UNKNOWN;
+    }
+
+    /**
+     * Sets whether the message access is allowed to this device.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
+     * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or
+     *              {@link #ACCESS_REJECTED}.
+     * @return Whether the value has been successfully set.
+     * @hide
+     */
+    public boolean setMessageAccessPermission(int value) {
+        if (sService == null) {
+            return false;
+        }
+        try {
+            return sService.setMessageAccessPermission(this, value);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
+        return false;
+    }
+
+    /**
      * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
      * outgoing connection to this remote device on given channel.
      * <p>The remote device will be authenticated and communication on this
@@ -1213,6 +1370,27 @@
      */
     public BluetoothGatt connectGatt(Context context, boolean autoConnect,
                                      BluetoothGattCallback callback) {
+        return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO));
+    }
+
+    /**
+     * Connect to GATT Server hosted by this device. Caller acts as GATT client.
+     * The callback is used to deliver results to Caller, such as connection status as well
+     * as any further GATT client operations.
+     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
+     * GATT client operations.
+     * @param callback GATT callback handler that will receive asynchronous callbacks.
+     * @param autoConnect Whether to directly connect to the remote device (false)
+     *                    or to automatically connect as soon as the remote
+     *                    device becomes available (true).
+     * @param transport preferred transport for GATT connections to remote dual-mode devices
+     *             {@link BluetoothDevice#TRANSPORT_AUTO} or
+     *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
+     * @throws IllegalArgumentException if callback is null
+     * @hide
+     */
+    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+                                     BluetoothGattCallback callback, int transport) {
         // TODO(Bluetooth) check whether platform support BLE
         //     Do the check here or in GattServer?
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -1223,7 +1401,7 @@
                 // BLE is not supported
                 return null;
             }
-            BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this);
+            BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this, transport);
             gatt.connect(autoConnect, callback);
             return gatt;
         } catch (RemoteException e) {Log.e(TAG, "", e);}
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index e7ab8de..c203a8e 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -16,20 +16,9 @@
 
 package android.bluetooth;
 
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfile.ServiceListener;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.IBluetoothStateChangeCallback;
-
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -50,7 +39,7 @@
 public final class BluetoothGatt implements BluetoothProfile {
     private static final String TAG = "BluetoothGatt";
     private static final boolean DBG = true;
-    private static final boolean VDBG = true;
+    private static final boolean VDBG = false;
 
     private final Context mContext;
     private IBluetoothGatt mService;
@@ -62,6 +51,7 @@
     private int mConnState;
     private final Object mStateLock = new Object();
     private Boolean mDeviceBusy = false;
+    private int mTransport;
 
     private static final int CONN_STATE_IDLE = 0;
     private static final int CONN_STATE_CONNECTING = 1;
@@ -95,10 +85,32 @@
     /** A write operation exceeds the maximum length of the attribute */
     public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 0xd;
 
+    /** A remote device connection is congested. */
+    public static final int GATT_CONNECTION_CONGESTED = 0x8f;
+
     /** A GATT operation failed, errors other than the above */
     public static final int GATT_FAILURE = 0x101;
 
     /**
+     * Connection paramter update - Use the connection paramters recommended by the
+     * Bluetooth SIG. This is the default value if no connection parameter update
+     * is requested.
+     */
+    public static final int CONNECTION_PRIORITY_BALANCED = 0;
+
+    /**
+     * Connection paramter update - Request a high priority, low latency connection.
+     * An application should only request high priority connection paramters to transfer
+     * large amounts of data over LE quickly. Once the transfer is complete, the application
+     * should request {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED} connectoin parameters
+     * to reduce energy use.
+     */
+    public static final int CONNECTION_PRIORITY_HIGH = 1;
+
+    /** Connection paramter update - Request low power, reduced data rate connection parameters. */
+    public static final int CONNECTION_PRIORITY_LOW_POWER = 2;
+
+    /**
      * No authentication required.
      * @hide
      */
@@ -117,10 +129,10 @@
     /*package*/ static final int AUTHENTICATION_MITM = 2;
 
     /**
-     * Bluetooth GATT interface callbacks
+     * Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation.
      */
     private final IBluetoothGattCallback mBluetoothGattCallback =
-        new IBluetoothGattCallback.Stub() {
+        new BluetoothGattCallbackWrapper() {
             /**
              * Application interface registered - app is ready to go
              * @hide
@@ -146,7 +158,7 @@
                 }
                 try {
                     mService.clientConnect(mClientIf, mDevice.getAddress(),
-                                           !mAutoConnect); // autoConnect is inverse of "isDirect"
+                                           !mAutoConnect, mTransport); // autoConnect is inverse of "isDirect"
                 } catch (RemoteException e) {
                     Log.e(TAG,"",e);
                 }
@@ -185,14 +197,6 @@
             }
 
             /**
-             * Callback reporting an LE scan result.
-             * @hide
-             */
-            public void onScanResult(String address, int rssi, byte[] advData) {
-                // no op
-            }
-
-            /**
              * A new GATT service has been discovered.
              * The service is added to the internal list and the search
              * continues.
@@ -200,7 +204,7 @@
              */
             public void onGetService(String address, int srvcType,
                                      int srvcInstId, ParcelUuid srvcUuid) {
-                if (DBG) Log.d(TAG, "onGetService() - Device=" + address + " UUID=" + srvcUuid);
+                if (VDBG) Log.d(TAG, "onGetService() - Device=" + address + " UUID=" + srvcUuid);
                 if (!address.equals(mDevice.getAddress())) {
                     return;
                 }
@@ -217,7 +221,7 @@
                                              int srvcInstId, ParcelUuid srvcUuid,
                                              int inclSrvcType, int inclSrvcInstId,
                                              ParcelUuid inclSrvcUuid) {
-                if (DBG) Log.d(TAG, "onGetIncludedService() - Device=" + address
+                if (VDBG) Log.d(TAG, "onGetIncludedService() - Device=" + address
                     + " UUID=" + srvcUuid + " Included=" + inclSrvcUuid);
 
                 if (!address.equals(mDevice.getAddress())) {
@@ -243,7 +247,7 @@
                              int srvcInstId, ParcelUuid srvcUuid,
                              int charInstId, ParcelUuid charUuid,
                              int charProps) {
-                if (DBG) Log.d(TAG, "onGetCharacteristic() - Device=" + address + " UUID=" +
+                if (VDBG) Log.d(TAG, "onGetCharacteristic() - Device=" + address + " UUID=" +
                                charUuid);
 
                 if (!address.equals(mDevice.getAddress())) {
@@ -267,7 +271,7 @@
                              int srvcInstId, ParcelUuid srvcUuid,
                              int charInstId, ParcelUuid charUuid,
                              int descrInstId, ParcelUuid descUuid) {
-                if (DBG) Log.d(TAG, "onGetDescriptor() - Device=" + address + " UUID=" + descUuid);
+                if (VDBG) Log.d(TAG, "onGetDescriptor() - Device=" + address + " UUID=" + descUuid);
 
                 if (!address.equals(mDevice.getAddress())) {
                     return;
@@ -277,7 +281,7 @@
                 if (service == null) return;
 
                 BluetoothGattCharacteristic characteristic = service.getCharacteristic(
-                    charUuid.getUuid());
+                    charUuid.getUuid(), charInstId);
                 if (characteristic == null) return;
 
                 characteristic.addDescriptor(new BluetoothGattDescriptor(
@@ -311,7 +315,7 @@
             public void onCharacteristicRead(String address, int status, int srvcType,
                              int srvcInstId, ParcelUuid srvcUuid,
                              int charInstId, ParcelUuid charUuid, byte[] value) {
-                if (DBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address
+                if (VDBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address
                             + " UUID=" + charUuid + " Status=" + status);
 
                 if (!address.equals(mDevice.getAddress())) {
@@ -363,7 +367,7 @@
             public void onCharacteristicWrite(String address, int status, int srvcType,
                              int srvcInstId, ParcelUuid srvcUuid,
                              int charInstId, ParcelUuid charUuid) {
-                if (DBG) Log.d(TAG, "onCharacteristicWrite() - Device=" + address
+                if (VDBG) Log.d(TAG, "onCharacteristicWrite() - Device=" + address
                             + " UUID=" + charUuid + " Status=" + status);
 
                 if (!address.equals(mDevice.getAddress())) {
@@ -415,7 +419,7 @@
                              int srvcInstId, ParcelUuid srvcUuid,
                              int charInstId, ParcelUuid charUuid,
                              byte[] value) {
-                if (DBG) Log.d(TAG, "onNotify() - Device=" + address + " UUID=" + charUuid);
+                if (VDBG) Log.d(TAG, "onNotify() - Device=" + address + " UUID=" + charUuid);
 
                 if (!address.equals(mDevice.getAddress())) {
                     return;
@@ -446,7 +450,7 @@
                              int charInstId, ParcelUuid charUuid,
                              int descrInstId, ParcelUuid descrUuid,
                              byte[] value) {
-                if (DBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " UUID=" + charUuid);
+                if (VDBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " UUID=" + charUuid);
 
                 if (!address.equals(mDevice.getAddress())) {
                     return;
@@ -478,6 +482,7 @@
                         mService.readDescriptor(mClientIf, address,
                             srvcType, srvcInstId, srvcUuid, charInstId, charUuid,
                             descrInstId, descrUuid, AUTHENTICATION_MITM);
+                        return;
                     } catch (RemoteException e) {
                         Log.e(TAG,"",e);
                     }
@@ -500,7 +505,7 @@
                              int srvcInstId, ParcelUuid srvcUuid,
                              int charInstId, ParcelUuid charUuid,
                              int descrInstId, ParcelUuid descrUuid) {
-                if (DBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " UUID=" + charUuid);
+                if (VDBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " UUID=" + charUuid);
 
                 if (!address.equals(mDevice.getAddress())) {
                     return;
@@ -531,6 +536,7 @@
                             srvcType, srvcInstId, srvcUuid, charInstId, charUuid,
                             descrInstId, descrUuid, characteristic.getWriteType(),
                             AUTHENTICATION_MITM, descriptor.getValue());
+                        return;
                     } catch (RemoteException e) {
                         Log.e(TAG,"",e);
                     }
@@ -550,7 +556,7 @@
              * @hide
              */
             public void onExecuteWrite(String address, int status) {
-                if (DBG) Log.d(TAG, "onExecuteWrite() - Device=" + address
+                if (VDBG) Log.d(TAG, "onExecuteWrite() - Device=" + address
                     + " status=" + status);
                 if (!address.equals(mDevice.getAddress())) {
                     return;
@@ -572,7 +578,7 @@
              * @hide
              */
             public void onReadRemoteRssi(String address, int rssi, int status) {
-                if (DBG) Log.d(TAG, "onReadRemoteRssi() - Device=" + address +
+                if (VDBG) Log.d(TAG, "onReadRemoteRssi() - Device=" + address +
                             " rssi=" + rssi + " status=" + status);
                 if (!address.equals(mDevice.getAddress())) {
                     return;
@@ -585,15 +591,6 @@
             }
 
             /**
-             * Advertise state change callback
-             * @hide
-             */
-            public void onAdvertiseStateChange(int state, int status) {
-                if (DBG) Log.d(TAG, "onAdvertiseStateChange() - state = "
-                        + state + " status=" + status);
-	    }
-
-            /**
              * Callback invoked when the MTU for a given connection changes
              * @hide
              */
@@ -604,17 +601,19 @@
                     return;
                 }
                 try {
-                    mCallback.onConfigureMTU(BluetoothGatt.this, mtu, status);
+                    mCallback.onMtuChanged(BluetoothGatt.this, mtu, status);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
         };
 
-    /*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device) {
+    /*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device,
+                                int transport) {
         mContext = context;
         mService = iGatt;
         mDevice = device;
+        mTransport = transport;
         mServices = new ArrayList<BluetoothGattService>();
 
         mConnState = CONN_STATE_IDLE;
@@ -705,7 +704,7 @@
      * {@link BluetoothGattCallback#onConnectionStateChange} callback will be
      * invoked when the connection state changes as a result of this function.
      *
-     * <p>The autoConnect paramter determines whether to actively connect to
+     * <p>The autoConnect parameter determines whether to actively connect to
      * the remote device, or rather passively scan and finalize the connection
      * when the remote device is in range/available. Generally, the first ever
      * connection to a device should be direct (autoConnect set to false) and
@@ -770,7 +769,7 @@
     public boolean connect() {
         try {
             mService.clientConnect(mClientIf, mDevice.getAddress(),
-                                   false); // autoConnect is inverse of "isDirect"
+                                   false, mTransport); // autoConnect is inverse of "isDirect"
             return true;
         } catch (RemoteException e) {
             Log.e(TAG,"",e);
@@ -883,7 +882,7 @@
         if ((characteristic.getProperties() &
                 BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false;
 
-        if (DBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid());
+        if (VDBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid());
         if (mService == null || mClientIf == 0) return false;
 
         BluetoothGattService service = characteristic.getService();
@@ -928,7 +927,7 @@
             && (characteristic.getProperties() &
                 BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false;
 
-        if (DBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
+        if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
         if (mService == null || mClientIf == 0) return false;
 
         BluetoothGattService service = characteristic.getService();
@@ -971,7 +970,7 @@
      * @return true, if the read operation was initiated successfully
      */
     public boolean readDescriptor(BluetoothGattDescriptor descriptor) {
-        if (DBG) Log.d(TAG, "readDescriptor() - uuid: " + descriptor.getUuid());
+        if (VDBG) Log.d(TAG, "readDescriptor() - uuid: " + descriptor.getUuid());
         if (mService == null || mClientIf == 0) return false;
 
         BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
@@ -1015,7 +1014,7 @@
      * @return true, if the write operation was initiated successfully
      */
     public boolean writeDescriptor(BluetoothGattDescriptor descriptor) {
-        if (DBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid());
+        if (VDBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid());
         if (mService == null || mClientIf == 0) return false;
 
         BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
@@ -1069,7 +1068,7 @@
      * @return true, if the reliable write transaction has been initiated
      */
     public boolean beginReliableWrite() {
-        if (DBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress());
+        if (VDBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress());
         if (mService == null || mClientIf == 0) return false;
 
         try {
@@ -1096,7 +1095,7 @@
      * @return true, if the request to execute the transaction has been sent
      */
     public boolean executeReliableWrite() {
-        if (DBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
+        if (VDBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
         if (mService == null || mClientIf == 0) return false;
 
         synchronized(mDeviceBusy) {
@@ -1124,7 +1123,7 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      */
     public void abortReliableWrite() {
-        if (DBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress());
+        if (VDBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress());
         if (mService == null || mClientIf == 0) return;
 
         try {
@@ -1225,21 +1224,20 @@
     }
 
     /**
-     * Configure the MTU used for a given connection.
+     * Request an MTU size used for a given connection.
      *
      * <p>When performing a write request operation (write without response),
      * the data sent is truncated to the MTU size. This function may be used
-     * to request a larget MTU size to be able to send more data at once.
+     * to request a larger MTU size to be able to send more data at once.
      *
-     * <p>A {@link BluetoothGattCallback#onConfigureMTU} callback will indicate
+     * <p>A {@link BluetoothGattCallback#onMtuChanged} callback will indicate
      * whether this operation was successful.
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @return true, if the new MTU value has been requested successfully
-     * @hide
      */
-    public boolean configureMTU(int mtu) {
+    public boolean requestMtu(int mtu) {
         if (DBG) Log.d(TAG, "configureMTU() - device: " + mDevice.getAddress()
                             + " mtu: " + mtu);
         if (mService == null || mClientIf == 0) return false;
@@ -1255,6 +1253,38 @@
     }
 
     /**
+     * Request a connection parameter update.
+     *
+     * <p>This function will send a connection parameter update request to the
+     * remote device.
+     *
+     * @param connectionPriority Request a specific connection priority. Must be one of
+     *          {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED},
+     *          {@link BluetoothGatt#CONNECTION_PRIORITY_HIGH}
+     *          or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}.
+     * @throws IllegalArgumentException If the parameters are outside of their
+     *                                  specified range.
+     */
+    public boolean requestConnectionPriority(int connectionPriority) {
+        if (connectionPriority < CONNECTION_PRIORITY_BALANCED ||
+            connectionPriority > CONNECTION_PRIORITY_LOW_POWER) {
+            throw new IllegalArgumentException("connectionPriority not within valid range");
+        }
+
+        if (DBG) Log.d(TAG, "requestConnectionPriority() - params: " + connectionPriority);
+        if (mService == null || mClientIf == 0) return false;
+
+        try {
+            mService.connectionParameterUpdate(mClientIf, mDevice.getAddress(), connectionPriority);
+        } catch (RemoteException e) {
+            Log.e(TAG,"",e);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
      * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
      * with {@link BluetoothProfile#GATT} as argument
      *
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index 5180259..a915620 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -143,14 +143,13 @@
      * Callback indicating the MTU for a given device connection has changed.
      *
      * This callback is triggered in response to the
-     * {@link BluetoothGatt#configureMTU} function, or in response to a connection
+     * {@link BluetoothGatt#requestMtu} function, or in response to a connection
      * event.
      *
-     * @param gatt GATT client invoked {@link BluetoothGatt#configureMTU}
+     * @param gatt GATT client invoked {@link BluetoothGatt#requestMtu}
      * @param mtu The new MTU size
      * @param status {@link BluetoothGatt#GATT_SUCCESS} if the MTU has been changed successfully
-     * @hide
      */
-    public void onConfigureMTU(BluetoothGatt gatt, int mtu, int status) {
+    public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
new file mode 100644
index 0000000..cdb24f4
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.ScanResult;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+
+import java.util.List;
+
+/**
+ * Wrapper class for default implementation of IBluetoothGattCallback.
+ *
+ * @hide
+ */
+public class BluetoothGattCallbackWrapper extends IBluetoothGattCallback.Stub {
+
+    @Override
+    public void onClientRegistered(int status, int clientIf) throws RemoteException {
+    }
+
+    @Override
+    public void onClientConnectionState(int status, int clientIf, boolean connected, String address)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onScanResult(ScanResult scanResult) throws RemoteException {
+    }
+
+    @Override
+    public void onBatchScanResults(List<ScanResult> batchResults) throws RemoteException {
+    }
+
+    @Override
+    public void onGetService(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onGetIncludedService(String address, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int inclSrvcType, int inclSrvcInstId, ParcelUuid inclSrvcUuid)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onGetCharacteristic(String address, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int charProps)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onGetDescriptor(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid, int descrInstId, ParcelUuid descrUuid)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onSearchComplete(String address, int status) throws RemoteException {
+    }
+
+    @Override
+    public void onCharacteristicRead(String address, int status, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, byte[] value)
+            throws RemoteException {
+    }
+
+    @Override
+    public void onCharacteristicWrite(String address, int status, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid) throws RemoteException {
+    }
+
+    @Override
+    public void onExecuteWrite(String address, int status) throws RemoteException {
+    }
+
+    @Override
+    public void onDescriptorRead(String address, int status, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int descrInstId,
+            ParcelUuid descrUuid, byte[] value) throws RemoteException {
+    }
+
+    @Override
+    public void onDescriptorWrite(String address, int status, int srvcType, int srvcInstId,
+            ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int descrInstId,
+            ParcelUuid descrUuid) throws RemoteException {
+    }
+
+    @Override
+    public void onNotify(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid,
+            int charInstId, ParcelUuid charUuid, byte[] value) throws RemoteException {
+    }
+
+    @Override
+    public void onReadRemoteRssi(String address, int rssi, int status) throws RemoteException {
+    }
+
+    @Override
+    public void onMultiAdvertiseCallback(int status, boolean isStart,
+            AdvertiseSettings advertiseSettings) throws RemoteException {
+    }
+
+    @Override
+    public void onConfigureMTU(String address, int mtu, int status) throws RemoteException {
+    }
+
+    @Override
+    public void onFoundOrLost(boolean onFound, ScanResult scanResult) throws RemoteException {
+    }
+
+}
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
index f0ecbb4..a86677c 100644
--- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -16,7 +16,6 @@
 package android.bluetooth;
 
 import java.util.ArrayList;
-import java.util.IllegalFormatConversionException;
 import java.util.List;
 import java.util.UUID;
 
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index 153215c..e94a8ce 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -19,18 +19,9 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfile.ServiceListener;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.IBluetoothStateChangeCallback;
-
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -41,16 +32,17 @@
  * Public API for the Bluetooth GATT Profile server role.
  *
  * <p>This class provides Bluetooth GATT server role functionality,
- * allowing applications to create and advertise Bluetooth Smart services
- * and characteristics.
+ * allowing applications to create Bluetooth Smart services and
+ * characteristics.
  *
  * <p>BluetoothGattServer is a proxy object for controlling the Bluetooth Service
- * via IPC.  Use {@link BluetoothAdapter#getProfileProxy} to get the
- * BluetoothGatt proxy object.
+ * via IPC.  Use {@link BluetoothManager#openGattServer} to get an instance
+ * of this class.
  */
 public final class BluetoothGattServer implements BluetoothProfile {
     private static final String TAG = "BluetoothGattServer";
     private static final boolean DBG = true;
+    private static final boolean VDBG = false;
 
     private final Context mContext;
     private BluetoothAdapter mAdapter;
@@ -59,6 +51,7 @@
 
     private Object mServerIfLock = new Object();
     private int mServerIf;
+    private int mTransport;
     private List<BluetoothGattService> mServices;
 
     private static final int CALLBACK_REG_TIMEOUT = 10000;
@@ -91,7 +84,7 @@
              * @hide
              */
             public void onScanResult(String address, int rssi, byte[] advData) {
-                if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
+                if (VDBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
                 // no op
             }
 
@@ -141,7 +134,7 @@
                             ParcelUuid srvcId, int charInstId, ParcelUuid charId) {
                 UUID srvcUuid = srvcId.getUuid();
                 UUID charUuid = charId.getUuid();
-                if (DBG) Log.d(TAG, "onCharacteristicReadRequest() - "
+                if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - "
                     + "service=" + srvcUuid + ", characteristic=" + charUuid);
 
                 BluetoothDevice device = mAdapter.getRemoteDevice(address);
@@ -169,7 +162,7 @@
                 UUID srvcUuid = srvcId.getUuid();
                 UUID charUuid = charId.getUuid();
                 UUID descrUuid = descrId.getUuid();
-                if (DBG) Log.d(TAG, "onCharacteristicReadRequest() - "
+                if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - "
                     + "service=" + srvcUuid + ", characteristic=" + charUuid
                     + "descriptor=" + descrUuid);
 
@@ -200,7 +193,7 @@
                             int charInstId, ParcelUuid charId, byte[] value) {
                 UUID srvcUuid = srvcId.getUuid();
                 UUID charUuid = charId.getUuid();
-                if (DBG) Log.d(TAG, "onCharacteristicWriteRequest() - "
+                if (VDBG) Log.d(TAG, "onCharacteristicWriteRequest() - "
                     + "service=" + srvcUuid + ", characteristic=" + charUuid);
 
                 BluetoothDevice device = mAdapter.getRemoteDevice(address);
@@ -231,7 +224,7 @@
                 UUID srvcUuid = srvcId.getUuid();
                 UUID charUuid = charId.getUuid();
                 UUID descrUuid = descrId.getUuid();
-                if (DBG) Log.d(TAG, "onDescriptorWriteRequest() - "
+                if (VDBG) Log.d(TAG, "onDescriptorWriteRequest() - "
                     + "service=" + srvcUuid + ", characteristic=" + charUuid
                     + "descriptor=" + descrUuid);
 
@@ -273,17 +266,36 @@
                     Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
+
+            /**
+             * A notification/indication has been sent.
+             * @hide
+             */
+            public void onNotificationSent(String address, int status) {
+                if (VDBG) Log.d(TAG, "onNotificationSent() - "
+                    + "device=" + address + ", status=" + status);
+
+                BluetoothDevice device = mAdapter.getRemoteDevice(address);
+                if (device == null) return;
+
+                try {
+                    mCallback.onNotificationSent(device, status);
+                } catch (Exception ex) {
+                    Log.w(TAG, "Unhandled exception: " + ex);
+                }
+            }
         };
 
     /**
      * Create a BluetoothGattServer proxy object.
      */
-    /*package*/ BluetoothGattServer(Context context, IBluetoothGatt iGatt) {
+    /*package*/ BluetoothGattServer(Context context, IBluetoothGatt iGatt, int transport) {
         mContext = context;
         mService = iGatt;
         mAdapter = BluetoothAdapter.getDefaultAdapter();
         mCallback = null;
         mServerIf = 0;
+        mTransport = transport;
         mServices = new ArrayList<BluetoothGattService>();
     }
 
@@ -410,7 +422,7 @@
 
         try {
             mService.serverConnect(mServerIf, device.getAddress(),
-                               autoConnect ? false : true); // autoConnect is inverse of "isDirect"
+                               autoConnect ? false : true,mTransport); // autoConnect is inverse of "isDirect"
         } catch (RemoteException e) {
             Log.e(TAG,"",e);
             return false;
@@ -461,7 +473,7 @@
      */
     public boolean sendResponse(BluetoothDevice device, int requestId,
                                 int status, int offset, byte[] value) {
-        if (DBG) Log.d(TAG, "sendResponse() - device: " + device.getAddress());
+        if (VDBG) Log.d(TAG, "sendResponse() - device: " + device.getAddress());
         if (mService == null || mServerIf == 0) return false;
 
         try {
@@ -489,16 +501,22 @@
      * @param characteristic The local characteristic that has been updated
      * @param confirm true to request confirmation from the client (indication),
      *                false to send a notification
+     * @throws IllegalArgumentException
      * @return true, if the notification has been triggered successfully
      */
     public boolean notifyCharacteristicChanged(BluetoothDevice device,
                     BluetoothGattCharacteristic characteristic, boolean confirm) {
-        if (DBG) Log.d(TAG, "notifyCharacteristicChanged() - device: " + device.getAddress());
+        if (VDBG) Log.d(TAG, "notifyCharacteristicChanged() - device: " + device.getAddress());
         if (mService == null || mServerIf == 0) return false;
 
         BluetoothGattService service = characteristic.getService();
         if (service == null) return false;
 
+        if (characteristic.getValue() == null) {
+            throw new IllegalArgumentException("Chracteristic value is empty. Use "
+                    + "BluetoothGattCharacteristic#setvalue to update");
+        }
+
         try {
             mService.sendNotification(mServerIf, device.getAddress(),
                     service.getType(), service.getInstanceId(),
@@ -516,7 +534,7 @@
     /**
      * Add a service to the list of services to be hosted.
      *
-     * <p>Once a service has been addded to the the list, the service and it's
+     * <p>Once a service has been addded to the the list, the service and its
      * included characteristics will be provided by the local device.
      *
      * <p>If the local device has already exposed services when this function
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
index f9f1d97..1dd06f2 100644
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java
@@ -18,8 +18,6 @@
 
 import android.bluetooth.BluetoothDevice;
 
-import android.util.Log;
-
 /**
  * This abstract class is used to implement {@link BluetoothGattServer} callbacks.
  */
@@ -133,4 +131,18 @@
      */
     public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
     }
+
+    /**
+     * Callback invoked when a notification or indication has been sent to
+     * a remote device.
+     *
+     * <p>When multiple notifications are to be sent, an application must
+     * wait for this callback to be received before sending additional
+     * notifications.
+     *
+     * @param device The remote device the notification has been sent to
+     * @param status {@link BluetoothGatt#GATT_SUCCESS} if the operation was successful
+     */
+    public void onNotificationSent(BluetoothDevice device, int status) {
+    }
 }
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 8ee955d..353f0fb 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -280,7 +280,8 @@
         Intent intent = new Intent(IBluetoothHeadset.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
-        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth Headset Service with " + intent);
             return false;
         }
@@ -885,6 +886,50 @@
         return false;
     }
 
+    /**
+     * enable WBS codec setting.
+     *
+     * @return true if successful
+     *         false if there was some error such as
+     *               there is no connected headset
+     * @hide
+     */
+    public boolean enableWBS() {
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.enableWBS();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return false;
+    }
+
+    /**
+     * disable WBS codec settting. It set NBS codec.
+     *
+     * @return true if successful
+     *         false if there was some error such as
+     *               there is no connected headset
+     * @hide
+     */
+    public boolean disableWBS() {
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.disableWBS();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return false;
+    }
+
     private final ServiceConnection mConnection = new ServiceConnection() {
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "Proxy object connected");
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
new file mode 100644
index 0000000..ff4ebee
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -0,0 +1,1167 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Public API to control Hands Free Profile (HFP role only).
+ * <p>
+ * This class defines methods that shall be used by application to manage profile
+ * connection, calls states and calls actions.
+ * <p>
+ *
+ * @hide
+ * */
+public final class BluetoothHeadsetClient implements BluetoothProfile {
+    private static final String TAG = "BluetoothHeadsetClient";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false;
+
+    /**
+     * Intent sent whenever connection to remote changes.
+     *
+     * <p>It includes two extras:
+     * <code>BluetoothProfile.EXTRA_PREVIOUS_STATE</code>
+     * and <code>BluetoothProfile.EXTRA_STATE</code>, which
+     * are mandatory.
+     * <p>There are also non mandatory feature extras:
+     * {@link #EXTRA_AG_FEATURE_3WAY_CALLING},
+     * {@link #EXTRA_AG_FEATURE_VOICE_RECOGNITION},
+     * {@link #EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT},
+     * {@link #EXTRA_AG_FEATURE_REJECT_CALL},
+     * {@link #EXTRA_AG_FEATURE_ECC},
+     * {@link #EXTRA_AG_FEATURE_RESPONSE_AND_HOLD},
+     * {@link #EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL},
+     * {@link #EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL},
+     * {@link #EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT},
+     * {@link #EXTRA_AG_FEATURE_MERGE},
+     * {@link #EXTRA_AG_FEATURE_MERGE_AND_DETACH},
+     * sent as boolean values only when <code>EXTRA_STATE</code>
+     * is set to <code>STATE_CONNECTED</code>.</p>
+     *
+     * <p>Note that features supported by AG are being sent as
+     * booleans with value <code>true</code>,
+     * and not supported ones are <strong>not</strong> being sent at all.</p>
+     */
+    public static final String ACTION_CONNECTION_STATE_CHANGED =
+        "android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED";
+
+    /**
+     * Intent sent whenever audio state changes.
+     *
+     * <p>It includes two mandatory extras:
+     * {@link BluetoothProfile.EXTRA_STATE},
+     * {@link BluetoothProfile.EXTRA_PREVIOUS_STATE},
+     * with possible values:
+     * {@link #STATE_AUDIO_CONNECTING},
+     * {@link #STATE_AUDIO_CONNECTED},
+     * {@link #STATE_AUDIO_DISCONNECTED}</p>
+     * <p>When <code>EXTRA_STATE</code> is set
+     * to </code>STATE_AUDIO_CONNECTED</code>,
+     * it also includes {@link #EXTRA_AUDIO_WBS}
+     * indicating wide band speech support.</p>
+     */
+    public static final String ACTION_AUDIO_STATE_CHANGED =
+        "android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED";
+
+    /**
+     * Intent sending updates of the Audio Gateway state.
+     * Each extra is being sent only when value it
+     * represents has been changed recently on AG.
+     * <p>It can contain one or more of the following extras:
+     * {@link #EXTRA_NETWORK_STATUS},
+     * {@link #EXTRA_NETWORK_SIGNAL_STRENGTH},
+     * {@link #EXTRA_NETWORK_ROAMING},
+     * {@link #EXTRA_BATTERY_LEVEL},
+     * {@link #EXTRA_OPERATOR_NAME},
+     * {@link #EXTRA_VOICE_RECOGNITION},
+     * {@link #EXTRA_IN_BAND_RING}</p>
+     */
+    public static final String ACTION_AG_EVENT =
+            "android.bluetooth.headsetclient.profile.action.AG_EVENT";
+
+    /**
+     * Intent sent whenever state of a call changes.
+     *
+     * <p>It includes:
+     * {@link #EXTRA_CALL},
+     * with value of {@link BluetoothHeadsetClientCall} instance,
+     * representing actual call state.</p>
+     */
+    public static final String ACTION_CALL_CHANGED =
+            "android.bluetooth.headsetclient.profile.action.AG_CALL_CHANGED";
+
+    /**
+     * Intent that notifies about the result of the last issued action.
+     * Please note that not every action results in explicit action result code being sent.
+     * Instead other notifications about new Audio Gateway state might be sent,
+     * like <code>ACTION_AG_EVENT</code> with <code>EXTRA_VOICE_RECOGNITION</code> value
+     * when for example user started voice recognition from HF unit.
+     */
+    public static final String ACTION_RESULT =
+            "android.bluetooth.headsetclient.profile.action.RESULT";
+
+    /**
+     * Intent that notifies about the number attached to the last voice tag
+     * recorded on AG.
+     *
+     * <p>It contains:
+     * {@link #EXTRA_NUMBER},
+     * with a <code>String</code> value representing phone number.</p>
+     */
+    public static final String ACTION_LAST_VTAG =
+            "android.bluetooth.headsetclient.profile.action.LAST_VTAG";
+
+    public static final int STATE_AUDIO_DISCONNECTED = 0;
+    public static final int STATE_AUDIO_CONNECTING = 1;
+    public static final int STATE_AUDIO_CONNECTED = 2;
+
+    /**
+     * Extra with information if connected audio is WBS.
+     * <p>Possible values: <code>true</code>,
+     *                     <code>false</code>.</p>
+     */
+    public static final String EXTRA_AUDIO_WBS =
+            "android.bluetooth.headsetclient.extra.AUDIO_WBS";
+
+    /**
+     * Extra for AG_EVENT indicates network status.
+     * <p>Value: 0 - network unavailable,
+     *           1 - network available </p>
+     */
+    public static final String EXTRA_NETWORK_STATUS =
+            "android.bluetooth.headsetclient.extra.NETWORK_STATUS";
+    /**
+     * Extra for AG_EVENT intent indicates network signal strength.
+     * <p>Value: <code>Integer</code> representing signal strength.</p>
+     */
+    public static final String EXTRA_NETWORK_SIGNAL_STRENGTH =
+            "android.bluetooth.headsetclient.extra.NETWORK_SIGNAL_STRENGTH";
+    /**
+     * Extra for AG_EVENT intent indicates roaming state.
+     * <p>Value: 0 - no roaming
+     *           1 - active roaming</p>
+     */
+    public static final String EXTRA_NETWORK_ROAMING =
+            "android.bluetooth.headsetclient.extra.NETWORK_ROAMING";
+    /**
+     * Extra for AG_EVENT intent indicates the battery level.
+     * <p>Value: <code>Integer</code> representing signal strength.</p>
+     */
+    public static final String EXTRA_BATTERY_LEVEL =
+            "android.bluetooth.headsetclient.extra.BATTERY_LEVEL";
+    /**
+     * Extra for AG_EVENT intent indicates operator name.
+     * <p>Value: <code>String</code> representing operator name.</p>
+     */
+    public static final String EXTRA_OPERATOR_NAME =
+            "android.bluetooth.headsetclient.extra.OPERATOR_NAME";
+    /**
+     * Extra for AG_EVENT intent indicates voice recognition state.
+     * <p>Value:
+     *          0 - voice recognition stopped,
+     *          1 - voice recognition started.</p>
+     */
+    public static final String EXTRA_VOICE_RECOGNITION =
+            "android.bluetooth.headsetclient.extra.VOICE_RECOGNITION";
+    /**
+     * Extra for AG_EVENT intent indicates in band ring state.
+     * <p>Value:
+     *          0 - in band ring tone not supported, or
+     *          1 - in band ring tone supported.</p>
+     */
+    public static final String EXTRA_IN_BAND_RING =
+            "android.bluetooth.headsetclient.extra.IN_BAND_RING";
+
+    /**
+     * Extra for AG_EVENT intent indicates subscriber info.
+     * <p>Value: <code>String</code> containing subscriber information.</p>
+     */
+    public static final String EXTRA_SUBSCRIBER_INFO =
+            "android.bluetooth.headsetclient.extra.SUBSCRIBER_INFO";
+
+    /**
+     *  Extra for AG_CALL_CHANGED intent indicates the
+     *  {@link BluetoothHeadsetClientCall} object that has changed.
+     */
+    public static final String EXTRA_CALL =
+            "android.bluetooth.headsetclient.extra.CALL";
+
+    /**
+     * Extra for ACTION_LAST_VTAG intent.
+     * <p>Value: <code>String</code> representing phone number
+     * corresponding to last voice tag recorded on AG</p>
+     */
+    public static final String EXTRA_NUMBER =
+            "android.bluetooth.headsetclient.extra.NUMBER";
+
+    /**
+     * Extra for ACTION_RESULT intent that shows the result code of
+     * last issued action.
+     * <p>Possible results:
+     * {@link #ACTION_RESULT_OK},
+     * {@link #ACTION_RESULT_ERROR},
+     * {@link #ACTION_RESULT_ERROR_NO_CARRIER},
+     * {@link #ACTION_RESULT_ERROR_BUSY},
+     * {@link #ACTION_RESULT_ERROR_NO_ANSWER},
+     * {@link #ACTION_RESULT_ERROR_DELAYED},
+     * {@link #ACTION_RESULT_ERROR_BLACKLISTED},
+     * {@link #ACTION_RESULT_ERROR_CME}</p>
+     */
+    public static final String EXTRA_RESULT_CODE =
+            "android.bluetooth.headsetclient.extra.RESULT_CODE";
+
+    /**
+     * Extra for ACTION_RESULT intent that shows the extended result code of
+     * last issued action.
+     * <p>Value: <code>Integer</code> - error code.</p>
+     */
+    public static final String EXTRA_CME_CODE =
+            "android.bluetooth.headsetclient.extra.CME_CODE";
+
+    /* Extras for AG_FEATURES, extras type is boolean */
+    // TODO verify if all of those are actually useful
+    /**
+     * AG feature: three way calling.
+     */
+    public final static String EXTRA_AG_FEATURE_3WAY_CALLING =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_3WAY_CALLING";
+    /**
+     * AG feature: voice recognition.
+     */
+    public final static String EXTRA_AG_FEATURE_VOICE_RECOGNITION =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_VOICE_RECOGNITION";
+    /**
+     * AG feature: fetching phone number for voice tagging procedure.
+     */
+    public final static String EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT";
+    /**
+     * AG feature: ability to reject incoming call.
+     */
+    public final static String EXTRA_AG_FEATURE_REJECT_CALL =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_REJECT_CALL";
+    /**
+     * AG feature: enhanced call handling (terminate specific call, private consultation).
+     */
+    public final static String EXTRA_AG_FEATURE_ECC =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ECC";
+    /**
+     * AG feature: response and hold.
+     */
+    public final static String EXTRA_AG_FEATURE_RESPONSE_AND_HOLD =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RESPONSE_AND_HOLD";
+    /**
+     * AG call handling feature: accept held or waiting call in three way calling scenarios.
+     */
+    public final static String EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL";
+    /**
+     * AG call handling feature: release held or waiting call in three way calling scenarios.
+     */
+    public final static String EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL";
+    /**
+     * AG call handling feature: release active call and accept held or waiting call in three way
+     * calling scenarios.
+     */
+    public final static String EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT";
+    /**
+     * AG call handling feature: merge two calls, held and active - multi party conference mode.
+     */
+    public final static String EXTRA_AG_FEATURE_MERGE =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_MERGE";
+    /**
+     * AG call handling feature: merge calls and disconnect from multi party
+     * conversation leaving peers connected to each other.
+     * Note that this feature needs to be supported by mobile network operator
+     * as it requires connection and billing transfer.
+     */
+    public final static String EXTRA_AG_FEATURE_MERGE_AND_DETACH =
+            "android.bluetooth.headsetclient.extra.EXTRA_AG_FEATURE_MERGE_AND_DETACH";
+
+    /* Action result codes */
+    public final static int ACTION_RESULT_OK = 0;
+    public final static int ACTION_RESULT_ERROR = 1;
+    public final static int ACTION_RESULT_ERROR_NO_CARRIER = 2;
+    public final static int ACTION_RESULT_ERROR_BUSY = 3;
+    public final static int ACTION_RESULT_ERROR_NO_ANSWER = 4;
+    public final static int ACTION_RESULT_ERROR_DELAYED = 5;
+    public final static int ACTION_RESULT_ERROR_BLACKLISTED = 6;
+    public final static int ACTION_RESULT_ERROR_CME = 7;
+
+    /* Detailed CME error codes */
+    public final static int CME_PHONE_FAILURE                           = 0;
+    public final static int CME_NO_CONNECTION_TO_PHONE                  = 1;
+    public final static int CME_OPERATION_NOT_ALLOWED                   = 3;
+    public final static int CME_OPERATION_NOT_SUPPORTED                 = 4;
+    public final static int CME_PHSIM_PIN_REQUIRED                      = 5;
+    public final static int CME_PHFSIM_PIN_REQUIRED                     = 6;
+    public final static int CME_PHFSIM_PUK_REQUIRED                     = 7;
+    public final static int CME_SIM_NOT_INSERTED                        = 10;
+    public final static int CME_SIM_PIN_REQUIRED                        = 11;
+    public final static int CME_SIM_PUK_REQUIRED                        = 12;
+    public final static int CME_SIM_FAILURE                             = 13;
+    public final static int CME_SIM_BUSY                                = 14;
+    public final static int CME_SIM_WRONG                               = 15;
+    public final static int CME_INCORRECT_PASSWORD                      = 16;
+    public final static int CME_SIM_PIN2_REQUIRED                       = 17;
+    public final static int CME_SIM_PUK2_REQUIRED                       = 18;
+    public final static int CME_MEMORY_FULL                             = 20;
+    public final static int CME_INVALID_INDEX                           = 21;
+    public final static int CME_NOT_FOUND                               = 22;
+    public final static int CME_MEMORY_FAILURE                          = 23;
+    public final static int CME_TEXT_STRING_TOO_LONG                    = 24;
+    public final static int CME_INVALID_CHARACTER_IN_TEXT_STRING        = 25;
+    public final static int CME_DIAL_STRING_TOO_LONG                    = 26;
+    public final static int CME_INVALID_CHARACTER_IN_DIAL_STRING        = 27;
+    public final static int CME_NO_NETWORK_SERVICE                      = 30;
+    public final static int CME_NETWORK_TIMEOUT                         = 31;
+    public final static int CME_EMERGENCY_SERVICE_ONLY                  = 32;
+    public final static int CME_NO_SIMULTANOUS_VOIP_CS_CALLS            = 33;
+    public final static int CME_NOT_SUPPORTED_FOR_VOIP                  = 34;
+    public final static int CME_SIP_RESPONSE_CODE                       = 35;
+    public final static int CME_NETWORK_PERSONALIZATION_PIN_REQUIRED    = 40;
+    public final static int CME_NETWORK_PERSONALIZATION_PUK_REQUIRED    = 41;
+    public final static int CME_NETWORK_SUBSET_PERSONALIZATION_PIN_REQUIRED   = 42;
+    public final static int CME_NETWORK_SUBSET_PERSONALIZATION_PUK_REQUIRED   = 43;
+    public final static int CME_SERVICE_PROVIDER_PERSONALIZATION_PIN_REQUIRED = 44;
+    public final static int CME_SERVICE_PROVIDER_PERSONALIZATION_PUK_REQUIRED = 45;
+    public final static int CME_CORPORATE_PERSONALIZATION_PIN_REQUIRED  = 46;
+    public final static int CME_CORPORATE_PERSONALIZATION_PUK_REQUIRED  = 47;
+    public final static int CME_HIDDEN_KEY_REQUIRED                     = 48;
+    public final static int CME_EAP_NOT_SUPPORTED                       = 49;
+    public final static int CME_INCORRECT_PARAMETERS                    = 50;
+
+    /* Action policy for other calls when accepting call */
+    public static final int CALL_ACCEPT_NONE = 0;
+    public static final int CALL_ACCEPT_HOLD = 1;
+    public static final int CALL_ACCEPT_TERMINATE = 2;
+
+    private Context mContext;
+    private ServiceListener mServiceListener;
+    private IBluetoothHeadsetClient mService;
+    private BluetoothAdapter mAdapter;
+
+    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                @Override
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    if (!up) {
+                        if (VDBG) Log.d(TAG,"Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (VDBG) Log.d(TAG,"Binding service...");
+                                    Intent intent = new Intent(IBluetoothHeadsetClient.class.getName());
+                                    doBind();
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    }
+                }
+        };
+
+    /**
+     * Create a BluetoothHeadsetClient proxy object.
+     */
+    /*package*/ BluetoothHeadsetClient(Context context, ServiceListener l) {
+        mContext = context;
+        mServiceListener = l;
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothHeadsetClient.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                 android.os.Process.myUserHandle())) {
+            Log.e(TAG, "Could not bind to Bluetooth Headset Client Service with " + intent);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Close the connection to the backing service.
+     * Other public functions of BluetoothHeadsetClient will return default error
+     * results once close() has been called. Multiple invocations of close()
+     * are ok.
+     */
+    /*package*/ void close() {
+        if (VDBG) log("close()");
+
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (Exception e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        synchronized (mConnection) {
+            if (mService != null) {
+                try {
+                    mService = null;
+                    mContext.unbindService(mConnection);
+                } catch (Exception re) {
+                    Log.e(TAG,"",re);
+                }
+            }
+        }
+        mServiceListener = null;
+    }
+
+    /**
+     * Connects to remote device.
+     *
+     * Currently, the system supports only 1 connection. So, in case of the
+     * second connection, this implementation will disconnect already connected
+     * device automatically and will process the new one.
+     *
+     * @param device    a remote device we want connect to
+     * @return <code>true</code> if command has been issued successfully;
+     *          <code>false</code> otherwise;
+     *          upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED}
+     *          intent.
+     */
+    public boolean connect(BluetoothDevice device) {
+        if (DBG) log("connect(" + device + ")");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.connect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Disconnects remote device
+     *
+     * @param device    a remote device we want disconnect
+     * @return          <code>true</code> if command has been issued successfully;
+     *                  <code>false</code> otherwise;
+     *                  upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED}
+     *                  intent.
+     */
+    public boolean disconnect(BluetoothDevice device) {
+        if (DBG) log("disconnect(" + device + ")");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.disconnect(device);
+            } catch (RemoteException e) {
+              Log.e(TAG, Log.getStackTraceString(new Throwable()));
+              return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Return the list of connected remote devices
+     *
+     * @return list of connected devices; empty list if nothing is connected.
+     */
+    @Override
+    public List<BluetoothDevice> getConnectedDevices() {
+        if (VDBG) log("getConnectedDevices()");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getConnectedDevices();
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return new ArrayList<BluetoothDevice>();
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * Returns list of remote devices in a particular state
+     *
+     * @param states    collection of states
+     * @return          list of devices that state matches the states listed in
+     *                  <code>states</code>; empty list if nothing matches the
+     *                  <code>states</code>
+     */
+    @Override
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        if (VDBG) log("getDevicesMatchingStates()");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getDevicesMatchingConnectionStates(states);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return new ArrayList<BluetoothDevice>();
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * Returns state of the <code>device</code>
+     *
+     * @param device    a remote device
+     * @return          the state of connection of the device
+     */
+    @Override
+    public int getConnectionState(BluetoothDevice device) {
+        if (VDBG) log("getConnectionState(" + device + ")");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.getConnectionState(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return BluetoothProfile.STATE_DISCONNECTED;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return BluetoothProfile.STATE_DISCONNECTED;
+    }
+
+    /**
+     * Set priority of the profile
+     *
+     * The device should already be paired.
+     */
+    public boolean setPriority(BluetoothDevice device, int priority) {
+        if (DBG) log("setPriority(" + device + ", " + priority + ")");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF &&
+                    priority != BluetoothProfile.PRIORITY_ON) {
+              return false;
+            }
+            try {
+                return mService.setPriority(device, priority);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Get the priority of the profile.
+     */
+    public int getPriority(BluetoothDevice device) {
+        if (VDBG) log("getPriority(" + device + ")");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.getPriority(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return PRIORITY_OFF;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return PRIORITY_OFF;
+    }
+
+    /**
+     * Starts voice recognition.
+     *
+     * @param device    remote device
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_AG_EVENT}
+     *                   intent.
+     *
+     * <p>Feature required for successful execution is being reported by:
+     * {@link #EXTRA_AG_FEATURE_VOICE_RECOGNITION}.
+     * This method invocation will fail silently when feature is not supported.</p>
+     */
+    public boolean startVoiceRecognition(BluetoothDevice device) {
+        if (DBG) log("startVoiceRecognition()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.startVoiceRecognition(device);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Stops voice recognition.
+     *
+     * @param device    remote device
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_AG_EVENT}
+     *                   intent.
+     *
+     * <p>Feature required for successful execution is being reported by:
+     * {@link #EXTRA_AG_FEATURE_VOICE_RECOGNITION}.
+     * This method invocation will fail silently when feature is not supported.</p>
+     */
+    public boolean stopVoiceRecognition(BluetoothDevice device) {
+        if (DBG) log("stopVoiceRecognition()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.stopVoiceRecognition(device);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Returns list of all calls in any state.
+     *
+     * @param device    remote device
+     * @return          list of calls; empty list if none call exists
+     */
+    public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
+        if (DBG) log("getCurrentCalls()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.getCurrentCalls(device);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return null;
+    }
+
+    /**
+     * Returns list of current values of AG indicators.
+     *
+     * @param device    remote device
+     * @return          bundle of AG  indicators; null if device is not in
+     *                  CONNECTED state
+     */
+    public Bundle getCurrentAgEvents(BluetoothDevice device) {
+        if (DBG) log("getCurrentCalls()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.getCurrentAgEvents(device);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return null;
+    }
+
+    /**
+     * Accepts a call
+     *
+     * @param device    remote device
+     * @param flag      action policy while accepting a call. Possible values
+     *                   {@link #CALL_ACCEPT_NONE}, {@link #CALL_ACCEPT_HOLD},
+     *                   {@link #CALL_ACCEPT_TERMINATE}
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
+     *                   intent.
+     */
+    public boolean acceptCall(BluetoothDevice device, int flag) {
+        if (DBG) log("acceptCall()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.acceptCall(device, flag);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Holds a call.
+     *
+     * @param device    remote device
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
+     *                   intent.
+     */
+    public boolean holdCall(BluetoothDevice device) {
+        if (DBG) log("holdCall()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.holdCall(device);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Rejects a call.
+     *
+     * @param device    remote device
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
+     *                   intent.
+     *
+     * <p>Feature required for successful execution is being reported by:
+     * {@link #EXTRA_AG_FEATURE_REJECT_CALL}.
+     * This method invocation will fail silently when feature is not supported.</p>
+     */
+    public boolean rejectCall(BluetoothDevice device) {
+        if (DBG) log("rejectCall()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.rejectCall(device);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Terminates a specified call.
+     *
+     * Works only when Extended Call Control is supported by Audio Gateway.
+     *
+     * @param device    remote device
+     * @param index     index of the call to be terminated
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
+     *                   intent.
+     *
+     * <p>Feature required for successful execution is being reported by:
+     * {@link #EXTRA_AG_FEATURE_ECC}.
+     * This method invocation will fail silently when feature is not supported.</p>
+     */
+    public boolean terminateCall(BluetoothDevice device, int index) {
+        if (DBG) log("terminateCall()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.terminateCall(device, index);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Enters private mode with a specified call.
+     *
+     * Works only when Extended Call Control is supported by Audio Gateway.
+     *
+     * @param device    remote device
+     * @param index     index of the call to connect in private mode
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
+     *                   intent.
+     *
+     * <p>Feature required for successful execution is being reported by:
+     * {@link #EXTRA_AG_FEATURE_ECC}.
+     * This method invocation will fail silently when feature is not supported.</p>
+     */
+    public boolean enterPrivateMode(BluetoothDevice device, int index) {
+        if (DBG) log("enterPrivateMode()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.enterPrivateMode(device, index);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Performs explicit call transfer.
+     *
+     * That means connect other calls and disconnect.
+     *
+     * @param device    remote device
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
+     *                   intent.
+     *
+     * <p>Feature required for successful execution is being reported by:
+     * {@link #EXTRA_AG_FEATURE_MERGE_AND_DETACH}.
+     * This method invocation will fail silently when feature is not supported.</p>
+     */
+    public boolean explicitCallTransfer(BluetoothDevice device) {
+        if (DBG) log("explicitCallTransfer()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.explicitCallTransfer(device);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Redials last number from Audio Gateway.
+     *
+     * @param device    remote device
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
+     *                   intent in case of success; {@link #ACTION_RESULT} is sent
+     *                   otherwise;
+     */
+    public boolean redial(BluetoothDevice device) {
+        if (DBG) log("redial()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.redial(device);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Places a call with specified number.
+     *
+     * @param device    remote device
+     * @param number    valid phone number
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
+     *                   intent in case of success; {@link #ACTION_RESULT} is sent
+     *                   otherwise;
+     */
+    public boolean dial(BluetoothDevice device, String number) {
+        if (DBG) log("dial()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.dial(device, number);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Places a call to the number under specified memory location.
+     *
+     * @param device    remote device
+     * @param location  valid memory location
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_CALL_CHANGED}
+     *                   intent in case of success; {@link #ACTION_RESULT} is sent
+     *                   otherwise;
+     */
+    public boolean dialMemory(BluetoothDevice device, int location) {
+        if (DBG) log("dialMemory()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.dialMemory(device, location);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Sends DTMF code.
+     *
+     * Possible code values : 0,1,2,3,4,5,6,7,8,9,A,B,C,D,*,#
+     *
+     * @param device    remote device
+     * @param code  ASCII code
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_RESULT} intent;
+     */
+    public boolean sendDTMF(BluetoothDevice device, byte code) {
+        if (DBG) log("sendDTMF()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.sendDTMF(device, code);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Get a number corresponding to last voice tag recorded on AG.
+     *
+     * @param device    remote device
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_LAST_VTAG}
+     *                   or {@link #ACTION_RESULT} intent;
+     *
+     * <p>Feature required for successful execution is being reported by:
+     * {@link #EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT}.
+     * This method invocation will fail silently when feature is not supported.</p>
+     */
+    public boolean getLastVoiceTagNumber(BluetoothDevice device) {
+        if (DBG) log("getLastVoiceTagNumber()");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.getLastVoiceTagNumber(device);
+            } catch (RemoteException e) {
+                Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Accept the incoming connection.
+     */
+    public boolean acceptIncomingConnect(BluetoothDevice device) {
+        if (DBG) log("acceptIncomingConnect");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.acceptIncomingConnect(device);
+            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return false;
+    }
+
+    /**
+     * Reject the incoming connection.
+     */
+    public boolean rejectIncomingConnect(BluetoothDevice device) {
+        if (DBG) log("rejectIncomingConnect");
+        if (mService != null) {
+            try {
+                return mService.rejectIncomingConnect(device);
+            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return false;
+    }
+
+    /**
+     * Returns current audio state of Audio Gateway.
+     *
+     * Note: This is an internal function and shouldn't be exposed
+     */
+    public int getAudioState(BluetoothDevice device) {
+        if (VDBG) log("getAudioState");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getAudioState(device);
+            } catch (RemoteException e) {Log.e(TAG, e.toString());}
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
+    }
+
+    /**
+     * Initiates a connection of audio channel.
+     *
+     * It setup SCO channel with remote connected Handsfree AG device.
+     *
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED}
+     *                   intent;
+     */
+    public boolean connectAudio() {
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.connectAudio();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return false;
+    }
+
+    /**
+     * Disconnects audio channel.
+     *
+     * It tears down the SCO channel from remote AG device.
+     *
+     * @return          <code>true</code> if command has been issued successfully;
+     *                   <code>false</code> otherwise;
+     *                   upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED}
+     *                   intent;
+     */
+    public boolean disconnectAudio() {
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.disconnectAudio();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return false;
+    }
+
+    /**
+     * Get Audio Gateway features
+     *
+     * @param device    remote device
+     * @return          bundle of AG features; null if no service or
+     *                  AG not connected
+     */
+    public Bundle getCurrentAgFeatures(BluetoothDevice device) {
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getCurrentAgFeatures(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return null;
+    }
+
+
+    private ServiceConnection mConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "Proxy object connected");
+            mService = IBluetoothHeadsetClient.Stub.asInterface(service);
+
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.HEADSET_CLIENT,
+                        BluetoothHeadsetClient.this);
+            }
+        }
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) Log.d(TAG, "Proxy object disconnected");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET_CLIENT);
+            }
+        }
+    };
+
+    private boolean isEnabled() {
+       if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
+       return false;
+    }
+
+    private boolean isValidDevice(BluetoothDevice device) {
+       if (device == null) return false;
+
+       if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+       return false;
+    }
+
+    private static void log(String msg) {
+        Log.d(TAG, msg);
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.aidl b/core/java/android/bluetooth/BluetoothHeadsetClientCall.aidl
new file mode 100644
index 0000000..35f7923
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothHeadsetClientCall.aidl
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.bluetooth;
+
+parcelable BluetoothHeadsetClientCall;
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
new file mode 100644
index 0000000..a15bd97
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class represents a single call, its state and properties.
+ * It implements {@link Parcelable} for inter-process message passing.
+ * @hide
+ */
+public final class BluetoothHeadsetClientCall implements Parcelable {
+
+    /* Call state */
+    /**
+     * Call is active.
+     */
+    public static final int CALL_STATE_ACTIVE = 0;
+    /**
+     * Call is in held state.
+     */
+    public static final int CALL_STATE_HELD = 1;
+    /**
+     * Outgoing call that is being dialed right now.
+     */
+    public static final int CALL_STATE_DIALING = 2;
+    /**
+     * Outgoing call that remote party has already been alerted about.
+     */
+    public static final int CALL_STATE_ALERTING = 3;
+    /**
+     * Incoming call that can be accepted or rejected.
+     */
+    public static final int CALL_STATE_INCOMING = 4;
+    /**
+     * Waiting call state when there is already an active call.
+     */
+    public static final int CALL_STATE_WAITING = 5;
+    /**
+     * Call that has been held by response and hold
+     * (see Bluetooth specification for further references).
+     */
+    public static final int CALL_STATE_HELD_BY_RESPONSE_AND_HOLD = 6;
+    /**
+     * Call that has been already terminated and should not be referenced as a valid call.
+     */
+    public static final int CALL_STATE_TERMINATED = 7;
+
+    private final int mId;
+    private int mState;
+    private String mNumber;
+    private boolean mMultiParty;
+    private final boolean mOutgoing;
+
+    /**
+     * Creates BluetoothHeadsetClientCall instance.
+     */
+    public BluetoothHeadsetClientCall(int id, int state, String number, boolean multiParty,
+            boolean outgoing) {
+        mId = id;
+        mState = state;
+        mNumber = number != null ? number : "";
+        mMultiParty = multiParty;
+        mOutgoing = outgoing;
+    }
+
+    /**
+     * Sets call's state.
+     *
+     * <p>Note: This is an internal function and shouldn't be exposed</p>
+     *
+     * @param  state    new call state.
+     */
+    public void setState(int state) {
+        mState = state;
+    }
+
+    /**
+     * Sets call's number.
+     *
+     * <p>Note: This is an internal function and shouldn't be exposed</p>
+     *
+     * @param number    String representing phone number.
+     */
+    public void setNumber(String number) {
+        mNumber = number;
+    }
+
+    /**
+     * Sets this call as multi party call.
+     *
+     * <p>Note: This is an internal function and shouldn't be exposed</p>
+     *
+     * @param multiParty    if <code>true</code> sets this call as a part
+     *                      of multi party conference.
+     */
+    public void setMultiParty(boolean multiParty) {
+        mMultiParty = multiParty;
+    }
+
+    /**
+     * Gets call's Id.
+     *
+     * @return call id.
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * Gets call's current state.
+     *
+     * @return state of this particular phone call.
+     */
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Gets call's number.
+     *
+     * @return string representing phone number.
+     */
+    public String getNumber() {
+        return mNumber;
+    }
+
+    /**
+     * Checks if call is an active call in a conference mode (aka multi party).
+     *
+     * @return <code>true</code> if call is a multi party call,
+     *         <code>false</code> otherwise.
+     */
+    public boolean isMultiParty() {
+        return mMultiParty;
+    }
+
+    /**
+     * Checks if this call is an outgoing call.
+     *
+     * @return <code>true</code> if its outgoing call,
+     *         <code>false</code> otherwise.
+     */
+    public boolean isOutgoing() {
+        return mOutgoing;
+    }
+
+    public String toString() {
+        StringBuilder builder = new StringBuilder("BluetoothHeadsetClientCall{mId: ");
+        builder.append(mId);
+        builder.append(", mState: ");
+        switch (mState) {
+            case CALL_STATE_ACTIVE: builder.append("ACTIVE"); break;
+            case CALL_STATE_HELD: builder.append("HELD"); break;
+            case CALL_STATE_DIALING: builder.append("DIALING"); break;
+            case CALL_STATE_ALERTING: builder.append("ALERTING"); break;
+            case CALL_STATE_INCOMING: builder.append("INCOMING"); break;
+            case CALL_STATE_WAITING: builder.append("WAITING"); break;
+            case CALL_STATE_HELD_BY_RESPONSE_AND_HOLD: builder.append("HELD_BY_RESPONSE_AND_HOLD"); break;
+            case CALL_STATE_TERMINATED: builder.append("TERMINATED"); break;
+            default: builder.append(mState); break;
+        }
+        builder.append(", mNumber: ");
+        builder.append(mNumber);
+        builder.append(", mMultiParty: ");
+        builder.append(mMultiParty);
+        builder.append(", mOutgoing: ");
+        builder.append(mOutgoing);
+        builder.append("}");
+        return builder.toString();
+    }
+
+    /**
+     * {@link Parcelable.Creator} interface implementation.
+     */
+    public static final Parcelable.Creator<BluetoothHeadsetClientCall> CREATOR =
+            new Parcelable.Creator<BluetoothHeadsetClientCall>() {
+                @Override
+                public BluetoothHeadsetClientCall createFromParcel(Parcel in) {
+                    return new BluetoothHeadsetClientCall(in.readInt(), in.readInt(),
+                            in.readString(), in.readInt() == 1, in.readInt() == 1);
+                }
+
+                @Override
+                public BluetoothHeadsetClientCall[] newArray(int size) {
+                    return new BluetoothHeadsetClientCall[size];
+                }
+            };
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mId);
+        out.writeInt(mState);
+        out.writeString(mNumber);
+        out.writeInt(mMultiParty ? 1 : 0);
+        out.writeInt(mOutgoing ? 1 : 0);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index 2e950fae..4949c24 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -23,7 +23,6 @@
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -488,7 +487,8 @@
         Intent intent = new Intent(IBluetoothHealth.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
-        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth Health Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index c48b15d..252e3d2 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -24,7 +24,6 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -260,7 +259,8 @@
         Intent intent = new Intent(IBluetoothInputDevice.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
-        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent);
             return false;
         }
@@ -640,7 +640,7 @@
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
      *
      * @param device Remote Bluetooth Device
-     * @param data Data to send
+     * @param report Report to send
      * @return false on immediate error,
      *               true otherwise
      * @hide
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index 172f3bc..b1618cf3 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -194,6 +194,26 @@
      */
     public BluetoothGattServer openGattServer(Context context,
                                               BluetoothGattServerCallback callback) {
+
+        return (openGattServer (context, callback, BluetoothDevice.TRANSPORT_AUTO));
+    }
+
+    /**
+     * Open a GATT Server
+     * The callback is used to deliver results to Caller, such as connection status as well
+     * as the results of any other GATT server operations.
+     * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
+     * to conduct GATT server operations.
+     * @param context App context
+     * @param callback GATT server callback handler that will receive asynchronous callbacks.
+     * @param transport preferred transport for GATT connections to remote dual-mode devices
+     *             {@link BluetoothDevice#TRANSPORT_AUTO} or
+     *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
+     * @return BluetoothGattServer instance
+     * @hide
+     */
+    public BluetoothGattServer openGattServer(Context context,
+                                              BluetoothGattServerCallback callback,int transport) {
         if (context == null || callback == null) {
             throw new IllegalArgumentException("null parameter: " + context + " " + callback);
         }
@@ -208,7 +228,7 @@
                 Log.e(TAG, "Fail to get GATT Server connection");
                 return null;
             }
-            BluetoothGattServer mGattServer = new BluetoothGattServer(context, iGatt);
+            BluetoothGattServer mGattServer = new BluetoothGattServer(context, iGatt,transport);
             Boolean regStatus = mGattServer.registerCallback(callback);
             return regStatus? mGattServer : null;
         } catch (RemoteException e) {
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index 92a2f1e..7f57acf 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -22,9 +22,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.ServiceManager;
+import android.os.*;
 import android.util.Log;
 
 /**
@@ -106,7 +104,8 @@
         Intent intent = new Intent(IBluetoothMap.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
-        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth MAP Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothMasInstance.java b/core/java/android/bluetooth/BluetoothMasInstance.java
new file mode 100644
index 0000000..4459e2c
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothMasInstance.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/** @hide */
+public final class BluetoothMasInstance implements Parcelable {
+    private final int mId;
+    private final String mName;
+    private final int mChannel;
+    private final int mMsgTypes;
+
+    public BluetoothMasInstance(int id, String name, int channel, int msgTypes) {
+        mId = id;
+        mName = name;
+        mChannel = channel;
+        mMsgTypes = msgTypes;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof BluetoothMasInstance) {
+            return mId == ((BluetoothMasInstance)o).mId;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return mId + (mChannel << 8) + (mMsgTypes << 16);
+    }
+
+    @Override
+    public String toString() {
+        return Integer.toString(mId) + ":" + mName + ":" + mChannel + ":" +
+                Integer.toHexString(mMsgTypes);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<BluetoothMasInstance> CREATOR =
+            new Parcelable.Creator<BluetoothMasInstance>() {
+        public BluetoothMasInstance createFromParcel(Parcel in) {
+            return new BluetoothMasInstance(in.readInt(), in.readString(),
+                    in.readInt(), in.readInt());
+        }
+        public BluetoothMasInstance[] newArray(int size) {
+            return new BluetoothMasInstance[size];
+        }
+    };
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mId);
+        out.writeString(mName);
+        out.writeInt(mChannel);
+        out.writeInt(mMsgTypes);
+    }
+
+    public static final class MessageType {
+        public static final int EMAIL    = 0x01;
+        public static final int SMS_GSM  = 0x02;
+        public static final int SMS_CDMA = 0x04;
+        public static final int MMS      = 0x08;
+    }
+
+    public int getId() {
+        return mId;
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public int getChannel() {
+        return mChannel;
+    }
+
+    public int getMsgTypes() {
+        return mMsgTypes;
+    }
+
+    public boolean msgSupported(int msg) {
+        return (mMsgTypes & msg) != 0;
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index b7a37f4..4f81f98 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -24,7 +24,6 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -146,7 +145,8 @@
         Intent intent = new Intent(IBluetoothPan.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
-        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth Pan Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index 7f45652..dc01fc7 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -22,7 +22,6 @@
 import android.content.ServiceConnection;
 import android.os.RemoteException;
 import android.os.IBinder;
-import android.os.ServiceManager;
 import android.util.Log;
 
 /**
@@ -161,7 +160,8 @@
         Intent intent = new Intent(IBluetoothPbap.class.getName());
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
-        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth Pbap Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 1574090..1367405 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2010-2014 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -104,6 +104,24 @@
     public static final int MAP = 9;
 
     /**
+     * A2DP Sink Profile
+     * @hide
+     */
+    public static final int A2DP_SINK = 10;
+
+    /**
+     * AVRCP Controller Profile
+     * @hide
+     */
+    public static final int AVRCP_CONTROLLER = 11;
+
+    /**
+     * Headset Client - HFP HF Role
+     * @hide
+     */
+    public static final int HEADSET_CLIENT = 16;
+
+    /**
      * Default priority for devices that we try to auto-connect to and
      * and allow incoming connections for the profile
      * @hide
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index 96be8a2..bc56e55 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -17,7 +17,6 @@
 package android.bluetooth;
 
 import android.os.Handler;
-import android.os.Message;
 import android.os.ParcelUuid;
 
 import java.io.Closeable;
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 5738b9a..36997e5 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -16,21 +16,16 @@
 
 package android.bluetooth;
 
-import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.io.Closeable;
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.List;
 import java.util.Locale;
 import java.util.UUID;
 import android.net.LocalSocket;
@@ -330,6 +325,7 @@
             }
         } catch (RemoteException e) {
             Log.e(TAG, Log.getStackTraceString(new Throwable()));
+            throw new IOException("unable to send RPC: " + e.getMessage());
         }
     }
 
@@ -379,6 +375,14 @@
             } // else ASSERT(mPort == channel)
             ret = 0;
         } catch (IOException e) {
+            if (mPfd != null) {
+                try {
+                    mPfd.close();
+                } catch (IOException e1) {
+                    Log.e(TAG, "bindListen, close mPfd: " + e1);
+                }
+                mPfd = null;
+            }
             Log.e(TAG, "bindListen, fail to get port number, exception: " + e);
             return -1;
         }
@@ -462,8 +466,10 @@
                     mSocket.close();
                     mSocket = null;
                 }
-                if(mPfd != null)
-                    mPfd.detachFd();
+                if (mPfd != null) {
+                    mPfd.close();
+                    mPfd = null;
+                }
            }
         }
     }
diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
deleted file mode 100644
index fe5e52b..0000000
--- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.net.BaseNetworkStateTracker;
-import android.os.IBinder;
-import android.os.ServiceManager;
-import android.os.INetworkManagementService;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.DhcpResults;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkStateTracker;
-import android.net.NetworkUtils;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.text.TextUtils;
-import android.util.Log;
-import java.net.InterfaceAddress;
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-import java.net.Inet4Address;
-import android.os.SystemProperties;
-
-import com.android.internal.util.AsyncChannel;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * This class tracks the data connection associated with Bluetooth
- * reverse tethering. This is a singleton class and an instance will be
- * created by ConnectivityService. BluetoothService will call into this
- * when a reverse tethered connection needs to be activated.
- *
- * @hide
- */
-public class BluetoothTetheringDataTracker extends BaseNetworkStateTracker {
-    private static final String NETWORKTYPE = "BLUETOOTH_TETHER";
-    private static final String TAG = "BluetoothTethering";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = true;
-
-    // Event sent to the mBtdtHandler when DHCP fails so we can tear down the network.
-    private static final int EVENT_NETWORK_FAILED = 1;
-
-    private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
-    private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
-    private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
-    private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
-
-    private final Object mLinkPropertiesLock = new Object();
-    private final Object mNetworkInfoLock = new Object();
-
-    private BluetoothPan mBluetoothPan;
-    private static String mRevTetheredIface;
-    /* For sending events to connectivity service handler */
-    private Handler mCsHandler;
-    private static BluetoothTetheringDataTracker sInstance;
-    private BtdtHandler mBtdtHandler;
-    private AtomicReference<AsyncChannel> mAsyncChannel = new AtomicReference<AsyncChannel>(null);
-
-    private BluetoothTetheringDataTracker() {
-        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_BLUETOOTH, 0, NETWORKTYPE, "");
-        mLinkProperties = new LinkProperties();
-        mLinkCapabilities = new LinkCapabilities();
-
-        mNetworkInfo.setIsAvailable(false);
-        setTeardownRequested(false);
-    }
-
-    public static synchronized BluetoothTetheringDataTracker getInstance() {
-        if (sInstance == null) sInstance = new BluetoothTetheringDataTracker();
-        return sInstance;
-    }
-
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException();
-    }
-
-    public void setTeardownRequested(boolean isRequested) {
-        mTeardownRequested.set(isRequested);
-    }
-
-    public boolean isTeardownRequested() {
-        return mTeardownRequested.get();
-    }
-
-    /**
-     * Begin monitoring connectivity
-     */
-    public void startMonitoring(Context context, Handler target) {
-        if (DBG) Log.d(TAG, "startMonitoring: target: " + target);
-        mContext = context;
-        mCsHandler = target;
-        if (VDBG) Log.d(TAG, "startMonitoring: mCsHandler: " + mCsHandler);
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        if (adapter != null) {
-            adapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.PAN);
-        }
-        mBtdtHandler = new BtdtHandler(target.getLooper(), this);
-    }
-
-    private BluetoothProfile.ServiceListener mProfileServiceListener =
-        new BluetoothProfile.ServiceListener() {
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            mBluetoothPan = (BluetoothPan) proxy;
-        }
-        public void onServiceDisconnected(int profile) {
-            mBluetoothPan = null;
-        }
-    };
-
-    /**
-     * Disable connectivity to a network
-     * TODO: do away with return value after making MobileDataStateTracker async
-     */
-    public boolean teardown() {
-        mTeardownRequested.set(true);
-        if (mBluetoothPan != null) {
-            for (BluetoothDevice device: mBluetoothPan.getConnectedDevices()) {
-                mBluetoothPan.disconnect(device);
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
-    public void captivePortalCheckCompleted(boolean isCaptivePortal) {
-        // not implemented
-    }
-
-    /**
-     * Re-enable connectivity to a network after a {@link #teardown()}.
-     */
-    public boolean reconnect() {
-        mTeardownRequested.set(false);
-        //Ignore
-        return true;
-    }
-
-    /**
-     * Turn the wireless radio off for a network.
-     * @param turnOn {@code true} to turn the radio on, {@code false}
-     */
-    public boolean setRadio(boolean turnOn) {
-        return true;
-    }
-
-    /**
-     * @return true - If are we currently tethered with another device.
-     */
-    public synchronized boolean isAvailable() {
-        return mNetworkInfo.isAvailable();
-    }
-
-    /**
-     * Tells the underlying networking system that the caller wants to
-     * begin using the named feature. The interpretation of {@code feature}
-     * is completely up to each networking implementation.
-     * @param feature the name of the feature to be used
-     * @param callingPid the process ID of the process that is issuing this request
-     * @param callingUid the user ID of the process that is issuing this request
-     * @return an integer value representing the outcome of the request.
-     * The interpretation of this value is specific to each networking
-     * implementation+feature combination, except that the value {@code -1}
-     * always indicates failure.
-     * TODO: needs to go away
-     */
-    public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
-        return -1;
-    }
-
-    /**
-     * Tells the underlying networking system that the caller is finished
-     * using the named feature. The interpretation of {@code feature}
-     * is completely up to each networking implementation.
-     * @param feature the name of the feature that is no longer needed.
-     * @param callingPid the process ID of the process that is issuing this request
-     * @param callingUid the user ID of the process that is issuing this request
-     * @return an integer value representing the outcome of the request.
-     * The interpretation of this value is specific to each networking
-     * implementation+feature combination, except that the value {@code -1}
-     * always indicates failure.
-     * TODO: needs to go away
-     */
-    public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
-        return -1;
-    }
-
-    @Override
-    public void setUserDataEnable(boolean enabled) {
-        Log.w(TAG, "ignoring setUserDataEnable(" + enabled + ")");
-    }
-
-    @Override
-    public void setPolicyDataEnable(boolean enabled) {
-        Log.w(TAG, "ignoring setPolicyDataEnable(" + enabled + ")");
-    }
-
-    /**
-     * Check if private DNS route is set for the network
-     */
-    public boolean isPrivateDnsRouteSet() {
-        return mPrivateDnsRouteSet.get();
-    }
-
-    /**
-     * Set a flag indicating private DNS route is set
-     */
-    public void privateDnsRouteSet(boolean enabled) {
-        mPrivateDnsRouteSet.set(enabled);
-    }
-
-    /**
-     * Fetch NetworkInfo for the network
-     */
-    public NetworkInfo getNetworkInfo() {
-        synchronized (mNetworkInfoLock) {
-            return new NetworkInfo(mNetworkInfo);
-        }
-    }
-
-    /**
-     * Fetch LinkProperties for the network
-     */
-    public LinkProperties getLinkProperties() {
-        synchronized (mLinkPropertiesLock) {
-            return new LinkProperties(mLinkProperties);
-        }
-    }
-
-   /**
-     * A capability is an Integer/String pair, the capabilities
-     * are defined in the class LinkSocket#Key.
-     *
-     * @return a copy of this connections capabilities, may be empty but never null.
-     */
-    public LinkCapabilities getLinkCapabilities() {
-        return new LinkCapabilities(mLinkCapabilities);
-    }
-
-    /**
-     * Fetch default gateway address for the network
-     */
-    public int getDefaultGatewayAddr() {
-        return mDefaultGatewayAddr.get();
-    }
-
-    /**
-     * Check if default route is set
-     */
-    public boolean isDefaultRouteSet() {
-        return mDefaultRouteSet.get();
-    }
-
-    /**
-     * Set a flag indicating default route is set for the network
-     */
-    public void defaultRouteSet(boolean enabled) {
-        mDefaultRouteSet.set(enabled);
-    }
-
-    /**
-     * Return the system properties name associated with the tcp buffer sizes
-     * for this network.
-     */
-    public String getTcpBufferSizesPropName() {
-        return "net.tcp.buffersize.wifi";
-    }
-
-    private static short countPrefixLength(byte [] mask) {
-        short count = 0;
-        for (byte b : mask) {
-            for (int i = 0; i < 8; ++i) {
-                if ((b & (1 << i)) != 0) {
-                    ++count;
-                }
-            }
-        }
-        return count;
-    }
-
-    void startReverseTether(final LinkProperties linkProperties) {
-        if (linkProperties == null || TextUtils.isEmpty(linkProperties.getInterfaceName())) {
-            Log.e(TAG, "attempted to reverse tether with empty interface");
-            return;
-        }
-        synchronized (mLinkPropertiesLock) {
-            if (mLinkProperties.getInterfaceName() != null) {
-                Log.e(TAG, "attempted to reverse tether while already in process");
-                return;
-            }
-            mLinkProperties = linkProperties;
-        }
-        Thread dhcpThread = new Thread(new Runnable() {
-            public void run() {
-                //Currently this thread runs independently.
-                DhcpResults dhcpResults = new DhcpResults();
-                boolean success = NetworkUtils.runDhcp(linkProperties.getInterfaceName(),
-                        dhcpResults);
-                synchronized (mLinkPropertiesLock) {
-                    if (linkProperties.getInterfaceName() != mLinkProperties.getInterfaceName()) {
-                        Log.e(TAG, "obsolete DHCP run aborted");
-                        return;
-                    }
-                    if (!success) {
-                        Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
-                        mBtdtHandler.obtainMessage(EVENT_NETWORK_FAILED).sendToTarget();
-                        return;
-                    }
-                    mLinkProperties = dhcpResults.linkProperties;
-                    synchronized (mNetworkInfoLock) {
-                        mNetworkInfo.setIsAvailable(true);
-                        mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
-                        if (mCsHandler != null) {
-                            Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED,
-                                    new NetworkInfo(mNetworkInfo));
-                            msg.sendToTarget();
-                       }
-                    }
-                    return;
-                }
-            }
-        });
-        dhcpThread.start();
-    }
-
-    void stopReverseTether() {
-        synchronized (mLinkPropertiesLock) {
-            if (TextUtils.isEmpty(mLinkProperties.getInterfaceName())) {
-                Log.e(TAG, "attempted to stop reverse tether with nothing tethered");
-                return;
-            }
-            NetworkUtils.stopDhcp(mLinkProperties.getInterfaceName());
-            mLinkProperties.clear();
-            synchronized (mNetworkInfoLock) {
-                mNetworkInfo.setIsAvailable(false);
-                mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
-
-                if (mCsHandler != null) {
-                    mCsHandler.obtainMessage(EVENT_STATE_CHANGED, new NetworkInfo(mNetworkInfo)).
-                            sendToTarget();
-                }
-            }
-        }
-    }
-
-    public void setDependencyMet(boolean met) {
-        // not supported on this network
-    }
-
-    @Override
-    public void addStackedLink(LinkProperties link) {
-        mLinkProperties.addStackedLink(link);
-    }
-
-    @Override
-    public void removeStackedLink(LinkProperties link) {
-        mLinkProperties.removeStackedLink(link);
-    }
-
-    static class BtdtHandler extends Handler {
-        private AsyncChannel mStackChannel;
-        private final BluetoothTetheringDataTracker mBtdt;
-
-        BtdtHandler(Looper looper, BluetoothTetheringDataTracker parent) {
-            super(looper);
-            mBtdt = parent;
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
-                    if (VDBG) Log.d(TAG, "got CMD_CHANNEL_HALF_CONNECTED");
-                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                        AsyncChannel ac = (AsyncChannel)msg.obj;
-                        if (mBtdt.mAsyncChannel.compareAndSet(null, ac) == false) {
-                            Log.e(TAG, "Trying to set mAsyncChannel twice!");
-                        } else {
-                            ac.sendMessage(
-                                    AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
-                        }
-                    }
-                    break;
-                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                    if (VDBG) Log.d(TAG, "got CMD_CHANNEL_DISCONNECTED");
-                    mBtdt.stopReverseTether();
-                    mBtdt.mAsyncChannel.set(null);
-                    break;
-                case NetworkStateTracker.EVENT_NETWORK_CONNECTED:
-                    LinkProperties linkProperties = (LinkProperties)(msg.obj);
-                    if (VDBG) Log.d(TAG, "got EVENT_NETWORK_CONNECTED, " + linkProperties);
-                    mBtdt.startReverseTether(linkProperties);
-                    break;
-                case NetworkStateTracker.EVENT_NETWORK_DISCONNECTED:
-                    linkProperties = (LinkProperties)(msg.obj);
-                    if (VDBG) Log.d(TAG, "got EVENT_NETWORK_DISCONNECTED, " + linkProperties);
-                    mBtdt.stopReverseTether();
-                    break;
-                case EVENT_NETWORK_FAILED:
-                    if (VDBG) Log.d(TAG, "got EVENT_NETWORK_FAILED");
-                    mBtdt.teardown();
-                    break;
-            }
-        }
-    }
-
-    @Override
-    public void supplyMessenger(Messenger messenger) {
-        if (messenger != null) {
-            new AsyncChannel().connect(mContext, mBtdtHandler, messenger);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 4b28516..1e22eb3 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -18,6 +18,8 @@
 
 import android.os.ParcelUuid;
 
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.UUID;
@@ -76,6 +78,12 @@
     public static final ParcelUuid BASE_UUID =
             ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
 
+    /** Length of bytes for 16 bit UUID */
+    public static final int UUID_BYTES_16_BIT = 2;
+    /** Length of bytes for 32 bit UUID */
+    public static final int UUID_BYTES_32_BIT = 4;
+    /** Length of bytes for 128 bit UUID */
+    public static final int UUID_BYTES_128_BIT = 16;
 
     public static final ParcelUuid[] RESERVED_UUIDS = {
         AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
@@ -216,15 +224,78 @@
     }
 
     /**
+     * Parse UUID from bytes. The {@code uuidBytes} can represent a 16-bit, 32-bit or 128-bit UUID,
+     * but the returned UUID is always in 128-bit format.
+     * Note UUID is little endian in Bluetooth.
+     *
+     * @param uuidBytes Byte representation of uuid.
+     * @return {@link ParcelUuid} parsed from bytes.
+     * @throws IllegalArgumentException If the {@code uuidBytes} cannot be parsed.
+     */
+    public static ParcelUuid parseUuidFrom(byte[] uuidBytes) {
+        if (uuidBytes == null) {
+            throw new IllegalArgumentException("uuidBytes cannot be null");
+        }
+        int length = uuidBytes.length;
+        if (length != UUID_BYTES_16_BIT && length != UUID_BYTES_32_BIT &&
+                length != UUID_BYTES_128_BIT) {
+            throw new IllegalArgumentException("uuidBytes length invalid - " + length);
+        }
+
+        // Construct a 128 bit UUID.
+        if (length == UUID_BYTES_128_BIT) {
+            ByteBuffer buf = ByteBuffer.wrap(uuidBytes).order(ByteOrder.LITTLE_ENDIAN);
+            long msb = buf.getLong(8);
+            long lsb = buf.getLong(0);
+            return new ParcelUuid(new UUID(msb, lsb));
+        }
+
+        // For 16 bit and 32 bit UUID we need to convert them to 128 bit value.
+        // 128_bit_value = uuid * 2^96 + BASE_UUID
+        long shortUuid;
+        if (length == UUID_BYTES_16_BIT) {
+            shortUuid = uuidBytes[0] & 0xFF;
+            shortUuid += (uuidBytes[1] & 0xFF) << 8;
+        } else {
+            shortUuid = uuidBytes[0] & 0xFF ;
+            shortUuid += (uuidBytes[1] & 0xFF) << 8;
+            shortUuid += (uuidBytes[2] & 0xFF) << 16;
+            shortUuid += (uuidBytes[3] & 0xFF) << 24;
+        }
+        long msb = BASE_UUID.getUuid().getMostSignificantBits() + (shortUuid << 32);
+        long lsb = BASE_UUID.getUuid().getLeastSignificantBits();
+        return new ParcelUuid(new UUID(msb, lsb));
+    }
+
+    /**
      * Check whether the given parcelUuid can be converted to 16 bit bluetooth uuid.
+     *
      * @param parcelUuid
      * @return true if the parcelUuid can be converted to 16 bit uuid, false otherwise.
      */
-    public static boolean isShortUuid(ParcelUuid parcelUuid) {
-      UUID uuid = parcelUuid.getUuid();
-      if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
-        return false;
-      }
-      return ((uuid.getMostSignificantBits() & 0xFFFF0000FFFFFFFFL) == 0x1000L);
+    public static boolean is16BitUuid(ParcelUuid parcelUuid) {
+        UUID uuid = parcelUuid.getUuid();
+        if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
+            return false;
+        }
+        return ((uuid.getMostSignificantBits() & 0xFFFF0000FFFFFFFFL) == 0x1000L);
+    }
+
+
+    /**
+     * Check whether the given parcelUuid can be converted to 32 bit bluetooth uuid.
+     *
+     * @param parcelUuid
+     * @return true if the parcelUuid can be converted to 32 bit uuid, false otherwise.
+     */
+    public static boolean is32BitUuid(ParcelUuid parcelUuid) {
+        UUID uuid = parcelUuid.getUuid();
+        if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) {
+            return false;
+        }
+        if (is16BitUuid(parcelUuid)) {
+            return false;
+        }
+        return ((uuid.getMostSignificantBits() & 0xFFFFFFFFL) == 0x1000L);
     }
 }
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 07db8cc..cf2a343 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -18,6 +18,7 @@
 
 import android.bluetooth.IBluetoothCallback;
 import android.bluetooth.IBluetoothStateChangeCallback;
+import android.bluetooth.BluetoothActivityEnergyInfo;
 import android.bluetooth.BluetoothDevice;
 import android.os.ParcelUuid;
 import android.os.ParcelFileDescriptor;
@@ -54,10 +55,11 @@
     int getProfileConnectionState(int profile);
 
     BluetoothDevice[] getBondedDevices();
-    boolean createBond(in BluetoothDevice device);
+    boolean createBond(in BluetoothDevice device, in int transport);
     boolean cancelBondProcess(in BluetoothDevice device);
     boolean removeBond(in BluetoothDevice device);
     int getBondState(in BluetoothDevice device);
+    boolean isConnected(in BluetoothDevice device);
 
     String getRemoteName(in BluetoothDevice device);
     int getRemoteType(in BluetoothDevice device);
@@ -66,12 +68,18 @@
     int getRemoteClass(in BluetoothDevice device);
     ParcelUuid[] getRemoteUuids(in BluetoothDevice device);
     boolean fetchRemoteUuids(in BluetoothDevice device);
+    boolean fetchRemoteMasInstances(in BluetoothDevice device);
 
     boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode);
     boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[]
     passkey);
     boolean setPairingConfirmation(in BluetoothDevice device, boolean accept);
 
+    int getPhonebookAccessPermission(in BluetoothDevice device);
+    boolean setPhonebookAccessPermission(in BluetoothDevice device, int value);
+    int getMessageAccessPermission(in BluetoothDevice device);
+    boolean setMessageAccessPermission(in BluetoothDevice device, int value);
+
     void sendConnectionStateChange(in BluetoothDevice device, int profile, int state, int prevState);
 
     void registerCallback(in IBluetoothCallback callback);
@@ -82,4 +90,11 @@
     ParcelFileDescriptor createSocketChannel(int type, in String serviceName, in ParcelUuid uuid, int port, int flag);
 
     boolean configHciSnoopLog(boolean enable);
+
+    boolean isMultiAdvertisementSupported();
+    boolean isOffloadedFilteringSupported();
+    boolean isOffloadedScanBatchingSupported();
+    boolean isActivityAndEnergyReportingSupported();
+    void getActivityEnergyInfoFromController();
+    BluetoothActivityEnergyInfo reportActivityInfo();
 }
diff --git a/core/java/android/bluetooth/IBluetoothA2dpSink.aidl b/core/java/android/bluetooth/IBluetoothA2dpSink.aidl
new file mode 100644
index 0000000..b7c6476
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothA2dpSink.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothAudioConfig;
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * APIs for Bluetooth A2DP sink service
+ *
+ * @hide
+ */
+interface IBluetoothA2dpSink {
+    boolean connect(in BluetoothDevice device);
+    boolean disconnect(in BluetoothDevice device);
+    List<BluetoothDevice> getConnectedDevices();
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
+    int getConnectionState(in BluetoothDevice device);
+    BluetoothAudioConfig getAudioConfig(in BluetoothDevice device);
+}
diff --git a/core/java/android/bluetooth/IBluetoothAvrcpController.aidl b/core/java/android/bluetooth/IBluetoothAvrcpController.aidl
new file mode 100644
index 0000000..f917a50
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothAvrcpController.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * APIs for Bluetooth AVRCP controller service
+ *
+ * @hide
+ */
+interface IBluetoothAvrcpController {
+    List<BluetoothDevice> getConnectedDevices();
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
+    int getConnectionState(in BluetoothDevice device);
+    void sendPassThroughCmd(in BluetoothDevice device, int keyCode, int keyState);
+}
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index c6b5c3d..7070bae 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -17,6 +17,11 @@
 package android.bluetooth;
 
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanSettings;
+import android.bluetooth.le.ResultStorageDescriptor;
 import android.os.ParcelUuid;
 
 import android.bluetooth.IBluetoothGattCallback;
@@ -29,23 +34,20 @@
 interface IBluetoothGatt {
     List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
 
-    void startScan(in int appIf, in boolean isServer);
-    void startScanWithUuids(in int appIf, in boolean isServer, in ParcelUuid[] ids);
+    void startScan(in int appIf, in boolean isServer, in ScanSettings settings,
+                   in List<ScanFilter> filters,
+                   in List scanStorages);
     void stopScan(in int appIf, in boolean isServer);
-
+    void flushPendingBatchResults(in int appIf, in boolean isServer);
+    void startMultiAdvertising(in int appIf,
+                               in AdvertiseData advertiseData,
+                               in AdvertiseData scanResponse,
+                               in AdvertiseSettings settings);
+    void stopMultiAdvertising(in int appIf);
     void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback);
     void unregisterClient(in int clientIf);
-    void clientConnect(in int clientIf, in String address, in boolean isDirect);
+    void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport);
     void clientDisconnect(in int clientIf, in String address);
-    void startAdvertising(in int appIf);
-    void stopAdvertising();
-    boolean setAdvServiceData(in byte[] serviceData);
-    byte[] getAdvServiceData();
-    boolean setAdvManufacturerCodeAndData(int manufactureCode, in byte[] manufacturerData);
-    byte[] getAdvManufacturerData();
-    List<ParcelUuid> getAdvServiceUuids();
-    void removeAdvManufacturerCodeAndData(int manufacturerCode);
-    boolean isAdvertising();
     void refreshDevice(in int clientIf, in String address);
     void discoverServices(in int clientIf, in String address);
     void readCharacteristic(in int clientIf, in String address, in int srvcType,
@@ -74,10 +76,11 @@
     void endReliableWrite(in int clientIf, in String address, in boolean execute);
     void readRemoteRssi(in int clientIf, in String address);
     void configureMTU(in int clientIf, in String address, in int mtu);
+    void connectionParameterUpdate(in int clientIf, in String address, in int connectionPriority);
 
     void registerServer(in ParcelUuid appId, in IBluetoothGattServerCallback callback);
     void unregisterServer(in int serverIf);
-    void serverConnect(in int servertIf, in String address, in boolean isDirect);
+    void serverConnect(in int servertIf, in String address, in boolean isDirect, in int transport);
     void serverDisconnect(in int serverIf, in String address);
     void beginServiceDeclaration(in int serverIf, in int srvcType,
                             in int srvcInstanceId, in int minHandles,
diff --git a/core/java/android/bluetooth/IBluetoothGattCallback.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
index a78c29b..91e62ea 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
@@ -16,17 +16,19 @@
 package android.bluetooth;
 
 import android.os.ParcelUuid;
-
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.ScanResult;
 
 /**
  * Callback definitions for interacting with BLE / GATT
  * @hide
  */
-interface IBluetoothGattCallback {
+oneway interface IBluetoothGattCallback {
     void onClientRegistered(in int status, in int clientIf);
     void onClientConnectionState(in int status, in int clientIf,
                                  in boolean connected, in String address);
-    void onScanResult(in String address, in int rssi, in byte[] advData);
+    void onScanResult(in ScanResult scanResult);
+    void onBatchScanResults(in List<ScanResult> batchResults);
     void onGetService(in String address, in int srvcType, in int srvcInstId,
                       in ParcelUuid srvcUuid);
     void onGetIncludedService(in String address, in int srvcType, in int srvcInstId,
@@ -63,6 +65,8 @@
                              in int charInstId, in ParcelUuid charUuid,
                              in byte[] value);
     void onReadRemoteRssi(in String address, in int rssi, in int status);
-    oneway void onAdvertiseStateChange(in int advertiseState, in int status);
+    void onMultiAdvertiseCallback(in int status, boolean isStart,
+                                  in AdvertiseSettings advertiseSettings);
     void onConfigureMTU(in String address, in int mtu, in int status);
+    void onFoundOrLost(in boolean onFound, in ScanResult scanResult);
 }
diff --git a/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
index ae9bffc..5d4d6c6 100644
--- a/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
@@ -22,7 +22,7 @@
  * Callback definitions for interacting with BLE / GATT
  * @hide
  */
-interface IBluetoothGattServerCallback {
+oneway interface IBluetoothGattServerCallback {
     void onServerRegistered(in int status, in int serverIf);
     void onScanResult(in String address, in int rssi, in byte[] advData);
     void onServerConnectionState(in int status, in int serverIf,
@@ -58,4 +58,5 @@
                                      in ParcelUuid descrId,
                                      in byte[] value);
     void onExecuteWrite(in String address, in int transId, in boolean execWrite);
+    void onNotificationSent(in String address, in int status);
 }
diff --git a/core/java/android/bluetooth/IBluetoothHeadset.aidl b/core/java/android/bluetooth/IBluetoothHeadset.aidl
index 524ca6f..0e23fad 100755
--- a/core/java/android/bluetooth/IBluetoothHeadset.aidl
+++ b/core/java/android/bluetooth/IBluetoothHeadset.aidl
@@ -55,4 +55,6 @@
     void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type);
     void clccResponse(int index, int direction, int status, int mode, boolean mpty,
                       String number, int type);
+    boolean enableWBS();
+    boolean disableWBS();
 }
diff --git a/core/java/android/bluetooth/IBluetoothHeadsetClient.aidl b/core/java/android/bluetooth/IBluetoothHeadsetClient.aidl
new file mode 100644
index 0000000..e518b7d
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothHeadsetClient.aidl
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadsetClientCall;
+import android.os.Bundle;
+
+/**
+ * API for Bluetooth Headset Client service (HFP HF Role)
+ *
+ * {@hide}
+ */
+interface IBluetoothHeadsetClient {
+    boolean connect(in BluetoothDevice device);
+    boolean disconnect(in BluetoothDevice device);
+
+    boolean acceptIncomingConnect(in BluetoothDevice device);
+    boolean rejectIncomingConnect(in BluetoothDevice device);
+
+    List<BluetoothDevice> getConnectedDevices();
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
+    int getConnectionState(in BluetoothDevice device);
+    boolean setPriority(in BluetoothDevice device, int priority);
+    int getPriority(in BluetoothDevice device);
+
+    boolean startVoiceRecognition(in BluetoothDevice device);
+    boolean stopVoiceRecognition(in BluetoothDevice device);
+
+    List<BluetoothHeadsetClientCall> getCurrentCalls(in BluetoothDevice device);
+    Bundle getCurrentAgEvents(in BluetoothDevice device);
+
+    boolean acceptCall(in BluetoothDevice device, int flag);
+    boolean holdCall(in BluetoothDevice device);
+    boolean rejectCall(in BluetoothDevice device);
+    boolean terminateCall(in BluetoothDevice device, int index);
+
+    boolean enterPrivateMode(in BluetoothDevice device, int index);
+    boolean explicitCallTransfer(in BluetoothDevice device);
+
+    boolean redial(in BluetoothDevice device);
+    boolean dial(in BluetoothDevice device, String number);
+    boolean dialMemory(in BluetoothDevice device, int location);
+
+    boolean sendDTMF(in BluetoothDevice device, byte code);
+    boolean getLastVoiceTagNumber(in BluetoothDevice device);
+
+    int getAudioState(in BluetoothDevice device);
+    boolean connectAudio();
+    boolean disconnectAudio();
+
+    Bundle getCurrentAgFeatures(in BluetoothDevice device);
+}
diff --git a/core/java/android/bluetooth/le/AdvertiseCallback.java b/core/java/android/bluetooth/le/AdvertiseCallback.java
new file mode 100644
index 0000000..706f469
--- /dev/null
+++ b/core/java/android/bluetooth/le/AdvertiseCallback.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+/**
+ * Bluetooth LE advertising callbacks, used to deliver advertising operation status.
+ */
+public abstract class AdvertiseCallback {
+
+    /**
+     * The requested operation was successful.
+     *
+     * @hide
+     */
+    public static final int ADVERTISE_SUCCESS = 0;
+
+    /**
+     * Failed to start advertising as the advertise data to be broadcasted is larger than 31 bytes.
+     */
+    public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1;
+
+    /**
+     * Failed to start advertising because no advertising instance is available.
+     */
+    public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2;
+
+    /**
+     * Failed to start advertising as the advertising is already started.
+     */
+    public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3;
+
+    /**
+     * Operation failed due to an internal error.
+     */
+    public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4;
+
+    /**
+     * This feature is not supported on this platform.
+     */
+    public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5;
+
+    /**
+     * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertising} indicating
+     * that the advertising has been started successfully.
+     *
+     * @param settingsInEffect The actual settings used for advertising, which may be different from
+     *            what has been requested.
+     */
+    public void onStartSuccess(AdvertiseSettings settingsInEffect) {
+    }
+
+    /**
+     * Callback when advertising could not be started.
+     *
+     * @param errorCode Error code (see ADVERTISE_FAILED_* constants) for advertising start
+     *            failures.
+     */
+    public void onStartFailure(int errorCode) {
+    }
+}
diff --git a/core/java/android/bluetooth/le/AdvertiseData.aidl b/core/java/android/bluetooth/le/AdvertiseData.aidl
new file mode 100644
index 0000000..bcbf224
--- /dev/null
+++ b/core/java/android/bluetooth/le/AdvertiseData.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+parcelable AdvertiseData;
diff --git a/core/java/android/bluetooth/le/AdvertiseData.java b/core/java/android/bluetooth/le/AdvertiseData.java
new file mode 100644
index 0000000..ff0db9a
--- /dev/null
+++ b/core/java/android/bluetooth/le/AdvertiseData.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Advertise data packet container for Bluetooth LE advertising. This represents the data to be
+ * advertised as well as the scan response data for active scans.
+ * <p>
+ * Use {@link AdvertiseData.Builder} to create an instance of {@link AdvertiseData} to be
+ * advertised.
+ *
+ * @see BluetoothLeAdvertiser
+ * @see ScanRecord
+ */
+public final class AdvertiseData implements Parcelable {
+
+    @Nullable
+    private final List<ParcelUuid> mServiceUuids;
+
+    private final SparseArray<byte[]> mManufacturerSpecificData;
+    private final Map<ParcelUuid, byte[]> mServiceData;
+    private final boolean mIncludeTxPowerLevel;
+    private final boolean mIncludeDeviceName;
+
+    private AdvertiseData(List<ParcelUuid> serviceUuids,
+            SparseArray<byte[]> manufacturerData,
+            Map<ParcelUuid, byte[]> serviceData,
+            boolean includeTxPowerLevel,
+            boolean includeDeviceName) {
+        mServiceUuids = serviceUuids;
+        mManufacturerSpecificData = manufacturerData;
+        mServiceData = serviceData;
+        mIncludeTxPowerLevel = includeTxPowerLevel;
+        mIncludeDeviceName = includeDeviceName;
+    }
+
+    /**
+     * Returns a list of service UUIDs within the advertisement that are used to identify the
+     * Bluetooth GATT services.
+     */
+    public List<ParcelUuid> getServiceUuids() {
+        return mServiceUuids;
+    }
+
+    /**
+     * Returns an array of manufacturer Id and the corresponding manufacturer specific data. The
+     * manufacturer id is a non-negative number assigned by Bluetooth SIG.
+     */
+    public SparseArray<byte[]> getManufacturerSpecificData() {
+        return mManufacturerSpecificData;
+    }
+
+    /**
+     * Returns a map of 16-bit UUID and its corresponding service data.
+     */
+    public Map<ParcelUuid, byte[]> getServiceData() {
+        return mServiceData;
+    }
+
+    /**
+     * Whether the transmission power level will be included in the advertisement packet.
+     */
+    public boolean getIncludeTxPowerLevel() {
+        return mIncludeTxPowerLevel;
+    }
+
+    /**
+     * Whether the device name will be included in the advertisement packet.
+     */
+    public boolean getIncludeDeviceName() {
+        return mIncludeDeviceName;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mServiceUuids, mManufacturerSpecificData, mServiceData,
+                mIncludeDeviceName, mIncludeTxPowerLevel);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        AdvertiseData other = (AdvertiseData) obj;
+        return Objects.equals(mServiceUuids, other.mServiceUuids) &&
+                BluetoothLeUtils.equals(mManufacturerSpecificData, other.mManufacturerSpecificData) &&
+                BluetoothLeUtils.equals(mServiceData, other.mServiceData) &&
+                        mIncludeDeviceName == other.mIncludeDeviceName &&
+                        mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
+    }
+
+    @Override
+    public String toString() {
+        return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mManufacturerSpecificData="
+                + BluetoothLeUtils.toString(mManufacturerSpecificData) + ", mServiceData="
+                + BluetoothLeUtils.toString(mServiceData)
+                + ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
+                + mIncludeDeviceName + "]";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeList(mServiceUuids);
+
+        // mManufacturerSpecificData could not be null.
+        dest.writeInt(mManufacturerSpecificData.size());
+        for (int i = 0; i < mManufacturerSpecificData.size(); ++i) {
+            dest.writeInt(mManufacturerSpecificData.keyAt(i));
+            byte[] data = mManufacturerSpecificData.valueAt(i);
+            if (data == null) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                dest.writeInt(data.length);
+                dest.writeByteArray(data);
+            }
+        }
+        dest.writeInt(mServiceData.size());
+        for (ParcelUuid uuid : mServiceData.keySet()) {
+            dest.writeParcelable(uuid, flags);
+            byte[] data = mServiceData.get(uuid);
+            if (data == null) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                dest.writeInt(data.length);
+                dest.writeByteArray(data);
+            }
+        }
+        dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0));
+        dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0));
+    }
+
+    public static final Parcelable.Creator<AdvertiseData> CREATOR =
+            new Creator<AdvertiseData>() {
+            @Override
+                public AdvertiseData[] newArray(int size) {
+                    return new AdvertiseData[size];
+                }
+
+            @Override
+                public AdvertiseData createFromParcel(Parcel in) {
+                    Builder builder = new Builder();
+                    @SuppressWarnings("unchecked")
+                    List<ParcelUuid> uuids = in.readArrayList(ParcelUuid.class.getClassLoader());
+                    if (uuids != null) {
+                        for (ParcelUuid uuid : uuids) {
+                            builder.addServiceUuid(uuid);
+                        }
+                    }
+                    int manufacturerSize = in.readInt();
+                    for (int i = 0; i < manufacturerSize; ++i) {
+                        int manufacturerId = in.readInt();
+                        if (in.readInt() == 1) {
+                            int manufacturerDataLength = in.readInt();
+                            byte[] manufacturerData = new byte[manufacturerDataLength];
+                            in.readByteArray(manufacturerData);
+                            builder.addManufacturerData(manufacturerId, manufacturerData);
+                        }
+                    }
+                    int serviceDataSize = in.readInt();
+                    for (int i = 0; i < serviceDataSize; ++i) {
+                        ParcelUuid serviceDataUuid = in.readParcelable(
+                                ParcelUuid.class.getClassLoader());
+                        if (in.readInt() == 1) {
+                            int serviceDataLength = in.readInt();
+                            byte[] serviceData = new byte[serviceDataLength];
+                            in.readByteArray(serviceData);
+                            builder.addServiceData(serviceDataUuid, serviceData);
+                        }
+                    }
+                    builder.setIncludeTxPowerLevel(in.readByte() == 1);
+                    builder.setIncludeDeviceName(in.readByte() == 1);
+                    return builder.build();
+                }
+            };
+
+    /**
+     * Builder for {@link AdvertiseData}.
+     */
+    public static final class Builder {
+        @Nullable
+        private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>();
+        private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>();
+        private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>();
+        private boolean mIncludeTxPowerLevel;
+        private boolean mIncludeDeviceName;
+
+        /**
+         * Add a service UUID to advertise data.
+         *
+         * @param serviceUuid A service UUID to be advertised.
+         * @throws IllegalArgumentException If the {@code serviceUuids} are null.
+         */
+        public Builder addServiceUuid(ParcelUuid serviceUuid) {
+            if (serviceUuid == null) {
+                throw new IllegalArgumentException("serivceUuids are null");
+            }
+            mServiceUuids.add(serviceUuid);
+            return this;
+        }
+
+        /**
+         * Add service data to advertise data.
+         *
+         * @param serviceDataUuid 16-bit UUID of the service the data is associated with
+         * @param serviceData Service data
+         * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is
+         *             empty.
+         */
+        public Builder addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
+            if (serviceDataUuid == null || serviceData == null) {
+                throw new IllegalArgumentException(
+                        "serviceDataUuid or serviceDataUuid is null");
+            }
+            mServiceData.put(serviceDataUuid, serviceData);
+            return this;
+        }
+
+        /**
+         * Add manufacturer specific data.
+         * <p>
+         * Please refer to the Bluetooth Assigned Numbers document provided by the <a
+         * href="https://www.bluetooth.org">Bluetooth SIG</a> for a list of existing company
+         * identifiers.
+         *
+         * @param manufacturerId Manufacturer ID assigned by Bluetooth SIG.
+         * @param manufacturerSpecificData Manufacturer specific data
+         * @throws IllegalArgumentException If the {@code manufacturerId} is negative or
+         *             {@code manufacturerSpecificData} is null.
+         */
+        public Builder addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) {
+            if (manufacturerId < 0) {
+                throw new IllegalArgumentException(
+                        "invalid manufacturerId - " + manufacturerId);
+            }
+            if (manufacturerSpecificData == null) {
+                throw new IllegalArgumentException("manufacturerSpecificData is null");
+            }
+            mManufacturerSpecificData.put(manufacturerId, manufacturerSpecificData);
+            return this;
+        }
+
+        /**
+         * Whether the transmission power level should be included in the advertise packet. Tx power
+         * level field takes 3 bytes in advertise packet.
+         */
+        public Builder setIncludeTxPowerLevel(boolean includeTxPowerLevel) {
+            mIncludeTxPowerLevel = includeTxPowerLevel;
+            return this;
+        }
+
+        /**
+         * Set whether the device name should be included in advertise packet.
+         */
+        public Builder setIncludeDeviceName(boolean includeDeviceName) {
+            mIncludeDeviceName = includeDeviceName;
+            return this;
+        }
+
+        /**
+         * Build the {@link AdvertiseData}.
+         */
+        public AdvertiseData build() {
+            return new AdvertiseData(mServiceUuids, mManufacturerSpecificData, mServiceData,
+                    mIncludeTxPowerLevel, mIncludeDeviceName);
+        }
+    }
+}
diff --git a/core/java/android/bluetooth/le/AdvertiseSettings.aidl b/core/java/android/bluetooth/le/AdvertiseSettings.aidl
new file mode 100644
index 0000000..9f47d74
--- /dev/null
+++ b/core/java/android/bluetooth/le/AdvertiseSettings.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+parcelable AdvertiseSettings;
\ No newline at end of file
diff --git a/core/java/android/bluetooth/le/AdvertiseSettings.java b/core/java/android/bluetooth/le/AdvertiseSettings.java
new file mode 100644
index 0000000..62c68a4
--- /dev/null
+++ b/core/java/android/bluetooth/le/AdvertiseSettings.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * The {@link AdvertiseSettings} provide a way to adjust advertising preferences for each
+ * Bluetooth LE advertisement instance. Use {@link AdvertiseSettings.Builder} to create an
+ * instance of this class.
+ */
+public final class AdvertiseSettings implements Parcelable {
+    /**
+     * Perform Bluetooth LE advertising in low power mode. This is the default and preferred
+     * advertising mode as it consumes the least power.
+     */
+    public static final int ADVERTISE_MODE_LOW_POWER = 0;
+
+    /**
+     * Perform Bluetooth LE advertising in balanced power mode. This is balanced between advertising
+     * frequency and power consumption.
+     */
+    public static final int ADVERTISE_MODE_BALANCED = 1;
+
+    /**
+     * Perform Bluetooth LE advertising in low latency, high power mode. This has the highest power
+     * consumption and should not be used for continuous background advertising.
+     */
+    public static final int ADVERTISE_MODE_LOW_LATENCY = 2;
+
+    /**
+     * Advertise using the lowest transmission (TX) power level. Low transmission power can be used
+     * to restrict the visibility range of advertising packets.
+     */
+    public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0;
+
+    /**
+     * Advertise using low TX power level.
+     */
+    public static final int ADVERTISE_TX_POWER_LOW = 1;
+
+    /**
+     * Advertise using medium TX power level.
+     */
+    public static final int ADVERTISE_TX_POWER_MEDIUM = 2;
+
+    /**
+     * Advertise using high TX power level. This corresponds to largest visibility range of the
+     * advertising packet.
+     */
+    public static final int ADVERTISE_TX_POWER_HIGH = 3;
+
+    /**
+     * The maximum limited advertisement duration as specified by the Bluetooth SIG
+     */
+    private static final int LIMITED_ADVERTISING_MAX_MILLIS = 180 * 1000;
+
+    private final int mAdvertiseMode;
+    private final int mAdvertiseTxPowerLevel;
+    private final int mAdvertiseTimeoutMillis;
+    private final boolean mAdvertiseConnectable;
+
+    private AdvertiseSettings(int advertiseMode, int advertiseTxPowerLevel,
+            boolean advertiseConnectable, int advertiseTimeout) {
+        mAdvertiseMode = advertiseMode;
+        mAdvertiseTxPowerLevel = advertiseTxPowerLevel;
+        mAdvertiseConnectable = advertiseConnectable;
+        mAdvertiseTimeoutMillis = advertiseTimeout;
+    }
+
+    private AdvertiseSettings(Parcel in) {
+        mAdvertiseMode = in.readInt();
+        mAdvertiseTxPowerLevel = in.readInt();
+        mAdvertiseConnectable = in.readInt() != 0 ? true : false;
+        mAdvertiseTimeoutMillis = in.readInt();
+    }
+
+    /**
+     * Returns the advertise mode.
+     */
+    public int getMode() {
+        return mAdvertiseMode;
+    }
+
+    /**
+     * Returns the TX power level for advertising.
+     */
+    public int getTxPowerLevel() {
+        return mAdvertiseTxPowerLevel;
+    }
+
+    /**
+     * Returns whether the advertisement will indicate connectable.
+     */
+    public boolean isConnectable() {
+        return mAdvertiseConnectable;
+    }
+
+    /**
+     * Returns the advertising time limit in milliseconds.
+     */
+    public int getTimeout() {
+        return mAdvertiseTimeoutMillis;
+    }
+
+    @Override
+    public String toString() {
+        return "Settings [mAdvertiseMode=" + mAdvertiseMode
+             + ", mAdvertiseTxPowerLevel=" + mAdvertiseTxPowerLevel
+             + ", mAdvertiseConnectable=" + mAdvertiseConnectable
+             + ", mAdvertiseTimeoutMillis=" + mAdvertiseTimeoutMillis + "]";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mAdvertiseMode);
+        dest.writeInt(mAdvertiseTxPowerLevel);
+        dest.writeInt(mAdvertiseConnectable ? 1 : 0);
+        dest.writeInt(mAdvertiseTimeoutMillis);
+    }
+
+    public static final Parcelable.Creator<AdvertiseSettings> CREATOR =
+            new Creator<AdvertiseSettings>() {
+            @Override
+                public AdvertiseSettings[] newArray(int size) {
+                    return new AdvertiseSettings[size];
+                }
+
+            @Override
+                public AdvertiseSettings createFromParcel(Parcel in) {
+                    return new AdvertiseSettings(in);
+                }
+            };
+
+    /**
+     * Builder class for {@link AdvertiseSettings}.
+     */
+    public static final class Builder {
+        private int mMode = ADVERTISE_MODE_LOW_POWER;
+        private int mTxPowerLevel = ADVERTISE_TX_POWER_MEDIUM;
+        private int mTimeoutMillis = 0;
+        private boolean mConnectable = true;
+
+        /**
+         * Set advertise mode to control the advertising power and latency.
+         *
+         * @param advertiseMode Bluetooth LE Advertising mode, can only be one of
+         *            {@link AdvertiseSettings#ADVERTISE_MODE_LOW_POWER},
+         *            {@link AdvertiseSettings#ADVERTISE_MODE_BALANCED}, or
+         *            {@link AdvertiseSettings#ADVERTISE_MODE_LOW_LATENCY}.
+         * @throws IllegalArgumentException If the advertiseMode is invalid.
+         */
+        public Builder setAdvertiseMode(int advertiseMode) {
+            if (advertiseMode < ADVERTISE_MODE_LOW_POWER
+                    || advertiseMode > ADVERTISE_MODE_LOW_LATENCY) {
+                throw new IllegalArgumentException("unknown mode " + advertiseMode);
+            }
+            mMode = advertiseMode;
+            return this;
+        }
+
+        /**
+         * Set advertise TX power level to control the transmission power level for the advertising.
+         *
+         * @param txPowerLevel Transmission power of Bluetooth LE Advertising, can only be one of
+         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_ULTRA_LOW},
+         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_LOW},
+         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_MEDIUM} or
+         *            {@link AdvertiseSettings#ADVERTISE_TX_POWER_HIGH}.
+         * @throws IllegalArgumentException If the {@code txPowerLevel} is invalid.
+         */
+        public Builder setTxPowerLevel(int txPowerLevel) {
+            if (txPowerLevel < ADVERTISE_TX_POWER_ULTRA_LOW
+                    || txPowerLevel > ADVERTISE_TX_POWER_HIGH) {
+                throw new IllegalArgumentException("unknown tx power level " + txPowerLevel);
+            }
+            mTxPowerLevel = txPowerLevel;
+            return this;
+        }
+
+        /**
+         * Set whether the advertisement type should be connectable or non-connectable.
+         *
+         * @param connectable Controls whether the advertisment type will be connectable (true)
+         *                    or non-connectable (false).
+         */
+        public Builder setConnectable(boolean connectable) {
+            mConnectable = connectable;
+            return this;
+        }
+
+        /**
+         * Limit advertising to a given amount of time.
+         * @param timeoutMillis Advertising time limit. May not exceed 180000 milliseconds.
+         *                       A value of 0 will disable the time limit.
+         * @throws IllegalArgumentException If the provided timeout is over 180000 ms.
+         */
+        public Builder setTimeout(int timeoutMillis) {
+            if (timeoutMillis < 0 || timeoutMillis > LIMITED_ADVERTISING_MAX_MILLIS) {
+                throw new IllegalArgumentException("timeoutMillis invalid (must be 0-"
+                                    + LIMITED_ADVERTISING_MAX_MILLIS + " milliseconds)");
+            }
+            mTimeoutMillis = timeoutMillis;
+            return this;
+        }
+
+        /**
+         * Build the {@link AdvertiseSettings} object.
+         */
+        public AdvertiseSettings build() {
+            return new AdvertiseSettings(mMode, mTxPowerLevel, mConnectable, mTimeoutMillis);
+        }
+    }
+}
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
new file mode 100644
index 0000000..d468508
--- /dev/null
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallbackWrapper;
+import android.bluetooth.BluetoothUuid;
+import android.bluetooth.IBluetoothGatt;
+import android.bluetooth.IBluetoothManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * This class provides a way to perform Bluetooth LE advertise operations, such as starting and
+ * stopping advertising. An advertiser can broadcast up to 31 bytes of advertisement data
+ * represented by {@link AdvertiseData}.
+ * <p>
+ * To get an instance of {@link BluetoothLeAdvertiser}, call the
+ * {@link BluetoothAdapter#getBluetoothLeAdvertiser()} method.
+ * <p>
+ * <b>Note:</b> Most of the methods here require {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+ * permission.
+ *
+ * @see AdvertiseData
+ */
+public final class BluetoothLeAdvertiser {
+
+    private static final String TAG = "BluetoothLeAdvertiser";
+
+    private static final int MAX_ADVERTISING_DATA_BYTES = 31;
+    // Each fields need one byte for field length and another byte for field type.
+    private static final int OVERHEAD_BYTES_PER_FIELD = 2;
+    // Flags field will be set by system.
+    private static final int FLAGS_FIELD_BYTES = 3;
+    private static final int MANUFACTURER_SPECIFIC_DATA_LENGTH = 2;
+    private static final int SERVICE_DATA_UUID_LENGTH = 2;
+
+    private final IBluetoothManager mBluetoothManager;
+    private final Handler mHandler;
+    private BluetoothAdapter mBluetoothAdapter;
+    private final Map<AdvertiseCallback, AdvertiseCallbackWrapper>
+            mLeAdvertisers = new HashMap<AdvertiseCallback, AdvertiseCallbackWrapper>();
+
+    /**
+     * Use BluetoothAdapter.getLeAdvertiser() instead.
+     *
+     * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management
+     * @hide
+     */
+    public BluetoothLeAdvertiser(IBluetoothManager bluetoothManager) {
+        mBluetoothManager = bluetoothManager;
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        mHandler = new Handler(Looper.getMainLooper());
+    }
+
+    /**
+     * Start Bluetooth LE Advertising. On success, the {@code advertiseData} will be broadcasted.
+     * Returns immediately, the operation status is delivered through {@code callback}.
+     * <p>
+     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param settings Settings for Bluetooth LE advertising.
+     * @param advertiseData Advertisement data to be broadcasted.
+     * @param callback Callback for advertising status.
+     */
+    public void startAdvertising(AdvertiseSettings settings,
+            AdvertiseData advertiseData, final AdvertiseCallback callback) {
+        startAdvertising(settings, advertiseData, null, callback);
+    }
+
+    /**
+     * Start Bluetooth LE Advertising. The {@code advertiseData} will be broadcasted if the
+     * operation succeeds. The {@code scanResponse} is returned when a scanning device sends an
+     * active scan request. This method returns immediately, the operation status is delivered
+     * through {@code callback}.
+     * <p>
+     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     *
+     * @param settings Settings for Bluetooth LE advertising.
+     * @param advertiseData Advertisement data to be advertised in advertisement packet.
+     * @param scanResponse Scan response associated with the advertisement data.
+     * @param callback Callback for advertising status.
+     */
+    public void startAdvertising(AdvertiseSettings settings,
+            AdvertiseData advertiseData, AdvertiseData scanResponse,
+            final AdvertiseCallback callback) {
+        synchronized (mLeAdvertisers) {
+            BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
+            if (callback == null) {
+                throw new IllegalArgumentException("callback cannot be null");
+            }
+            if (!mBluetoothAdapter.isMultipleAdvertisementSupported()) {
+                postStartFailure(callback,
+                        AdvertiseCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED);
+                return;
+            }
+            if (totalBytes(advertiseData) > MAX_ADVERTISING_DATA_BYTES ||
+                    totalBytes(scanResponse) > MAX_ADVERTISING_DATA_BYTES) {
+                postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
+                return;
+            }
+            if (mLeAdvertisers.containsKey(callback)) {
+                postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED);
+                return;
+            }
+
+            IBluetoothGatt gatt;
+            try {
+                gatt = mBluetoothManager.getBluetoothGatt();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+                postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
+                return;
+            }
+            AdvertiseCallbackWrapper wrapper = new AdvertiseCallbackWrapper(callback, advertiseData,
+                    scanResponse, settings, gatt);
+            wrapper.startRegisteration();
+        }
+    }
+
+    /**
+     * Stop Bluetooth LE advertising. The {@code callback} must be the same one use in
+     * {@link BluetoothLeAdvertiser#startAdvertising}.
+     * <p>
+     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param callback {@link AdvertiseCallback} identifies the advertising instance to stop.
+     */
+    public void stopAdvertising(final AdvertiseCallback callback) {
+        synchronized (mLeAdvertisers) {
+            BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
+            if (callback == null) {
+                throw new IllegalArgumentException("callback cannot be null");
+            }
+            AdvertiseCallbackWrapper wrapper = mLeAdvertisers.get(callback);
+            if (wrapper == null) return;
+            wrapper.stopAdvertising();
+        }
+    }
+
+    /**
+     * Cleans up advertise clients. Should be called when bluetooth is down.
+     *
+     * @hide
+     */
+    public void cleanup() {
+        mLeAdvertisers.clear();
+    }
+
+    // Compute the size of the advertise data.
+    private int totalBytes(AdvertiseData data) {
+        if (data == null) return 0;
+        int size = FLAGS_FIELD_BYTES; // flags field is always set.
+        if (data.getServiceUuids() != null) {
+            int num16BitUuids = 0;
+            int num32BitUuids = 0;
+            int num128BitUuids = 0;
+            for (ParcelUuid uuid : data.getServiceUuids()) {
+                if (BluetoothUuid.is16BitUuid(uuid)) {
+                    ++num16BitUuids;
+                } else if (BluetoothUuid.is32BitUuid(uuid)) {
+                    ++num32BitUuids;
+                } else {
+                    ++num128BitUuids;
+                }
+            }
+            // 16 bit service uuids are grouped into one field when doing advertising.
+            if (num16BitUuids != 0) {
+                size += OVERHEAD_BYTES_PER_FIELD +
+                        num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
+            }
+            // 32 bit service uuids are grouped into one field when doing advertising.
+            if (num32BitUuids != 0) {
+                size += OVERHEAD_BYTES_PER_FIELD +
+                        num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
+            }
+            // 128 bit service uuids are grouped into one field when doing advertising.
+            if (num128BitUuids != 0) {
+                size += OVERHEAD_BYTES_PER_FIELD +
+                        num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
+            }
+        }
+        for (ParcelUuid uuid : data.getServiceData().keySet()) {
+            size += OVERHEAD_BYTES_PER_FIELD + SERVICE_DATA_UUID_LENGTH
+                    + byteLength(data.getServiceData().get(uuid));
+        }
+        for (int i = 0; i < data.getManufacturerSpecificData().size(); ++i) {
+            size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH +
+                    byteLength(data.getManufacturerSpecificData().valueAt(i));
+        }
+        if (data.getIncludeTxPowerLevel()) {
+            size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
+        }
+        if (data.getIncludeDeviceName() && mBluetoothAdapter.getName() != null) {
+            size += OVERHEAD_BYTES_PER_FIELD + mBluetoothAdapter.getName().length();
+        }
+        return size;
+    }
+
+    private int byteLength(byte[] array) {
+        return array == null ? 0 : array.length;
+    }
+
+    /**
+     * Bluetooth GATT interface callbacks for advertising.
+     */
+    private class AdvertiseCallbackWrapper extends BluetoothGattCallbackWrapper {
+        private static final int LE_CALLBACK_TIMEOUT_MILLIS = 2000;
+        private final AdvertiseCallback mAdvertiseCallback;
+        private final AdvertiseData mAdvertisement;
+        private final AdvertiseData mScanResponse;
+        private final AdvertiseSettings mSettings;
+        private final IBluetoothGatt mBluetoothGatt;
+
+        // mClientIf 0: not registered
+        // -1: scan stopped
+        // >0: registered and scan started
+        private int mClientIf;
+        private boolean mIsAdvertising = false;
+
+        public AdvertiseCallbackWrapper(AdvertiseCallback advertiseCallback,
+                AdvertiseData advertiseData, AdvertiseData scanResponse,
+                AdvertiseSettings settings,
+                IBluetoothGatt bluetoothGatt) {
+            mAdvertiseCallback = advertiseCallback;
+            mAdvertisement = advertiseData;
+            mScanResponse = scanResponse;
+            mSettings = settings;
+            mBluetoothGatt = bluetoothGatt;
+            mClientIf = 0;
+        }
+
+        public void startRegisteration() {
+            synchronized (this) {
+                if (mClientIf == -1) return;
+
+                try {
+                    UUID uuid = UUID.randomUUID();
+                    mBluetoothGatt.registerClient(new ParcelUuid(uuid), this);
+                    wait(LE_CALLBACK_TIMEOUT_MILLIS);
+                } catch (InterruptedException | RemoteException e) {
+                    Log.e(TAG, "Failed to start registeration", e);
+                }
+                if (mClientIf > 0 && mIsAdvertising) {
+                    mLeAdvertisers.put(mAdvertiseCallback, this);
+                } else if (mClientIf <= 0) {
+                    // Post internal error if registration failed.
+                    postStartFailure(mAdvertiseCallback,
+                            AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
+                } else {
+                    // Unregister application if it's already registered but advertise failed.
+                    try {
+                        mBluetoothGatt.unregisterClient(mClientIf);
+                        mClientIf = -1;
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "remote exception when unregistering", e);
+                    }
+                }
+            }
+        }
+
+        public void stopAdvertising() {
+            synchronized (this) {
+                try {
+                    mBluetoothGatt.stopMultiAdvertising(mClientIf);
+                    wait(LE_CALLBACK_TIMEOUT_MILLIS);
+                } catch (InterruptedException | RemoteException e) {
+                    Log.e(TAG, "Failed to stop advertising", e);
+                }
+                // Advertise callback should have been removed from LeAdvertisers when
+                // onMultiAdvertiseCallback was called. In case onMultiAdvertiseCallback is never
+                // invoked and wait timeout expires, remove callback here.
+                if (mLeAdvertisers.containsKey(mAdvertiseCallback)) {
+                    mLeAdvertisers.remove(mAdvertiseCallback);
+                }
+            }
+        }
+
+        /**
+         * Application interface registered - app is ready to go
+         */
+        @Override
+        public void onClientRegistered(int status, int clientIf) {
+            Log.d(TAG, "onClientRegistered() - status=" + status + " clientIf=" + clientIf);
+            synchronized (this) {
+                if (status == BluetoothGatt.GATT_SUCCESS) {
+                    mClientIf = clientIf;
+                    try {
+                        mBluetoothGatt.startMultiAdvertising(mClientIf, mAdvertisement,
+                                mScanResponse, mSettings);
+                        return;
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "failed to start advertising", e);
+                    }
+                }
+                // Registration failed.
+                mClientIf = -1;
+                notifyAll();
+            }
+        }
+
+        @Override
+        public void onMultiAdvertiseCallback(int status, boolean isStart,
+                AdvertiseSettings settings) {
+            synchronized (this) {
+                if (isStart) {
+                    if (status == AdvertiseCallback.ADVERTISE_SUCCESS) {
+                        // Start success
+                        mIsAdvertising = true;
+                        postStartSuccess(mAdvertiseCallback, settings);
+                    } else {
+                        // Start failure.
+                        postStartFailure(mAdvertiseCallback, status);
+                    }
+                } else {
+                    // unregister client for stop.
+                    try {
+                        mBluetoothGatt.unregisterClient(mClientIf);
+                        mClientIf = -1;
+                        mIsAdvertising = false;
+                        mLeAdvertisers.remove(mAdvertiseCallback);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "remote exception when unregistering", e);
+                    }
+                }
+                notifyAll();
+            }
+
+        }
+    }
+
+    private void postStartFailure(final AdvertiseCallback callback, final int error) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                callback.onStartFailure(error);
+            }
+        });
+    }
+
+    private void postStartSuccess(final AdvertiseCallback callback,
+            final AdvertiseSettings settings) {
+        mHandler.post(new Runnable() {
+
+            @Override
+            public void run() {
+                callback.onStartSuccess(settings);
+            }
+        });
+    }
+}
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
new file mode 100644
index 0000000..a57c3ca
--- /dev/null
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.bluetooth.le;
+
+import android.annotation.SystemApi;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallbackWrapper;
+import android.bluetooth.IBluetoothGatt;
+import android.bluetooth.IBluetoothManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * This class provides methods to perform scan related operations for Bluetooth LE devices. An
+ * application can scan for a particular type of Bluetotoh LE devices using {@link ScanFilter}. It
+ * can also request different types of callbacks for delivering the result.
+ * <p>
+ * Use {@link BluetoothAdapter#getBluetoothLeScanner()} to get an instance of
+ * {@link BluetoothLeScanner}.
+ * <p>
+ * <b>Note:</b> Most of the scan methods here require
+ * {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+ *
+ * @see ScanFilter
+ */
+public final class BluetoothLeScanner {
+
+    private static final String TAG = "BluetoothLeScanner";
+    private static final boolean DBG = true;
+
+    private final IBluetoothManager mBluetoothManager;
+    private final Handler mHandler;
+    private BluetoothAdapter mBluetoothAdapter;
+    private final Map<ScanCallback, BleScanCallbackWrapper> mLeScanClients;
+
+    /**
+     * Use {@link BluetoothAdapter#getBluetoothLeScanner()} instead.
+     *
+     * @param bluetoothManager BluetoothManager that conducts overall Bluetooth Management.
+     * @hide
+     */
+    public BluetoothLeScanner(IBluetoothManager bluetoothManager) {
+        mBluetoothManager = bluetoothManager;
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        mHandler = new Handler(Looper.getMainLooper());
+        mLeScanClients = new HashMap<ScanCallback, BleScanCallbackWrapper>();
+    }
+
+    /**
+     * Start Bluetooth LE scan with default parameters and no filters. The scan results will be
+     * delivered through {@code callback}.
+     * <p>
+     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param callback Callback used to deliver scan results.
+     * @throws IllegalArgumentException If {@code callback} is null.
+     */
+    public void startScan(final ScanCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback is null");
+        }
+        startScan(null, new ScanSettings.Builder().build(), callback);
+    }
+
+    /**
+     * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
+     * <p>
+     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param filters {@link ScanFilter}s for finding exact BLE devices.
+     * @param settings Settings for the scan.
+     * @param callback Callback used to deliver scan results.
+     * @throws IllegalArgumentException If {@code settings} or {@code callback} is null.
+     */
+    public void startScan(List<ScanFilter> filters, ScanSettings settings,
+            final ScanCallback callback) {
+        startScan(filters, settings, callback, null);
+    }
+
+    private void startScan(List<ScanFilter> filters, ScanSettings settings,
+            final ScanCallback callback, List<List<ResultStorageDescriptor>> resultStorages) {
+        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
+        if (settings == null || callback == null) {
+            throw new IllegalArgumentException("settings or callback is null");
+        }
+        synchronized (mLeScanClients) {
+            if (mLeScanClients.containsKey(callback)) {
+                postCallbackError(callback, ScanCallback.SCAN_FAILED_ALREADY_STARTED);
+                return;
+            }
+            IBluetoothGatt gatt;
+            try {
+                gatt = mBluetoothManager.getBluetoothGatt();
+            } catch (RemoteException e) {
+                gatt = null;
+            }
+            if (gatt == null) {
+                postCallbackError(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
+                return;
+            }
+            if (!isSettingsConfigAllowedForScan(settings)) {
+                postCallbackError(callback,
+                        ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
+                return;
+            }
+            BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
+                    settings, callback, resultStorages);
+            wrapper.startRegisteration();
+        }
+    }
+
+    /**
+     * Stops an ongoing Bluetooth LE scan.
+     * <p>
+     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param callback
+     */
+    public void stopScan(ScanCallback callback) {
+        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
+        synchronized (mLeScanClients) {
+            BleScanCallbackWrapper wrapper = mLeScanClients.remove(callback);
+            if (wrapper == null) {
+                if (DBG) Log.d(TAG, "could not find callback wrapper");
+                return;
+            }
+            wrapper.stopLeScan();
+        }
+    }
+
+    /**
+     * Flush pending batch scan results stored in Bluetooth controller. This will return Bluetooth
+     * LE scan results batched on bluetooth controller. Returns immediately, batch scan results data
+     * will be delivered through the {@code callback}.
+     *
+     * @param callback Callback of the Bluetooth LE Scan, it has to be the same instance as the one
+     *            used to start scan.
+     */
+    public void flushPendingScanResults(ScanCallback callback) {
+        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
+        if (callback == null) {
+            throw new IllegalArgumentException("callback cannot be null!");
+        }
+        synchronized (mLeScanClients) {
+            BleScanCallbackWrapper wrapper = mLeScanClients.get(callback);
+            if (wrapper == null) {
+                return;
+            }
+            wrapper.flushPendingBatchResults();
+        }
+    }
+
+    /**
+     * Start truncated scan.
+     *
+     * @hide
+     */
+    @SystemApi
+    public void startTruncatedScan(List<TruncatedFilter> truncatedFilters, ScanSettings settings,
+            final ScanCallback callback) {
+        int filterSize = truncatedFilters.size();
+        List<ScanFilter> scanFilters = new ArrayList<ScanFilter>(filterSize);
+        List<List<ResultStorageDescriptor>> scanStorages =
+                new ArrayList<List<ResultStorageDescriptor>>(filterSize);
+        for (TruncatedFilter filter : truncatedFilters) {
+            scanFilters.add(filter.getFilter());
+            scanStorages.add(filter.getStorageDescriptors());
+        }
+        startScan(scanFilters, settings, callback, scanStorages);
+    }
+
+    /**
+     * Cleans up scan clients. Should be called when bluetooth is down.
+     *
+     * @hide
+     */
+    public void cleanup() {
+        mLeScanClients.clear();
+    }
+
+    /**
+     * Bluetooth GATT interface callbacks
+     */
+    private class BleScanCallbackWrapper extends BluetoothGattCallbackWrapper {
+        private static final int REGISTRATION_CALLBACK_TIMEOUT_MILLIS = 2000;
+
+        private final ScanCallback mScanCallback;
+        private final List<ScanFilter> mFilters;
+        private ScanSettings mSettings;
+        private IBluetoothGatt mBluetoothGatt;
+        private List<List<ResultStorageDescriptor>> mResultStorages;
+
+        // mLeHandle 0: not registered
+        // -1: scan stopped
+        // > 0: registered and scan started
+        private int mClientIf;
+
+        public BleScanCallbackWrapper(IBluetoothGatt bluetoothGatt,
+                List<ScanFilter> filters, ScanSettings settings,
+                ScanCallback scanCallback, List<List<ResultStorageDescriptor>> resultStorages) {
+            mBluetoothGatt = bluetoothGatt;
+            mFilters = filters;
+            mSettings = settings;
+            mScanCallback = scanCallback;
+            mClientIf = 0;
+            mResultStorages = resultStorages;
+        }
+
+        public void startRegisteration() {
+            synchronized (this) {
+                // Scan stopped.
+                if (mClientIf == -1) return;
+                try {
+                    UUID uuid = UUID.randomUUID();
+                    mBluetoothGatt.registerClient(new ParcelUuid(uuid), this);
+                    wait(REGISTRATION_CALLBACK_TIMEOUT_MILLIS);
+                } catch (InterruptedException | RemoteException e) {
+                    Log.e(TAG, "application registeration exception", e);
+                    postCallbackError(mScanCallback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
+                }
+                if (mClientIf > 0) {
+                    mLeScanClients.put(mScanCallback, this);
+                } else {
+                    postCallbackError(mScanCallback,
+                            ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED);
+                }
+            }
+        }
+
+        public void stopLeScan() {
+            synchronized (this) {
+                if (mClientIf <= 0) {
+                    Log.e(TAG, "Error state, mLeHandle: " + mClientIf);
+                    return;
+                }
+                try {
+                    mBluetoothGatt.stopScan(mClientIf, false);
+                    mBluetoothGatt.unregisterClient(mClientIf);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Failed to stop scan and unregister", e);
+                }
+                mClientIf = -1;
+            }
+        }
+
+        void flushPendingBatchResults() {
+            synchronized (this) {
+                if (mClientIf <= 0) {
+                    Log.e(TAG, "Error state, mLeHandle: " + mClientIf);
+                    return;
+                }
+                try {
+                    mBluetoothGatt.flushPendingBatchResults(mClientIf, false);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Failed to get pending scan results", e);
+                }
+            }
+        }
+
+        /**
+         * Application interface registered - app is ready to go
+         */
+        @Override
+        public void onClientRegistered(int status, int clientIf) {
+            Log.d(TAG, "onClientRegistered() - status=" + status +
+                    " clientIf=" + clientIf);
+            synchronized (this) {
+                if (mClientIf == -1) {
+                    if (DBG) Log.d(TAG, "onClientRegistered LE scan canceled");
+                }
+
+                if (status == BluetoothGatt.GATT_SUCCESS) {
+                    mClientIf = clientIf;
+                    try {
+                        mBluetoothGatt.startScan(mClientIf, false, mSettings, mFilters,
+                                mResultStorages);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "fail to start le scan: " + e);
+                        mClientIf = -1;
+                    }
+                } else {
+                    // registration failed
+                    mClientIf = -1;
+                }
+                notifyAll();
+            }
+        }
+
+        /**
+         * Callback reporting an LE scan result.
+         *
+         * @hide
+         */
+        @Override
+        public void onScanResult(final ScanResult scanResult) {
+            if (DBG) Log.d(TAG, "onScanResult() - " + scanResult.toString());
+
+            // Check null in case the scan has been stopped
+            synchronized (this) {
+                if (mClientIf <= 0) return;
+            }
+            Handler handler = new Handler(Looper.getMainLooper());
+            handler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, scanResult);
+                }
+            });
+
+        }
+
+        @Override
+        public void onBatchScanResults(final List<ScanResult> results) {
+            Handler handler = new Handler(Looper.getMainLooper());
+            handler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mScanCallback.onBatchScanResults(results);
+                }
+            });
+        }
+
+        @Override
+        public void onFoundOrLost(final boolean onFound, final ScanResult scanResult) {
+            if (DBG) {
+                Log.d(TAG, "onFoundOrLost() - onFound = " + onFound +
+                        " " + scanResult.toString());
+            }
+
+            // Check null in case the scan has been stopped
+            synchronized (this) {
+                if (mClientIf <= 0)
+                    return;
+            }
+            Handler handler = new Handler(Looper.getMainLooper());
+            handler.post(new Runnable() {
+                    @Override
+                public void run() {
+                    if (onFound) {
+                        mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_FIRST_MATCH,
+                                scanResult);
+                    } else {
+                        mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_MATCH_LOST,
+                                scanResult);
+                    }
+                }
+            });
+        }
+    }
+
+    private void postCallbackError(final ScanCallback callback, final int errorCode) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                callback.onScanFailed(errorCode);
+            }
+        });
+    }
+
+    private boolean isSettingsConfigAllowedForScan(ScanSettings settings) {
+        if (mBluetoothAdapter.isOffloadedFilteringSupported()) {
+            return true;
+        }
+        final int callbackType = settings.getCallbackType();
+        // Only support regular scan if no offloaded filter support.
+        if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES
+                && settings.getReportDelayMillis() == 0) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/core/java/android/bluetooth/le/BluetoothLeUtils.java b/core/java/android/bluetooth/le/BluetoothLeUtils.java
new file mode 100644
index 0000000..4916bd9
--- /dev/null
+++ b/core/java/android/bluetooth/le/BluetoothLeUtils.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+import android.bluetooth.BluetoothAdapter;
+import android.util.SparseArray;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Helper class for Bluetooth LE utils.
+ *
+ * @hide
+ */
+public class BluetoothLeUtils {
+
+    /**
+     * Returns a string composed from a {@link SparseArray}.
+     */
+    static String toString(SparseArray<byte[]> array) {
+        if (array == null) {
+            return "null";
+        }
+        if (array.size() == 0) {
+            return "{}";
+        }
+        StringBuilder buffer = new StringBuilder();
+        buffer.append('{');
+        for (int i = 0; i < array.size(); ++i) {
+            buffer.append(array.keyAt(i)).append("=").append(Arrays.toString(array.valueAt(i)));
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
+
+    /**
+     * Returns a string composed from a {@link Map}.
+     */
+    static <T> String toString(Map<T, byte[]> map) {
+        if (map == null) {
+            return "null";
+        }
+        if (map.isEmpty()) {
+            return "{}";
+        }
+        StringBuilder buffer = new StringBuilder();
+        buffer.append('{');
+        Iterator<Map.Entry<T, byte[]>> it = map.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<T, byte[]> entry = it.next();
+            Object key = entry.getKey();
+            buffer.append(key).append("=").append(Arrays.toString(map.get(key)));
+            if (it.hasNext()) {
+                buffer.append(", ");
+            }
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
+
+    /**
+     * Check whether two {@link SparseArray} equal.
+     */
+    static boolean equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray) {
+        if (array == otherArray) {
+            return true;
+        }
+        if (array == null || otherArray == null) {
+            return false;
+        }
+        if (array.size() != otherArray.size()) {
+            return false;
+        }
+
+        // Keys are guaranteed in ascending order when indices are in ascending order.
+        for (int i = 0; i < array.size(); ++i) {
+            if (array.keyAt(i) != otherArray.keyAt(i) ||
+                    !Arrays.equals(array.valueAt(i), otherArray.valueAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Check whether two {@link Map} equal.
+     */
+    static <T> boolean equals(Map<T, byte[]> map, Map<T, byte[]> otherMap) {
+        if (map == otherMap) {
+            return true;
+        }
+        if (map == null || otherMap == null) {
+            return false;
+        }
+        if (map.size() != otherMap.size()) {
+            return false;
+        }
+        Set<T> keys = map.keySet();
+        if (!keys.equals(otherMap.keySet())) {
+            return false;
+        }
+        for (T key : keys) {
+            if (!Objects.deepEquals(map.get(key), otherMap.get(key))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Ensure Bluetooth is turned on.
+     *
+     * @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not
+     *             {@link BluetoothAdapter#STATE_ON}.
+     */
+    static void checkAdapterStateOn(BluetoothAdapter adapter) {
+        if (adapter == null || adapter.getState() != BluetoothAdapter.STATE_ON) {
+            throw new IllegalStateException("BT Adapter is not turned ON");
+        }
+    }
+
+}
diff --git a/core/java/android/bluetooth/le/ResultStorageDescriptor.aidl b/core/java/android/bluetooth/le/ResultStorageDescriptor.aidl
new file mode 100644
index 0000000..f218a01
--- /dev/null
+++ b/core/java/android/bluetooth/le/ResultStorageDescriptor.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+/**
+ * {@hide}
+ */
+
+parcelable ResultStorageDescriptor;
diff --git a/core/java/android/bluetooth/le/ResultStorageDescriptor.java b/core/java/android/bluetooth/le/ResultStorageDescriptor.java
new file mode 100644
index 0000000..748f97d
--- /dev/null
+++ b/core/java/android/bluetooth/le/ResultStorageDescriptor.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Describes the way to store scan result.
+ *
+ * @hide
+ */
+@SystemApi
+public final class ResultStorageDescriptor implements Parcelable {
+    private int mType;
+    private int mOffset;
+    private int mLength;
+
+    public int getType() {
+        return mType;
+    }
+
+    public int getOffset() {
+        return mOffset;
+    }
+
+    public int getLength() {
+        return mLength;
+    }
+
+    /**
+     * Constructor of {@link ResultStorageDescriptor}
+     *
+     * @param type Type of the data.
+     * @param offset Offset from start of the advertise packet payload.
+     * @param length Byte length of the data
+     */
+    public ResultStorageDescriptor(int type, int offset, int length) {
+        mType = type;
+        mOffset = offset;
+        mLength = length;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mType);
+        dest.writeInt(mOffset);
+        dest.writeInt(mLength);
+    }
+
+    private ResultStorageDescriptor(Parcel in) {
+        ReadFromParcel(in);
+    }
+
+    private void ReadFromParcel(Parcel in) {
+        mType = in.readInt();
+        mOffset = in.readInt();
+        mLength = in.readInt();
+    }
+
+    public static final Parcelable.Creator<ResultStorageDescriptor>
+            CREATOR = new Creator<ResultStorageDescriptor>() {
+                    @Override
+                public ResultStorageDescriptor createFromParcel(Parcel source) {
+                    return new ResultStorageDescriptor(source);
+                }
+
+                    @Override
+                public ResultStorageDescriptor[] newArray(int size) {
+                    return new ResultStorageDescriptor[size];
+                }
+            };
+}
diff --git a/core/java/android/bluetooth/le/ScanCallback.java b/core/java/android/bluetooth/le/ScanCallback.java
new file mode 100644
index 0000000..05782a8
--- /dev/null
+++ b/core/java/android/bluetooth/le/ScanCallback.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.le;
+
+import java.util.List;
+
+/**
+ * Bluetooth LE scan callbacks. Scan results are reported using these callbacks.
+ *
+ * @see BluetoothLeScanner#startScan
+ */
+public abstract class ScanCallback {
+    /**
+     * Fails to start scan as BLE scan with the same settings is already started by the app.
+     */
+    public static final int SCAN_FAILED_ALREADY_STARTED = 1;
+
+    /**
+     * Fails to start scan as app cannot be registered.
+     */
+    public static final int SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = 2;
+
+    /**
+     * Fails to start scan due an internal error
+     */
+    public static final int SCAN_FAILED_INTERNAL_ERROR = 3;
+
+    /**
+     * Fails to start power optimized scan as this feature is not supported.
+     */
+    public static final int SCAN_FAILED_FEATURE_UNSUPPORTED = 4;
+
+    /**
+     * Callback when a BLE advertisement has been found.
+     *
+     * @param callbackType Determines how this callback was triggered. Currently could only be
+     *            {@link ScanSettings#CALLBACK_TYPE_ALL_MATCHES}.
+     * @param result A Bluetooth LE scan result.
+     */
+    public void onScanResult(int callbackType, ScanResult result) {
+    }
+
+    /**
+     * Callback when batch results are delivered.
+     *
+     * @param results List of scan results that are previously scanned.
+     */