Merge "Make ActivityStarter single use."
diff --git a/Android.bp b/Android.bp
index d8027c1..32adc1c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,6 +12,649 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// Build the master framework library.
+
+// READ ME: ########################################################
+//
+// When updating this list of aidl files, consider if that aidl is
+// part of the SDK API. If it is, also add it to the list in Android.mk
+// that is preprocessed and distributed with the SDK. This list should
+// not contain any aidl files for parcelables, but the one below should
+// if you intend for 3rd parties to be able to send those objects
+// across process boundaries.
+//
+// READ ME: ########################################################
+
+java_library {
+ name: "framework",
+
+ srcs: [
+ // From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS
+ "core/java/**/*.java",
+ "graphics/java/**/*.java",
+ "location/java/**/*.java",
+ "lowpan/java/**/*.java",
+ "media/java/**/*.java",
+ "media/mca/effect/java/**/*.java",
+ "media/mca/filterfw/java/**/*.java",
+ "media/mca/filterpacks/java/**/*.java",
+ "drm/java/**/*.java",
+ "opengl/java/**/*.java",
+ "sax/java/**/*.java",
+ "telecomm/java/**/*.java",
+ "telephony/java/**/*.java",
+ "wifi/java/**/*.java",
+ "keystore/java/**/*.java",
+ "rs/java/**/*.java",
+
+ ":framework-javastream-protos",
+
+ "core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl",
+ "core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl",
+ "core/java/android/accounts/IAccountManager.aidl",
+ "core/java/android/accounts/IAccountManagerResponse.aidl",
+ "core/java/android/accounts/IAccountAuthenticator.aidl",
+ "core/java/android/accounts/IAccountAuthenticatorResponse.aidl",
+ "core/java/android/app/IActivityController.aidl",
+ "core/java/android/app/IActivityManager.aidl",
+ "core/java/android/app/IActivityPendingResult.aidl",
+ "core/java/android/app/IAlarmCompleteListener.aidl",
+ "core/java/android/app/IAlarmListener.aidl",
+ "core/java/android/app/IAlarmManager.aidl",
+ "core/java/android/app/IAppTask.aidl",
+ "core/java/android/app/IApplicationThread.aidl",
+ "core/java/android/app/IAssistDataReceiver.aidl",
+ "core/java/android/app/ITaskStackListener.aidl",
+ "core/java/android/app/IBackupAgent.aidl",
+ "core/java/android/app/IEphemeralResolver.aidl",
+ "core/java/android/app/IInputForwarder.aidl",
+ "core/java/android/app/IInstantAppResolver.aidl",
+ "core/java/android/app/IInstrumentationWatcher.aidl",
+ "core/java/android/app/INotificationManager.aidl",
+ "core/java/android/app/IProcessObserver.aidl",
+ "core/java/android/app/ISearchManager.aidl",
+ "core/java/android/app/ISearchManagerCallback.aidl",
+ "core/java/android/app/IServiceConnection.aidl",
+ "core/java/android/app/IStopUserCallback.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/IUidObserver.aidl",
+ "core/java/android/app/IUiAutomationConnection.aidl",
+ "core/java/android/app/IUiModeManager.aidl",
+ "core/java/android/app/IUserSwitchObserver.aidl",
+ "core/java/android/app/IWallpaperManager.aidl",
+ "core/java/android/app/IWallpaperManagerCallback.aidl",
+ "core/java/android/app/admin/IDeviceAdminService.aidl",
+ "core/java/android/app/admin/IDevicePolicyManager.aidl",
+ "core/java/android/app/trust/IStrongAuthTracker.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/IBackupObserver.aidl",
+ "core/java/android/app/backup/IBackupManagerMonitor.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/backup/ISelectBackupTransportCallback.aidl",
+ "core/java/android/app/timezone/ICallback.aidl",
+ "core/java/android/app/timezone/IRulesManager.aidl",
+ "core/java/android/app/usage/ICacheQuotaService.aidl",
+ "core/java/android/app/usage/IStorageStatsManager.aidl",
+ "core/java/android/app/usage/IUsageStatsManager.aidl",
+ ":libbluetooth-binder-aidl",
+ "core/java/android/content/IClipboard.aidl",
+ "core/java/android/content/IContentService.aidl",
+ "core/java/android/content/IIntentReceiver.aidl",
+ "core/java/android/content/IIntentSender.aidl",
+ "core/java/android/content/IOnPrimaryClipChangedListener.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/om/IOverlayManager.aidl",
+ "core/java/android/content/pm/crossprofile/ICrossProfileApps.aidl",
+ "core/java/android/content/pm/IDexModuleRegisterCallback.aidl",
+ "core/java/android/content/pm/ILauncherApps.aidl",
+ "core/java/android/content/pm/IOnAppsChangedListener.aidl",
+ "core/java/android/content/pm/IOnPermissionsChangeListener.aidl",
+ "core/java/android/content/pm/IOtaDexopt.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/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",
+ ":libbinder_aidl",
+ "core/java/android/content/pm/IPackageMoveObserver.aidl",
+ "core/java/android/content/pm/IPackageStatsObserver.aidl",
+ "core/java/android/content/pm/IPinItemRequest.aidl",
+ "core/java/android/content/pm/IShortcutService.aidl",
+ "core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl",
+ "core/java/android/database/IContentObserver.aidl",
+ ":libcamera_client_aidl",
+ ":libcamera_client_framework_aidl",
+ "core/java/android/hardware/IConsumerIrService.aidl",
+ "core/java/android/hardware/ISerialManager.aidl",
+ "core/java/android/hardware/display/IDisplayManager.aidl",
+ "core/java/android/hardware/display/IDisplayManagerCallback.aidl",
+ "core/java/android/hardware/display/IVirtualDisplayCallback.aidl",
+ "core/java/android/hardware/fingerprint/IFingerprintService.aidl",
+ "core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl",
+ "core/java/android/hardware/fingerprint/IFingerprintClientActiveCallback.aidl",
+ "core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.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/input/ITabletModeChangedListener.aidl",
+ "core/java/android/hardware/location/IActivityRecognitionHardware.aidl",
+ "core/java/android/hardware/location/IActivityRecognitionHardwareClient.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/location/IContextHubCallback.aidl",
+ "core/java/android/hardware/location/IContextHubClient.aidl",
+ "core/java/android/hardware/location/IContextHubClientCallback.aidl",
+ "core/java/android/hardware/location/IContextHubService.aidl",
+ "core/java/android/hardware/location/IContextHubTransactionCallback.aidl",
+ "core/java/android/hardware/radio/IRadioService.aidl",
+ "core/java/android/hardware/radio/ITuner.aidl",
+ "core/java/android/hardware/radio/ITunerCallback.aidl",
+ "core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl",
+ "core/java/android/hardware/usb/IUsbManager.aidl",
+ "core/java/android/net/ICaptivePortal.aidl",
+ "core/java/android/net/IConnectivityManager.aidl",
+ "core/java/android/net/IIpConnectivityMetrics.aidl",
+ "core/java/android/net/IEthernetManager.aidl",
+ "core/java/android/net/IEthernetServiceListener.aidl",
+ "core/java/android/net/INetdEventCallback.aidl",
+ "core/java/android/net/IIpSecService.aidl",
+ "core/java/android/net/INetworkManagementEventObserver.aidl",
+ "core/java/android/net/INetworkPolicyListener.aidl",
+ "core/java/android/net/INetworkPolicyManager.aidl",
+ "core/java/android/net/INetworkRecommendationProvider.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/ITetheringStatsProvider.aidl",
+ "core/java/android/net/nsd/INsdManager.aidl",
+ "core/java/android/nfc/IAppCallback.aidl",
+ "core/java/android/nfc/INfcAdapter.aidl",
+ "core/java/android/nfc/INfcAdapterExtras.aidl",
+ "core/java/android/nfc/INfcTag.aidl",
+ "core/java/android/nfc/INfcCardEmulation.aidl",
+ "core/java/android/nfc/INfcFCardEmulation.aidl",
+ "core/java/android/nfc/INfcUnlockHandler.aidl",
+ "core/java/android/nfc/INfcDta.aidl",
+ "core/java/android/nfc/ITagRemovedCallback.aidl",
+ "core/java/android/os/IBatteryPropertiesListener.aidl",
+ "core/java/android/os/IBatteryPropertiesRegistrar.aidl",
+ "core/java/android/os/ICancellationSignal.aidl",
+ "core/java/android/os/IDeviceIdentifiersPolicyService.aidl",
+ "core/java/android/os/IDeviceIdleController.aidl",
+ "core/java/android/os/IHardwarePropertiesManager.aidl",
+ "core/java/android/os/IIncidentManager.aidl",
+ "core/java/android/os/IIncidentReportCompletedListener.aidl",
+ "core/java/android/os/IIncidentReportStatusListener.aidl",
+ "core/java/android/os/IMaintenanceActivityListener.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/IProcessInfoService.aidl",
+ "core/java/android/os/IProgressListener.aidl",
+ "core/java/android/os/IPowerManager.aidl",
+ "core/java/android/os/IRecoverySystem.aidl",
+ "core/java/android/os/IRecoverySystemProgressListener.aidl",
+ "core/java/android/os/IRemoteCallback.aidl",
+ "core/java/android/os/ISchedulingPolicyService.aidl",
+ "core/java/android/os/IStatsCompanionService.aidl",
+ "core/java/android/os/IStatsManager.aidl",
+ "core/java/android/os/IThermalEventListener.aidl",
+ "core/java/android/os/IThermalService.aidl",
+ "core/java/android/os/IUpdateLock.aidl",
+ "core/java/android/os/IUserManager.aidl",
+ "core/java/android/os/IVibratorService.aidl",
+ "core/java/android/os/storage/IStorageManager.aidl",
+ "core/java/android/os/storage/IStorageEventListener.aidl",
+ "core/java/android/os/storage/IStorageShutdownObserver.aidl",
+ "core/java/android/os/storage/IObbActionListener.aidl",
+ "core/java/android/security/IKeystoreService.aidl",
+ "core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl",
+ "core/java/android/service/autofill/IAutoFillService.aidl",
+ "core/java/android/service/autofill/IFillCallback.aidl",
+ "core/java/android/service/autofill/ISaveCallback.aidl",
+ "core/java/android/service/carrier/ICarrierService.aidl",
+ "core/java/android/service/carrier/ICarrierMessagingCallback.aidl",
+ "core/java/android/service/carrier/ICarrierMessagingService.aidl",
+ "core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl",
+ "core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl",
+ "core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl",
+ "core/java/android/service/euicc/IEuiccService.aidl",
+ "core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl",
+ "core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl",
+ "core/java/android/service/euicc/IGetEidCallback.aidl",
+ "core/java/android/service/euicc/IGetEuiccInfoCallback.aidl",
+ "core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl",
+ "core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl",
+ "core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl",
+ "core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl",
+ "core/java/android/service/gatekeeper/IGateKeeperService.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/service/settings/suggestions/ISuggestionService.aidl",
+ "core/java/android/service/vr/IPersistentVrStateCallbacks.aidl",
+ "core/java/android/service/vr/IVrListener.aidl",
+ "core/java/android/service/vr/IVrManager.aidl",
+ "core/java/android/service/vr/IVrStateCallbacks.aidl",
+ "core/java/android/print/ILayoutResultCallback.aidl",
+ "core/java/android/print/IPrinterDiscoveryObserver.aidl",
+ "core/java/android/print/IPrintDocumentAdapter.aidl",
+ "core/java/android/print/IPrintDocumentAdapterObserver.aidl",
+ "core/java/android/print/IPrintJobStateChangeListener.aidl",
+ "core/java/android/print/IPrintServicesChangeListener.aidl",
+ "core/java/android/printservice/recommendation/IRecommendationsChangeListener.aidl",
+ "core/java/android/print/IPrintManager.aidl",
+ "core/java/android/print/IPrintSpooler.aidl",
+ "core/java/android/print/IPrintSpoolerCallbacks.aidl",
+ "core/java/android/print/IPrintSpoolerClient.aidl",
+ "core/java/android/printservice/recommendation/IRecommendationServiceCallbacks.aidl",
+ "core/java/android/printservice/recommendation/IRecommendationService.aidl",
+ "core/java/android/print/IWriteResultCallback.aidl",
+ "core/java/android/printservice/IPrintService.aidl",
+ "core/java/android/printservice/IPrintServiceClient.aidl",
+ "core/java/android/companion/ICompanionDeviceManager.aidl",
+ "core/java/android/companion/ICompanionDeviceDiscoveryService.aidl",
+ "core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl",
+ "core/java/android/companion/IFindDeviceCallback.aidl",
+ "core/java/android/service/dreams/IDreamManager.aidl",
+ "core/java/android/service/dreams/IDreamService.aidl",
+ "core/java/android/service/oemlock/IOemLockService.aidl",
+ "core/java/android/service/persistentdata/IPersistentDataBlockService.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",
+ "core/java/android/service/chooser/IChooserTargetService.aidl",
+ "core/java/android/service/chooser/IChooserTargetResult.aidl",
+ "core/java/android/service/resolver/IResolverRankerService.aidl",
+ "core/java/android/service/resolver/IResolverRankerResult.aidl",
+ "core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl",
+ "core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl",
+ "core/java/android/view/accessibility/IAccessibilityManager.aidl",
+ "core/java/android/view/accessibility/IAccessibilityManagerClient.aidl",
+ "core/java/android/view/autofill/IAutoFillManager.aidl",
+ "core/java/android/view/autofill/IAutoFillManagerClient.aidl",
+ "core/java/android/view/autofill/IAutofillWindowPresenter.aidl",
+ "core/java/android/view/IApplicationToken.aidl",
+ "core/java/android/view/IAppTransitionAnimationSpecsFuture.aidl",
+ "core/java/android/view/IDockedStackListener.aidl",
+ "core/java/android/view/IGraphicsStats.aidl",
+ "core/java/android/view/IGraphicsStatsCallback.aidl",
+ "core/java/android/view/IInputFilter.aidl",
+ "core/java/android/view/IInputFilterHost.aidl",
+ "core/java/android/view/IOnKeyguardExitResult.aidl",
+ "core/java/android/view/IPinnedStackController.aidl",
+ "core/java/android/view/IPinnedStackListener.aidl",
+ "core/java/android/view/IRotationWatcher.aidl",
+ "core/java/android/view/IWallpaperVisibilityListener.aidl",
+ "core/java/android/view/IWindow.aidl",
+ "core/java/android/view/IWindowFocusObserver.aidl",
+ "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",
+ "core/java/android/speech/tts/ITextToSpeechService.aidl",
+ "core/java/com/android/internal/app/IAppOpsCallback.aidl",
+ "core/java/com/android/internal/app/IAppOpsService.aidl",
+ "core/java/com/android/internal/app/IBatteryStats.aidl",
+ "core/java/com/android/internal/app/ISoundTriggerService.aidl",
+ "core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl",
+ "core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl",
+ "core/java/com/android/internal/app/IVoiceInteractionSessionShowCallback.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/app/procstats/IProcessStats.aidl",
+ "core/java/com/android/internal/appwidget/IAppWidgetService.aidl",
+ "core/java/com/android/internal/appwidget/IAppWidgetHost.aidl",
+ "core/java/com/android/internal/backup/IBackupTransport.aidl",
+ "core/java/com/android/internal/backup/IObbBackupService.aidl",
+ "core/java/com/android/internal/car/ICarServiceHelper.aidl",
+ "core/java/com/android/internal/inputmethod/IInputContentUriToken.aidl",
+ "core/java/com/android/internal/net/INetworkWatchlistManager.aidl",
+ "core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl",
+ "core/java/com/android/internal/policy/IKeyguardDismissCallback.aidl",
+ "core/java/com/android/internal/policy/IKeyguardExitCallback.aidl",
+ "core/java/com/android/internal/policy/IKeyguardService.aidl",
+ "core/java/com/android/internal/policy/IKeyguardStateCallback.aidl",
+ "core/java/com/android/internal/policy/IShortcutService.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/os/IShellCallback.aidl",
+ "core/java/com/android/internal/statusbar/IStatusBar.aidl",
+ "core/java/com/android/internal/statusbar/IStatusBarService.aidl",
+ "core/java/com/android/internal/textservice/ISpellCheckerService.aidl",
+ "core/java/com/android/internal/textservice/ISpellCheckerServiceCallback.aidl",
+ "core/java/com/android/internal/textservice/ISpellCheckerSession.aidl",
+ "core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl",
+ "core/java/com/android/internal/textservice/ITextServicesManager.aidl",
+ "core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl",
+ "core/java/com/android/internal/view/IDragAndDropPermissions.aidl",
+ "core/java/com/android/internal/view/IInputContext.aidl",
+ "core/java/com/android/internal/view/IInputContextCallback.aidl",
+ "core/java/com/android/internal/view/IInputMethod.aidl",
+ "core/java/com/android/internal/view/IInputMethodClient.aidl",
+ "core/java/com/android/internal/view/IInputMethodManager.aidl",
+ "core/java/com/android/internal/view/IInputMethodSession.aidl",
+ "core/java/com/android/internal/view/IInputSessionCallback.aidl",
+ "core/java/com/android/internal/widget/ICheckCredentialProgressCallback.aidl",
+ "core/java/com/android/internal/widget/ILockSettings.aidl",
+ "core/java/com/android/internal/widget/IRemoteViewsFactory.aidl",
+ "keystore/java/android/security/IKeyChainAliasCallback.aidl",
+ "keystore/java/android/security/IKeyChainService.aidl",
+ "location/java/android/location/IBatchedLocationCallback.aidl",
+ "location/java/android/location/ICountryDetector.aidl",
+ "location/java/android/location/ICountryListener.aidl",
+ "location/java/android/location/IFusedProvider.aidl",
+ "location/java/android/location/IGeocodeProvider.aidl",
+ "location/java/android/location/IGeofenceProvider.aidl",
+ "location/java/android/location/IGnssStatusListener.aidl",
+ "location/java/android/location/IGnssStatusProvider.aidl",
+ "location/java/android/location/IGnssMeasurementsListener.aidl",
+ "location/java/android/location/IGnssNavigationMessageListener.aidl",
+ "location/java/android/location/ILocationListener.aidl",
+ "location/java/android/location/ILocationManager.aidl",
+ "location/java/android/location/IFusedGeofenceHardware.aidl",
+ "location/java/android/location/IGpsGeofenceHardware.aidl",
+ "location/java/android/location/INetInitiatedListener.aidl",
+ "location/java/com/android/internal/location/ILocationProvider.aidl",
+ "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/IMediaResourceMonitor.aidl",
+ "media/java/android/media/IMediaRouterClient.aidl",
+ "media/java/android/media/IMediaRouterService.aidl",
+ "media/java/android/media/IMediaScannerListener.aidl",
+ "media/java/android/media/IMediaScannerService.aidl",
+ "media/java/android/media/IPlaybackConfigDispatcher.aidl",
+ ":libaudioclient_aidl",
+ "media/java/android/media/IRecordingConfigDispatcher.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/audiopolicy/IAudioPolicyCallback.aidl",
+ "media/java/android/media/midi/IBluetoothMidiService.aidl",
+ "media/java/android/media/midi/IMidiDeviceListener.aidl",
+ "media/java/android/media/midi/IMidiDeviceOpenCallback.aidl",
+ "media/java/android/media/midi/IMidiDeviceServer.aidl",
+ "media/java/android/media/midi/IMidiManager.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/ICallback.aidl",
+ "media/java/android/media/session/IOnMediaKeyListener.aidl",
+ "media/java/android/media/session/IOnVolumeKeyLongPressListener.aidl",
+ "media/java/android/media/session/ISession.aidl",
+ "media/java/android/media/session/ISessionCallback.aidl",
+ "media/java/android/media/session/ISessionController.aidl",
+ "media/java/android/media/session/ISessionControllerCallback.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/media/tv/ITvRemoteProvider.aidl",
+ "media/java/android/media/tv/ITvRemoteServiceInput.aidl",
+ "media/java/android/service/media/IMediaBrowserService.aidl",
+ "media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl",
+ "telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl",
+ "telecomm/java/com/android/internal/telecom/ICallScreeningService.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/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl",
+ "telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl",
+ "telephony/java/android/telephony/mbms/IDownloadStateCallback.aidl",
+ "telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl",
+ "telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl",
+ "telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.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/IImsExternalCallStateListener.aidl",
+ "telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl",
+ "telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl",
+ "telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl",
+ "telephony/java/com/android/ims/internal/IImsRcsFeature.aidl",
+ "telephony/java/com/android/ims/internal/IImsService.aidl",
+ "telephony/java/com/android/ims/internal/IImsServiceController.aidl",
+ "telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl",
+ "telephony/java/com/android/ims/internal/IImsSmsFeature.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/internal/ISmsListener.aidl",
+ "telephony/java/com/android/ims/internal/uce/uceservice/IUceService.aidl",
+ "telephony/java/com/android/ims/internal/uce/uceservice/IUceListener.aidl",
+ "telephony/java/com/android/ims/internal/uce/options/IOptionsService.aidl",
+ "telephony/java/com/android/ims/internal/uce/options/IOptionsListener.aidl",
+ "telephony/java/com/android/ims/internal/uce/presence/IPresenceService.aidl",
+ "telephony/java/com/android/ims/internal/uce/presence/IPresenceListener.aidl",
+ "telephony/java/com/android/ims/ImsConfigListener.aidl",
+ "telephony/java/com/android/internal/telephony/IApnSourceService.aidl",
+ "telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl",
+ "telephony/java/com/android/internal/telephony/IMms.aidl",
+ "telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl",
+ "telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl",
+ "telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl",
+ "telephony/java/com/android/internal/telephony/ISms.aidl",
+ "telephony/java/com/android/internal/telephony/ISub.aidl",
+ "telephony/java/com/android/internal/telephony/ITelephony.aidl",
+ "telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl",
+ "telephony/java/com/android/internal/telephony/IWapPushManager.aidl",
+ "telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl",
+ "wifi/java/android/net/wifi/IWifiManager.aidl",
+ "wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl",
+ "wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl",
+ "wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl",
+ "wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl",
+ "wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl",
+ "wifi/java/android/net/wifi/rtt/IRttCallback.aidl",
+ "wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl",
+ "wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.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",
+ "core/java/android/service/quicksettings/IQSService.aidl",
+ "core/java/android/service/quicksettings/IQSTileService.aidl",
+
+ ":libupdate_engine_aidl",
+
+ ":storaged_aidl",
+ ":netd_aidl",
+ ":vold_aidl",
+ ":installd_aidl",
+
+ "lowpan/java/android/net/lowpan/ILowpanEnergyScanCallback.aidl",
+ "lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl",
+ "lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl",
+ "lowpan/java/android/net/lowpan/ILowpanInterface.aidl",
+ "lowpan/java/android/net/lowpan/ILowpanManagerListener.aidl",
+ "lowpan/java/android/net/lowpan/ILowpanManager.aidl",
+
+ "core/java/android/app/admin/SecurityLogTags.logtags",
+ "core/java/android/content/EventLogTags.logtags",
+ "core/java/android/speech/tts/EventLogTags.logtags",
+ "core/java/android/net/EventLogTags.logtags",
+ "core/java/android/webkit/EventLogTags.logtags",
+ "core/java/com/android/internal/logging/EventLogTags.logtags",
+
+ ":framework-statslog-gen",
+ ],
+ logtags: [
+ "core/java/android/app/admin/SecurityLogTags.logtags",
+ "core/java/android/content/EventLogTags.logtags",
+ "core/java/android/speech/tts/EventLogTags.logtags",
+ "core/java/android/net/EventLogTags.logtags",
+ "core/java/android/webkit/EventLogTags.logtags",
+ "core/java/com/android/internal/logging/EventLogTags.logtags",
+ ],
+
+ aidl: {
+ local_include_dirs: [
+ // From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS
+ "core/java",
+ "graphics/java",
+ "location/java",
+ "lowpan/java",
+ "media/java",
+ "media/mca/effect/java",
+ "media/mca/filterfw/java",
+ "media/mca/filterpacks/java",
+ "drm/java",
+ "opengl/java",
+ "sax/java",
+ "telecomm/java",
+ "telephony/java",
+ "wifi/java",
+ "keystore/java",
+ "rs/java",
+ ],
+
+ include_dirs: [
+ "system/update_engine/binder_bindings",
+ "frameworks/native/aidl/binder",
+ "frameworks/av/camera/aidl",
+ "frameworks/av/media/libaudioclient/aidl",
+ "frameworks/native/aidl/gui",
+ "system/core/storaged/binder",
+ "system/netd/server/binder",
+ "system/vold/binder",
+ "system/bt/binder",
+ ],
+ },
+
+ no_framework_libs: true,
+ libs: [
+ "conscrypt",
+ "okhttp",
+ "bouncycastle",
+ "ext",
+ ],
+
+ static_libs: [
+ "framework-protos",
+ "android.hidl.base-V1.0-java",
+ "android.hardware.cas-V1.0-java",
+ "android.hardware.contexthub-V1.0-java",
+ "android.hardware.health-V1.0-java-constants",
+ "android.hardware.thermal-V1.0-java-constants",
+ "android.hardware.tv.input-V1.0-java-constants",
+ "android.hardware.usb-V1.0-java-constants",
+ "android.hardware.usb-V1.1-java-constants",
+ "android.hardware.vibrator-V1.0-java-constants",
+ "android.hardware.vibrator-V1.1-java-constants",
+ "android.hardware.wifi-V1.0-java-constants",
+ ],
+
+ // Loaded with System.loadLibrary by android.view.textclassifier
+ required: ["libtextclassifier"],
+
+ javac_shard_size: 150,
+
+ dxflags: [
+ "--core-library",
+ "--multi-dex",
+ ],
+}
+
+genrule {
+ name: "framework-statslog-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out)",
+ out: ["android/util/StatsLog.java"],
+}
+
+gensrcs {
+ name: "framework-javastream-protos",
+ depfile: true,
+
+ tools: [
+ "aprotoc",
+ "protoc-gen-javastream",
+ "soong_zip",
+ ],
+
+ // Append protoc-gen-javastream tool's PATH otherwise aprotoc can't find the plugin tool
+ cmd: "export PATH=$$PATH:$$(dirname $(location protoc-gen-javastream)) " +
+ "&& mkdir -p $(genDir)/$(in) " +
+ "&& $(location aprotoc) " +
+ " --plugin=protoc-gen-java-stream=protoc-gen-javastream " +
+ " --dependency_out=$(depfile) " +
+ " --javastream_out=$(genDir)/$(in) " +
+ " -Iexternal/protobuf/src " +
+ " -I . " +
+ " $(in) " +
+ "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
+
+ srcs: ["core/proto/**/*.proto"],
+ output_extension: "srcjar",
+}
+
// Build ext.jar
// ============================================================
java_library {
diff --git a/Android.mk b/Android.mk
index a69170f..8ce2616 100644
--- a/Android.mk
+++ b/Android.mk
@@ -15,16 +15,8 @@
#
LOCAL_PATH := $(call my-dir)
-# We have a special case here where we build the library's resources
-# independently from its code, so we need to find where the resource
-# class source got placed in the course of building the resources.
-# Thus, the magic here.
-# Also, this module cannot depend directly on the R.java file; if it
-# did, the PRIVATE_* vars for R.java wouldn't be guaranteed to be correct.
-# Instead, it depends on the R.stamp file, which lists the corresponding
-# R.java file as a prerequisite.
-# TODO: find a more appropriate way to do this.
-framework_res_source_path := APPS/framework-res_intermediates/src
+# Load framework-specific path mappings used later in the build.
+include $(LOCAL_PATH)/pathmap.mk
# Build the master framework library.
# The framework contains too many method references (>64K) for poor old DEX.
@@ -35,651 +27,6 @@
# embedded builds use nothing in frameworks/base
ifneq ($(ANDROID_BUILD_EMBEDDED),true)
-include $(CLEAR_VARS)
-
-# Load framework-specific path mappings used later in the build.
-include $(LOCAL_PATH)/pathmap.mk
-
-# FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
-LOCAL_SRC_FILES := \
- $(call find-other-java-files,$(FRAMEWORKS_BASE_SUBDIRS)) \
- $(call all-proto-files-under, core/proto)
-
-# EventLogTags files.
-LOCAL_SRC_FILES += \
- core/java/android/app/admin/SecurityLogTags.logtags \
- core/java/android/content/EventLogTags.logtags \
- core/java/android/speech/tts/EventLogTags.logtags \
- core/java/android/net/EventLogTags.logtags \
- core/java/android/webkit/EventLogTags.logtags \
- core/java/com/android/internal/logging/EventLogTags.logtags \
-
-## READ ME: ########################################################
-##
-## When updating this list of aidl files, consider if that aidl is
-## part of the SDK API. If it is, also add it to the list below that
-## is preprocessed and distributed with the SDK. This list should
-## not contain any aidl files for parcelables, but the one below should
-## if you intend for 3rd parties to be able to send those objects
-## across process boundaries.
-##
-## READ ME: ########################################################
-LOCAL_SRC_FILES += \
- core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
- core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
- core/java/android/accounts/IAccountManager.aidl \
- core/java/android/accounts/IAccountManagerResponse.aidl \
- core/java/android/accounts/IAccountAuthenticator.aidl \
- core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
- core/java/android/app/IActivityController.aidl \
- core/java/android/app/IActivityManager.aidl \
- core/java/android/app/IActivityPendingResult.aidl \
- core/java/android/app/IAlarmCompleteListener.aidl \
- core/java/android/app/IAlarmListener.aidl \
- core/java/android/app/IAlarmManager.aidl \
- core/java/android/app/IAppTask.aidl \
- core/java/android/app/IApplicationThread.aidl \
- core/java/android/app/IAssistDataReceiver.aidl \
- core/java/android/app/ITaskStackListener.aidl \
- core/java/android/app/IBackupAgent.aidl \
- core/java/android/app/IEphemeralResolver.aidl \
- core/java/android/app/IInputForwarder.aidl \
- core/java/android/app/IInstantAppResolver.aidl \
- core/java/android/app/IInstrumentationWatcher.aidl \
- core/java/android/app/INotificationManager.aidl \
- core/java/android/app/IProcessObserver.aidl \
- core/java/android/app/ISearchManager.aidl \
- core/java/android/app/ISearchManagerCallback.aidl \
- core/java/android/app/IServiceConnection.aidl \
- core/java/android/app/IStopUserCallback.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/IUidObserver.aidl \
- core/java/android/app/IUiAutomationConnection.aidl \
- core/java/android/app/IUiModeManager.aidl \
- core/java/android/app/IUserSwitchObserver.aidl \
- core/java/android/app/IWallpaperManager.aidl \
- core/java/android/app/IWallpaperManagerCallback.aidl \
- core/java/android/app/admin/IDeviceAdminService.aidl \
- core/java/android/app/admin/IDevicePolicyManager.aidl \
- core/java/android/app/trust/IStrongAuthTracker.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/IBackupObserver.aidl \
- core/java/android/app/backup/IBackupManagerMonitor.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/backup/ISelectBackupTransportCallback.aidl \
- core/java/android/app/timezone/ICallback.aidl \
- core/java/android/app/timezone/IRulesManager.aidl \
- core/java/android/app/usage/ICacheQuotaService.aidl \
- core/java/android/app/usage/IStorageStatsManager.aidl \
- core/java/android/app/usage/IUsageStatsManager.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetooth.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothA2dp.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothA2dpSink.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothAvrcpController.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothCallback.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothProfileServiceConnection.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothHeadset.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothHeadsetPhone.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothHealth.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothHealthCallback.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothHidHost.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothPan.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothManager.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothManagerCallback.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothMap.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothMapClient.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothPbap.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothPbapClient.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothSap.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothSocketManager.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothStateChangeCallback.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothHeadsetClient.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothHidDevice.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothHidDeviceCallback.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothGatt.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothGattCallback.aidl \
- ../../system/bt/binder/android/bluetooth/IBluetoothGattServerCallback.aidl \
- ../../system/bt/binder/android/bluetooth/le/IAdvertisingSetCallback.aidl \
- ../../system/bt/binder/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl \
- ../../system/bt/binder/android/bluetooth/le/IScannerCallback.aidl \
- core/java/android/content/IClipboard.aidl \
- core/java/android/content/IContentService.aidl \
- core/java/android/content/IIntentReceiver.aidl \
- core/java/android/content/IIntentSender.aidl \
- core/java/android/content/IOnPrimaryClipChangedListener.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/om/IOverlayManager.aidl \
- core/java/android/content/pm/crossprofile/ICrossProfileApps.aidl \
- core/java/android/content/pm/IDexModuleRegisterCallback.aidl \
- core/java/android/content/pm/ILauncherApps.aidl \
- core/java/android/content/pm/IOnAppsChangedListener.aidl \
- core/java/android/content/pm/IOnPermissionsChangeListener.aidl \
- core/java/android/content/pm/IOtaDexopt.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/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 \
- ../native/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl \
- core/java/android/content/pm/IPackageMoveObserver.aidl \
- core/java/android/content/pm/IPackageStatsObserver.aidl \
- core/java/android/content/pm/IPinItemRequest.aidl \
- core/java/android/content/pm/IShortcutService.aidl \
- core/java/android/content/pm/permission/IRuntimePermissionPresenter.aidl \
- core/java/android/database/IContentObserver.aidl \
- ../av/camera/aidl/android/hardware/ICameraService.aidl \
- ../av/camera/aidl/android/hardware/ICameraServiceListener.aidl \
- ../av/camera/aidl/android/hardware/ICameraServiceProxy.aidl \
- ../av/camera/aidl/android/hardware/ICamera.aidl \
- ../av/camera/aidl/android/hardware/ICameraClient.aidl \
- ../av/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl \
- ../av/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl \
- core/java/android/hardware/IConsumerIrService.aidl \
- core/java/android/hardware/ISerialManager.aidl \
- core/java/android/hardware/display/IDisplayManager.aidl \
- core/java/android/hardware/display/IDisplayManagerCallback.aidl \
- core/java/android/hardware/display/IVirtualDisplayCallback.aidl \
- core/java/android/hardware/fingerprint/IFingerprintService.aidl \
- core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl \
- core/java/android/hardware/fingerprint/IFingerprintClientActiveCallback.aidl \
- core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.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/input/ITabletModeChangedListener.aidl \
- core/java/android/hardware/location/IActivityRecognitionHardware.aidl \
- core/java/android/hardware/location/IActivityRecognitionHardwareClient.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/location/IContextHubCallback.aidl \
- core/java/android/hardware/location/IContextHubClient.aidl \
- core/java/android/hardware/location/IContextHubClientCallback.aidl \
- core/java/android/hardware/location/IContextHubService.aidl \
- core/java/android/hardware/location/IContextHubTransactionCallback.aidl \
- core/java/android/hardware/radio/IRadioService.aidl \
- core/java/android/hardware/radio/ITuner.aidl \
- core/java/android/hardware/radio/ITunerCallback.aidl \
- core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl \
- core/java/android/hardware/usb/IUsbManager.aidl \
- core/java/android/net/ICaptivePortal.aidl \
- core/java/android/net/IConnectivityManager.aidl \
- core/java/android/net/IIpConnectivityMetrics.aidl \
- core/java/android/net/IEthernetManager.aidl \
- core/java/android/net/IEthernetServiceListener.aidl \
- core/java/android/net/INetdEventCallback.aidl \
- core/java/android/net/IIpSecService.aidl \
- core/java/android/net/INetworkManagementEventObserver.aidl \
- core/java/android/net/INetworkPolicyListener.aidl \
- core/java/android/net/INetworkPolicyManager.aidl \
- core/java/android/net/INetworkRecommendationProvider.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/ITetheringStatsProvider.aidl \
- core/java/android/net/nsd/INsdManager.aidl \
- core/java/android/nfc/IAppCallback.aidl \
- core/java/android/nfc/INfcAdapter.aidl \
- core/java/android/nfc/INfcAdapterExtras.aidl \
- core/java/android/nfc/INfcTag.aidl \
- core/java/android/nfc/INfcCardEmulation.aidl \
- core/java/android/nfc/INfcFCardEmulation.aidl \
- core/java/android/nfc/INfcUnlockHandler.aidl \
- core/java/android/nfc/INfcDta.aidl \
- core/java/android/nfc/ITagRemovedCallback.aidl \
- core/java/android/os/IBatteryPropertiesListener.aidl \
- core/java/android/os/IBatteryPropertiesRegistrar.aidl \
- core/java/android/os/ICancellationSignal.aidl \
- core/java/android/os/IDeviceIdentifiersPolicyService.aidl \
- core/java/android/os/IDeviceIdleController.aidl \
- core/java/android/os/IHardwarePropertiesManager.aidl \
- core/java/android/os/IIncidentManager.aidl \
- core/java/android/os/IIncidentReportCompletedListener.aidl \
- core/java/android/os/IIncidentReportStatusListener.aidl \
- core/java/android/os/IMaintenanceActivityListener.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/IProcessInfoService.aidl \
- core/java/android/os/IProgressListener.aidl \
- core/java/android/os/IPowerManager.aidl \
- core/java/android/os/IRecoverySystem.aidl \
- core/java/android/os/IRecoverySystemProgressListener.aidl \
- core/java/android/os/IRemoteCallback.aidl \
- core/java/android/os/ISchedulingPolicyService.aidl \
- core/java/android/os/IStatsCompanionService.aidl \
- core/java/android/os/IStatsManager.aidl \
- core/java/android/os/IThermalEventListener.aidl \
- core/java/android/os/IThermalService.aidl \
- core/java/android/os/IUpdateLock.aidl \
- core/java/android/os/IUserManager.aidl \
- core/java/android/os/IVibratorService.aidl \
- core/java/android/os/storage/IStorageManager.aidl \
- core/java/android/os/storage/IStorageEventListener.aidl \
- core/java/android/os/storage/IStorageShutdownObserver.aidl \
- core/java/android/os/storage/IObbActionListener.aidl \
- core/java/android/security/IKeystoreService.aidl \
- core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl \
- core/java/android/service/autofill/IAutoFillService.aidl \
- core/java/android/service/autofill/IFillCallback.aidl \
- core/java/android/service/autofill/ISaveCallback.aidl \
- core/java/android/service/carrier/ICarrierService.aidl \
- core/java/android/service/carrier/ICarrierMessagingCallback.aidl \
- core/java/android/service/carrier/ICarrierMessagingService.aidl \
- core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl \
- core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl \
- core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl \
- core/java/android/service/euicc/IEuiccService.aidl \
- core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl \
- core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl \
- core/java/android/service/euicc/IGetEidCallback.aidl \
- core/java/android/service/euicc/IGetEuiccInfoCallback.aidl \
- core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl \
- core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl \
- core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl \
- core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl \
- core/java/android/service/gatekeeper/IGateKeeperService.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/service/settings/suggestions/ISuggestionService.aidl \
- core/java/android/service/vr/IPersistentVrStateCallbacks.aidl \
- core/java/android/service/vr/IVrListener.aidl \
- core/java/android/service/vr/IVrManager.aidl \
- core/java/android/service/vr/IVrStateCallbacks.aidl \
- core/java/android/print/ILayoutResultCallback.aidl \
- core/java/android/print/IPrinterDiscoveryObserver.aidl \
- core/java/android/print/IPrintDocumentAdapter.aidl \
- core/java/android/print/IPrintDocumentAdapterObserver.aidl \
- core/java/android/print/IPrintJobStateChangeListener.aidl \
- core/java/android/print/IPrintServicesChangeListener.aidl \
- core/java/android/printservice/recommendation/IRecommendationsChangeListener.aidl \
- core/java/android/print/IPrintManager.aidl \
- core/java/android/print/IPrintSpooler.aidl \
- core/java/android/print/IPrintSpoolerCallbacks.aidl \
- core/java/android/print/IPrintSpoolerClient.aidl \
- core/java/android/printservice/recommendation/IRecommendationServiceCallbacks.aidl \
- core/java/android/printservice/recommendation/IRecommendationService.aidl \
- core/java/android/print/IWriteResultCallback.aidl \
- core/java/android/printservice/IPrintService.aidl \
- core/java/android/printservice/IPrintServiceClient.aidl \
- core/java/android/companion/ICompanionDeviceManager.aidl \
- core/java/android/companion/ICompanionDeviceDiscoveryService.aidl \
- core/java/android/companion/ICompanionDeviceDiscoveryServiceCallback.aidl \
- core/java/android/companion/IFindDeviceCallback.aidl \
- core/java/android/service/dreams/IDreamManager.aidl \
- core/java/android/service/dreams/IDreamService.aidl \
- core/java/android/service/oemlock/IOemLockService.aidl \
- core/java/android/service/persistentdata/IPersistentDataBlockService.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 \
- core/java/android/service/chooser/IChooserTargetService.aidl \
- core/java/android/service/chooser/IChooserTargetResult.aidl \
- core/java/android/service/resolver/IResolverRankerService.aidl \
- core/java/android/service/resolver/IResolverRankerResult.aidl \
- core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl\
- core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl\
- core/java/android/view/accessibility/IAccessibilityManager.aidl \
- core/java/android/view/accessibility/IAccessibilityManagerClient.aidl \
- core/java/android/view/autofill/IAutoFillManager.aidl \
- core/java/android/view/autofill/IAutoFillManagerClient.aidl \
- core/java/android/view/autofill/IAutofillWindowPresenter.aidl \
- core/java/android/view/IApplicationToken.aidl \
- core/java/android/view/IAppTransitionAnimationSpecsFuture.aidl \
- core/java/android/view/IDockedStackListener.aidl \
- core/java/android/view/IGraphicsStats.aidl \
- core/java/android/view/IGraphicsStatsCallback.aidl \
- core/java/android/view/IInputFilter.aidl \
- core/java/android/view/IInputFilterHost.aidl \
- core/java/android/view/IOnKeyguardExitResult.aidl \
- core/java/android/view/IPinnedStackController.aidl \
- core/java/android/view/IPinnedStackListener.aidl \
- core/java/android/view/IRotationWatcher.aidl \
- core/java/android/view/IWallpaperVisibilityListener.aidl \
- core/java/android/view/IWindow.aidl \
- core/java/android/view/IWindowFocusObserver.aidl \
- 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 \
- core/java/android/speech/tts/ITextToSpeechService.aidl \
- core/java/com/android/internal/app/IAppOpsCallback.aidl \
- core/java/com/android/internal/app/IAppOpsService.aidl \
- core/java/com/android/internal/app/IBatteryStats.aidl \
- core/java/com/android/internal/app/ISoundTriggerService.aidl \
- core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl \
- core/java/com/android/internal/app/IVoiceInteractionSessionListener.aidl \
- core/java/com/android/internal/app/IVoiceInteractionSessionShowCallback.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/app/procstats/IProcessStats.aidl \
- core/java/com/android/internal/appwidget/IAppWidgetService.aidl \
- core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
- core/java/com/android/internal/backup/IBackupTransport.aidl \
- core/java/com/android/internal/backup/IObbBackupService.aidl \
- core/java/com/android/internal/car/ICarServiceHelper.aidl \
- core/java/com/android/internal/inputmethod/IInputContentUriToken.aidl \
- core/java/com/android/internal/net/INetworkWatchlistManager.aidl \
- core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl \
- core/java/com/android/internal/policy/IKeyguardDismissCallback.aidl \
- core/java/com/android/internal/policy/IKeyguardExitCallback.aidl \
- core/java/com/android/internal/policy/IKeyguardService.aidl \
- core/java/com/android/internal/policy/IKeyguardStateCallback.aidl \
- core/java/com/android/internal/policy/IShortcutService.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/os/IShellCallback.aidl \
- core/java/com/android/internal/statusbar/IStatusBar.aidl \
- core/java/com/android/internal/statusbar/IStatusBarService.aidl \
- core/java/com/android/internal/textservice/ISpellCheckerService.aidl \
- core/java/com/android/internal/textservice/ISpellCheckerServiceCallback.aidl \
- core/java/com/android/internal/textservice/ISpellCheckerSession.aidl \
- core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl \
- core/java/com/android/internal/textservice/ITextServicesManager.aidl \
- core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl \
- core/java/com/android/internal/view/IDragAndDropPermissions.aidl \
- core/java/com/android/internal/view/IInputContext.aidl \
- core/java/com/android/internal/view/IInputContextCallback.aidl \
- core/java/com/android/internal/view/IInputMethod.aidl \
- core/java/com/android/internal/view/IInputMethodClient.aidl \
- core/java/com/android/internal/view/IInputMethodManager.aidl \
- core/java/com/android/internal/view/IInputMethodSession.aidl \
- core/java/com/android/internal/view/IInputSessionCallback.aidl \
- core/java/com/android/internal/widget/ICheckCredentialProgressCallback.aidl \
- core/java/com/android/internal/widget/ILockSettings.aidl \
- core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \
- keystore/java/android/security/IKeyChainAliasCallback.aidl \
- keystore/java/android/security/IKeyChainService.aidl \
- location/java/android/location/IBatchedLocationCallback.aidl \
- location/java/android/location/ICountryDetector.aidl \
- location/java/android/location/ICountryListener.aidl \
- location/java/android/location/IFusedProvider.aidl \
- location/java/android/location/IGeocodeProvider.aidl \
- location/java/android/location/IGeofenceProvider.aidl \
- location/java/android/location/IGnssStatusListener.aidl \
- location/java/android/location/IGnssStatusProvider.aidl \
- location/java/android/location/IGnssMeasurementsListener.aidl \
- location/java/android/location/IGnssNavigationMessageListener.aidl \
- location/java/android/location/ILocationListener.aidl \
- location/java/android/location/ILocationManager.aidl \
- location/java/android/location/IFusedGeofenceHardware.aidl \
- location/java/android/location/IGpsGeofenceHardware.aidl \
- location/java/android/location/INetInitiatedListener.aidl \
- location/java/com/android/internal/location/ILocationProvider.aidl \
- 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/IMediaResourceMonitor.aidl \
- media/java/android/media/IMediaRouterClient.aidl \
- media/java/android/media/IMediaRouterService.aidl \
- media/java/android/media/IMediaScannerListener.aidl \
- media/java/android/media/IMediaScannerService.aidl \
- media/java/android/media/IPlaybackConfigDispatcher.aidl \
- ../av/media/libaudioclient/aidl/android/media/IPlayer.aidl \
- media/java/android/media/IRecordingConfigDispatcher.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/audiopolicy/IAudioPolicyCallback.aidl \
- media/java/android/media/midi/IBluetoothMidiService.aidl \
- media/java/android/media/midi/IMidiDeviceListener.aidl \
- media/java/android/media/midi/IMidiDeviceOpenCallback.aidl \
- media/java/android/media/midi/IMidiDeviceServer.aidl \
- media/java/android/media/midi/IMidiManager.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/ICallback.aidl \
- media/java/android/media/session/IOnMediaKeyListener.aidl \
- media/java/android/media/session/IOnVolumeKeyLongPressListener.aidl \
- media/java/android/media/session/ISession.aidl \
- media/java/android/media/session/ISessionCallback.aidl \
- media/java/android/media/session/ISessionController.aidl \
- media/java/android/media/session/ISessionControllerCallback.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/media/tv/ITvRemoteProvider.aidl \
- media/java/android/media/tv/ITvRemoteServiceInput.aidl \
- media/java/android/service/media/IMediaBrowserService.aidl \
- media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl \
- telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl \
- telecomm/java/com/android/internal/telecom/ICallScreeningService.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/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl \
- telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl \
- telephony/java/android/telephony/mbms/IDownloadStateCallback.aidl \
- telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl \
- telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl \
- telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.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/IImsExternalCallStateListener.aidl \
- telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl \
- telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl \
- telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl \
- telephony/java/com/android/ims/internal/IImsRcsFeature.aidl \
- telephony/java/com/android/ims/internal/IImsService.aidl \
- telephony/java/com/android/ims/internal/IImsServiceController.aidl \
- telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl \
- telephony/java/com/android/ims/internal/IImsSmsFeature.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/internal/ISmsListener.aidl \
- telephony/java/com/android/ims/internal/uce/uceservice/IUceService.aidl \
- telephony/java/com/android/ims/internal/uce/uceservice/IUceListener.aidl \
- telephony/java/com/android/ims/internal/uce/options/IOptionsService.aidl \
- telephony/java/com/android/ims/internal/uce/options/IOptionsListener.aidl \
- telephony/java/com/android/ims/internal/uce/presence/IPresenceService.aidl \
- telephony/java/com/android/ims/internal/uce/presence/IPresenceListener.aidl \
- telephony/java/com/android/ims/ImsConfigListener.aidl \
- telephony/java/com/android/internal/telephony/IApnSourceService.aidl \
- telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl \
- telephony/java/com/android/internal/telephony/IMms.aidl \
- telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl \
- telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
- telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
- telephony/java/com/android/internal/telephony/ISms.aidl \
- telephony/java/com/android/internal/telephony/ISub.aidl \
- telephony/java/com/android/internal/telephony/ITelephony.aidl \
- telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
- telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
- telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl \
- wifi/java/android/net/wifi/IWifiManager.aidl \
- wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl \
- wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl \
- wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl \
- wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl \
- wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
- wifi/java/android/net/wifi/rtt/IRttCallback.aidl \
- wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl \
- wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.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 \
- core/java/android/service/quicksettings/IQSService.aidl \
- core/java/android/service/quicksettings/IQSTileService.aidl \
-
-# The following are native binders that need to go with the native component
-# at system/update_engine/binder_bindings/. Use relative path to refer to them.
-LOCAL_SRC_FILES += \
- ../../system/update_engine/binder_bindings/android/os/IUpdateEngine.aidl \
- ../../system/update_engine/binder_bindings/android/os/IUpdateEngineCallback.aidl \
-
-LOCAL_SRC_FILES += \
- ../../system/core/storaged/binder/android/os/IStoraged.aidl \
- ../../system/netd/server/binder/android/net/INetd.aidl \
- ../../system/vold/binder/android/os/IVold.aidl \
- ../../system/vold/binder/android/os/IVoldListener.aidl \
- ../../system/vold/binder/android/os/IVoldTaskListener.aidl \
- ../native/cmds/installd/binder/android/os/IInstalld.aidl \
-
-LOCAL_AIDL_INCLUDES += system/update_engine/binder_bindings
-
-LOCAL_AIDL_INCLUDES += core/java/android/os/StatsLogEventWrapper.aidl
-
-LOCAL_AIDL_INCLUDES += frameworks/base/lowpan/java
-LOCAL_SRC_FILES += \
- lowpan/java/android/net/lowpan/ILowpanEnergyScanCallback.aidl \
- lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl \
- lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl \
- lowpan/java/android/net/lowpan/ILowpanInterface.aidl \
- lowpan/java/android/net/lowpan/ILowpanManagerListener.aidl \
- lowpan/java/android/net/lowpan/ILowpanManager.aidl
-
-# StatsLog generated functions
-statslog_src_dir := $(call intermediates-dir-for,JAVA_LIBRARIES,framework,,COMMON)/statslog
-gen := $(statslog_src_dir)/android/util/StatsLog.java
-$(gen): PRIVATE_PATH := $(LOCAL_PATH)
-$(gen): PRIVATE_CUSTOM_TOOL = $(HOST_OUT_EXECUTABLES)/stats-log-api-gen --java $@
-$(gen): $(HOST_OUT_EXECUTABLES)/stats-log-api-gen
- $(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(gen)
-statslog_src_dir:=
-gen:=
-
-# FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk
-LOCAL_AIDL_INCLUDES += \
- $(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
- frameworks/native/aidl/binder
-
-LOCAL_AIDL_INCLUDES += \
- frameworks/av/camera/aidl \
- frameworks/av/drm/libmediadrm/aidl \
- frameworks/av/media/libaudioclient/aidl \
- frameworks/native/aidl/gui \
- system/core/storaged/binder \
- system/netd/server/binder \
- system/vold/binder \
- system/bt/binder
-
-LOCAL_INTERMEDIATE_SOURCES := \
- $(framework_res_source_path)/android/R.java \
- $(framework_res_source_path)/android/Manifest.java \
- $(framework_res_source_path)/com/android/internal/R.java
-
-# 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
-LOCAL_ADDITIONAL_DEPENDENCIES := $(framework_res_R_stamp)
-
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-oj core-libart conscrypt okhttp bouncycastle ext
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- framework-protos \
- android.hidl.base-V1.0-java \
- android.hardware.cas-V1.0-java \
- android.hardware.contexthub-V1.0-java \
- android.hardware.health-V1.0-java-constants \
- android.hardware.thermal-V1.0-java-constants \
- android.hardware.tv.input-V1.0-java-constants \
- android.hardware.usb-V1.0-java-constants \
- android.hardware.usb-V1.1-java-constants \
- android.hardware.vibrator-V1.0-java-constants \
- android.hardware.vibrator-V1.1-java-constants \
- android.hardware.wifi-V1.0-java-constants \
-
-# Loaded with System.loadLibrary by android.view.textclassifier
-LOCAL_REQUIRED_MODULES += libtextclassifier
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := stream
-LOCAL_PROTOC_FLAGS := \
- -Iexternal/protobuf/src
-
-LOCAL_MODULE := framework
-
-LOCAL_JAVAC_SHARD_SIZE := 150
-
-LOCAL_DX_FLAGS := --core-library --multi-dex
-LOCAL_JACK_FLAGS := --multi-dex native
-
-LOCAL_RMTYPEDEFS := true
-
-ifeq ($(EMMA_INSTRUMENT_FRAMEWORK),true)
-LOCAL_EMMA_INSTRUMENT := true
-endif
-
-include $(BUILD_JAVA_LIBRARY)
-
-framework_module := $(LOCAL_INSTALLED_MODULE)
-$(framework_module): | $(dir $(framework_module))framework-res.apk
-
-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.
# ============================================================
@@ -910,85 +257,79 @@
# TODO: deal with com/google/android/googleapps
packages_to_document := \
- android \
- javax/microedition/khronos \
- org/apache/http/conn \
- org/apache/http/params
-
-
-# Search through the base framework dirs for these packages.
-# The result will be relative to frameworks/base.
-fwbase_dirs_to_document := \
- test-base/src \
- $(patsubst $(LOCAL_PATH)/%,%, \
- $(wildcard \
- $(foreach dir, $(FRAMEWORKS_BASE_JAVA_SRC_DIRS), \
- $(addprefix $(dir)/, $(packages_to_document)) \
- ) \
- ) \
- )
+ android \
+ javax/microedition/khronos \
+ org/apache/http/conn \
+ org/apache/http/params \
# include definition of libcore_to_document
include libcore/Docs.mk
non_base_dirs := \
- ../opt/telephony/src/java/android/telephony \
- ../opt/telephony/src/java/android/telephony/gsm \
- ../opt/net/voip/src/java/android/net/rtp \
- ../opt/net/voip/src/java/android/net/sip
+ ../opt/telephony/src/java/android/telephony \
+ ../opt/telephony/src/java/android/telephony/gsm \
+ ../opt/net/voip/src/java/android/net/rtp \
+ ../opt/net/voip/src/java/android/net/sip \
framework_base_android_test_mock_src_files := \
- $(call all-java-files-under, test-mock/src/android/test/mock)
+ $(call all-java-files-under, test-mock/src/android/test/mock)
framework_base_android_test_runner_excluding_mock_src_files := \
- $(filter-out $(framework_base_android_test_mock_src_files), $(call all-java-files-under, test-runner/src))
+ $(filter-out $(framework_base_android_test_mock_src_files), $(call all-java-files-under, test-runner/src))
-# These are relative to frameworks/base
-dirs_to_check_apis := \
- $(fwbase_dirs_to_document) \
- $(non_base_dirs)
+# Find all files in specific directories (relative to frameworks/base)
+# to document and check apis
+files_to_check_apis := \
+ $(call find-other-java-files, \
+ test-base/src \
+ $(non_base_dirs) \
+ )
-###########################################################
-## Return all directories that have a 'NO_DOCS' file in
-## them, appending a '%' to them to form a pattern to
-## filter out files under those directories.
-## $(1): A list of base directories to look at.
-###########################################################
-define find-no-docs-pattern
-$(addsuffix %, $(dir $(foreach dir, $(1), $(shell cd $(LOCAL_PATH); find $(dir) -name NO_DOCS))))
-endef
+# Find all files in specific packages that were used to compile
+# framework.jar to document and check apis
+files_to_check_apis += \
+ $(addprefix ../../,\
+ $(filter \
+ $(foreach dir,$(FRAMEWORKS_BASE_JAVA_SRC_DIRS),\
+ $(foreach package,$(packages_to_document),\
+ $(dir)/$(package)/%.java)),\
+ $(SOONG_FRAMEWORK_SRCS)))
+
+# Find all generated files that were used to compile framework.jar
+files_to_check_apis += \
+ $(addprefix ../../,\
+ $(filter $(OUT_DIR)/%,\
+ $(SOONG_FRAMEWORK_SRCS)))
# These are relative to frameworks/base
# FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
-dirs_to_document := \
- $(dirs_to_check_apis) \
- test-runner/src \
- $(addprefix ../../, $(FRAMEWORKS_DATA_BINDING_JAVA_SRC_DIRS))
-
-patterns_to_not_document := \
- $(call find-no-docs-pattern, $(dirs_to_document))
+files_to_document := \
+ $(files_to_check_apis) \
+ $(call find-other-java-files,\
+ $(addprefix ../../, $(FRAMEWORKS_DATA_BINDING_JAVA_SRC_DIRS)) \
+ test-runner/src)
# These are relative to frameworks/base
html_dirs := \
$(FRAMEWORKS_BASE_SUBDIRS) \
- $(non_base_dirs)
+ $(non_base_dirs) \
# Common sources for doc check and api check
common_src_files := \
$(call find-other-html-files, $(html_dirs)) \
- $(addprefix ../../, $(libcore_to_document))
+ $(addprefix ../../, $(libcore_to_document)) \
# These are relative to frameworks/base
framework_docs_LOCAL_SRC_FILES := \
- $(filter-out $(patterns_to_not_document), $(call find-other-java-files, $(dirs_to_document))) \
- $(common_src_files)
+ $(files_to_document) \
+ $(common_src_files) \
# These are relative to frameworks/base
framework_docs_LOCAL_API_CHECK_SRC_FILES := \
- $(framework_base_android_test_mock_src_files) \
- $(framework_base_android_test_runner_excluding_mock_src_files) \
- $(call all-java-files-under, $(dirs_to_check_apis)) \
- $(common_src_files)
+ $(framework_base_android_test_mock_src_files) \
+ $(framework_base_android_test_runner_excluding_mock_src_files) \
+ $(files_to_check_apis) \
+ $(common_src_files) \
# This is used by ide.mk as the list of source files that are
# always included.
@@ -997,10 +338,9 @@
framework_docs_LOCAL_DROIDDOC_SOURCE_PATH := \
$(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
+framework_docs_LOCAL_SRCJARS := $(SOONG_FRAMEWORK_SRCJARS)
+
framework_docs_LOCAL_INTERMEDIATE_SOURCES := \
- $(framework_res_source_path)/android/R.java \
- $(framework_res_source_path)/android/Manifest.java \
- $(framework_res_source_path)/com/android/internal/R.java \
$(patsubst $(TARGET_OUT_COMMON_INTERMEDIATES)/%,%,$(libcore_to_document_generated))
framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES := \
@@ -1123,6 +463,7 @@
LOCAL_SRC_FILES := $(framework_docs_LOCAL_API_CHECK_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES := $(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
LOCAL_JAVA_LIBRARIES := $(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
LOCAL_MODULE_CLASS := $(framework_docs_LOCAL_MODULE_CLASS)
LOCAL_ADDITIONAL_JAVA_DIR := $(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
@@ -1148,6 +489,7 @@
LOCAL_SRC_FILES := $(framework_docs_LOCAL_API_CHECK_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES := $(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
LOCAL_JAVA_LIBRARIES := $(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
LOCAL_MODULE_CLASS := $(framework_docs_LOCAL_MODULE_CLASS)
LOCAL_ADDITIONAL_JAVA_DIR := $(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
@@ -1173,6 +515,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_API_CHECK_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
@@ -1198,7 +541,7 @@
include $(BUILD_DROIDDOC)
# $(gen), i.e. framework.aidl, is also needed while building against the current stub.
-$(full_target): $(framework_built) $(gen)
+$(full_target): $(gen)
$(INTERNAL_PLATFORM_API_FILE): $(full_target)
$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_API_FILE))
@@ -1207,6 +550,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_API_CHECK_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
@@ -1234,7 +578,7 @@
include $(BUILD_DROIDDOC)
# $(gen), i.e. framework.aidl, is also needed while building against the current stub.
-$(full_target): $(framework_built) $(gen)
+$(full_target): $(gen)
$(INTERNAL_PLATFORM_SYSTEM_API_FILE): $(full_target)
$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_API_FILE))
@@ -1243,6 +587,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_API_CHECK_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
@@ -1271,7 +616,7 @@
include $(BUILD_DROIDDOC)
# $(gen), i.e. framework.aidl, is also needed while building against the current stub.
-$(full_target): $(framework_built) $(gen)
+$(full_target): $(gen)
$(INTERNAL_PLATFORM_TEST_API_FILE): $(full_target)
$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_TEST_API_FILE))
@@ -1280,6 +625,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
@@ -1301,7 +647,7 @@
include $(BUILD_DROIDDOC)
# $(gen), i.e. framework.aidl, is also needed while building against the current stub.
-$(full_target): $(framework_built) $(gen)
+$(full_target): $(gen)
# Run this for checkbuild
checkbuild: doc-comment-check-docs
@@ -1313,6 +659,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
@@ -1341,7 +688,6 @@
$(hide) $(ACP) $< $@
$(full_target): $(static_doc_index_redirect)
-$(full_target): $(framework_built)
# ==== Public API static reference docs ==================================
@@ -1349,6 +695,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
@@ -1383,7 +730,6 @@
$(full_target): $(static_doc_index_redirect)
$(full_target): $(static_doc_properties)
-$(full_target): $(framework_built)
# ==== System API static reference docs ==================================
@@ -1391,6 +737,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
@@ -1435,6 +782,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
@@ -1463,6 +811,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
@@ -1498,6 +847,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
@@ -1527,6 +877,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
@@ -1556,6 +907,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
@@ -1581,6 +933,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
@@ -1609,6 +962,7 @@
LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
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)
diff --git a/api/current.txt b/api/current.txt
index 182dd3a..279a6f2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7209,6 +7209,7 @@
}
public final class UsageStatsManager {
+ method public int getAppStandbyBucket();
method public boolean isAppInactive(java.lang.String);
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);
@@ -7219,6 +7220,10 @@
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
+ field public static final int STANDBY_BUCKET_ACTIVE = 10; // 0xa
+ field public static final int STANDBY_BUCKET_FREQUENT = 30; // 0x1e
+ field public static final int STANDBY_BUCKET_RARE = 40; // 0x28
+ field public static final int STANDBY_BUCKET_WORKING_SET = 20; // 0x14
}
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 4cf9d95..50a8ea4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -609,8 +609,11 @@
}
public final class UsageStatsManager {
+ method public int getAppStandbyBucket(java.lang.String);
method public void setAppStandbyBucket(java.lang.String, int);
method public void whitelistAppTemporarily(java.lang.String, long, android.os.UserHandle);
+ field public static final int STANDBY_BUCKET_EXEMPTED = 5; // 0x5
+ field public static final int STANDBY_BUCKET_NEVER = 50; // 0x32
}
}
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 9259793..eb3ea0b 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -731,6 +731,7 @@
*success = true;
return Status::ok();
} else {
+ *success = false;
return Status::fromExceptionCode(binder::Status::EX_SECURITY);
}
}
@@ -740,6 +741,7 @@
if (checkCallingPermission(String16(kPermissionDump))) {
string keyStr = string(String8(key).string());
mConfigManager->RemoveConfig(ConfigKey(ipc->getCallingUid(), keyStr));
+ *success = true;
return Status::ok();
} else {
*success = false;
diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
index 8e96399..e1c02d7 100644
--- a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
+++ b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
@@ -45,10 +45,11 @@
if (statsCompanion != NULL) {
Status status = statsCompanion->pullData(tagId, &returned_value);
if (!status.isOk()) {
- ALOGW("error pulling kernel wakelock");
+ ALOGW("error pulling for %d", tagId);
return false;
}
data->clear();
+ long timestamp = time(nullptr);
for (const StatsLogEventWrapper& it : returned_value) {
log_msg tmp;
tmp.entry_v1.len = it.bytes.size();
@@ -56,9 +57,10 @@
tmp.entry.hdr_size = kLogMsgHeaderSize;
// And set the received bytes starting after the 28 bytes reserved for header.
std::copy(it.bytes.begin(), it.bytes.end(), tmp.buf + kLogMsgHeaderSize);
+ tmp.entry_v1.sec = timestamp;
data->push_back(make_shared<LogEvent>(tmp));
}
- ALOGD("KernelWakelockPuller::pull succeeded!");
+ ALOGD("StatsCompanionServicePuller::pull succeeded for %d", tagId);
return true;
} else {
ALOGW("statsCompanion not found!");
diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
index 3ffcd77..c4688a2 100644
--- a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
+++ b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
@@ -76,7 +76,9 @@
if (DEBUG) ALOGD("Initiating pulling %d", tagId);
if (mPullers.find(tagId) != mPullers.end()) {
- return mPullers.find(tagId)->second->Pull(tagId, data);
+ bool ret = mPullers.find(tagId)->second->Pull(tagId, data);
+ ALOGD("pulled %d items", (int)data->size());
+ return ret;
} else {
ALOGD("Unknown tagId %d", tagId);
return false; // Return early since we don't know what to pull.
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 2284ff1..50cc8d4 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -99,6 +99,9 @@
GaugeMetricProducer::~GaugeMetricProducer() {
VLOG("~GaugeMetricProducer() called");
+ if (mPullTagId != -1) {
+ mStatsPullerManager.UnRegisterReceiver(mPullTagId, this);
+ }
}
void GaugeMetricProducer::startNewProtoOutputStreamLocked(long long startTime) {
diff --git a/cmds/statsd/tools/loadtest/Android.mk b/cmds/statsd/tools/loadtest/Android.mk
new file mode 100644
index 0000000..f3f0a7c
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2017 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.
+#
+#
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SRC_FILES += ../../src/stats_log.proto \
+ ../../src/atoms_copy.proto \
+ ../../src/statsd_config.proto
+
+LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/../../src/
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := lite-static
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := StatsdLoadtest
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_DEX_PREOPT := false
+include $(BUILD_PACKAGE)
diff --git a/cmds/statsd/tools/loadtest/AndroidManifest.xml b/cmds/statsd/tools/loadtest/AndroidManifest.xml
new file mode 100644
index 0000000..d74c707
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2007, 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.
+*/
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.statsd.loadtest"
+ android:sharedUserId="android.uid.system"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-permission android:name="android.permission.DUMP" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <activity
+ android:name=".LoadtestActivity"
+ android:label="@string/app_name"
+ android:launchMode="singleTop" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <receiver android:name=".LoadtestActivity$PusherAlarmReceiver" />
+ <receiver android:name=".LoadtestActivity$StopperAlarmReceiver"/>
+ </application>
+</manifest>
diff --git a/cmds/statsd/tools/loadtest/res/drawable-hdpi/ic_launcher.png b/cmds/statsd/tools/loadtest/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..55621cc
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/cmds/statsd/tools/loadtest/res/drawable-mdpi/ic_launcher.png b/cmds/statsd/tools/loadtest/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..11ec206
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/cmds/statsd/tools/loadtest/res/drawable-xhdpi/ic_launcher.png b/cmds/statsd/tools/loadtest/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..7c02b78
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/cmds/statsd/tools/loadtest/res/drawable-xxhdpi/ic_launcher.png b/cmds/statsd/tools/loadtest/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..915d914
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml b/cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml
new file mode 100644
index 0000000..82964ab
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2007, 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.
+*/
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:id="@+id/outside"
+ android:clickable="true"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginRight="10dp"
+ android:layout_marginLeft="10dp"
+ android:orientation="vertical">
+ <requestFocus />
+
+ <LinearLayout
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+ <TextView
+ android:textSize="30dp"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/replication_label" />
+ <EditText
+ android:id="@+id/replication"
+ android:inputType="number"
+ android:layout_weight="1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLength="3"
+ android:text="@integer/replication_default"
+ android:textSize="30dp"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+ <TextView
+ android:textSize="30dp"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/bucket_label" />
+ <EditText
+ android:id="@+id/bucket"
+ android:inputType="number"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:maxLength="3"
+ android:text="@integer/bucket_default"
+ android:textSize="30dp"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+ <TextView
+ android:textSize="30dp"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/period_label" />
+ <EditText
+ android:id="@+id/period"
+ android:inputType="number"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:maxLength="3"
+ android:text="@integer/period_default"
+ android:textSize="30dp"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+ <TextView
+ android:textSize="30dp"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/burst_label" />
+ <EditText
+ android:id="@+id/burst"
+ android:inputType="number"
+ android:layout_weight="1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLength="2"
+ android:text="@integer/burst_default"
+ android:textSize="30dp"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+ <TextView
+ android:textSize="30dp"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/duration_label" />
+ <EditText
+ android:id="@+id/duration"
+ android:inputType="number"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:maxLength="4"
+ android:text="@integer/duration_default"
+ android:textSize="30dp"/>
+ </LinearLayout>
+ <CheckBox
+ android:id="@+id/placebo"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/placebo"
+ android:checked="false" />
+
+ <Space
+ android:layout_width="1dp"
+ android:layout_height="30dp"/>
+
+ <Button
+ android:id="@+id/start_stop"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="#ffff0000"
+ android:text="@string/start"
+ android:textSize="50dp"/>
+
+ <Space
+ android:layout_width="1dp"
+ android:layout_height="30dp"/>
+
+ <Button
+ android:id="@+id/display_output"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/display_output"
+ android:textSize="30dp"/>
+ <Button
+ android:id="@+id/display_perf"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/display_perf"
+ android:textSize="30dp"/>
+
+ <Space
+ android:layout_width="1dp"
+ android:layout_height="30dp"/>
+
+ <TextView
+ android:id="@+id/report_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
+
+</ScrollView>
diff --git a/cmds/statsd/tools/loadtest/res/raw/loadtest_config b/cmds/statsd/tools/loadtest/res/raw/loadtest_config
new file mode 100755
index 0000000..7822367
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/res/raw/loadtest_config
Binary files differ
diff --git a/cmds/statsd/tools/loadtest/res/values/integers.xml b/cmds/statsd/tools/loadtest/res/values/integers.xml
new file mode 100644
index 0000000..76b5692
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/res/values/integers.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2007, 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.
+*/
+-->
+<resources>
+ <integer name="bucket_default">10</integer>
+ <integer name="burst_default">1</integer>
+ <integer name="period_default">2</integer>
+ <integer name="replication_default">1</integer>
+ <integer name="duration_default">240</integer>
+</resources>
diff --git a/cmds/statsd/tools/loadtest/res/values/strings.xml b/cmds/statsd/tools/loadtest/res/values/strings.xml
new file mode 100644
index 0000000..9913503
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/res/values/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2007, 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.
+*/
+-->
+<resources>
+ <string name="app_name">Statsd Loadtest</string>
+ <string name="bucket_label">bucket size (mins): </string>
+ <string name="burst_label">burst: </string>
+ <string name="display_output">Show metrics data</string>
+ <string name="display_perf">Show perf data</string>
+ <string name="placebo">placebo</string>
+ <string name="period_label">logging period (secs): </string>
+ <string name="replication_label">metric replication: </string>
+ <string name="duration_label">test duration (mins): </string>
+ <string name="start">  Start  </string>
+ <string name="stop">  Stop  </string>
+
+</resources>
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryStatsParser.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryStatsParser.java
new file mode 100644
index 0000000..96e6bef
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryStatsParser.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 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.statsd.loadtest;
+
+import android.annotation.Nullable;
+import android.util.Log;
+import java.text.ParseException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class BatteryStatsParser {
+
+ private static final Pattern LINE_PATTERN =
+ Pattern.compile("\\s*\\+*(\\S*)\\s\\(\\d+\\)\\s(\\d\\d\\d)\\s.*");
+ private static final Pattern TIME_PATTERN =
+ Pattern.compile("(\\d+)?(h)?(\\d+)?(m)?(\\d+)?(s)?(\\d+)?(ms)?");
+ private static final String TAG = "BatteryStatsParser";
+
+ private boolean mHistoryStarted;
+ private boolean mHistoryEnded;
+
+ public BatteryStatsParser() {
+ }
+
+ @Nullable
+ public String parseLine(String line) {
+ if (mHistoryEnded) {
+ return null;
+ }
+ if (!mHistoryStarted) {
+ if (line.contains("Battery History")) {
+ mHistoryStarted = true;
+ }
+ return null;
+ }
+ if (line.isEmpty()) {
+ mHistoryEnded = true;
+ return null;
+ }
+ Matcher lineMatcher = LINE_PATTERN.matcher(line);
+ if (lineMatcher.find() && lineMatcher.group(1) != null && lineMatcher.group(2) != null) {
+ if (lineMatcher.group(1).equals("0")) {
+ return "0," + lineMatcher.group(2) + "\n";
+ } else {
+ Matcher timeMatcher = TIME_PATTERN.matcher(lineMatcher.group(1));
+ if (timeMatcher.find()) {
+ Long time = getTime(lineMatcher.group(1));
+ if (time != null) {
+ return time + "," + lineMatcher.group(2) + "\n";
+ } else {
+ return null; // bad time
+ }
+ } else {
+ return null; // bad or no time
+ }
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private Long getTime(String group) {
+ if ("0".equals(group)) {
+ return 0L;
+ }
+ Matcher timeMatcher = TIME_PATTERN.matcher(group);
+ if (!timeMatcher.find()) {
+ return null;
+ }
+
+ // Get rid of "ms".
+ String[] matches = group.split("ms", -1);
+ if (matches.length > 1) {
+ group = matches[0];
+ }
+
+ long time = 0L;
+ matches = group.split("h");
+ if (matches.length > 1) {
+ time += Long.parseLong(matches[0]) * 60 * 60 * 1000; // hours
+ group = matches[1];
+ }
+ matches = group.split("m");
+ if (matches.length > 1) {
+ time += Long.parseLong(matches[0]) * 60 * 1000; // minutes
+ group = matches[1];
+ }
+ matches = group.split("s");
+ if (matches.length > 1) {
+ time += Long.parseLong(matches[0]) * 1000; // seconds
+ group = matches[1];
+ }
+
+ if (!group.isEmpty()) {
+ time += Long.parseLong(group); // milliseconds
+ }
+ return time;
+ }
+}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ConfigFactory.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ConfigFactory.java
new file mode 100644
index 0000000..7ecc124
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ConfigFactory.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2017 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.statsd.loadtest;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+import android.util.StatsLog;
+
+import com.android.internal.os.StatsdConfigProto.Bucket;
+import com.android.internal.os.StatsdConfigProto.Condition;
+import com.android.internal.os.StatsdConfigProto.CountMetric;
+import com.android.internal.os.StatsdConfigProto.DurationMetric;
+import com.android.internal.os.StatsdConfigProto.EventConditionLink;
+import com.android.internal.os.StatsdConfigProto.EventMetric;
+import com.android.internal.os.StatsdConfigProto.GaugeMetric;
+import com.android.internal.os.StatsdConfigProto.ValueMetric;
+import com.android.internal.os.StatsdConfigProto.KeyMatcher;
+import com.android.internal.os.StatsdConfigProto.KeyValueMatcher;
+import com.android.internal.os.StatsdConfigProto.LogEntryMatcher;
+import com.android.internal.os.StatsdConfigProto.SimpleCondition;
+import com.android.internal.os.StatsdConfigProto.SimpleLogEntryMatcher;
+import com.android.internal.os.StatsdConfigProto.StatsdConfig;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Creates StatsdConfig protos for loadtesting.
+ */
+public class ConfigFactory {
+ public static final String CONFIG_NAME = "LOADTEST";
+
+ private static final String TAG = "ConfigFactory";
+
+ private final StatsdConfig mTemplate;
+
+ public ConfigFactory(Context context) {
+ // Read the config template from the resoures.
+ Resources res = context.getResources();
+ byte[] template = null;
+ StatsdConfig templateProto = null;
+ try {
+ InputStream inputStream = res.openRawResource(R.raw.loadtest_config);
+ template = new byte[inputStream.available()];
+ inputStream.read(template);
+ templateProto = StatsdConfig.parseFrom(template);
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to read or parse loadtest config template. Using an empty config.");
+ }
+ mTemplate = templateProto == null ? StatsdConfig.newBuilder().build() : templateProto;
+
+ Log.d(TAG, "Loadtest template config: " + mTemplate);
+ }
+
+ /**
+ * Generates a config.
+ *
+ * All configs are based on the same template.
+ * That template is designed to make the most use of the set of atoms that {@code SequencePusher}
+ * pushes, and to exercise as many of the metrics features as possible.
+ * Furthermore, by passing a replication factor to this method, one can artificially inflate
+ * the number of metrics in the config. One can also adjust the bucket size for aggregate
+ * metrics.
+ *
+ * @param replication The number of times each metric is replicated in the config.
+ * If the config template has n metrics, the generated config will have n * replication
+ * ones
+ * @param bucketMillis The bucket size, in milliseconds, for aggregate metrics
+ * @param placebo If true, only return an empty config
+ * @return The serialized config
+ */
+ public byte[] getConfig(int replication, long bucketMillis, boolean placebo) {
+ StatsdConfig.Builder config = StatsdConfig.newBuilder()
+ .setName(CONFIG_NAME);
+ if (placebo) {
+ replication = 0; // Config will be empty, aside from a name.
+ }
+ int numMetrics = 0;
+ for (int i = 0; i < replication; i++) {
+ // metrics
+ for (EventMetric metric : mTemplate.getEventMetricList()) {
+ addEventMetric(metric, i, config);
+ numMetrics++;
+ }
+ for (CountMetric metric : mTemplate.getCountMetricList()) {
+ addCountMetric(metric, i, bucketMillis, config);
+ numMetrics++;
+ }
+ for (DurationMetric metric : mTemplate.getDurationMetricList()) {
+ addDurationMetric(metric, i, bucketMillis, config);
+ numMetrics++;
+ }
+ for (GaugeMetric metric : mTemplate.getGaugeMetricList()) {
+ addGaugeMetric(metric, i, bucketMillis, config);
+ numMetrics++;
+ }
+ for (ValueMetric metric : mTemplate.getValueMetricList()) {
+ addValueMetric(metric, i, bucketMillis, config);
+ numMetrics++;
+ }
+ // conditions
+ for (Condition condition : mTemplate.getConditionList()) {
+ addCondition(condition, i, config);
+ }
+ // matchers
+ for (LogEntryMatcher matcher : mTemplate.getLogEntryMatcherList()) {
+ addMatcher(matcher, i, config);
+ }
+ }
+
+ Log.d(TAG, "Loadtest config is : " + config.build());
+ Log.d(TAG, "Generated config has " + numMetrics + " metrics");
+
+ return config.build().toByteArray();
+ }
+
+ /**
+ * Creates {@link EventConditionLink}s that are identical to the one passed to this method,
+ * except that the names are appended with the provided suffix.
+ */
+ private List<EventConditionLink> getLinks(
+ List<EventConditionLink> links, int suffix) {
+ List<EventConditionLink> newLinks = new ArrayList();
+ for (EventConditionLink link : links) {
+ newLinks.add(link.toBuilder()
+ .setCondition(link.getCondition() + suffix)
+ .build());
+ }
+ return newLinks;
+ }
+
+ /**
+ * Creates an {@link EventMetric} based on the template. Makes sure that all names are appended
+ * with the provided suffix. Then adds that metric to the config.
+ */
+ private void addEventMetric(EventMetric template, int suffix, StatsdConfig.Builder config) {
+ EventMetric.Builder metric = template.toBuilder()
+ .setName(template.getName() + suffix)
+ .setWhat(template.getWhat() + suffix);
+ if (template.hasCondition()) {
+ metric.setCondition(template.getCondition() + suffix);
+ }
+ if (template.getLinksCount() > 0) {
+ List<EventConditionLink> links = getLinks(template.getLinksList(), suffix);
+ metric.clearLinks();
+ metric.addAllLinks(links);
+ }
+ config.addEventMetric(metric);
+ }
+
+ private Bucket getBucket(long bucketMillis) {
+ return Bucket.newBuilder()
+ .setBucketSizeMillis(bucketMillis)
+ .build();
+ }
+
+ /**
+ * Creates a {@link CountMetric} based on the template. Makes sure that all names are appended
+ * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
+ */
+ private void addCountMetric(CountMetric template, int suffix, long bucketMillis,
+ StatsdConfig.Builder config) {
+ CountMetric.Builder metric = template.toBuilder()
+ .setName(template.getName() + suffix)
+ .setWhat(template.getWhat() + suffix);
+ if (template.hasCondition()) {
+ metric.setCondition(template.getCondition() + suffix);
+ }
+ if (template.getLinksCount() > 0) {
+ List<EventConditionLink> links = getLinks(template.getLinksList(), suffix);
+ metric.clearLinks();
+ metric.addAllLinks(links);
+ }
+ metric.setBucket(getBucket(bucketMillis));
+ config.addCountMetric(metric);
+ }
+
+ /**
+ * Creates a {@link DurationMetric} based on the template. Makes sure that all names are appended
+ * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
+ */
+ private void addDurationMetric(DurationMetric template, int suffix, long bucketMillis,
+ StatsdConfig.Builder config) {
+ DurationMetric.Builder metric = template.toBuilder()
+ .setName(template.getName() + suffix)
+ .setWhat(template.getWhat() + suffix);
+ if (template.hasCondition()) {
+ metric.setCondition(template.getCondition() + suffix);
+ }
+ if (template.getLinksCount() > 0) {
+ List<EventConditionLink> links = getLinks(template.getLinksList(), suffix);
+ metric.clearLinks();
+ metric.addAllLinks(links);
+ }
+ metric.setBucket(getBucket(bucketMillis));
+ config.addDurationMetric(metric);
+ }
+
+ /**
+ * Creates a {@link GaugeMetric} based on the template. Makes sure that all names are appended
+ * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
+ */
+ private void addGaugeMetric(GaugeMetric template, int suffix, long bucketMillis,
+ StatsdConfig.Builder config) {
+ GaugeMetric.Builder metric = template.toBuilder()
+ .setName(template.getName() + suffix)
+ .setWhat(template.getWhat() + suffix);
+ if (template.hasCondition()) {
+ metric.setCondition(template.getCondition() + suffix);
+ }
+ if (template.getLinksCount() > 0) {
+ List<EventConditionLink> links = getLinks(template.getLinksList(), suffix);
+ metric.clearLinks();
+ metric.addAllLinks(links);
+ }
+ metric.setBucket(getBucket(bucketMillis));
+ config.addGaugeMetric(metric);
+ }
+
+ /**
+ * Creates a {@link ValueMetric} based on the template. Makes sure that all names are appended
+ * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
+ */
+ private void addValueMetric(ValueMetric template, int suffix, long bucketMillis,
+ StatsdConfig.Builder config) {
+ ValueMetric.Builder metric = template.toBuilder()
+ .setName(template.getName() + suffix)
+ .setWhat(template.getWhat() + suffix);
+ if (template.hasCondition()) {
+ metric.setCondition(template.getCondition() + suffix);
+ }
+ if (template.getLinksCount() > 0) {
+ List<EventConditionLink> links = getLinks(template.getLinksList(), suffix);
+ metric.clearLinks();
+ metric.addAllLinks(links);
+ }
+ metric.setBucket(getBucket(bucketMillis));
+ config.addValueMetric(metric);
+ }
+
+ /**
+ * Creates a {@link Condition} based on the template. Makes sure that all names
+ * are appended with the provided suffix. Then adds that condition to the config.
+ */
+ private void addCondition(Condition template, int suffix, StatsdConfig.Builder config) {
+ Condition.Builder condition = template.toBuilder()
+ .setName(template.getName() + suffix);
+ if (template.hasCombination()) {
+ Condition.Combination.Builder cb = template.getCombination().toBuilder()
+ .clearCondition();
+ for (String child : template.getCombination().getConditionList()) {
+ cb.addCondition(child + suffix);
+ }
+ condition.setCombination(cb.build());
+ }
+ if (template.hasSimpleCondition()) {
+ SimpleCondition.Builder sc = template.getSimpleCondition().toBuilder()
+ .setStart(template.getSimpleCondition().getStart() + suffix)
+ .setStop(template.getSimpleCondition().getStop() + suffix);
+ if (template.getSimpleCondition().hasStopAll()) {
+ sc.setStopAll(template.getSimpleCondition().getStopAll() + suffix);
+ }
+ condition.setSimpleCondition(sc.build());
+ }
+ config.addCondition(condition);
+ }
+
+ /**
+ * Creates a {@link LogEntryMatcher} based on the template. Makes sure that all names
+ * are appended with the provided suffix. Then adds that matcher to the config.
+ */
+ private void addMatcher(LogEntryMatcher template, int suffix, StatsdConfig.Builder config) {
+ LogEntryMatcher.Builder matcher = template.toBuilder()
+ .setName(template.getName() + suffix);
+ if (template.hasCombination()) {
+ LogEntryMatcher.Combination.Builder cb = template.getCombination().toBuilder()
+ .clearMatcher();
+ for (String child : template.getCombination().getMatcherList()) {
+ cb.addMatcher(child + suffix);
+ }
+ matcher.setCombination(cb);
+ }
+ config.addLogEntryMatcher(matcher);
+ }
+}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java
new file mode 100644
index 0000000..5e8f26d
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2017 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.statsd.loadtest;
+
+import android.text.format.DateFormat;
+
+import com.android.os.StatsLog;
+
+import java.util.List;
+
+public class DisplayProtoUtils {
+ public static void displayLogReport(StringBuilder sb, StatsLog.ConfigMetricsReportList reports) {
+ sb.append("ConfigKey: ");
+ if (reports.hasConfigKey()) {
+ com.android.os.StatsLog.ConfigMetricsReportList.ConfigKey key = reports.getConfigKey();
+ sb.append("\tuid: ").append(key.getUid()).append(" name: ").append(key.getName())
+ .append("\n");
+ }
+
+ for (StatsLog.ConfigMetricsReport report : reports.getReportsList()) {
+ sb.append("StatsLogReport size: ").append(report.getMetricsCount()).append("\n");
+ for (StatsLog.StatsLogReport log : report.getMetricsList()) {
+ sb.append("\n\n");
+ sb.append("metric id: ").append(log.getMetricName()).append("\n");
+ sb.append("start time:").append(getDateStr(log.getStartReportNanos())).append("\n");
+ sb.append("end time:").append(getDateStr(log.getEndReportNanos())).append("\n");
+
+ switch (log.getDataCase()) {
+ case DURATION_METRICS:
+ sb.append("Duration metric data\n");
+ displayDurationMetricData(sb, log);
+ break;
+ case EVENT_METRICS:
+ sb.append("Event metric data\n");
+ displayEventMetricData(sb, log);
+ break;
+ case COUNT_METRICS:
+ sb.append("Count metric data\n");
+ displayCountMetricData(sb, log);
+ break;
+ case GAUGE_METRICS:
+ sb.append("Gauge metric data\n");
+ displayGaugeMetricData(sb, log);
+ break;
+ case VALUE_METRICS:
+ sb.append("Value metric data\n");
+ displayValueMetricData(sb, log);
+ break;
+ case DATA_NOT_SET:
+ sb.append("No metric data\n");
+ break;
+ }
+ }
+ }
+ }
+
+ public static String getDateStr(long nanoSec) {
+ return DateFormat.format("dd/MM hh:mm:ss", nanoSec/1000000).toString();
+ }
+
+ private static void displayDimension(StringBuilder sb, List<StatsLog.KeyValuePair> pairs) {
+ for (com.android.os.StatsLog.KeyValuePair kv : pairs) {
+ sb.append(kv.getKey()).append(":");
+ if (kv.hasValueBool()) {
+ sb.append(kv.getValueBool());
+ } else if (kv.hasValueFloat()) {
+ sb.append(kv.getValueFloat());
+ } else if (kv.hasValueInt()) {
+ sb.append(kv.getValueInt());
+ } else if (kv.hasValueStr()) {
+ sb.append(kv.getValueStr());
+ }
+ sb.append(" ");
+ }
+ }
+
+ public static void displayDurationMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
+ StatsLog.StatsLogReport.DurationMetricDataWrapper durationMetricDataWrapper
+ = log.getDurationMetrics();
+ sb.append("Dimension size: ").append(durationMetricDataWrapper.getDataCount()).append("\n");
+ for (StatsLog.DurationMetricData duration : durationMetricDataWrapper.getDataList()) {
+ sb.append("dimension: ");
+ displayDimension(sb, duration.getDimensionList());
+ sb.append("\n");
+
+ for (StatsLog.DurationBucketInfo info : duration.getBucketInfoList()) {
+ sb.append("\t[").append(getDateStr(info.getStartBucketNanos())).append("-")
+ .append(getDateStr(info.getEndBucketNanos())).append("] -> ")
+ .append(info.getDurationNanos()).append(" ns\n");
+ }
+ }
+ }
+
+ public static void displayEventMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
+ sb.append("Contains ").append(log.getEventMetrics().getDataCount()).append(" events\n");
+ StatsLog.StatsLogReport.EventMetricDataWrapper eventMetricDataWrapper =
+ log.getEventMetrics();
+ for (StatsLog.EventMetricData event : eventMetricDataWrapper.getDataList()) {
+ sb.append(getDateStr(event.getTimestampNanos())).append(": ");
+ switch (event.getAtom().getPushedCase()) {
+ case SETTING_CHANGED:
+ sb.append("SETTING_CHANGED\n");
+ break;
+ case SYNC_STATE_CHANGED:
+ sb.append("SYNC_STATE_CHANGED\n");
+ break;
+ case AUDIO_STATE_CHANGED:
+ sb.append("AUDIO_STATE_CHANGED\n");
+ break;
+ case CAMERA_STATE_CHANGED:
+ sb.append("CAMERA_STATE_CHANGED\n");
+ break;
+ case ISOLATED_UID_CHANGED:
+ sb.append("ISOLATED_UID_CHANGED\n");
+ break;
+ case SCREEN_STATE_CHANGED:
+ sb.append("SCREEN_STATE_CHANGED\n");
+ break;
+ case SENSOR_STATE_CHANGED:
+ sb.append("SENSOR_STATE_CHANGED\n");
+ break;
+ case BATTERY_LEVEL_CHANGED:
+ sb.append("BATTERY_LEVEL_CHANGED\n");
+ break;
+ case PLUGGED_STATE_CHANGED:
+ sb.append("PLUGGED_STATE_CHANGED\n");
+ break;
+ case WAKEUP_ALARM_OCCURRED:
+ sb.append("WAKEUP_ALARM_OCCURRED\n");
+ break;
+ case BLE_SCAN_STATE_CHANGED:
+ sb.append("BLE_SCAN_STATE_CHANGED\n");
+ break;
+ case CHARGING_STATE_CHANGED:
+ sb.append("CHARGING_STATE_CHANGED\n");
+ break;
+ case GPS_SCAN_STATE_CHANGED:
+ sb.append("GPS_SCAN_STATE_CHANGED\n");
+ break;
+ case KERNEL_WAKEUP_REPORTED:
+ sb.append("KERNEL_WAKEUP_REPORTED\n");
+ break;
+ case WAKELOCK_STATE_CHANGED:
+ sb.append("WAKELOCK_STATE_CHANGED\n");
+ break;
+ case WIFI_LOCK_STATE_CHANGED:
+ sb.append("WIFI_LOCK_STATE_CHANGED\n");
+ break;
+ case WIFI_SCAN_STATE_CHANGED:
+ sb.append("WIFI_SCAN_STATE_CHANGED\n");
+ break;
+ case BLE_SCAN_RESULT_RECEIVED:
+ sb.append("BLE_SCAN_RESULT_RECEIVED\n");
+ break;
+ case DEVICE_ON_STATUS_CHANGED:
+ sb.append("DEVICE_ON_STATUS_CHANGED\n");
+ break;
+ case FLASHLIGHT_STATE_CHANGED:
+ sb.append("FLASHLIGHT_STATE_CHANGED\n");
+ break;
+ case SCREEN_BRIGHTNESS_CHANGED:
+ sb.append("SCREEN_BRIGHTNESS_CHANGED\n");
+ break;
+ case UID_PROCESS_STATE_CHANGED:
+ sb.append("UID_PROCESS_STATE_CHANGED\n");
+ break;
+ case UID_WAKELOCK_STATE_CHANGED:
+ sb.append("UID_WAKELOCK_STATE_CHANGED\n");
+ break;
+ case DEVICE_TEMPERATURE_REPORTED:
+ sb.append("DEVICE_TEMPERATURE_REPORTED\n");
+ break;
+ case SCHEDULED_JOB_STATE_CHANGED:
+ sb.append("SCHEDULED_JOB_STATE_CHANGED\n");
+ break;
+ case MEDIA_CODEC_ACTIVITY_CHANGED:
+ sb.append("MEDIA_CODEC_ACTIVITY_CHANGED\n");
+ break;
+ case WIFI_SIGNAL_STRENGTH_CHANGED:
+ sb.append("WIFI_SIGNAL_STRENGTH_CHANGED\n");
+ break;
+ case PHONE_SIGNAL_STRENGTH_CHANGED:
+ sb.append("PHONE_SIGNAL_STRENGTH_CHANGED\n");
+ break;
+ case DEVICE_IDLE_MODE_STATE_CHANGED:
+ sb.append("DEVICE_IDLE_MODE_STATE_CHANGED\n");
+ break;
+ case BATTERY_SAVER_MODE_STATE_CHANGED:
+ sb.append("BATTERY_SAVER_MODE_STATE_CHANGED\n");
+ break;
+ case PROCESS_LIFE_CYCLE_STATE_CHANGED:
+ sb.append("PROCESS_LIFE_CYCLE_STATE_CHANGED\n");
+ break;
+ case ACTIVITY_FOREGROUND_STATE_CHANGED:
+ sb.append("ACTIVITY_FOREGROUND_STATE_CHANGED\n");
+ break;
+ case BLE_UNOPTIMIZED_SCAN_STATE_CHANGED:
+ sb.append("BLE_UNOPTIMIZED_SCAN_STATE_CHANGED\n");
+ break;
+ case LONG_PARTIAL_WAKELOCK_STATE_CHANGED:
+ sb.append("LONG_PARTIAL_WAKELOCK_STATE_CHANGED\n");
+ break;
+ case PUSHED_NOT_SET:
+ sb.append("PUSHED_NOT_SET\n");
+ break;
+ }
+ }
+ }
+
+ public static void displayCountMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
+ StatsLog.StatsLogReport.CountMetricDataWrapper countMetricDataWrapper
+ = log.getCountMetrics();
+ sb.append("Dimension size: ").append(countMetricDataWrapper.getDataCount()).append("\n");
+ for (StatsLog.CountMetricData count : countMetricDataWrapper.getDataList()) {
+ sb.append("dimension: ");
+ displayDimension(sb, count.getDimensionList());
+ sb.append("\n");
+
+ for (StatsLog.CountBucketInfo info : count.getBucketInfoList()) {
+ sb.append("\t[").append(getDateStr(info.getStartBucketNanos())).append("-")
+ .append(getDateStr(info.getEndBucketNanos())).append("] -> ")
+ .append(info.getCount()).append("\n");
+ }
+ }
+ }
+
+ public static void displayGaugeMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
+ sb.append("Display me!");
+ }
+
+ public static void displayValueMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
+ sb.append("Display me!");
+ }
+}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java
new file mode 100644
index 0000000..3ae85a7
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2017 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.statsd.loadtest;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IStatsManager;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.util.StatsLog;
+import android.util.StatsManager;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.view.MotionEvent;
+import android.view.View.OnFocusChangeListener;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * Runs a load test for statsd.
+ * How it works:
+ * <ul>
+ * <li> Sets up and pushes a custom config with metrics that exercise a large swath of code paths.
+ * <li> Periodically logs certain atoms into logd.
+ * <li> Impact on battery can be printed to logcat, or a bug report can be filed and analyzed
+ * in battery Historian.
+ * </ul>
+ * The load depends on how demanding the config is, as well as how frequently atoms are pushsed
+ * to logd. Those are all controlled by 4 adjustable parameters:
+ * <ul>
+ * <li> The 'replication' parameter artificially multiplies the number of metrics in the config.
+ * <li> The bucket size controls the time-bucketing the aggregate metrics.
+ * <li> The period parameter controls how frequently atoms are pushed to logd.
+ * <li> The 'burst' parameter controls how many atoms are pushed at the same time (per period).
+ * </ul>
+ */
+public class LoadtestActivity extends Activity {
+
+ private static final String TAG = "StatsdLoadtest";
+ private static final String TYPE = "type";
+ private static final String ALARM = "push_alarm";
+ private static final String START = "start";
+ private static final String STOP = "stop";
+
+ public final static class PusherAlarmReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Intent activityIntent = new Intent(context, LoadtestActivity.class);
+ activityIntent.putExtra(TYPE, ALARM);
+ context.startActivity(activityIntent);
+ }
+ }
+
+ public final static class StopperAlarmReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Intent activityIntent = new Intent(context, LoadtestActivity.class);
+ activityIntent.putExtra(TYPE, STOP);
+ context.startActivity(activityIntent);
+ }
+ }
+
+ private AlarmManager mAlarmMgr;
+
+ /** Used to periodically log atoms to logd. */
+ private PendingIntent mPushPendingIntent;
+
+ /** Used to end the loadtest. */
+ private PendingIntent mStopPendingIntent;
+
+ private Button mStartStop;
+ private EditText mReplicationText;
+ private EditText mBucketText;
+ private EditText mPeriodText;
+ private EditText mBurstText;
+ private EditText mDurationText;
+ private TextView mReportText;
+ private CheckBox mPlaceboCheckBox;
+
+ /** For measuring perf data. */
+ private PerfData mPerfData;
+
+ /** For communicating with statsd. */
+ private StatsManager mStatsManager;
+
+ private PowerManager mPowerManager;
+ private WakeLock mWakeLock;
+
+ /**
+ * If true, we only measure the effect of the loadtest infrastructure. No atom are pushed and
+ * the configuration is empty.
+ */
+ private boolean mPlacebo;
+
+ /** The burst size. */
+ private int mBurst;
+
+ /** The metrics replication. */
+ private int mReplication;
+
+ /** The period, in seconds, at which batches of atoms are pushed. */
+ private long mPeriodSecs;
+
+ /** The bucket size, in minutes, for aggregate metrics. */
+ private long mBucketMins;
+
+ /** The duration, in minutes, of the loadtest. */
+ private long mDurationMins;
+
+ /** Whether the loadtest has started. */
+ private boolean mStarted = false;
+
+ /** Orchestrates the logging of pushed events into logd. */
+ private SequencePusher mPusher;
+
+ /** Generates statsd configs. */
+ private ConfigFactory mFactory;
+
+ /** For intra-minute periods. */
+ private final Handler mHandler = new Handler();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Log.d(TAG, "Starting loadtest");
+
+ setContentView(R.layout.activity_loadtest);
+ mReportText = (TextView) findViewById(R.id.report_text);
+ initBurst();
+ initReplication();
+ initBucket();
+ initPeriod();
+ initDuration();
+ initPlacebo();
+
+ // Hide the keyboard outside edit texts.
+ findViewById(R.id.outside).setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ InputMethodManager imm =
+ (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (getCurrentFocus() != null) {
+ imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
+ }
+ return true;
+ }
+ });
+
+ mStartStop = findViewById(R.id.start_stop);
+ mStartStop.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mStarted) {
+ stopLoadtest(true);
+ } else {
+ startLoadtest();
+ }
+ }
+ });
+
+ findViewById(R.id.display_output).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ fetchAndDisplayData();
+ }
+ });
+
+ findViewById(R.id.display_perf).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mPerfData.publishData(LoadtestActivity.this, mPlacebo, mReplication, mBucketMins,
+ mPeriodSecs, mBurst);
+ }
+ });
+
+ mAlarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+ mStatsManager = (StatsManager) getSystemService("stats");
+ mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+ mFactory = new ConfigFactory(this);
+ mPerfData = new PerfData();
+ stopLoadtest(false);
+ mReportText.setText("");
+ }
+
+ @Override
+ public void onNewIntent(Intent intent) {
+ String type = intent.getStringExtra(TYPE);
+ if (type == null) {
+ return;
+ }
+ switch (type) {
+ case ALARM:
+ onAlarm(intent);
+ break;
+ case START:
+ startLoadtest();
+ break;
+ case STOP:
+ stopLoadtest(true);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown type: " + type);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.d(TAG, "Destroying");
+ stopLoadtest(false);
+ clearConfigs();
+ super.onDestroy();
+ }
+
+ private void onAlarm(Intent intent) {
+ Log.d(TAG, "ON ALARM");
+
+ // Set the next task.
+ scheduleNext();
+
+ // Do the work.
+ mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "StatsdLoadTest");
+ mWakeLock.acquire();
+ if (mPusher != null) {
+ mPusher.next();
+ }
+ mWakeLock.release();
+ mWakeLock = null;
+ }
+
+ /** Schedules the next cycle of pushing atoms into logd. */
+ private void scheduleNext() {
+ Intent intent = new Intent(this, PusherAlarmReceiver.class);
+ intent.putExtra(TYPE, ALARM);
+ mPushPendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
+ long nextTime = SystemClock.elapsedRealtime() + mPeriodSecs * 1000;
+ mAlarmMgr.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextTime, mPushPendingIntent);
+ }
+
+ private synchronized void startLoadtest() {
+ if (mStarted) {
+ return;
+ }
+
+ // Clean up the state.
+ stopLoadtest(false);
+
+ // Prepare to push a sequence of atoms to logd.
+ mPusher = new SequencePusher(mBurst, mPlacebo);
+
+ // Create a config and push it to statsd.
+ if (!setConfig(mFactory.getConfig(mReplication, mBucketMins * 60 * 1000, mPlacebo))) {
+ return;
+ }
+
+ // Remember to stop in the future.
+ Intent intent = new Intent(this, StopperAlarmReceiver.class);
+ intent.putExtra(TYPE, STOP);
+ mStopPendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
+ long nextTime = SystemClock.elapsedRealtime() + mDurationMins * 60 * 1000;
+ mAlarmMgr.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextTime, mStopPendingIntent);
+
+ // Log atoms.
+ scheduleNext();
+
+ // Reset battery data.
+ mPerfData.resetData(this);
+
+ mReportText.setText("");
+
+ updateStarted(true);
+ }
+
+ private synchronized void stopLoadtest(boolean publishPerfData) {
+ if (mPushPendingIntent != null) {
+ Log.d(TAG, "Canceling pre-existing push alarm");
+ mAlarmMgr.cancel(mPushPendingIntent);
+ mPushPendingIntent = null;
+ }
+ if (mStopPendingIntent != null) {
+ Log.d(TAG, "Canceling pre-existing stop alarm");
+ mAlarmMgr.cancel(mStopPendingIntent);
+ mStopPendingIntent = null;
+ }
+ if (mWakeLock != null) {
+ mWakeLock.release();
+ mWakeLock = null;
+ }
+ fetchAndDisplayData();
+ clearConfigs();
+ updateStarted(false);
+ if (publishPerfData) {
+ mPerfData.publishData(this, mPlacebo, mReplication, mBucketMins, mPeriodSecs, mBurst);
+ }
+ }
+
+ private synchronized void updateStarted(boolean started) {
+ mStarted = started;
+ mStartStop.setBackgroundColor(started ?
+ Color.parseColor("#FFFF0000") : Color.parseColor("#FF00FF00"));
+ mStartStop.setText(started ? getString(R.string.stop) : getString(R.string.start));
+ updateControlsEnabled();
+ }
+
+ private void updateControlsEnabled() {
+ mBurstText.setEnabled(!mPlacebo && !mStarted);
+ mReplicationText.setEnabled(!mPlacebo && !mStarted);
+ mPeriodText.setEnabled(!mStarted);
+ mBucketText.setEnabled(!mPlacebo && !mStarted);
+ mDurationText.setEnabled(!mStarted);
+ mPlaceboCheckBox.setEnabled(!mStarted);
+ }
+
+ private void fetchAndDisplayData() {
+ if (!statsdRunning()) {
+ return;
+ }
+ if (mStatsManager != null) {
+ byte[] data = mStatsManager.getData(ConfigFactory.CONFIG_NAME);
+ if (data != null) {
+ displayData(data);
+ } else {
+ mReportText.setText("Failed to pull data");
+ }
+ }
+ }
+
+ private void displayData(byte[] data) {
+ com.android.os.StatsLog.ConfigMetricsReportList reports = null;
+ boolean good = false;
+ if (data != null) {
+ try {
+ reports = com.android.os.StatsLog.ConfigMetricsReportList.parseFrom(data);
+ good = true;
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ // display it in the text view.
+ }
+ }
+ int size = data == null ? 0 : data.length;
+ StringBuilder sb = new StringBuilder();
+ sb.append(good ? "Proto parsing OK!" : "Proto parsing Error!");
+ sb.append(" size:").append(size).append("\n");
+
+ if (good && reports != null) {
+ DisplayProtoUtils.displayLogReport(sb, reports);
+ mReportText.setText(sb.toString());
+ }
+ }
+
+ private boolean statsdRunning() {
+ if (IStatsManager.Stub.asInterface(ServiceManager.getService("stats")) == null) {
+ Log.d(TAG, "Statsd not running");
+ Toast.makeText(LoadtestActivity.this, "Statsd NOT running!", Toast.LENGTH_LONG).show();
+ return false;
+ }
+ return true;
+ }
+
+ private int sanitizeInt(int val, int min, int max) {
+ if (val > max) {
+ val = max;
+ } else if (val < min) {
+ val = min;
+ }
+ return val;
+ }
+
+ private void clearConfigs() {
+ // TODO: Clear all configs instead of specific ones.
+ if (mStatsManager != null) {
+ if (!mStatsManager.removeConfiguration("fake")) {
+ Log.d(TAG, "Removed \"fake\" statsd configs.");
+ } else {
+ Log.d(TAG, "Failed to remove \"fake\" config. Loadtest results cannot be trusted.");
+ }
+ if (mStarted) {
+ if (!mStatsManager.removeConfiguration(ConfigFactory.CONFIG_NAME)) {
+ Log.d(TAG, "Removed loadtest statsd configs.");
+ } else {
+ Log.d(TAG, "Failed to remove loadtest configs.");
+ }
+ }
+ }
+ }
+
+ private boolean setConfig(byte[] config) {
+ if (mStatsManager != null) {
+ if (mStatsManager.addConfiguration(ConfigFactory.CONFIG_NAME,
+ config, getPackageName(), LoadtestActivity.this.getClass().getName())) {
+ Log.d(TAG, "Config pushed to statsd");
+ return true;
+ } else {
+ Log.d(TAG, "Failed to push config to statsd");
+ }
+ }
+ return false;
+ }
+
+ private synchronized void setReplication(int replication) {
+ mReplication = replication;
+ }
+
+ private synchronized void setPeriodSecs(long periodSecs) {
+ mPeriodSecs = periodSecs;
+ }
+
+ private synchronized void setBucketMins(long bucketMins) {
+ mBucketMins = bucketMins;
+ }
+
+ private synchronized void setBurst(int burst) {
+ mBurst = burst;
+ }
+
+ private synchronized void setDurationMins(long durationMins) {
+ mDurationMins = durationMins;
+ }
+
+ private synchronized void setPlacebo(boolean placebo) {
+ mPlacebo = placebo;
+ updateControlsEnabled();
+ }
+
+ private void handleFocus(EditText editText) {
+ editText.setOnFocusChangeListener(new OnFocusChangeListener() {
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (!hasFocus && editText.getText().toString().isEmpty()) {
+ editText.setText("-1", TextView.BufferType.EDITABLE);
+ }
+ }
+ });
+ }
+
+ private void initBurst() {
+ mBurst = getResources().getInteger(R.integer.burst_default);
+ mBurstText = (EditText) findViewById(R.id.burst);
+ mBurstText.addTextChangedListener(new NumericalWatcher(mBurstText, 0, 50) {
+ @Override
+ public void onNewValue(int newValue) {
+ setBurst(newValue);
+ }
+ });
+ handleFocus(mBurstText);
+ }
+
+ private void initReplication() {
+ mReplication = getResources().getInteger(R.integer.replication_default);
+ mReplicationText = (EditText) findViewById(R.id.replication);
+ mReplicationText.addTextChangedListener(new NumericalWatcher(mReplicationText, 1, 100) {
+ @Override
+ public void onNewValue(int newValue) {
+ setReplication(newValue);
+ }
+ });
+ handleFocus(mReplicationText);
+ }
+
+ private void initBucket() {
+ mBucketMins = getResources().getInteger(R.integer.bucket_default);
+ mBucketText = (EditText) findViewById(R.id.bucket);
+ mBucketText.addTextChangedListener(new NumericalWatcher(mBucketText, 1, 24 * 60) {
+ @Override
+ public void onNewValue(int newValue) {
+ setBucketMins(newValue);
+ }
+ });
+ handleFocus(mBucketText);
+ }
+
+ private void initPeriod() {
+ mPeriodSecs = getResources().getInteger(R.integer.period_default);
+ mPeriodText = (EditText) findViewById(R.id.period);
+ mPeriodText.addTextChangedListener(new NumericalWatcher(mPeriodText, 1, 60) {
+ @Override
+ public void onNewValue(int newValue) {
+ setPeriodSecs(newValue);
+ }
+ });
+ handleFocus(mPeriodText);
+ }
+
+ private void initDuration() {
+ mDurationMins = getResources().getInteger(R.integer.duration_default);
+ mDurationText = (EditText) findViewById(R.id.duration);
+ mDurationText.addTextChangedListener(new NumericalWatcher(mDurationText, 1, 24 * 60) {
+ @Override
+ public void onNewValue(int newValue) {
+ setDurationMins(newValue);
+ }
+ });
+ handleFocus(mDurationText);
+ }
+
+ private void initPlacebo() {
+ mPlaceboCheckBox = findViewById(R.id.placebo);
+ mPlacebo = false;
+ mPlaceboCheckBox.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ setPlacebo(((CheckBox) view).isChecked());
+ }
+ });
+ }
+}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java
new file mode 100644
index 0000000..57f85b5
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 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.statsd.loadtest;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.util.StatsLog;
+import android.util.StatsManager;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.os.IStatsManager;
+import android.os.ServiceManager;
+import android.view.View.OnFocusChangeListener;
+
+public abstract class NumericalWatcher implements TextWatcher {
+
+ private static final String TAG = "NumericalWatcher";
+
+ private final TextView mTextView;
+ private final int mMin;
+ private final int mMax;
+ private int currentValue = -1;
+
+ public NumericalWatcher(TextView textView, int min, int max) {
+ mTextView = textView;
+ mMin = min;
+ mMax = max;
+ }
+
+ public abstract void onNewValue(int newValue);
+
+ @Override
+ final public void afterTextChanged(Editable editable) {
+ String s = mTextView.getText().toString();
+ if (s.isEmpty()) {
+ return;
+ }
+ int unsanitized = Integer.parseInt(s);
+ int newValue = sanitize(unsanitized);
+
+ Log.d(TAG, "YOYO " + currentValue + " " + newValue + " " + unsanitized);
+
+ if (currentValue != newValue || unsanitized != newValue) {
+ currentValue = newValue;
+ editable.clear();
+ editable.append(newValue + "");
+ }
+ onNewValue(newValue);
+ }
+
+ @Override
+ final public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ final public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ private int sanitize(int val) {
+ if (val > mMax) {
+ val = mMax;
+ } else if (val < mMin) {
+ val = mMin;
+ }
+ return val;
+ }
+}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java
new file mode 100644
index 0000000..e3e23f5
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 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.statsd.loadtest;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.os.Debug;
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/** Prints some information about the device via Dumpsys in order to evaluate health metrics. */
+public class PerfData {
+
+ private static final String TAG = "PerfData";
+ private static final String DUMP_FILENAME = TAG + "_dump.tmp";
+
+ public void resetData(Context context) {
+ runDumpsysStats(context, "batterystats", "--reset");
+ }
+
+ public void publishData(Context context, boolean placebo, int replication, long bucketMins,
+ long periodSecs, int burst) {
+ publishBatteryData(context, placebo, replication, bucketMins, periodSecs, burst);
+ }
+
+ private void publishBatteryData(Context context, boolean placebo, int replication,
+ long bucketMins, long periodSecs, int burst) {
+ // Don't use --checkin.
+ runDumpsysStats(context, "batterystats");
+ writeBatteryData(context, placebo, replication, bucketMins, periodSecs, burst);
+ }
+
+ private void runDumpsysStats(Context context, String cmd, String... args) {
+ boolean success = false;
+ // Call dumpsys Dump statistics to a file.
+ FileOutputStream fo = null;
+ try {
+ fo = context.openFileOutput(DUMP_FILENAME, Context.MODE_PRIVATE);
+ if (!Debug.dumpService(cmd, fo.getFD(), args)) {
+ Log.w(TAG, "Dumpsys failed.");
+ }
+ success = true;
+ } catch (IOException | SecurityException | NullPointerException e) {
+ // SecurityException may occur when trying to dump multi-user info.
+ // NPE can occur during dumpService (root cause unknown).
+ throw new RuntimeException(e);
+ } finally {
+ closeQuietly(fo);
+ }
+ }
+
+ private String readDumpFile(Context context) {
+ StringBuilder sb = new StringBuilder();
+ FileInputStream fi = null;
+ BufferedReader br = null;
+ try {
+ fi = context.openFileInput(DUMP_FILENAME);
+ br = new BufferedReader(new InputStreamReader(fi));
+ String line = br.readLine();
+ while (line != null) {
+ sb.append(line);
+ sb.append(System.lineSeparator());
+ line = br.readLine();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ closeQuietly(br);
+ }
+ return sb.toString();
+ }
+
+ private static void closeQuietly(@Nullable Closeable c) {
+ if (c != null) {
+ try {
+ c.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+
+ public void writeBatteryData(Context context, boolean placebo, int replication, long bucketMins,
+ long periodSecs, int burst) {
+ BatteryStatsParser parser = new BatteryStatsParser();
+ FileInputStream fi = null;
+ BufferedReader br = null;
+ String suffix = new SimpleDateFormat("YYYY_MM_dd_HH_mm_ss").format(new Date());
+ File batteryDataFile = new File(getStorageDir(), "battery_" + suffix + ".csv");
+ Log.d(TAG, "Writing battery data to " + batteryDataFile.getAbsolutePath());
+
+ FileWriter writer = null;
+ try {
+ fi = context.openFileInput(DUMP_FILENAME);
+ writer = new FileWriter(batteryDataFile);
+ writer.append("time,battery_level"
+ + getColumnName(placebo, replication, bucketMins, periodSecs, burst) + "\n");
+ br = new BufferedReader(new InputStreamReader(fi));
+ String line = br.readLine();
+ while (line != null) {
+ String recordLine = parser.parseLine(line);
+ if (recordLine != null) {
+ writer.append(recordLine);
+ }
+ line = br.readLine();
+ }
+ writer.flush();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ closeQuietly(writer);
+ closeQuietly(br);
+ }
+ }
+
+ private File getStorageDir() {
+ File file = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_DOCUMENTS), "loadtest");
+ if (!file.mkdirs()) {
+ Log.e(TAG, "Directory not created");
+ }
+ return file;
+ }
+
+ private String getColumnName(boolean placebo, int replication, long bucketMins, long periodSecs,
+ int burst) {
+ if (placebo) {
+ return "_placebo_p=" + periodSecs;
+ }
+ return "_r=" + replication + "_bkt=" + bucketMins + "_p=" + periodSecs + "_bst=" + burst;
+ }
+}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java
new file mode 100644
index 0000000..d4b2aa4
--- /dev/null
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2017 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.statsd.loadtest;
+
+import android.util.Log;
+import android.util.StatsLog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Manages the pushing of atoms into logd for loadtesting.
+ * We rely on small number of pushed atoms, and a config with metrics based on those atoms.
+ * The atoms are:
+ * <ul>
+ * <li> BatteryLevelChanged - For EventMetric, CountMetric and GaugeMetric (no dimensions).
+ * <li> BleScanResultReceived - For CountMetric and ValueMetric, sliced by uid.
+ * <li> ChargingStateChanged - For DurationMetric (no dimension).
+ * <li> GpsScanStateChanged - For DurationMetric, sliced by uid.
+ * <li> ScreenStateChanged - For Conditions with no dimensions.
+ * <li> AudioStateChanged - For Conditions with dimensions (uid).
+ * </ul>
+ * The sequence is played over and over at a given frequency.
+ */
+public class SequencePusher {
+ private static final String TAG = "SequencePusher";
+
+ /** Some atoms are pushed in burst of {@code mBurst} events. */
+ private final int mBurst;
+
+ /** If this is true, we don't log anything in logd. */
+ private final boolean mPlacebo;
+
+ /** Current state in the automaton. */
+ private int mCursor = 0;
+
+ public SequencePusher(int burst, boolean placebo) {
+ mBurst = burst;
+ mPlacebo = placebo;
+ }
+
+ /**
+ * Pushes the next atom to logd.
+ * This follows a small automaton which makes the right events and conditions overlap:
+ * (0) Push a burst of BatteryLevelChanged atoms.
+ * (1) Push a burst of BleScanResultReceived atoms.
+ * (2) Push ChargingStateChanged with BATTERY_STATUS_CHARGING once.
+ * (3) Push a burst of GpsScanStateChanged atoms with ON, with a different uid each time.
+ * (4) Push ChargingStateChanged with BATTERY_STATUS_NOT_CHARGING once.
+ * (5) Push a burst GpsScanStateChanged atoms with OFF, with a different uid each time.
+ * (6) Push ScreenStateChanged with STATE_ON once.
+ * (7) Push a burst of AudioStateChanged with ON, with a different uid each time.
+ * (8) Repeat steps (0)-(5).
+ * (9) Push ScreenStateChanged with STATE_OFF once.
+ * (10) Push a burst of AudioStateChanged with OFF, with a different uid each time.
+ * and repeat.
+ */
+ public void next() {
+ Log.d(TAG, "Next step: " + mCursor);
+ if (mPlacebo) {
+ return;
+ }
+ switch (mCursor) {
+ case 0:
+ case 8:
+ for (int i = 0; i < mBurst; i++) {
+ StatsLog.write(StatsLog.BATTERY_LEVEL_CHANGED, 50 + i /* battery_level */);
+ }
+ break;
+ case 1:
+ case 9:
+ for (int i = 0; i < mBurst; i++) {
+ StatsLog.write(StatsLog.BLE_SCAN_RESULT_RECEIVED, i /* uid */,
+ 100 /* num_of_results */);
+ }
+ break;
+ case 2:
+ case 10:
+ StatsLog.write(StatsLog.CHARGING_STATE_CHANGED,
+ StatsLog.CHARGING_STATE_CHANGED__CHARGING_STATE__BATTERY_STATUS_CHARGING
+ /* charging_state */);
+ break;
+ case 3:
+ case 11:
+ for (int i = 0; i < mBurst; i++) {
+ StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, i /* uid */,
+ StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON /* state */);
+ }
+ break;
+ case 4:
+ case 12:
+ StatsLog.write(StatsLog.CHARGING_STATE_CHANGED,
+ StatsLog.CHARGING_STATE_CHANGED__CHARGING_STATE__BATTERY_STATUS_NOT_CHARGING
+ /* charging_state */);
+ break;
+ case 5:
+ case 13:
+ for (int i = 0; i < mBurst; i++) {
+ StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, i /* uid */,
+ StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF /* state */);
+ }
+ break;
+ case 6:
+ StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
+ StatsLog.SCREEN_STATE_CHANGED__DISPLAY_STATE__STATE_ON /* display_state */);
+ break;
+ case 7:
+ for (int i = 0; i < mBurst; i++) {
+ StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, i /* uid */,
+ StatsLog.AUDIO_STATE_CHANGED__STATE__ON /* state */);
+ }
+ break;
+ case 14:
+ StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
+ StatsLog.SCREEN_STATE_CHANGED__DISPLAY_STATE__STATE_OFF /* display_state */);
+ break;
+ case 15:
+ for (int i = 0; i < mBurst; i++) {
+ StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, i /* uid */,
+ StatsLog.AUDIO_STATE_CHANGED__STATE__OFF /* state */);
+ }
+ break;
+ default:
+ }
+ mCursor++;
+ if (mCursor > 15) {
+ mCursor = 0;
+ }
+ }
+
+ /**
+ * Properly finishes in order to be close all conditions and durations.
+ */
+ public void finish() {
+ // Screen goes back to off. This will ensure that conditions get back to false.
+ StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
+ StatsLog.SCREEN_STATE_CHANGED__DISPLAY_STATE__STATE_OFF /* display_state */);
+ for (int i = 0; i < mBurst; i++) {
+ StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, i /* uid */,
+ StatsLog.AUDIO_STATE_CHANGED__STATE__OFF /* state */);
+ }
+ // Stop charging, to ensure the corresponding durations are closed.
+ StatsLog.write(StatsLog.CHARGING_STATE_CHANGED,
+ StatsLog.CHARGING_STATE_CHANGED__CHARGING_STATE__BATTERY_STATUS_NOT_CHARGING
+ /* charging_state */);
+ // Stop scanning GPS, to ensure the corresponding conditions get back to false.
+ for (int i = 0; i < mBurst; i++) {
+ StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, i /* uid */,
+ StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF /* state */);
+ }
+ }
+}
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index f6d9710..de6230c 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -638,8 +638,7 @@
final String defaultSearchPaths = System.getProperty("java.library.path");
final boolean treatVendorApkAsUnbundled = !defaultSearchPaths.contains("/vendor/lib");
if (mApplicationInfo.getCodePath() != null
- && mApplicationInfo.getCodePath().startsWith("/vendor/")
- && treatVendorApkAsUnbundled) {
+ && mApplicationInfo.isVendor() && treatVendorApkAsUnbundled) {
isBundledApp = false;
}
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 8c47598..b186666 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -50,6 +50,11 @@
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
final class SharedPreferencesImpl implements SharedPreferences {
private static final String TAG = "SharedPreferencesImpl";
@@ -69,16 +74,12 @@
private final Object mLock = new Object();
private final Object mWritingToDiskLock = new Object();
- @GuardedBy("mLock")
- private Map<String, Object> mMap;
+ private Future<Map<String, Object>> mMap;
@GuardedBy("mLock")
private int mDiskWritesInFlight = 0;
@GuardedBy("mLock")
- private boolean mLoaded = false;
-
- @GuardedBy("mLock")
private StructTimespec mStatTimestamp;
@GuardedBy("mLock")
@@ -105,27 +106,18 @@
mFile = file;
mBackupFile = makeBackupFile(file);
mMode = mode;
- mLoaded = false;
mMap = null;
startLoadFromDisk();
}
private void startLoadFromDisk() {
- synchronized (mLock) {
- mLoaded = false;
- }
- new Thread("SharedPreferencesImpl-load") {
- public void run() {
- loadFromDisk();
- }
- }.start();
+ FutureTask<Map<String, Object>> futureTask = new FutureTask<>(() -> loadFromDisk());
+ mMap = futureTask;
+ new Thread(futureTask, "SharedPreferencesImpl-load").start();
}
- private void loadFromDisk() {
+ private Map<String, Object> loadFromDisk() {
synchronized (mLock) {
- if (mLoaded) {
- return;
- }
if (mBackupFile.exists()) {
mFile.delete();
mBackupFile.renameTo(mFile);
@@ -158,16 +150,14 @@
}
synchronized (mLock) {
- mLoaded = true;
if (map != null) {
- mMap = map;
mStatTimestamp = stat.st_mtim;
mStatSize = stat.st_size;
} else {
- mMap = new HashMap<>();
+ map = new HashMap<>();
}
- mLock.notifyAll();
}
+ return map;
}
static File makeBackupFile(File prefsFile) {
@@ -226,36 +216,37 @@
}
}
- private void awaitLoadedLocked() {
- if (!mLoaded) {
+ private @GuardedBy("mLock") Map<String, Object> getLoaded() {
+ try {
+ return mMap.get();
+ } catch (InterruptedException | ExecutionException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ private @GuardedBy("mLock") Map<String, Object> getLoadedWithBlockGuard() {
+ if (!mMap.isDone()) {
// Raise an explicit StrictMode onReadFromDisk for this
// thread, since the real read will be in a different
// thread and otherwise ignored by StrictMode.
BlockGuard.getThreadPolicy().onReadFromDisk();
}
- while (!mLoaded) {
- try {
- mLock.wait();
- } catch (InterruptedException unused) {
- }
- }
+ return getLoaded();
}
@Override
public Map<String, ?> getAll() {
+ Map<String, Object> map = getLoadedWithBlockGuard();
synchronized (mLock) {
- awaitLoadedLocked();
- //noinspection unchecked
- return new HashMap<String, Object>(mMap);
+ return new HashMap<String, Object>(map);
}
}
@Override
@Nullable
public String getString(String key, @Nullable String defValue) {
+ Map<String, Object> map = getLoadedWithBlockGuard();
synchronized (mLock) {
- awaitLoadedLocked();
- String v = (String)mMap.get(key);
+ String v = (String) map.get(key);
return v != null ? v : defValue;
}
}
@@ -263,66 +254,65 @@
@Override
@Nullable
public Set<String> getStringSet(String key, @Nullable Set<String> defValues) {
+ Map<String, Object> map = getLoadedWithBlockGuard();
synchronized (mLock) {
- awaitLoadedLocked();
- Set<String> v = (Set<String>) mMap.get(key);
+ @SuppressWarnings("unchecked")
+ Set<String> v = (Set<String>) map.get(key);
return v != null ? v : defValues;
}
}
@Override
public int getInt(String key, int defValue) {
+ Map<String, Object> map = getLoadedWithBlockGuard();
synchronized (mLock) {
- awaitLoadedLocked();
- Integer v = (Integer)mMap.get(key);
+ Integer v = (Integer) map.get(key);
return v != null ? v : defValue;
}
}
@Override
public long getLong(String key, long defValue) {
+ Map<String, Object> map = getLoadedWithBlockGuard();
synchronized (mLock) {
- awaitLoadedLocked();
- Long v = (Long)mMap.get(key);
+ Long v = (Long) map.get(key);
return v != null ? v : defValue;
}
}
@Override
public float getFloat(String key, float defValue) {
+ Map<String, Object> map = getLoadedWithBlockGuard();
synchronized (mLock) {
- awaitLoadedLocked();
- Float v = (Float)mMap.get(key);
+ Float v = (Float) map.get(key);
return v != null ? v : defValue;
}
}
@Override
public boolean getBoolean(String key, boolean defValue) {
+ Map<String, Object> map = getLoadedWithBlockGuard();
synchronized (mLock) {
- awaitLoadedLocked();
- Boolean v = (Boolean)mMap.get(key);
+ Boolean v = (Boolean) map.get(key);
return v != null ? v : defValue;
}
}
@Override
public boolean contains(String key) {
+ Map<String, Object> map = getLoadedWithBlockGuard();
synchronized (mLock) {
- awaitLoadedLocked();
- return mMap.containsKey(key);
+ return map.containsKey(key);
}
}
@Override
public Editor edit() {
- // TODO: remove the need to call awaitLoadedLocked() when
+ // TODO: remove the need to call getLoaded() when
// requesting an editor. will require some work on the
// Editor, but then we should be able to do:
//
// context.getSharedPreferences(..).edit().putString(..).apply()
//
// ... all without blocking.
- synchronized (mLock) {
- awaitLoadedLocked();
- }
+ getLoadedWithBlockGuard();
return new EditorImpl();
}
@@ -476,13 +466,43 @@
// a memory commit comes in when we're already
// writing to disk.
if (mDiskWritesInFlight > 0) {
- // We can't modify our mMap as a currently
+ // We can't modify our map as a currently
// in-flight write owns it. Clone it before
// modifying it.
// noinspection unchecked
- mMap = new HashMap<String, Object>(mMap);
+ mMap = new Future<Map<String, Object>>() {
+ private Map<String, Object> mCopiedMap =
+ new HashMap<String, Object>(getLoaded());
+
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ return false;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return false;
+ }
+
+ @Override
+ public boolean isDone() {
+ return true;
+ }
+
+ @Override
+ public Map<String, Object> get()
+ throws InterruptedException, ExecutionException {
+ return mCopiedMap;
+ }
+
+ @Override
+ public Map<String, Object> get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ return mCopiedMap;
+ }
+ };
}
- mapToWriteToDisk = mMap;
+ mapToWriteToDisk = getLoaded();
mDiskWritesInFlight++;
boolean hasListeners = mListeners.size() > 0;
diff --git a/core/java/android/app/usage/AppStandby.java b/core/java/android/app/usage/AppStandby.java
deleted file mode 100644
index 6f9fc2f..0000000
--- a/core/java/android/app/usage/AppStandby.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2017 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.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Set of constants for app standby buckets and reasons. Apps will be moved into different buckets
- * that affect how frequently they can run in the background or perform other battery-consuming
- * actions. Buckets will be assigned based on how frequently or when the system thinks the user
- * is likely to use the app.
- * @hide
- */
-public class AppStandby {
-
- /** The app was used very recently, currently in use or likely to be used very soon. */
- public static final int STANDBY_BUCKET_ACTIVE = 0;
-
- // Leave some gap in case we want to increase the number of buckets
-
- /** The app was used recently and/or likely to be used in the next few hours */
- public static final int STANDBY_BUCKET_WORKING_SET = 3;
-
- // Leave some gap in case we want to increase the number of buckets
-
- /** The app was used in the last few days and/or likely to be used in the next few days */
- public static final int STANDBY_BUCKET_FREQUENT = 6;
-
- // Leave some gap in case we want to increase the number of buckets
-
- /** The app has not be used for several days and/or is unlikely to be used for several days */
- public static final int STANDBY_BUCKET_RARE = 9;
-
- // Leave some gap in case we want to increase the number of buckets
-
- /** The app has never been used. */
- public static final int STANDBY_BUCKET_NEVER = 12;
-
- /** Reason for bucketing -- default initial state */
- public static final String REASON_DEFAULT = "default";
-
- /** Reason for bucketing -- timeout */
- public static final String REASON_TIMEOUT = "timeout";
-
- /** Reason for bucketing -- usage */
- public static final String REASON_USAGE = "usage";
-
- /** Reason for bucketing -- forced by user / shell command */
- public static final String REASON_FORCED = "forced";
-
- /**
- * Reason for bucketing -- predicted. This is a prefix and the UID of the bucketeer will
- * be appended.
- */
- public static final String REASON_PREDICTED = "predicted";
-
- @IntDef(flag = false, value = {
- STANDBY_BUCKET_ACTIVE,
- STANDBY_BUCKET_WORKING_SET,
- STANDBY_BUCKET_FREQUENT,
- STANDBY_BUCKET_RARE,
- STANDBY_BUCKET_NEVER,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface StandbyBuckets {}
-}
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 3a3e16e..d614b20 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -16,16 +16,18 @@
package android.app.usage;
+import android.annotation.IntDef;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.app.usage.AppStandby.StandbyBuckets;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -90,6 +92,76 @@
*/
public static final int INTERVAL_COUNT = 4;
+
+ /**
+ * The app is whitelisted for some reason and the bucket cannot be changed.
+ * {@hide}
+ */
+ @SystemApi
+ public static final int STANDBY_BUCKET_EXEMPTED = 5;
+
+ /**
+ * The app was used very recently, currently in use or likely to be used very soon.
+ * @see #getAppStandbyBucket()
+ */
+ public static final int STANDBY_BUCKET_ACTIVE = 10;
+
+ /**
+ * The app was used recently and/or likely to be used in the next few hours.
+ * @see #getAppStandbyBucket()
+ */
+ public static final int STANDBY_BUCKET_WORKING_SET = 20;
+
+ /**
+ * The app was used in the last few days and/or likely to be used in the next few days.
+ * @see #getAppStandbyBucket()
+ */
+ public static final int STANDBY_BUCKET_FREQUENT = 30;
+
+ /**
+ * The app has not be used for several days and/or is unlikely to be used for several days.
+ * @see #getAppStandbyBucket()
+ */
+ public static final int STANDBY_BUCKET_RARE = 40;
+
+ /**
+ * The app has never been used.
+ * {@hide}
+ */
+ @SystemApi
+ public static final int STANDBY_BUCKET_NEVER = 50;
+
+ /** {@hide} Reason for bucketing -- default initial state */
+ public static final String REASON_DEFAULT = "default";
+
+ /** {@hide} Reason for bucketing -- timeout */
+ public static final String REASON_TIMEOUT = "timeout";
+
+ /** {@hide} Reason for bucketing -- usage */
+ public static final String REASON_USAGE = "usage";
+
+ /** {@hide} Reason for bucketing -- forced by user / shell command */
+ public static final String REASON_FORCED = "forced";
+
+ /**
+ * {@hide}
+ * Reason for bucketing -- predicted. This is a prefix and the UID of the bucketeer will
+ * be appended.
+ */
+ public static final String REASON_PREDICTED = "predicted";
+
+ /** @hide */
+ @IntDef(flag = false, value = {
+ STANDBY_BUCKET_EXEMPTED,
+ STANDBY_BUCKET_ACTIVE,
+ STANDBY_BUCKET_WORKING_SET,
+ STANDBY_BUCKET_FREQUENT,
+ STANDBY_BUCKET_RARE,
+ STANDBY_BUCKET_NEVER,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StandbyBuckets {}
+
private static final UsageEvents sEmptyResults = new UsageEvents();
private final Context mContext;
@@ -237,7 +309,7 @@
}
/**
- * @hide
+ * {@hide}
*/
public void setAppInactive(String packageName, boolean inactive) {
try {
@@ -248,19 +320,45 @@
}
/**
- * @hide
+ * Returns the current standby bucket of the calling app. The system determines the standby
+ * state of the app based on app usage patterns. Standby buckets determine how much an app will
+ * be restricted from running background tasks such as jobs, alarms and certain PendingIntent
+ * callbacks.
+ * Restrictions increase progressively from {@link #STANDBY_BUCKET_ACTIVE} to
+ * {@link #STANDBY_BUCKET_RARE}, with {@link #STANDBY_BUCKET_ACTIVE} being the least
+ * restrictive. The battery level of the device might also affect the restrictions.
+ *
+ * @return the current standby bucket of the calling app.
*/
+ public @StandbyBuckets int getAppStandbyBucket() {
+ try {
+ return mService.getAppStandbyBucket(mContext.getOpPackageName(),
+ mContext.getOpPackageName(),
+ mContext.getUserId());
+ } catch (RemoteException e) {
+ }
+ return STANDBY_BUCKET_ACTIVE;
+ }
+
+ /**
+ * {@hide}
+ * Returns the current standby bucket of the specified app. The caller must hold the permission
+ * android.permission.PACKAGE_USAGE_STATS.
+ * @param packageName the package for which to fetch the current standby bucket.
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
public @StandbyBuckets int getAppStandbyBucket(String packageName) {
try {
return mService.getAppStandbyBucket(packageName, mContext.getOpPackageName(),
mContext.getUserId());
} catch (RemoteException e) {
}
- return AppStandby.STANDBY_BUCKET_ACTIVE;
+ return STANDBY_BUCKET_ACTIVE;
}
/**
- * @hide
+ * {@hide}
* Changes the app standby state to the provided bucket.
*/
@SystemApi
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
index 9954484f..4b4fe72 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -16,7 +16,7 @@
package android.app.usage;
-import android.app.usage.AppStandby.StandbyBuckets;
+import android.app.usage.UsageStatsManager.StandbyBuckets;
import android.content.ComponentName;
import android.content.res.Configuration;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index edb27cd..5298f57 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -594,6 +594,13 @@
*/
public static final int PRIVATE_FLAG_OEM = 1 << 17;
+ /**
+ * Value for {@linl #privateFlags}: whether this app is pre-installed on the
+ * vendor partition of the system image.
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_VENDOR = 1 << 18;
+
/** @hide */
@IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = {
PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE,
@@ -613,6 +620,7 @@
PRIVATE_FLAG_PRIVILEGED,
PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER,
PRIVATE_FLAG_STATIC_SHARED_LIBRARY,
+ PRIVATE_FLAG_VENDOR,
PRIVATE_FLAG_VIRTUAL_PRELOAD,
})
@Retention(RetentionPolicy.SOURCE)
@@ -1569,6 +1577,11 @@
return (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
}
+ /** @hide */
+ public boolean isVendor() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
+ }
+
/**
* Returns whether or not this application was installed as a virtual preload.
*/
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ebeaad7..98c824d 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -6267,6 +6267,11 @@
}
/** @hide */
+ public boolean isVendor() {
+ return applicationInfo.isVendor();
+ }
+
+ /** @hide */
public boolean isPrivileged() {
return applicationInfo.isPrivilegedApp();
}
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 7588762..551d53b 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -144,6 +144,15 @@
public static final int PROTECTION_FLAG_OEM = 0x4000;
/**
+ * Additional flag for {${link #protectionLevel}, corresponding
+ * to the <code>vendorPrivileged</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ *
+ * @hide
+ */
+ public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 0x8000;
+
+ /**
* Mask for {@link #protectionLevel}: the basic protection type.
*/
public static final int PROTECTION_MASK_BASE = 0xf;
@@ -231,6 +240,12 @@
if (level == PROTECTION_SIGNATURE_OR_SYSTEM) {
level = PROTECTION_SIGNATURE | PROTECTION_FLAG_PRIVILEGED;
}
+ if ((level & PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0
+ && (level & PROTECTION_FLAG_PRIVILEGED) == 0) {
+ // 'vendorPrivileged' must be 'privileged'. If not,
+ // drop the vendorPrivileged.
+ level = level & ~PROTECTION_FLAG_VENDOR_PRIVILEGED;
+ }
return level;
}
@@ -284,6 +299,9 @@
if ((level & PermissionInfo.PROTECTION_FLAG_OEM) != 0) {
protLevel += "|oem";
}
+ if ((level & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0) {
+ protLevel += "|vendorPrivileged";
+ }
return protLevel;
}
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index b5031f2..b7a6719 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -146,6 +146,9 @@
final ArrayMap<String, ArraySet<String>> mPrivAppPermissions = new ArrayMap<>();
final ArrayMap<String, ArraySet<String>> mPrivAppDenyPermissions = new ArrayMap<>();
+ final ArrayMap<String, ArraySet<String>> mVendorPrivAppPermissions = new ArrayMap<>();
+ final ArrayMap<String, ArraySet<String>> mVendorPrivAppDenyPermissions = new ArrayMap<>();
+
final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>();
public static SystemConfig getInstance() {
@@ -229,6 +232,14 @@
return mPrivAppDenyPermissions.get(packageName);
}
+ public ArraySet<String> getVendorPrivAppPermissions(String packageName) {
+ return mVendorPrivAppPermissions.get(packageName);
+ }
+
+ public ArraySet<String> getVendorPrivAppDenyPermissions(String packageName) {
+ return mVendorPrivAppDenyPermissions.get(packageName);
+ }
+
public Map<String, Boolean> getOemPermissions(String packageName) {
final Map<String, Boolean> oemPermissions = mOemPermissions.get(packageName);
if (oemPermissions != null) {
@@ -248,7 +259,7 @@
// Allow Vendor to customize system configs around libs, features, permissions and apps
int vendorPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PERMISSIONS |
- ALLOW_APP_CONFIGS;
+ ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS;
readPermissions(Environment.buildPath(
Environment.getVendorDirectory(), "etc", "sysconfig"), vendorPermissionFlag);
readPermissions(Environment.buildPath(
@@ -587,7 +598,19 @@
}
XmlUtils.skipCurrentTag(parser);
} else if ("privapp-permissions".equals(name) && allowPrivappPermissions) {
- readPrivAppPermissions(parser);
+ // privapp permissions from system and vendor partitions are stored
+ // separately. This is to prevent xml files in the vendor partition from
+ // granting permissions to priv apps in the system partition and vice
+ // versa.
+ boolean vendor = permFile.toPath().startsWith(
+ Environment.getVendorDirectory().toPath());
+ if (vendor) {
+ readPrivAppPermissions(parser, mVendorPrivAppPermissions,
+ mVendorPrivAppDenyPermissions);
+ } else {
+ readPrivAppPermissions(parser, mPrivAppPermissions,
+ mPrivAppDenyPermissions);
+ }
} else if ("oem-permissions".equals(name) && allowOemPermissions) {
readOemPermissions(parser);
} else {
@@ -674,7 +697,10 @@
}
}
- void readPrivAppPermissions(XmlPullParser parser) throws IOException, XmlPullParserException {
+ private void readPrivAppPermissions(XmlPullParser parser,
+ ArrayMap<String, ArraySet<String>> grantMap,
+ ArrayMap<String, ArraySet<String>> denyMap)
+ throws IOException, XmlPullParserException {
String packageName = parser.getAttributeValue(null, "package");
if (TextUtils.isEmpty(packageName)) {
Slog.w(TAG, "package is required for <privapp-permissions> in "
@@ -682,11 +708,11 @@
return;
}
- ArraySet<String> permissions = mPrivAppPermissions.get(packageName);
+ ArraySet<String> permissions = grantMap.get(packageName);
if (permissions == null) {
permissions = new ArraySet<>();
}
- ArraySet<String> denyPermissions = mPrivAppDenyPermissions.get(packageName);
+ ArraySet<String> denyPermissions = denyMap.get(packageName);
int depth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, depth)) {
String name = parser.getName();
@@ -711,9 +737,9 @@
denyPermissions.add(permName);
}
}
- mPrivAppPermissions.put(packageName, permissions);
+ grantMap.put(packageName, permissions);
if (denyPermissions != null) {
- mPrivAppDenyPermissions.put(packageName, denyPermissions);
+ denyMap.put(packageName, denyPermissions);
}
}
diff --git a/core/res/Android.bp b/core/res/Android.bp
new file mode 100644
index 0000000..e66f1a2
--- /dev/null
+++ b/core/res/Android.bp
@@ -0,0 +1,41 @@
+//
+// 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.
+//
+
+android_app {
+ name: "framework-res",
+ no_framework_libs: true,
+ certificate: "platform",
+
+ // Soong special-cases framework-res to install this alongside
+ // the libraries at /system/framework/framework-res.apk.
+
+ // Generate private symbols into the com.android.internal.R class
+ // so they are not accessible to 3rd party apps.
+ aaptflags: [
+ "--private-symbols",
+ "com.android.internal",
+
+ // Framework doesn't need versioning since it IS the platform.
+ "--no-auto-version",
+
+ // Allow overlay to add resource
+ "--auto-add-overlay",
+ ],
+
+ // Create package-export.apk, which other packages can use to get
+ // PRODUCT-agnostic resource data like IDs and type definitions.
+ export_package_resources: true,
+}
diff --git a/core/res/Android.mk b/core/res/Android.mk
deleted file mode 100644
index 370a01f..0000000
--- a/core/res/Android.mk
+++ /dev/null
@@ -1,42 +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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_PACKAGE_NAME := framework-res
-LOCAL_CERTIFICATE := platform
-LOCAL_MODULE_TAGS := optional
-
-# Generate private symbols into the com.android.internal.R class
-# so they are not accessible to 3rd party apps.
-LOCAL_AAPT_FLAGS += --private-symbols com.android.internal
-
-# Framework doesn't need versioning since it IS the platform.
-LOCAL_AAPT_FLAGS += --no-auto-version
-
-# Allow overlay to add resource
-LOCAL_AAPT_FLAGS += --auto-add-overlay
-
-# Install this alongside the libraries.
-LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES)
-
-# Create package-export.apk, which other packages can use to get
-# PRODUCT-agnostic resource data like IDs and type definitions.
-LOCAL_EXPORT_PACKAGE_RESOURCES := true
-
-include $(BUILD_PACKAGE)
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5906b27..d9fb230 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1740,7 +1740,7 @@
@hide
-->
<permission android:name="android.permission.BIND_IMS_SERVICE"
- android:protectionLevel="signature|privileged" />
+ android:protectionLevel="signature|privileged|vendorPrivileged" />
<!-- Allows an application to manage embedded subscriptions (those on a eUICC) through
EuiccManager APIs.
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 4d410e5..4d67494 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -262,6 +262,9 @@
and the OEM has white-listed the app to receive this permission by the OEM.
-->
<flag name="oem" value="0x4000" />
+ <!-- Additional flag from base permission type: this permission can be granted to
+ privileged apps in vendor partition. -->
+ <flag name="vendorPrivileged" value="0x8000" />
</attr>
<!-- Flags indicating more context for a permission group. -->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 23d9cae..e04bd0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -112,6 +112,7 @@
private int mNotificationMaxHeight;
private int mNotificationAmbientHeight;
private int mIncreasedPaddingBetweenElements;
+ private boolean mMustStayOnScreen;
/** Does this row contain layouts that can adapt to row expansion */
private boolean mExpandable;
@@ -491,6 +492,7 @@
notifyHeightChanged(false /* needsAnimation */);
}
if (isHeadsUp) {
+ mMustStayOnScreen = true;
setAboveShelf(true);
} else if (isAboveShelf() != wasAboveShelf) {
mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
@@ -517,6 +519,12 @@
addChildNotification(row, -1);
}
+ @Override
+ public void setHeadsUpIsVisible() {
+ super.setHeadsUpIsVisible();
+ mMustStayOnScreen = false;
+ }
+
/**
* Add a child notification to this view.
*
@@ -1942,7 +1950,7 @@
@Override
public boolean mustStayOnScreen() {
- return mIsHeadsUp;
+ return mIsHeadsUp && mMustStayOnScreen;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 18b9860..f762513 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -478,6 +478,9 @@
return false;
}
+ public void setHeadsUpIsVisible() {
+ }
+
public boolean isChildInGroup() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java
index e0fd481..0650e23 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java
@@ -95,6 +95,12 @@
public boolean inShelf;
/**
+ * A state indicating whether a headsup is currently fully visible, even when not scrolled.
+ * Only valid if the view is heads upped.
+ */
+ public boolean headsUpIsVisible;
+
+ /**
* How much the child overlaps with the previous child on top. This is used to
* show the background properly when the child on top is translating away.
*/
@@ -126,6 +132,7 @@
clipTopAmount = svs.clipTopAmount;
notGoneIndex = svs.notGoneIndex;
location = svs.location;
+ headsUpIsVisible = svs.headsUpIsVisible;
}
}
@@ -175,6 +182,10 @@
expandableView.setTransformingInShelf(false);
expandableView.setInShelf(inShelf);
+
+ if (headsUpIsVisible) {
+ expandableView.setHeadsUpIsVisible();
+ }
}
}
@@ -229,6 +240,10 @@
expandableView.setTransformingInShelf(true);
}
expandableView.setInShelf(this.inShelf);
+
+ if (headsUpIsVisible) {
+ expandableView.setHeadsUpIsVisible();
+ }
}
private void startHeightAnimation(final ExpandableView child, AnimationProperties properties) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index ebebfac..a3d2423 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -624,7 +624,7 @@
if (childViewState == null) {
return false;
}
- if ((childViewState.location &= ExpandableViewState.VISIBLE_LOCATIONS) == 0) {
+ if ((childViewState.location & ExpandableViewState.VISIBLE_LOCATIONS) == 0) {
return false;
}
if (row.getVisibility() != View.VISIBLE) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index c060b08..195607d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -135,7 +135,7 @@
for (int i = 0; i < childCount; i++) {
ExpandableView child = algorithmState.visibleChildren.get(i);
ExpandableViewState state = resultState.getViewStateForView(child);
- if (!child.mustStayOnScreen()) {
+ if (!child.mustStayOnScreen() || state.headsUpIsVisible) {
previousNotificationEnd = Math.max(drawStart, previousNotificationEnd);
previousNotificationStart = Math.max(drawStart, previousNotificationStart);
}
@@ -378,6 +378,13 @@
boolean isEmptyShadeView = child instanceof EmptyShadeView;
childViewState.location = ExpandableViewState.LOCATION_MAIN_AREA;
+ float inset = ambientState.getTopPadding() + ambientState.getStackTranslation();
+ if (child.mustStayOnScreen() && childViewState.yTranslation >= 0) {
+ // Even if we're not scrolled away we're in view and we're also not in the
+ // shelf. We can relax the constraints and let us scroll off the top!
+ float end = childViewState.yTranslation + childViewState.height + inset;
+ childViewState.headsUpIsVisible = end < ambientState.getMaxHeadsUpTranslation();
+ }
if (isDismissView) {
childViewState.yTranslation = Math.min(childViewState.yTranslation,
ambientState.getInnerHeight() - childHeight);
@@ -396,8 +403,7 @@
Log.wtf(LOG_TAG, "Failed to assign location for child " + i);
}
- childViewState.yTranslation += ambientState.getTopPadding()
- + ambientState.getStackTranslation();
+ childViewState.yTranslation += inset;
return currentYPosition;
}
@@ -420,19 +426,21 @@
break;
}
ExpandableViewState childState = resultState.getViewStateForView(row);
- if (topHeadsUpEntry == null) {
+ if (topHeadsUpEntry == null && row.mustStayOnScreen() && !childState.headsUpIsVisible) {
topHeadsUpEntry = row;
childState.location = ExpandableViewState.LOCATION_FIRST_HUN;
}
boolean isTopEntry = topHeadsUpEntry == row;
float unmodifiedEndLocation = childState.yTranslation + childState.height;
if (mIsExpanded) {
- // Ensure that the heads up is always visible even when scrolled off
- clampHunToTop(ambientState, row, childState);
- if (i == 0 && ambientState.isAboveShelf(row)) {
- // the first hun can't get off screen.
- clampHunToMaxTranslation(ambientState, row, childState);
- childState.hidden = false;
+ if (row.mustStayOnScreen() && !childState.headsUpIsVisible) {
+ // Ensure that the heads up is always visible even when scrolled off
+ clampHunToTop(ambientState, row, childState);
+ if (i == 0 && ambientState.isAboveShelf(row)) {
+ // the first hun can't get off screen.
+ clampHunToMaxTranslation(ambientState, row, childState);
+ childState.hidden = false;
+ }
}
}
if (row.isPinned()) {
@@ -493,6 +501,7 @@
if (childViewState.yTranslation >= shelfStart) {
childViewState.hidden = true;
childViewState.inShelf = true;
+ childViewState.headsUpIsVisible = false;
}
if (!ambientState.isShadeExpanded()) {
childViewState.height = (int) (mStatusBarHeight - childViewState.yTranslation);
@@ -531,7 +540,8 @@
ExpandableViewState childViewState = resultState.getViewStateForView(child);
int zDistanceBetweenElements = ambientState.getZDistanceBetweenElements();
float baseZ = ambientState.getBaseZHeight();
- if (child.mustStayOnScreen() && !ambientState.isDozingAndNotPulsing(child)
+ if (child.mustStayOnScreen() && !childViewState.headsUpIsVisible
+ && !ambientState.isDozingAndNotPulsing(child)
&& childViewState.yTranslation < ambientState.getTopPadding()
+ ambientState.getStackTranslation()) {
if (childrenOnTop != 0.0f) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index e3c746b..588b758 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -84,6 +84,7 @@
viewState.scaleX = view.getScaleX();
viewState.scaleY = view.getScaleY();
viewState.inShelf = false;
+ viewState.headsUpIsVisible = false;
}
public ExpandableViewState getViewStateForView(View requestedView) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 7eb922c..979323f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -224,6 +224,8 @@
return runGetInactive(pw);
case "set-standby-bucket":
return runSetStandbyBucket(pw);
+ case "get-standby-bucket":
+ return runGetStandbyBucket(pw);
case "send-trim-memory":
return runSendTrimMemory(pw);
case "display":
@@ -1826,6 +1828,29 @@
return 0;
}
+ private int bucketNameToBucketValue(String name) {
+ String lower = name.toLowerCase();
+ if (lower.startsWith("ac")) {
+ return UsageStatsManager.STANDBY_BUCKET_ACTIVE;
+ } else if (lower.startsWith("wo")) {
+ return UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
+ } else if (lower.startsWith("fr")) {
+ return UsageStatsManager.STANDBY_BUCKET_FREQUENT;
+ } else if (lower.startsWith("ra")) {
+ return UsageStatsManager.STANDBY_BUCKET_RARE;
+ } else if (lower.startsWith("ne")) {
+ return UsageStatsManager.STANDBY_BUCKET_NEVER;
+ } else {
+ try {
+ int bucket = Integer.parseInt(lower);
+ return bucket;
+ } catch (NumberFormatException nfe) {
+ getErrPrintWriter().println("Error: Unknown bucket: " + name);
+ }
+ }
+ return -1;
+ }
+
int runSetStandbyBucket(PrintWriter pw) throws RemoteException {
int userId = UserHandle.USER_CURRENT;
@@ -1840,10 +1865,33 @@
}
String packageName = getNextArgRequired();
String value = getNextArgRequired();
+ int bucket = bucketNameToBucketValue(value);
+ if (bucket < 0) return -1;
IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
Context.USAGE_STATS_SERVICE));
- usm.setAppStandbyBucket(packageName, Integer.parseInt(value), userId);
+ usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
+ return 0;
+ }
+
+ int runGetStandbyBucket(PrintWriter pw) throws RemoteException {
+ int userId = UserHandle.USER_CURRENT;
+
+ String opt;
+ while ((opt=getNextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ } else {
+ getErrPrintWriter().println("Error: Unknown option: " + opt);
+ return -1;
+ }
+ }
+ String packageName = getNextArgRequired();
+
+ IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
+ Context.USAGE_STATS_SERVICE));
+ int bucket = usm.getAppStandbyBucket(packageName, null, userId);
+ pw.println(bucket);
return 0;
}
@@ -2597,8 +2645,10 @@
pw.println(" Sets the inactive state of an app.");
pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>");
pw.println(" Returns the inactive state of an app.");
- pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> <BUCKET>");
+ pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare");
pw.println(" Puts an app in the standby bucket.");
+ pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>");
+ pw.println(" Returns the standby bucket of an app.");
pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>");
pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
pw.println(" Send a memory trim event to a <PROCESS>. May also supply a raw trim int level.");
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 4af86a0..3f014b5 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -29,7 +29,7 @@
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.app.job.JobWorkItem;
-import android.app.usage.AppStandby;
+import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.content.BroadcastReceiver;
@@ -2074,10 +2074,10 @@
public static int standbyBucketToBucketIndex(int bucket) {
// Normalize AppStandby constants to indices into our bookkeeping
- if (bucket == AppStandby.STANDBY_BUCKET_NEVER) return 4;
- else if (bucket >= AppStandby.STANDBY_BUCKET_RARE) return 3;
- else if (bucket >= AppStandby.STANDBY_BUCKET_FREQUENT) return 2;
- else if (bucket >= AppStandby.STANDBY_BUCKET_WORKING_SET) return 1;
+ if (bucket == UsageStatsManager.STANDBY_BUCKET_NEVER) return 4;
+ else if (bucket >= UsageStatsManager.STANDBY_BUCKET_RARE) return 3;
+ else if (bucket >= UsageStatsManager.STANDBY_BUCKET_FREQUENT) return 2;
+ else if (bucket >= UsageStatsManager.STANDBY_BUCKET_WORKING_SET) return 1;
else return 0;
}
diff --git a/services/core/java/com/android/server/location/ContextHubServiceTransaction.java b/services/core/java/com/android/server/location/ContextHubServiceTransaction.java
index 66145bb..a543daf 100644
--- a/services/core/java/com/android/server/location/ContextHubServiceTransaction.java
+++ b/services/core/java/com/android/server/location/ContextHubServiceTransaction.java
@@ -54,18 +54,10 @@
abstract int onTransact();
/**
- * A function to invoke when a transaction times out.
- *
- * All instances of this class must implement this method by reporting the timeout to the
- * client.
- */
- /* package */
- abstract void onTimeout();
-
- /**
* A function to invoke when the transaction completes.
*
- * Only relevant for load, unload, enable, or disable transactions.
+ * For transactions with expected contents (such as a query), the class instance should
+ * implement the appropriate behavior (e.g. invoke onQueryResponse with an empty list).
*
* @param result the result of the transaction
*/
diff --git a/services/core/java/com/android/server/location/ContextHubTransactionManager.java b/services/core/java/com/android/server/location/ContextHubTransactionManager.java
index 47d9d56..3fcc682 100644
--- a/services/core/java/com/android/server/location/ContextHubTransactionManager.java
+++ b/services/core/java/com/android/server/location/ContextHubTransactionManager.java
@@ -106,17 +106,12 @@
contextHubId, hidlNanoAppBinary, this.getTransactionId());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException while trying to load nanoapp with ID 0x" +
- Long.toHexString(nanoAppBinary.getNanoAppId()));
+ Long.toHexString(nanoAppBinary.getNanoAppId()), e);
return Result.UNKNOWN_FAILURE;
}
}
@Override
- /* package */ void onTimeout() {
- onTransactionComplete(ContextHubTransaction.TRANSACTION_FAILED_TIMEOUT);
- }
-
- @Override
/* package */ void onTransactionComplete(int result) {
try {
onCompleteCallback.onTransactionComplete(result);
@@ -124,7 +119,7 @@
mClientManager.onNanoAppLoaded(contextHubId, nanoAppBinary.getNanoAppId());
}
} catch (RemoteException e) {
- Log.e(TAG, "RemoteException while calling client onTransactionComplete");
+ Log.e(TAG, "RemoteException while calling client onTransactionComplete", e);
}
}
};
@@ -149,17 +144,12 @@
contextHubId, nanoAppId, this.getTransactionId());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException while trying to unload nanoapp with ID 0x" +
- Long.toHexString(nanoAppId));
+ Long.toHexString(nanoAppId), e);
return Result.UNKNOWN_FAILURE;
}
}
@Override
- /* package */ void onTimeout() {
- onTransactionComplete(ContextHubTransaction.TRANSACTION_FAILED_TIMEOUT);
- }
-
- @Override
/* package */ void onTransactionComplete(int result) {
try {
onCompleteCallback.onTransactionComplete(result);
@@ -167,7 +157,7 @@
mClientManager.onNanoAppUnloaded(contextHubId, nanoAppId);
}
} catch (RemoteException e) {
- Log.e(TAG, "RemoteException while calling client onTransactionComplete");
+ Log.e(TAG, "RemoteException while calling client onTransactionComplete", e);
}
}
};
@@ -189,15 +179,14 @@
try {
return mContextHubProxy.queryApps(contextHubId);
} catch (RemoteException e) {
- Log.e(TAG, "RemoteException while trying to query for nanoapps");
+ Log.e(TAG, "RemoteException while trying to query for nanoapps", e);
return Result.UNKNOWN_FAILURE;
}
}
@Override
- /* package */ void onTimeout() {
- onQueryResponse(ContextHubTransaction.TRANSACTION_FAILED_TIMEOUT,
- Collections.emptyList());
+ /* package */ void onTransactionComplete(int result) {
+ onQueryResponse(result, Collections.emptyList());
}
@Override
@@ -205,7 +194,7 @@
try {
onCompleteCallback.onQueryResponse(result, nanoAppStateList);
} catch (RemoteException e) {
- Log.e(TAG, "RemoteException while calling client onQueryComplete");
+ Log.e(TAG, "RemoteException while calling client onQueryComplete", e);
}
}
};
@@ -333,7 +322,8 @@
synchronized (this) {
if (!transaction.isComplete()) {
Log.d(TAG, transaction + " timed out");
- transaction.onTimeout();
+ transaction.onTransactionComplete(
+ ContextHubTransaction.TRANSACTION_FAILED_TIMEOUT);
removeTransactionAndStartNext();
}
@@ -344,6 +334,8 @@
mTimeoutFuture = mTimeoutExecutor.schedule(onTimeoutFunc, timeoutSeconds,
TimeUnit.SECONDS);
} else {
+ transaction.onTransactionComplete(
+ ContextHubServiceUtil.toTransactionResult(result));
mTransactionQueue.remove();
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d0ad4ac..4b6589c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -467,6 +467,7 @@
static final int SCAN_AS_SYSTEM = 1<<17;
static final int SCAN_AS_PRIVILEGED = 1<<18;
static final int SCAN_AS_OEM = 1<<19;
+ static final int SCAN_AS_VENDOR = 1<<20;
@IntDef(flag = true, prefix = { "SCAN_" }, value = {
SCAN_NO_DEX,
@@ -2574,8 +2575,25 @@
| SCAN_AS_SYSTEM,
0);
- // Collect all vendor packages.
- File vendorAppDir = new File("/vendor/app");
+ // Collected privileged vendor packages.
+ File privilegedVendorAppDir = new File(Environment.getVendorDirectory(),
+ "priv-app");
+ try {
+ privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
+ } catch (IOException e) {
+ // failed to look up canonical path, continue with original one
+ }
+ scanDirTracedLI(privilegedVendorAppDir,
+ mDefParseFlags
+ | PackageParser.PARSE_IS_SYSTEM_DIR,
+ scanFlags
+ | SCAN_AS_SYSTEM
+ | SCAN_AS_VENDOR
+ | SCAN_AS_PRIVILEGED,
+ 0);
+
+ // Collect ordinary vendor packages.
+ File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
try {
vendorAppDir = vendorAppDir.getCanonicalFile();
} catch (IOException e) {
@@ -2585,7 +2603,8 @@
mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags
- | SCAN_AS_SYSTEM,
+ | SCAN_AS_SYSTEM
+ | SCAN_AS_VENDOR,
0);
// Collect all OEM packages.
@@ -2770,13 +2789,23 @@
rescanFlags =
scanFlags
| SCAN_AS_SYSTEM;
+ } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)) {
+ reparseFlags =
+ mDefParseFlags |
+ PackageParser.PARSE_IS_SYSTEM_DIR;
+ rescanFlags =
+ scanFlags
+ | SCAN_AS_SYSTEM
+ | SCAN_AS_VENDOR
+ | SCAN_AS_PRIVILEGED;
} else if (FileUtils.contains(vendorAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
PackageParser.PARSE_IS_SYSTEM_DIR;
rescanFlags =
scanFlags
- | SCAN_AS_SYSTEM;
+ | SCAN_AS_SYSTEM
+ | SCAN_AS_VENDOR;
} else if (FileUtils.contains(oemAppDir, scanFile)) {
reparseFlags =
mDefParseFlags |
@@ -8335,6 +8364,13 @@
} else {
updatedPs.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_OEM;
}
+ // If new package is not located in "/vendor" (e.g. due to an OTA),
+ // it needs to drop FLAG_VENDOR.
+ if (locationIsVendor(pkg.codePath)) {
+ updatedPs.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
+ } else {
+ updatedPs.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_VENDOR;
+ }
if (ps != null && !ps.codePathString.equals(pkg.codePath)) {
// The path has changed from what was last scanned... check the
@@ -8455,11 +8491,17 @@
scanFlags |= SCAN_AS_PRIVILEGED;
}
- // An updated OEM app will not have the PARSE_IS_OEM
+ // An updated OEM app will not have the SCAN_AS_OEM
// flag set initially
if ((updatedPs.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
scanFlags |= SCAN_AS_OEM;
}
+
+ // An updated vendor app will not have the SCAN_AS_VENDOR
+ // flag set initially
+ if ((updatedPs.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
+ scanFlags |= SCAN_AS_VENDOR;
+ }
}
// Verify certificates against what was last scanned
@@ -10208,6 +10250,10 @@
pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
}
+ if ((scanFlags & SCAN_AS_VENDOR) != 0) {
+ pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
+ }
+
if (!isSystemApp(pkg)) {
// Only system apps can use these features.
pkg.mOriginalPackages = null;
@@ -15493,6 +15539,15 @@
return;
}
+ // check if the new package supports all of the abis which the old package supports
+ boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
+ boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
+ if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
+ res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
+ "Update to package " + pkgName + " doesn't support multi arch");
+ return;
+ }
+
// In case of rollback, remember per-user/profile install state
allUsers = sUserManager.getUserIds();
installedUsers = ps.queryInstalledUsers(allUsers, true);
@@ -15574,18 +15629,22 @@
boolean sysPkg = (isSystemApp(oldPackage));
if (sysPkg) {
- // Set the system/privileged/oem flags as needed
+ // Set the system/privileged/oem/vendor flags as needed
final boolean privileged =
(oldPackage.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
final boolean oem =
(oldPackage.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
+ final boolean vendor =
+ (oldPackage.applicationInfo.privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
final @ParseFlags int systemParseFlags = parseFlags;
final @ScanFlags int systemScanFlags = scanFlags
| SCAN_AS_SYSTEM
| (privileged ? SCAN_AS_PRIVILEGED : 0)
- | (oem ? SCAN_AS_OEM : 0);
+ | (oem ? SCAN_AS_OEM : 0)
+ | (vendor ? SCAN_AS_VENDOR : 0);
replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
user, allUsers, installerPackageName, res, installReason);
@@ -16764,6 +16823,10 @@
return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
}
+ private static boolean isVendorApp(PackageParser.Package pkg) {
+ return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
+ }
+
private static boolean hasDomainURLs(PackageParser.Package pkg) {
return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
}
@@ -17498,7 +17561,9 @@
static boolean locationIsPrivileged(String path) {
try {
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
- return path.startsWith(privilegedAppDir.getCanonicalPath());
+ final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
+ return path.startsWith(privilegedAppDir.getCanonicalPath())
+ || path.startsWith(privilegedVendorAppDir.getCanonicalPath());
} catch (IOException e) {
Slog.e(TAG, "Unable to access code path " + path);
}
@@ -17514,6 +17579,15 @@
return false;
}
+ static boolean locationIsVendor(String path) {
+ try {
+ return path.startsWith(Environment.getVendorDirectory().getCanonicalPath());
+ } catch (IOException e) {
+ Slog.e(TAG, "Unable to access code path " + path);
+ }
+ return false;
+ }
+
/*
* Tries to delete system package.
*/
@@ -17635,6 +17709,9 @@
if (locationIsOem(codePathString)) {
scanFlags |= SCAN_AS_OEM;
}
+ if (locationIsVendor(codePathString)) {
+ scanFlags |= SCAN_AS_VENDOR;
+ }
final File codePath = new File(codePathString);
final PackageParser.Package pkg =
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 44f36d1..45b94a4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1538,13 +1538,26 @@
return 0;
}
+ private boolean isVendorApp(String pkg) {
+ try {
+ final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
+ return info != null && info.applicationInfo.isVendor();
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
private int runGetPrivappPermissions() {
final String pkg = getNextArg();
if (pkg == null) {
getErrPrintWriter().println("Error: no package specified.");
return 1;
}
- ArraySet<String> privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
+
+ ArraySet<String> privAppPermissions = isVendorApp(pkg) ?
+ SystemConfig.getInstance().getVendorPrivAppPermissions(pkg)
+ : SystemConfig.getInstance().getPrivAppPermissions(pkg);
+
getOutPrintWriter().println(privAppPermissions == null
? "{}" : privAppPermissions.toString());
return 0;
@@ -1556,10 +1569,13 @@
getErrPrintWriter().println("Error: no package specified.");
return 1;
}
- ArraySet<String> privAppDenyPermissions =
- SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
- getOutPrintWriter().println(privAppDenyPermissions == null
- ? "{}" : privAppDenyPermissions.toString());
+
+ ArraySet<String> privAppPermissions = isVendorApp(pkg) ?
+ SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg)
+ : SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
+
+ getOutPrintWriter().println(privAppPermissions == null
+ ? "{}" : privAppPermissions.toString());
return 0;
}
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 3b414e9..258dd4d4 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -140,6 +140,10 @@
return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
}
+ public boolean isVendor() {
+ return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
+ }
+
public boolean isForwardLocked() {
return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0;
}
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index c97f5e5..46ba006 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -61,6 +61,7 @@
this.pkgPrivateFlags = pkgPrivateFlags
& (ApplicationInfo.PRIVATE_FLAG_PRIVILEGED
| ApplicationInfo.PRIVATE_FLAG_OEM
+ | ApplicationInfo.PRIVATE_FLAG_VENDOR
| ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK
| ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER);
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index ddad677..af1a4d1 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -847,6 +847,8 @@
pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
pkgSetting.pkgPrivateFlags |=
pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM;
+ pkgSetting.pkgPrivateFlags |=
+ pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR;
pkgSetting.primaryCpuAbiString = primaryCpuAbi;
pkgSetting.secondaryCpuAbiString = secondaryCpuAbi;
if (childPkgNames != null) {
@@ -4421,6 +4423,7 @@
ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED",
ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER",
ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY, "STATIC_SHARED_LIBRARY",
+ ApplicationInfo.PRIVATE_FLAG_VENDOR, "VENDOR",
ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD",
};
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 8c86db6..75a6106 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -225,6 +225,9 @@
public boolean isVerifier() {
return (protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0;
}
+ public boolean isVendorPrivileged() {
+ return (protectionLevel & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0;
+ }
public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) {
if (!origPackageName.equals(sourcePackageName)) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 7d8e206..90ac4ab 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -959,8 +959,9 @@
* <p>This handles parent/child apps.
*/
private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
- ArraySet<String> wlPermissions = SystemConfig.getInstance()
- .getPrivAppPermissions(pkg.packageName);
+ ArraySet<String> wlPermissions = pkg.isVendor() ?
+ SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName)
+ : SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
// Let's check if this package is whitelisted...
boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
// If it's not, we'll also tail-recurse to the parent.
@@ -971,7 +972,8 @@
private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
BasePermission bp, PermissionsState origPermissions) {
boolean oemPermission = bp.isOEM();
- boolean privilegedPermission = bp.isPrivileged();
+ boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
+ boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
boolean privappPermissionsDisable =
RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
@@ -982,8 +984,11 @@
// Only report violations for apps on system image
if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
// it's only a reportable violation if the permission isn't explicitly denied
- final ArraySet<String> deniedPermissions = SystemConfig.getInstance()
- .getPrivAppDenyPermissions(pkg.packageName);
+ final ArraySet<String> deniedPermissions = pkg.isVendor() ?
+ SystemConfig.getInstance()
+ .getVendorPrivAppDenyPermissions(pkg.packageName)
+ : SystemConfig.getInstance()
+ .getPrivAppDenyPermissions(pkg.packageName);
final boolean permissionViolation =
deniedPermissions == null || !deniedPermissions.contains(perm);
if (permissionViolation) {
@@ -1086,6 +1091,15 @@
|| (oemPermission && pkg.isOem()
&& canGrantOemPermission(ps, perm));
}
+ // In any case, don't grant a privileged permission to privileged vendor apps, if
+ // the permission's protectionLevel does not have the extra 'vendorPrivileged'
+ // flag.
+ if (allowed && privilegedPermission &&
+ !vendorPrivilegedPermission && pkg.isVendor()) {
+ Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
+ + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
+ allowed = false;
+ }
}
}
if (!allowed) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
deleted file mode 100644
index e6b4540f..0000000
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2016 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.server.pm;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PermissionInfo;
-import android.platform.test.annotations.GlobalPresubmit;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.util.ArraySet;
-
-import com.android.internal.os.RoSystemProperties;
-import com.android.internal.util.ArrayUtils;
-import com.android.server.SystemConfig;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-import static android.content.pm.PackageManager.GET_PERMISSIONS;
-import static junit.framework.Assert.assertTrue;
-
-
-/**
- * Presubmit tests for {@link PackageManager}.
- */
-@RunWith(AndroidJUnit4.class)
-public class PackageManagerPresubmitTest {
-
- private Context mContext;
-
- private PackageManager mPackageManager;
-
- @Before
- public void setUp() {
- mContext = InstrumentationRegistry.getContext();
- mPackageManager = mContext.getPackageManager();
- }
-
- /**
- * <p>This test ensures that all signature|privileged permissions are granted to priv-apps.
- * If CONTROL_PRIVAPP_PERMISSIONS_ENFORCE is set, the test also verifies that
- * granted permissions are whitelisted in {@link SystemConfig}
- */
- @Test
- @SmallTest
- @GlobalPresubmit
- public void testPrivAppPermissions() throws PackageManager.NameNotFoundException {
- List<PackageInfo> installedPackages = mPackageManager
- .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES | GET_PERMISSIONS);
- for (PackageInfo packageInfo : installedPackages) {
- if (!packageInfo.applicationInfo.isPrivilegedApp()
- || PackageManagerService.PLATFORM_PACKAGE_NAME.equals(packageInfo.packageName)) {
- continue;
- }
- testPackagePrivAppPermission(packageInfo);
- }
-
- }
-
- private void testPackagePrivAppPermission(PackageInfo packageInfo)
- throws PackageManager.NameNotFoundException {
- String packageName = packageInfo.packageName;
- ArraySet<String> privAppPermissions = SystemConfig.getInstance()
- .getPrivAppPermissions(packageName);
- if (ArrayUtils.isEmpty(packageInfo.requestedPermissions)) {
- return;
- }
- for (int i = 0; i < packageInfo.requestedPermissions.length; i++) {
- String pName = packageInfo.requestedPermissions[i];
- int protectionLevel;
- boolean platformPermission;
- try {
- PermissionInfo permissionInfo = mPackageManager.getPermissionInfo(pName, 0);
- platformPermission = PackageManagerService.PLATFORM_PACKAGE_NAME.equals(
- permissionInfo.packageName);
- protectionLevel = permissionInfo.protectionLevel;
- } catch (PackageManager.NameNotFoundException e) {
- continue;
- }
- if ((protectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
- boolean granted = (packageInfo.requestedPermissionsFlags[i]
- & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
- // if privapp permissions are enforced, platform permissions must be whitelisted
- // in SystemConfig
- if (platformPermission && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
- assertTrue("Permission " + pName + " should be declared in "
- + "privapp-permissions-<category>.xml file for package "
- + packageName,
- privAppPermissions != null && privAppPermissions.contains(pName));
- }
- assertTrue("Permission " + pName + " should be granted to " + packageName, granted);
- }
- }
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java b/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
index 39d256a..b62d724 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
@@ -16,14 +16,17 @@
package com.android.server.usage;
-import android.app.usage.AppStandby;
+import static android.app.usage.UsageStatsManager.REASON_TIMEOUT;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
+
+import android.app.usage.UsageStatsManager;
import android.os.FileUtils;
import android.test.AndroidTestCase;
import java.io.File;
-import static android.app.usage.AppStandby.*;
-
public class AppIdleHistoryTests extends AndroidTestCase {
File mStorageDir;
@@ -85,12 +88,12 @@
AppIdleHistory aih = new AppIdleHistory(mStorageDir, 1000);
aih.setAppStandbyBucket(PACKAGE_1, USER_ID, 1000, STANDBY_BUCKET_ACTIVE,
- AppStandby.REASON_USAGE);
+ UsageStatsManager.REASON_USAGE);
// ACTIVE means not idle
assertFalse(aih.isIdle(PACKAGE_1, USER_ID, 2000));
aih.setAppStandbyBucket(PACKAGE_2, USER_ID, 2000, STANDBY_BUCKET_ACTIVE,
- AppStandby.REASON_USAGE);
+ UsageStatsManager.REASON_USAGE);
aih.setAppStandbyBucket(PACKAGE_1, USER_ID, 3000, STANDBY_BUCKET_RARE,
REASON_TIMEOUT);
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 40edfd2..87b34ab 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -16,9 +16,12 @@
package com.android.server.usage;
-import static android.app.usage.AppStandby.*;
import static android.app.usage.UsageEvents.Event.NOTIFICATION_SEEN;
import static android.app.usage.UsageEvents.Event.USER_INTERACTION;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -30,8 +33,8 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import android.app.usage.AppStandby;
import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManager;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.ContextWrapper;
@@ -280,7 +283,7 @@
public void testBuckets() throws Exception {
AppStandbyController controller = setupController();
- assertTimeout(controller, 0, STANDBY_BUCKET_NEVER);
+ assertTimeout(controller, 0, UsageStatsManager.STANDBY_BUCKET_NEVER);
reportEvent(controller, USER_INTERACTION, 0);
@@ -312,7 +315,7 @@
AppStandbyController controller = setupController();
mInjector.setDisplayOn(false);
- assertTimeout(controller, 0, STANDBY_BUCKET_NEVER);
+ assertTimeout(controller, 0, UsageStatsManager.STANDBY_BUCKET_NEVER);
reportEvent(controller, USER_INTERACTION, 0);
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java
index ee11241..5aef55b 100644
--- a/services/usage/java/com/android/server/usage/AppIdleHistory.java
+++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java
@@ -16,10 +16,7 @@
package com.android.server.usage;
-import static android.app.usage.AppStandby.*;
-
-import android.app.usage.AppStandby;
-import android.os.Environment;
+import android.app.usage.UsageStatsManager;
import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.AtomicFile;
@@ -99,7 +96,8 @@
final byte[] recent = new byte[HISTORY_SIZE];
long lastUsedElapsedTime;
long lastUsedScreenTime;
- @StandbyBuckets int currentBucket;
+ @UsageStatsManager.StandbyBuckets
+ int currentBucket;
String bucketingReason;
int lastInformedBucket;
}
@@ -190,14 +188,14 @@
+ (elapsedRealtime - mElapsedSnapshot);
appUsageHistory.lastUsedScreenTime = getScreenOnTime(elapsedRealtime);
appUsageHistory.recent[HISTORY_SIZE - 1] = FLAG_LAST_STATE | FLAG_PARTIAL_ACTIVE;
- if (appUsageHistory.currentBucket > STANDBY_BUCKET_ACTIVE) {
- appUsageHistory.currentBucket = STANDBY_BUCKET_ACTIVE;
+ if (appUsageHistory.currentBucket > UsageStatsManager.STANDBY_BUCKET_ACTIVE) {
+ appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_ACTIVE;
if (DEBUG) {
Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory.currentBucket
+ ", reason=" + appUsageHistory.bucketingReason);
}
}
- appUsageHistory.bucketingReason = AppStandby.REASON_USAGE;
+ appUsageHistory.bucketingReason = UsageStatsManager.REASON_USAGE;
return appUsageHistory.currentBucket;
}
@@ -206,15 +204,15 @@
ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName,
elapsedRealtime, true);
- if (appUsageHistory.currentBucket > STANDBY_BUCKET_WORKING_SET) {
- appUsageHistory.currentBucket = STANDBY_BUCKET_WORKING_SET;
+ if (appUsageHistory.currentBucket > UsageStatsManager.STANDBY_BUCKET_WORKING_SET) {
+ appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
if (DEBUG) {
Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory.currentBucket
+ ", reason=" + appUsageHistory.bucketingReason);
}
}
// TODO: Should this be a different reason for partial usage?
- appUsageHistory.bucketingReason = AppStandby.REASON_USAGE;
+ appUsageHistory.bucketingReason = UsageStatsManager.REASON_USAGE;
return appUsageHistory.currentBucket;
}
@@ -271,8 +269,9 @@
appUsageHistory = new AppUsageHistory();
appUsageHistory.lastUsedElapsedTime = getElapsedTime(elapsedRealtime);
appUsageHistory.lastUsedScreenTime = getScreenOnTime(elapsedRealtime);
- appUsageHistory.currentBucket = AppStandby.STANDBY_BUCKET_NEVER;
- appUsageHistory.bucketingReason = REASON_DEFAULT;
+ appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_NEVER;
+ appUsageHistory.bucketingReason = UsageStatsManager.REASON_DEFAULT;
+ appUsageHistory.lastInformedBucket = -1;
userHistory.put(packageName, appUsageHistory);
}
return appUsageHistory;
@@ -289,7 +288,7 @@
if (appUsageHistory == null) {
return false; // Default to not idle
} else {
- return appUsageHistory.currentBucket >= AppStandby.STANDBY_BUCKET_RARE;
+ return appUsageHistory.currentBucket >= UsageStatsManager.STANDBY_BUCKET_RARE;
// Whether or not it's passed will now be externally calculated and the
// bucket will be pushed to the history using setAppStandbyBucket()
//return hasPassedThresholds(appUsageHistory, elapsedRealtime);
@@ -333,12 +332,12 @@
AppUsageHistory appUsageHistory = getPackageHistory(userHistory, packageName,
elapsedRealtime, true);
if (idle) {
- appUsageHistory.currentBucket = STANDBY_BUCKET_RARE;
- appUsageHistory.bucketingReason = REASON_FORCED;
+ appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_RARE;
+ appUsageHistory.bucketingReason = UsageStatsManager.REASON_FORCED;
} else {
- appUsageHistory.currentBucket = STANDBY_BUCKET_ACTIVE;
+ appUsageHistory.currentBucket = UsageStatsManager.STANDBY_BUCKET_ACTIVE;
// This is to pretend that the app was just used, don't freeze the state anymore.
- appUsageHistory.bucketingReason = REASON_USAGE;
+ appUsageHistory.bucketingReason = UsageStatsManager.REASON_USAGE;
}
return appUsageHistory.currentBucket;
}
@@ -435,12 +434,12 @@
String currentBucketString = parser.getAttributeValue(null,
ATTR_CURRENT_BUCKET);
appUsageHistory.currentBucket = currentBucketString == null
- ? AppStandby.STANDBY_BUCKET_ACTIVE
+ ? UsageStatsManager.STANDBY_BUCKET_ACTIVE
: Integer.parseInt(currentBucketString);
appUsageHistory.bucketingReason =
parser.getAttributeValue(null, ATTR_BUCKETING_REASON);
if (appUsageHistory.bucketingReason == null) {
- appUsageHistory.bucketingReason = REASON_DEFAULT;
+ appUsageHistory.bucketingReason = UsageStatsManager.REASON_DEFAULT;
}
userHistory.put(packageName, appUsageHistory);
}
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index 3c099c2..4527879 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -16,15 +16,23 @@
package com.android.server.usage;
+import static android.app.usage.UsageStatsManager.REASON_FORCED;
+import static android.app.usage.UsageStatsManager.REASON_TIMEOUT;
+import static android.app.usage.UsageStatsManager.REASON_USAGE;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
+
import static com.android.server.SystemService.PHASE_BOOT_COMPLETED;
import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.admin.DevicePolicyManager;
-import android.app.usage.AppStandby;
-import android.app.usage.AppStandby.StandbyBuckets;
+import android.app.usage.UsageStatsManager.StandbyBuckets;
import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
@@ -102,10 +110,10 @@
};
static final int[] THRESHOLD_BUCKETS = {
- AppStandby.STANDBY_BUCKET_ACTIVE,
- AppStandby.STANDBY_BUCKET_WORKING_SET,
- AppStandby.STANDBY_BUCKET_FREQUENT,
- AppStandby.STANDBY_BUCKET_RARE
+ STANDBY_BUCKET_ACTIVE,
+ STANDBY_BUCKET_WORKING_SET,
+ STANDBY_BUCKET_FREQUENT,
+ STANDBY_BUCKET_RARE
};
// To name the lock for stack traces
@@ -371,18 +379,18 @@
}
if (isSpecial) {
maybeInformListeners(packageName, userId, elapsedRealtime,
- AppStandby.STANDBY_BUCKET_ACTIVE);
+ STANDBY_BUCKET_ACTIVE);
} else {
synchronized (mAppIdleLock) {
String bucketingReason = mAppIdleHistory.getAppStandbyReason(packageName,
userId, elapsedRealtime);
// If the bucket was forced by the developer, leave it alone
- if (AppStandby.REASON_FORCED.equals(bucketingReason)) {
+ if (REASON_FORCED.equals(bucketingReason)) {
continue;
}
// If the bucket was moved up due to usage, let the timeouts apply.
- if (AppStandby.REASON_USAGE.equals(bucketingReason)
- || AppStandby.REASON_TIMEOUT.equals(bucketingReason)) {
+ if (REASON_USAGE.equals(bucketingReason)
+ || REASON_TIMEOUT.equals(bucketingReason)) {
int oldBucket = mAppIdleHistory.getAppStandbyBucket(packageName, userId,
elapsedRealtime);
int newBucket = getBucketForLocked(packageName, userId,
@@ -393,7 +401,7 @@
}
if (oldBucket < newBucket) {
mAppIdleHistory.setAppStandbyBucket(packageName, userId,
- elapsedRealtime, newBucket, AppStandby.REASON_TIMEOUT);
+ elapsedRealtime, newBucket, REASON_TIMEOUT);
maybeInformListeners(packageName, userId, elapsedRealtime,
newBucket);
}
@@ -742,7 +750,7 @@
long elapsedRealtime, boolean shouldObfuscateInstantApps) {
if (shouldObfuscateInstantApps &&
mInjector.isPackageEphemeral(userId, packageName)) {
- return AppStandby.STANDBY_BUCKET_ACTIVE;
+ return STANDBY_BUCKET_ACTIVE;
}
return mAppIdleHistory.getAppStandbyBucket(packageName, userId, elapsedRealtime);
@@ -811,7 +819,7 @@
}
void informListeners(String packageName, int userId, int bucket) {
- final boolean idle = bucket >= AppStandby.STANDBY_BUCKET_RARE;
+ final boolean idle = bucket >= STANDBY_BUCKET_RARE;
for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
listener.onAppIdleStateChanged(packageName, userId, idle, bucket);
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 65c1cef..878fbed 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -20,11 +20,11 @@
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IUidObserver;
-import android.app.usage.AppStandby;
import android.app.usage.ConfigurationStats;
import android.app.usage.IUsageStatsManager;
import android.app.usage.UsageEvents;
-import android.app.usage.AppStandby.StandbyBuckets;
+import android.app.usage.UsageStatsManager;
+import android.app.usage.UsageStatsManager.StandbyBuckets;
import android.app.usage.UsageEvents.Event;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManagerInternal;
@@ -149,6 +149,8 @@
publishLocalService(UsageStatsManagerInternal.class, new LocalService());
publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
+ // Make sure we initialize the data, in case job scheduler needs it early.
+ getUserDataAndInitializeIfNeededLocked(UserHandle.USER_SYSTEM, mSystemTimeSnapshot);
}
@Override
@@ -678,10 +680,6 @@
@Override
public int getAppStandbyBucket(String packageName, String callingPackage, int userId) {
- if (!hasPermission(callingPackage)) {
- throw new SecurityException("Don't have permission to query app standby bucket");
- }
-
final int callingUid = Binder.getCallingUid();
try {
userId = ActivityManager.getService().handleIncomingUser(
@@ -690,6 +688,14 @@
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
+ // If the calling app is asking about itself, continue, else check for permission.
+ if (mPackageManagerInternal.getPackageUid(packageName, PackageManager.MATCH_ANY_USER,
+ userId) != callingUid) {
+ if (!hasPermission(callingPackage)) {
+ throw new SecurityException(
+ "Don't have permission to query app standby bucket");
+ }
+ }
final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(callingUid,
userId);
final long token = Binder.clearCallingIdentity();
@@ -707,6 +713,10 @@
getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
"No permission to change app standby state");
+ if (bucket < UsageStatsManager.STANDBY_BUCKET_ACTIVE
+ || bucket > UsageStatsManager.STANDBY_BUCKET_NEVER) {
+ throw new IllegalArgumentException("Cannot set the standby bucket to " + bucket);
+ }
final int callingUid = Binder.getCallingUid();
try {
userId = ActivityManager.getService().handleIncomingUser(
@@ -717,8 +727,13 @@
}
final long token = Binder.clearCallingIdentity();
try {
+ // Caller cannot set their own standby state
+ if (mPackageManagerInternal.getPackageUid(packageName,
+ PackageManager.MATCH_ANY_USER, userId) == callingUid) {
+ throw new IllegalArgumentException("Cannot set your own standby bucket");
+ }
mAppStandby.setAppStandbyBucket(packageName, userId, bucket,
- AppStandby.REASON_PREDICTED + ":" + callingUid,
+ UsageStatsManager.REASON_PREDICTED + ":" + callingUid,
SystemClock.elapsedRealtime());
} finally {
Binder.restoreCallingIdentity(token);
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
index f392570..a554c69 100644
--- a/telephony/java/android/telephony/MbmsDownloadSession.java
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -347,6 +347,7 @@
@Override
public void onServiceDisconnected(ComponentName name) {
+ Log.w(LOG_TAG, "bindAndInitialize: Remote service disconnected");
sIsInitialized.set(false);
mService.set(null);
}
@@ -385,6 +386,7 @@
} catch (RemoteException e) {
Log.w(LOG_TAG, "Remote process died");
mService.set(null);
+ sIsInitialized.set(false);
sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
}
}
@@ -438,6 +440,7 @@
}
} catch (RemoteException e) {
mService.set(null);
+ sIsInitialized.set(false);
sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
return;
}
@@ -521,6 +524,7 @@
downloadService.download(request);
} catch (RemoteException e) {
mService.set(null);
+ sIsInitialized.set(false);
sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
}
}
@@ -542,6 +546,7 @@
return downloadService.listPendingDownloads(mSubscriptionId);
} catch (RemoteException e) {
mService.set(null);
+ sIsInitialized.set(false);
sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
return Collections.emptyList();
}
@@ -583,6 +588,7 @@
}
} catch (RemoteException e) {
mService.set(null);
+ sIsInitialized.set(false);
sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
return;
}
@@ -622,6 +628,7 @@
}
} catch (RemoteException e) {
mService.set(null);
+ sIsInitialized.set(false);
sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
}
} finally {
@@ -658,6 +665,7 @@
}
} catch (RemoteException e) {
mService.set(null);
+ sIsInitialized.set(false);
sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
return;
}
@@ -686,6 +694,7 @@
return downloadService.getDownloadStatus(downloadRequest, fileInfo);
} catch (RemoteException e) {
mService.set(null);
+ sIsInitialized.set(false);
sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
return STATUS_UNKNOWN;
}
@@ -727,6 +736,7 @@
}
} catch (RemoteException e) {
mService.set(null);
+ sIsInitialized.set(false);
sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
}
}
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index a13af5f..2507cfee 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -63,7 +63,7 @@
* embedded SIM.
*
* <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
- * {@link #isEnabled} is false or if the device is already provisioned.
+ * {@link #isEnabled} is false.
*
* TODO(b/35851809): Make this a SystemApi.
*/
diff --git a/tests/privapp-permissions/Android.mk b/tests/privapp-permissions/Android.mk
new file mode 100644
index 0000000..b001c8c
--- /dev/null
+++ b/tests/privapp-permissions/Android.mk
@@ -0,0 +1,31 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := PrivAppPermissionTest
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_MANIFEST_FILE := system/AndroidManifest.xml
+LOCAL_REQUIRED_MODULES := privapp-permissions-test.xml
+include $(BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := privapp-permissions-test.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+LOCAL_SRC_FILES:= system/privapp-permissions-test.xml
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := VendorPrivAppPermissionTest
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_MANIFEST_FILE := vendor/AndroidManifest.xml
+LOCAL_VENDOR_MODULE := true
+LOCAL_REQUIRED_MODULES := vendorprivapp-permissions-test.xml
+include $(BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := vendorprivapp-permissions-test.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/permissions
+LOCAL_SRC_FILES:= vendor/privapp-permissions-test.xml
+include $(BUILD_PREBUILT)
+
diff --git a/tests/privapp-permissions/system/AndroidManifest.xml b/tests/privapp-permissions/system/AndroidManifest.xml
new file mode 100644
index 0000000..2099e31
--- /dev/null
+++ b/tests/privapp-permissions/system/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2017 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.framework.permission.privapp.tests.system">
+
+ <!-- MANAGE_USB is signature|privileged -->
+ <uses-permission android:name="android.permission.MANAGE_USB"/>
+</manifest>
diff --git a/tests/privapp-permissions/system/privapp-permissions-test.xml b/tests/privapp-permissions/system/privapp-permissions-test.xml
new file mode 100644
index 0000000..a0cb6bc
--- /dev/null
+++ b/tests/privapp-permissions/system/privapp-permissions-test.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<permissions>
+ <privapp-permissions package="com.android.framework.permission.privapp.tests.system">
+ <permission name="android.permission.MANAGE_USB"/>
+ </privapp-permissions>
+</permissions>
diff --git a/tests/privapp-permissions/vendor/AndroidManifest.xml b/tests/privapp-permissions/vendor/AndroidManifest.xml
new file mode 100644
index 0000000..78dedc5
--- /dev/null
+++ b/tests/privapp-permissions/vendor/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2017 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.framework.permission.privapp.tests.vendor">
+
+ <!-- BIND_IMS_SERVICE is signature|privileged|vendorPrivileged -->
+ <uses-permission android:name="android.permission.BIND_IMS_SERVICE"/>
+ <!-- MANAGE_USB is signature|privileged and thus cannot be granted to this app -->
+ <uses-permission android:name="android.permission.MANAGE_USB"/>
+</manifest>
diff --git a/tests/privapp-permissions/vendor/privapp-permissions-test.xml b/tests/privapp-permissions/vendor/privapp-permissions-test.xml
new file mode 100644
index 0000000..51c588f
--- /dev/null
+++ b/tests/privapp-permissions/vendor/privapp-permissions-test.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<permissions>
+ <privapp-permissions package="com.android.framework.permission.privapp.tests.vendor">
+ <permission name="android.permission.BIND_IMS_SERVICE"/>
+ <permission name="android.permission.MANAGE_USB"/>
+ </privapp-permissions>
+</permissions>
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index e0c9d1c..c9987b8 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -1,7 +1,11 @@
+LOCAL_PATH := $(call my-dir)
+
include $(CLEAR_VARS)
+# Target for running host unit tests on post/pre-submit.
.PHONY: aapt2_run_host_unit_tests
aapt2_run_host_unit_tests: PRIVATE_GTEST_OPTIONS := --gtest_output=xml:$(DIST_DIR)/gtest/aapt2_host_unit_tests_result.xml
aapt2_run_host_unit_tests: $(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests
-$(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests $(PRIVATE_GTEST_OPTIONS) > /dev/null 2>&1
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index e94c0b4..d2aebfd 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -36,6 +36,7 @@
#include "ValueVisitor.h"
#include "cmd/Util.h"
#include "compile/IdAssigner.h"
+#include "compile/XmlIdCollector.h"
#include "filter/ConfigFilter.h"
#include "format/Archive.h"
#include "format/Container.h"
@@ -1235,19 +1236,10 @@
return true;
}
- bool MergeCompiledFile(const ResourceFile& compiled_file, io::IFile* file, bool override) {
- if (context_->IsVerbose()) {
- context_->GetDiagnostics()->Note(DiagMessage()
- << "merging '" << compiled_file.name
- << "' from compiled file " << compiled_file.source);
- }
-
- if (!table_merger_->MergeFile(compiled_file, override, file)) {
- return false;
- }
-
+ bool MergeExportedSymbols(const Source& source,
+ const std::vector<SourcedResourceName>& exported_symbols) {
// Add the exports of this file to the table.
- for (const SourcedResourceName& exported_symbol : compiled_file.exported_symbols) {
+ for (const SourcedResourceName& exported_symbol : exported_symbols) {
ResourceName res_name = exported_symbol.name;
if (res_name.package.empty()) {
res_name.package = context_->GetCompilationPackage();
@@ -1259,7 +1251,7 @@
}
std::unique_ptr<Id> id = util::make_unique<Id>();
- id->SetSource(compiled_file.source.WithLine(exported_symbol.line));
+ id->SetSource(source.WithLine(exported_symbol.line));
bool result = final_table_.AddResourceAllowMangled(
res_name, ConfigDescription::DefaultConfig(), std::string(), std::move(id),
context_->GetDiagnostics());
@@ -1270,6 +1262,19 @@
return true;
}
+ bool MergeCompiledFile(const ResourceFile& compiled_file, io::IFile* file, bool override) {
+ if (context_->IsVerbose()) {
+ context_->GetDiagnostics()->Note(DiagMessage()
+ << "merging '" << compiled_file.name
+ << "' from compiled file " << compiled_file.source);
+ }
+
+ if (!table_merger_->MergeFile(compiled_file, override, file)) {
+ return false;
+ }
+ return MergeExportedSymbols(compiled_file.source, compiled_file.exported_symbols);
+ }
+
// Takes a path to load as a ZIP file and merges the files within into the master ResourceTable.
// If override is true, conflicting resources are allowed to override each other, in order of last
// seen.
@@ -1573,6 +1578,19 @@
context_->GetPackageId()));
}
+ // Extract symbols from AndroidManifest.xml, since this isn't merged like the other XML files
+ // in res/**/*.
+ {
+ XmlIdCollector collector;
+ if (!collector.Consume(context_, manifest_xml.get())) {
+ return false;
+ }
+
+ if (!MergeExportedSymbols(manifest_xml->file.source, manifest_xml->file.exported_symbols)) {
+ return false;
+ }
+ }
+
for (const std::string& input : input_files) {
if (!MergePath(input, false)) {
context_->GetDiagnostics()->Error(DiagMessage() << "failed parsing input");
diff --git a/tools/aapt2/integration-tests/StaticLibTest/App/AndroidManifest.xml b/tools/aapt2/integration-tests/StaticLibTest/App/AndroidManifest.xml
index a5f202d..c8f4bda 100644
--- a/tools/aapt2/integration-tests/StaticLibTest/App/AndroidManifest.xml
+++ b/tools/aapt2/integration-tests/StaticLibTest/App/AndroidManifest.xml
@@ -21,7 +21,7 @@
<uses-permission-sdk-23 android:name="android.permission.TEST" android:maxSdkVersion="22" />
<application>
- <activity android:name=".MyActivity">
+ <activity android:name=".MyActivity" android:id="@+id/sample_generated_id">
<layout android:defaultHeight="500dp"
android:defaultWidth="600dp" />
</activity>
diff --git a/tools/aapt2/integration-tests/StaticLibTest/App/res/layout/main.xml b/tools/aapt2/integration-tests/StaticLibTest/App/res/layout/main.xml
index aaa884b..5a73429 100644
--- a/tools/aapt2/integration-tests/StaticLibTest/App/res/layout/main.xml
+++ b/tools/aapt2/integration-tests/StaticLibTest/App/res/layout/main.xml
@@ -19,7 +19,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
- <fragment class="android.test.sample.App$Inner" />
+ <fragment class="android.test.sample.App$Inner" android:id="@id/sample_generated_id"/>
<variable name="user" type="com.android.User" />