diff options
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | CleanSpec.mk | 2 | ||||
-rw-r--r-- | api/current.txt | 9 | ||||
-rw-r--r-- | cmds/am/src/com/android/commands/am/Am.java | 96 | ||||
-rw-r--r-- | core/java/android/app/ActivityManager.java | 101 | ||||
-rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 160 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 16 | ||||
-rw-r--r-- | core/java/android/app/ActivityView.java | 163 | ||||
-rw-r--r-- | core/java/android/app/IActivityContainer.aidl | 32 | ||||
-rw-r--r-- | core/java/android/app/IActivityContainerCallback.aidl | 24 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.java | 27 | ||||
-rw-r--r-- | core/java/android/app/IWallpaperManager.aidl | 10 | ||||
-rw-r--r-- | core/java/android/hardware/display/DisplayManager.java | 21 | ||||
-rw-r--r-- | core/java/android/view/SurfaceControl.java | 11 | ||||
-rw-r--r-- | core/java/android/view/accessibility/AccessibilityManager.java | 40 | ||||
-rw-r--r-- | core/java/com/android/internal/view/menu/ActionMenuPresenter.java | 36 | ||||
-rw-r--r-- | core/java/com/android/server/LocalServices.java | 60 | ||||
-rw-r--r-- | core/java/com/android/server/SystemService.java | 177 | ||||
-rw-r--r-- | core/java/com/android/server/SystemServiceManager.java | 166 | ||||
-rw-r--r-- | core/res/AndroidManifest.xml | 2 | ||||
-rw-r--r-- | core/res/res/values/styles_micro.xml | 22 | ||||
-rw-r--r-- | core/res/res/values/themes_micro.xml | 27 | ||||
-rw-r--r-- | libs/common_time/Android.mk (renamed from services/common_time/Android.mk) | 0 | ||||
-rw-r--r-- | libs/common_time/clock_recovery.cpp (renamed from services/common_time/clock_recovery.cpp) | 0 | ||||
-rw-r--r-- | libs/common_time/clock_recovery.h (renamed from services/common_time/clock_recovery.h) | 0 | ||||
-rw-r--r-- | libs/common_time/common_clock.cpp (renamed from services/common_time/common_clock.cpp) | 0 | ||||
-rw-r--r-- | libs/common_time/common_clock.h (renamed from services/common_time/common_clock.h) | 0 | ||||
-rw-r--r-- | libs/common_time/common_clock_service.cpp (renamed from services/common_time/common_clock_service.cpp) | 0 | ||||
-rw-r--r-- | libs/common_time/common_clock_service.h (renamed from services/common_time/common_clock_service.h) | 0 | ||||
-rw-r--r-- | libs/common_time/common_time_config_service.cpp (renamed from services/common_time/common_time_config_service.cpp) | 0 | ||||
-rw-r--r-- | libs/common_time/common_time_config_service.h (renamed from services/common_time/common_time_config_service.h) | 0 | ||||
-rw-r--r-- | libs/common_time/common_time_server.cpp (renamed from services/common_time/common_time_server.cpp) | 0 | ||||
-rw-r--r-- | libs/common_time/common_time_server.h (renamed from services/common_time/common_time_server.h) | 0 | ||||
-rw-r--r-- | libs/common_time/common_time_server_api.cpp (renamed from services/common_time/common_time_server_api.cpp) | 0 | ||||
-rw-r--r-- | libs/common_time/common_time_server_packets.cpp (renamed from services/common_time/common_time_server_packets.cpp) | 0 | ||||
-rw-r--r-- | libs/common_time/common_time_server_packets.h (renamed from services/common_time/common_time_server_packets.h) | 0 | ||||
-rw-r--r-- | libs/common_time/diag_thread.cpp (renamed from services/common_time/diag_thread.cpp) | 0 | ||||
-rw-r--r-- | libs/common_time/diag_thread.h (renamed from services/common_time/diag_thread.h) | 0 | ||||
-rw-r--r-- | libs/common_time/main.cpp (renamed from services/common_time/main.cpp) | 0 | ||||
-rw-r--r-- | libs/common_time/utils.cpp (renamed from services/common_time/utils.cpp) | 0 | ||||
-rw-r--r-- | libs/common_time/utils.h (renamed from services/common_time/utils.h) | 0 | ||||
-rw-r--r-- | libs/input/Android.mk (renamed from services/input/Android.mk) | 0 | ||||
-rw-r--r-- | libs/input/EventHub.cpp (renamed from services/input/EventHub.cpp) | 0 | ||||
-rw-r--r-- | libs/input/EventHub.h (renamed from services/input/EventHub.h) | 0 | ||||
-rw-r--r-- | libs/input/InputApplication.cpp (renamed from services/input/InputApplication.cpp) | 0 | ||||
-rw-r--r-- | libs/input/InputApplication.h (renamed from services/input/InputApplication.h) | 0 | ||||
-rw-r--r-- | libs/input/InputDispatcher.cpp (renamed from services/input/InputDispatcher.cpp) | 0 | ||||
-rw-r--r-- | libs/input/InputDispatcher.h (renamed from services/input/InputDispatcher.h) | 0 | ||||
-rw-r--r-- | libs/input/InputListener.cpp (renamed from services/input/InputListener.cpp) | 0 | ||||
-rw-r--r-- | libs/input/InputListener.h (renamed from services/input/InputListener.h) | 0 | ||||
-rw-r--r-- | libs/input/InputManager.cpp (renamed from services/input/InputManager.cpp) | 0 | ||||
-rw-r--r-- | libs/input/InputManager.h (renamed from services/input/InputManager.h) | 0 | ||||
-rw-r--r-- | libs/input/InputReader.cpp (renamed from services/input/InputReader.cpp) | 0 | ||||
-rw-r--r-- | libs/input/InputReader.h (renamed from services/input/InputReader.h) | 0 | ||||
-rw-r--r-- | libs/input/InputWindow.cpp (renamed from services/input/InputWindow.cpp) | 0 | ||||
-rw-r--r-- | libs/input/InputWindow.h (renamed from services/input/InputWindow.h) | 0 | ||||
-rw-r--r-- | libs/input/PointerController.cpp (renamed from services/input/PointerController.cpp) | 0 | ||||
-rw-r--r-- | libs/input/PointerController.h (renamed from services/input/PointerController.h) | 0 | ||||
-rw-r--r-- | libs/input/SpriteController.cpp (renamed from services/input/SpriteController.cpp) | 0 | ||||
-rw-r--r-- | libs/input/SpriteController.h (renamed from services/input/SpriteController.h) | 0 | ||||
-rw-r--r-- | libs/input/tests/Android.mk (renamed from services/input/tests/Android.mk) | 0 | ||||
-rw-r--r-- | libs/input/tests/InputDispatcher_test.cpp (renamed from services/input/tests/InputDispatcher_test.cpp) | 0 | ||||
-rw-r--r-- | libs/input/tests/InputReader_test.cpp (renamed from services/input/tests/InputReader_test.cpp) | 0 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java | 3 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneWindowManager.java | 15 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java | 3 | ||||
-rw-r--r-- | services/Android.mk | 49 | ||||
-rw-r--r-- | services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java (renamed from services/java/com/android/server/accessibility/AccessibilityInputFilter.java) | 0 | ||||
-rw-r--r-- | services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java (renamed from services/java/com/android/server/accessibility/AccessibilityManagerService.java) | 0 | ||||
-rw-r--r-- | services/accessibility/java/com/android/server/accessibility/EventStreamTransformation.java (renamed from services/java/com/android/server/accessibility/EventStreamTransformation.java) | 0 | ||||
-rw-r--r-- | services/accessibility/java/com/android/server/accessibility/GestureUtils.java (renamed from services/java/com/android/server/accessibility/GestureUtils.java) | 0 | ||||
-rw-r--r-- | services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java (renamed from services/java/com/android/server/accessibility/ScreenMagnifier.java) | 0 | ||||
-rw-r--r-- | services/accessibility/java/com/android/server/accessibility/TouchExplorer.java (renamed from services/java/com/android/server/accessibility/TouchExplorer.java) | 0 | ||||
-rw-r--r-- | services/accessibility/java/service.mk | 11 | ||||
-rw-r--r-- | services/appwidget/java/com/android/server/appwidget/AppWidgetService.java | 384 | ||||
-rw-r--r-- | services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java (renamed from services/java/com/android/server/AppWidgetServiceImpl.java) | 2 | ||||
-rw-r--r-- | services/appwidget/java/service.mk | 11 | ||||
-rw-r--r-- | services/backup/java/com/android/server/backup/BackupManagerService.java (renamed from services/java/com/android/server/BackupManagerService.java) | 17 | ||||
-rw-r--r-- | services/backup/java/com/android/server/backup/BackupManagerSystemService.java | 36 | ||||
-rw-r--r-- | services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java (renamed from services/java/com/android/server/PackageManagerBackupAgent.java) | 2 | ||||
-rw-r--r-- | services/backup/java/com/android/server/backup/SystemBackupAgent.java (renamed from services/java/com/android/server/SystemBackupAgent.java) | 48 | ||||
-rw-r--r-- | services/backup/java/service.mk | 11 | ||||
-rw-r--r-- | services/core/java/com/android/server/AlarmManagerService.java (renamed from services/java/com/android/server/AlarmManagerService.java) | 575 | ||||
-rw-r--r-- | services/core/java/com/android/server/AppOpsService.java (renamed from services/java/com/android/server/AppOpsService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/AssetAtlasService.java (renamed from services/java/com/android/server/AssetAtlasService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/AttributeCache.java (renamed from services/java/com/android/server/AttributeCache.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/BatteryService.java (renamed from services/java/com/android/server/BatteryService.java) | 33 | ||||
-rw-r--r-- | services/core/java/com/android/server/BluetoothManagerService.java (renamed from services/java/com/android/server/BluetoothManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/BootReceiver.java (renamed from services/java/com/android/server/BootReceiver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/BrickReceiver.java (renamed from services/java/com/android/server/BrickReceiver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/CertBlacklister.java (renamed from services/java/com/android/server/CertBlacklister.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/CommonTimeManagementService.java (renamed from services/java/com/android/server/CommonTimeManagementService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/ConnectivityService.java (renamed from services/java/com/android/server/ConnectivityService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/ConsumerIrService.java (renamed from services/java/com/android/server/ConsumerIrService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/CountryDetectorService.java (renamed from services/java/com/android/server/CountryDetectorService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/DiskStatsService.java (renamed from services/java/com/android/server/DiskStatsService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/DockObserver.java (renamed from services/java/com/android/server/DockObserver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/DropBoxManagerService.java (renamed from services/java/com/android/server/DropBoxManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/EntropyMixer.java (renamed from services/java/com/android/server/EntropyMixer.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/EventLogTags.logtags (renamed from services/java/com/android/server/EventLogTags.logtags) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/FgThread.java (renamed from services/java/com/android/server/FgThread.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java (renamed from services/java/com/android/server/INativeDaemonConnectorCallbacks.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/IdleMaintenanceService.java (renamed from services/java/com/android/server/IdleMaintenanceService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/InputMethodManagerService.java (renamed from services/java/com/android/server/InputMethodManagerService.java) | 2 | ||||
-rw-r--r-- | services/core/java/com/android/server/IntentResolver.java (renamed from services/java/com/android/server/IntentResolver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/IoThread.java (renamed from services/java/com/android/server/IoThread.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/LocationManagerService.java (renamed from services/java/com/android/server/LocationManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/LockSettingsService.java (renamed from services/java/com/android/server/LockSettingsService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/MasterClearReceiver.java (renamed from services/java/com/android/server/MasterClearReceiver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/MountService.java (renamed from services/java/com/android/server/MountService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/NativeDaemonConnector.java (renamed from services/java/com/android/server/NativeDaemonConnector.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/NativeDaemonConnectorException.java (renamed from services/java/com/android/server/NativeDaemonConnectorException.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/NativeDaemonEvent.java (renamed from services/java/com/android/server/NativeDaemonEvent.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/NetworkManagementService.java (renamed from services/java/com/android/server/NetworkManagementService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/NetworkTimeUpdateService.java (renamed from services/java/com/android/server/NetworkTimeUpdateService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/NsdService.java (renamed from services/java/com/android/server/NsdService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/RandomBlock.java (renamed from services/java/com/android/server/RandomBlock.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/RecognitionManagerService.java (renamed from services/java/com/android/server/RecognitionManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/SamplingProfilerService.java (renamed from services/java/com/android/server/SamplingProfilerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/SerialService.java (renamed from services/java/com/android/server/SerialService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/ServiceWatcher.java (renamed from services/java/com/android/server/ServiceWatcher.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/ShutdownActivity.java (renamed from services/java/com/android/server/ShutdownActivity.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/SystemServer.java (renamed from services/java/com/android/server/SystemServer.java) | 161 | ||||
-rw-r--r-- | services/core/java/com/android/server/TelephonyRegistry.java (renamed from services/java/com/android/server/TelephonyRegistry.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/TextServicesManagerService.java (renamed from services/java/com/android/server/TextServicesManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/TwilightCalculator.java (renamed from services/java/com/android/server/TwilightCalculator.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/UiModeManagerService.java (renamed from services/java/com/android/server/UiModeManagerService.java) | 286 | ||||
-rw-r--r-- | services/core/java/com/android/server/UiThread.java (renamed from services/java/com/android/server/UiThread.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/UpdateLockService.java (renamed from services/java/com/android/server/UpdateLockService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/VibratorService.java (renamed from services/java/com/android/server/VibratorService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/Watchdog.java (renamed from services/java/com/android/server/Watchdog.java) | 10 | ||||
-rw-r--r-- | services/core/java/com/android/server/WiredAccessoryManager.java (renamed from services/java/com/android/server/WiredAccessoryManager.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java (renamed from services/java/com/android/server/accounts/AccountAuthenticatorCache.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/accounts/AccountManagerService.java (renamed from services/java/com/android/server/accounts/AccountManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/accounts/IAccountAuthenticatorCache.java (renamed from services/java/com/android/server/accounts/IAccountAuthenticatorCache.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ActiveServices.java (renamed from services/java/com/android/server/am/ActiveServices.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java (renamed from services/java/com/android/server/am/ActivityManagerService.java) | 189 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ActivityRecord.java (renamed from services/java/com/android/server/am/ActivityRecord.java) | 7 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ActivityResult.java (renamed from services/java/com/android/server/am/ActivityResult.java) | 0 | ||||
-rwxr-xr-x | services/core/java/com/android/server/am/ActivityStack.java (renamed from services/java/com/android/server/am/ActivityStack.java) | 111 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ActivityStackSupervisor.java (renamed from services/java/com/android/server/am/ActivityStackSupervisor.java) | 1121 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/AppBindRecord.java (renamed from services/java/com/android/server/am/AppBindRecord.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/AppErrorDialog.java (renamed from services/java/com/android/server/am/AppErrorDialog.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/AppErrorResult.java (renamed from services/java/com/android/server/am/AppErrorResult.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/AppNotRespondingDialog.java (renamed from services/java/com/android/server/am/AppNotRespondingDialog.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java (renamed from services/java/com/android/server/am/AppWaitingForDebuggerDialog.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/BackupRecord.java (renamed from services/java/com/android/server/am/BackupRecord.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/BaseErrorDialog.java (renamed from services/java/com/android/server/am/BaseErrorDialog.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/BatteryStatsService.java (renamed from services/java/com/android/server/am/BatteryStatsService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/BroadcastFilter.java (renamed from services/java/com/android/server/am/BroadcastFilter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/BroadcastQueue.java (renamed from services/java/com/android/server/am/BroadcastQueue.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/BroadcastRecord.java (renamed from services/java/com/android/server/am/BroadcastRecord.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/CompatModeDialog.java (renamed from services/java/com/android/server/am/CompatModeDialog.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/CompatModePackages.java (renamed from services/java/com/android/server/am/CompatModePackages.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ConnectionRecord.java (renamed from services/java/com/android/server/am/ConnectionRecord.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ContentProviderConnection.java (renamed from services/java/com/android/server/am/ContentProviderConnection.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ContentProviderRecord.java (renamed from services/java/com/android/server/am/ContentProviderRecord.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/CoreSettingsObserver.java (renamed from services/java/com/android/server/am/CoreSettingsObserver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/EventLogTags.logtags (renamed from services/java/com/android/server/am/EventLogTags.logtags) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/FactoryErrorDialog.java (renamed from services/java/com/android/server/am/FactoryErrorDialog.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/IntentBindRecord.java (renamed from services/java/com/android/server/am/IntentBindRecord.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/LaunchWarningWindow.java (renamed from services/java/com/android/server/am/LaunchWarningWindow.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/NativeCrashListener.java (renamed from services/java/com/android/server/am/NativeCrashListener.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/PendingIntentRecord.java (renamed from services/java/com/android/server/am/PendingIntentRecord.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/PendingThumbnailsRecord.java (renamed from services/java/com/android/server/am/PendingThumbnailsRecord.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ProcessList.java (renamed from services/java/com/android/server/am/ProcessList.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ProcessMemInfo.java (renamed from services/java/com/android/server/am/ProcessMemInfo.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ProcessRecord.java (renamed from services/java/com/android/server/am/ProcessRecord.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ProcessStatsService.java (renamed from services/java/com/android/server/am/ProcessStatsService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ProviderMap.java (renamed from services/java/com/android/server/am/ProviderMap.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ReceiverList.java (renamed from services/java/com/android/server/am/ReceiverList.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ServiceRecord.java (renamed from services/java/com/android/server/am/ServiceRecord.java) | 9 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/StrictModeViolationDialog.java (renamed from services/java/com/android/server/am/StrictModeViolationDialog.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/TaskAccessInfo.java (renamed from services/java/com/android/server/am/TaskAccessInfo.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/TaskRecord.java (renamed from services/java/com/android/server/am/TaskRecord.java) | 26 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ThumbnailHolder.java (renamed from services/java/com/android/server/am/ThumbnailHolder.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/UriPermission.java (renamed from services/java/com/android/server/am/UriPermission.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/UriPermissionOwner.java (renamed from services/java/com/android/server/am/UriPermissionOwner.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/UsageStatsService.java (renamed from services/java/com/android/server/am/UsageStatsService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/UserStartedState.java (renamed from services/java/com/android/server/am/UserStartedState.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/package.html (renamed from services/java/com/android/server/am/package.html) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/clipboard/ClipboardService.java (renamed from services/java/com/android/server/ClipboardService.java) | 2 | ||||
-rw-r--r-- | services/core/java/com/android/server/connectivity/DataConnectionStats.java (renamed from services/java/com/android/server/connectivity/DataConnectionStats.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/connectivity/Nat464Xlat.java (renamed from services/java/com/android/server/connectivity/Nat464Xlat.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/connectivity/PacManager.java (renamed from services/java/com/android/server/connectivity/PacManager.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/connectivity/Tethering.java (renamed from services/java/com/android/server/connectivity/Tethering.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/connectivity/Vpn.java (renamed from services/java/com/android/server/connectivity/Vpn.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/content/ContentService.java (renamed from services/java/com/android/server/content/ContentService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/content/SyncManager.java (renamed from services/java/com/android/server/content/SyncManager.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/content/SyncOperation.java (renamed from services/java/com/android/server/content/SyncOperation.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/content/SyncQueue.java (renamed from services/java/com/android/server/content/SyncQueue.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/content/SyncStorageEngine.java (renamed from services/java/com/android/server/content/SyncStorageEngine.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/DisplayAdapter.java (renamed from services/java/com/android/server/display/DisplayAdapter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/DisplayDevice.java (renamed from services/java/com/android/server/display/DisplayDevice.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/DisplayDeviceInfo.java (renamed from services/java/com/android/server/display/DisplayDeviceInfo.java) | 10 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/DisplayManagerService.java (renamed from services/java/com/android/server/display/DisplayManagerService.java) | 35 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/DisplayTransactionListener.java (renamed from services/java/com/android/server/display/DisplayTransactionListener.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/DisplayViewport.java (renamed from services/java/com/android/server/display/DisplayViewport.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/LocalDisplayAdapter.java (renamed from services/java/com/android/server/display/LocalDisplayAdapter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/LogicalDisplay.java (renamed from services/java/com/android/server/display/LogicalDisplay.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/OverlayDisplayAdapter.java (renamed from services/java/com/android/server/display/OverlayDisplayAdapter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/OverlayDisplayWindow.java (renamed from services/java/com/android/server/display/OverlayDisplayWindow.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/PersistentDataStore.java (renamed from services/java/com/android/server/display/PersistentDataStore.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/VirtualDisplayAdapter.java (renamed from services/java/com/android/server/display/VirtualDisplayAdapter.java) | 7 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/WifiDisplayAdapter.java (renamed from services/java/com/android/server/display/WifiDisplayAdapter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/display/WifiDisplayController.java (renamed from services/java/com/android/server/display/WifiDisplayController.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/dreams/DreamController.java (renamed from services/java/com/android/server/dreams/DreamController.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/dreams/DreamManagerService.java (renamed from services/java/com/android/server/dreams/DreamManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/AndFilter.java (renamed from services/java/com/android/server/firewall/AndFilter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/CategoryFilter.java (renamed from services/java/com/android/server/firewall/CategoryFilter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/Filter.java (renamed from services/java/com/android/server/firewall/Filter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/FilterFactory.java (renamed from services/java/com/android/server/firewall/FilterFactory.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/FilterList.java (renamed from services/java/com/android/server/firewall/FilterList.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/IntentFirewall.java (renamed from services/java/com/android/server/firewall/IntentFirewall.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/NotFilter.java (renamed from services/java/com/android/server/firewall/NotFilter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/OrFilter.java (renamed from services/java/com/android/server/firewall/OrFilter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/PortFilter.java (renamed from services/java/com/android/server/firewall/PortFilter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/SenderFilter.java (renamed from services/java/com/android/server/firewall/SenderFilter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/SenderPermissionFilter.java (renamed from services/java/com/android/server/firewall/SenderPermissionFilter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/firewall/StringFilter.java (renamed from services/java/com/android/server/firewall/StringFilter.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/input/InputApplicationHandle.java (renamed from services/java/com/android/server/input/InputApplicationHandle.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/input/InputManagerService.java (renamed from services/java/com/android/server/input/InputManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/input/InputWindowHandle.java (renamed from services/java/com/android/server/input/InputWindowHandle.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/input/PersistentDataStore.java (renamed from services/java/com/android/server/input/PersistentDataStore.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/lights/Light.java | 41 | ||||
-rw-r--r-- | services/core/java/com/android/server/lights/LightsManager.java | 31 | ||||
-rw-r--r-- | services/core/java/com/android/server/lights/LightsService.java (renamed from services/java/com/android/server/LightsService.java) | 92 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/ComprehensiveCountryDetector.java (renamed from services/java/com/android/server/location/ComprehensiveCountryDetector.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/CountryDetectorBase.java (renamed from services/java/com/android/server/location/CountryDetectorBase.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/FlpHardwareProvider.java (renamed from services/java/com/android/server/location/FlpHardwareProvider.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/FusedLocationHardwareSecure.java (renamed from services/java/com/android/server/location/FusedLocationHardwareSecure.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/FusedProxy.java (renamed from services/java/com/android/server/location/FusedProxy.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/GeocoderProxy.java (renamed from services/java/com/android/server/location/GeocoderProxy.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/GeofenceManager.java (renamed from services/java/com/android/server/location/GeofenceManager.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/GeofenceProxy.java (renamed from services/java/com/android/server/location/GeofenceProxy.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/GeofenceState.java (renamed from services/java/com/android/server/location/GeofenceState.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/GpsLocationProvider.java (renamed from services/java/com/android/server/location/GpsLocationProvider.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/GpsXtraDownloader.java (renamed from services/java/com/android/server/location/GpsXtraDownloader.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/LocationBasedCountryDetector.java (renamed from services/java/com/android/server/location/LocationBasedCountryDetector.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/LocationBlacklist.java (renamed from services/java/com/android/server/location/LocationBlacklist.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/LocationFudger.java (renamed from services/java/com/android/server/location/LocationFudger.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/LocationProviderInterface.java (renamed from services/java/com/android/server/location/LocationProviderInterface.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/LocationProviderProxy.java (renamed from services/java/com/android/server/location/LocationProviderProxy.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/MockProvider.java (renamed from services/java/com/android/server/location/MockProvider.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/location/PassiveProvider.java (renamed from services/java/com/android/server/location/PassiveProvider.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/media/MediaRouterService.java (renamed from services/java/com/android/server/media/MediaRouterService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/media/RemoteDisplayProviderProxy.java (renamed from services/java/com/android/server/media/RemoteDisplayProviderProxy.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/media/RemoteDisplayProviderWatcher.java (renamed from services/java/com/android/server/media/RemoteDisplayProviderWatcher.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/net/LockdownVpnTracker.java (renamed from services/java/com/android/server/net/LockdownVpnTracker.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/net/NetworkIdentitySet.java (renamed from services/java/com/android/server/net/NetworkIdentitySet.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/net/NetworkPolicyManagerService.java (renamed from services/java/com/android/server/net/NetworkPolicyManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/net/NetworkStatsCollection.java (renamed from services/java/com/android/server/net/NetworkStatsCollection.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/net/NetworkStatsRecorder.java (renamed from services/java/com/android/server/net/NetworkStatsRecorder.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/net/NetworkStatsService.java (renamed from services/java/com/android/server/net/NetworkStatsService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/notification/NotificationDelegate.java | 27 | ||||
-rw-r--r-- | services/core/java/com/android/server/notification/NotificationManagerInternal.java | 8 | ||||
-rw-r--r-- | services/core/java/com/android/server/notification/NotificationManagerService.java (renamed from services/java/com/android/server/NotificationManagerService.java) | 1231 | ||||
-rw-r--r-- | services/core/java/com/android/server/os/SchedulingPolicyService.java (renamed from services/java/com/android/server/os/SchedulingPolicyService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/BasePermission.java (renamed from services/java/com/android/server/pm/BasePermission.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/GrantedPermissions.java (renamed from services/java/com/android/server/pm/GrantedPermissions.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/Installer.java (renamed from services/java/com/android/server/pm/Installer.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/KeySetManager.java (renamed from services/java/com/android/server/pm/KeySetManager.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageKeySetData.java (renamed from services/java/com/android/server/pm/PackageKeySetData.java) | 0 | ||||
-rwxr-xr-x | services/core/java/com/android/server/pm/PackageManagerService.java (renamed from services/java/com/android/server/pm/PackageManagerService.java) | 55 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageSetting.java (renamed from services/java/com/android/server/pm/PackageSetting.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageSettingBase.java (renamed from services/java/com/android/server/pm/PackageSettingBase.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageSignatures.java (renamed from services/java/com/android/server/pm/PackageSignatures.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageVerificationResponse.java (renamed from services/java/com/android/server/pm/PackageVerificationResponse.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageVerificationState.java (renamed from services/java/com/android/server/pm/PackageVerificationState.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PendingPackage.java (renamed from services/java/com/android/server/pm/PendingPackage.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PreferredActivity.java (renamed from services/java/com/android/server/pm/PreferredActivity.java) | 1 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PreferredComponent.java (renamed from services/java/com/android/server/PreferredComponent.java) | 2 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PreferredIntentResolver.java (renamed from services/java/com/android/server/pm/PreferredIntentResolver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/SELinuxMMAC.java (renamed from services/java/com/android/server/pm/SELinuxMMAC.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/Settings.java (renamed from services/java/com/android/server/pm/Settings.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/SharedUserSetting.java (renamed from services/java/com/android/server/pm/SharedUserSetting.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/UserManagerService.java (renamed from services/java/com/android/server/pm/UserManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/DisplayBlanker.java (renamed from services/java/com/android/server/power/DisplayBlanker.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/DisplayPowerController.java (renamed from services/java/com/android/server/power/DisplayPowerController.java) | 18 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/DisplayPowerRequest.java (renamed from services/java/com/android/server/power/DisplayPowerRequest.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/DisplayPowerState.java (renamed from services/java/com/android/server/power/DisplayPowerState.java) | 6 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/ElectronBeam.java (renamed from services/java/com/android/server/power/ElectronBeam.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/Notifier.java (renamed from services/java/com/android/server/power/Notifier.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/PowerManagerService.java (renamed from services/java/com/android/server/power/PowerManagerService.java) | 29 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/RampAnimator.java (renamed from services/java/com/android/server/power/RampAnimator.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/ScreenOnBlocker.java (renamed from services/java/com/android/server/power/ScreenOnBlocker.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/ShutdownThread.java (renamed from services/java/com/android/server/power/ShutdownThread.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/SuspendBlocker.java (renamed from services/java/com/android/server/power/SuspendBlocker.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/power/WirelessChargerDetector.java (renamed from services/java/com/android/server/power/WirelessChargerDetector.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/search/SearchManagerService.java (renamed from services/java/com/android/server/search/SearchManagerService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/search/Searchables.java (renamed from services/java/com/android/server/search/Searchables.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java | 29 | ||||
-rw-r--r-- | services/core/java/com/android/server/statusbar/StatusBarManagerService.java (renamed from services/java/com/android/server/StatusBarManagerService.java) | 236 | ||||
-rw-r--r-- | services/core/java/com/android/server/storage/DeviceStorageMonitorInternal.java | 24 | ||||
-rw-r--r-- | services/core/java/com/android/server/storage/DeviceStorageMonitorService.java (renamed from services/java/com/android/server/DeviceStorageMonitorService.java) | 226 | ||||
-rw-r--r-- | services/core/java/com/android/server/twilight/TwilightListener.java | 21 | ||||
-rw-r--r-- | services/core/java/com/android/server/twilight/TwilightManager.java | 24 | ||||
-rw-r--r-- | services/core/java/com/android/server/twilight/TwilightService.java (renamed from services/java/com/android/server/TwilightService.java) | 249 | ||||
-rw-r--r-- | services/core/java/com/android/server/twilight/TwilightState.java | 112 | ||||
-rw-r--r-- | services/core/java/com/android/server/updates/CarrierProvisioningUrlsInstallReceiver.java (renamed from services/java/com/android/server/updates/CarrierProvisioningUrlsInstallReceiver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/updates/CertPinInstallReceiver.java (renamed from services/java/com/android/server/updates/CertPinInstallReceiver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java (renamed from services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/updates/IntentFirewallInstallReceiver.java (renamed from services/java/com/android/server/updates/IntentFirewallInstallReceiver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java (renamed from services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/updates/SmsShortCodesInstallReceiver.java (renamed from services/java/com/android/server/updates/SmsShortCodesInstallReceiver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/updates/TZInfoInstallReceiver.java (renamed from services/java/com/android/server/updates/TZInfoInstallReceiver.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/usb/UsbDebuggingManager.java (renamed from services/java/com/android/server/usb/UsbDebuggingManager.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/usb/UsbDeviceManager.java (renamed from services/java/com/android/server/usb/UsbDeviceManager.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/usb/UsbHostManager.java (renamed from services/java/com/android/server/usb/UsbHostManager.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/usb/UsbService.java (renamed from services/java/com/android/server/usb/UsbService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/usb/UsbSettingsManager.java (renamed from services/java/com/android/server/usb/UsbSettingsManager.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wallpaper/WallpaperManagerService.java (renamed from services/java/com/android/server/WallpaperManagerService.java) | 20 | ||||
-rw-r--r-- | services/core/java/com/android/server/wifi/README.txt (renamed from services/java/com/android/server/wifi/README.txt) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wifi/WifiController.java (renamed from services/java/com/android/server/wifi/WifiController.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wifi/WifiNotificationController.java (renamed from services/java/com/android/server/wifi/WifiNotificationController.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wifi/WifiService.java (renamed from services/java/com/android/server/wifi/WifiService.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wifi/WifiSettingsStore.java (renamed from services/java/com/android/server/wifi/WifiSettingsStore.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wifi/WifiTrafficPoller.java (renamed from services/java/com/android/server/wifi/WifiTrafficPoller.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/AppTransition.java (renamed from services/java/com/android/server/wm/AppTransition.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/AppWindowAnimator.java (renamed from services/java/com/android/server/wm/AppWindowAnimator.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/AppWindowToken.java (renamed from services/java/com/android/server/wm/AppWindowToken.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/BlackFrame.java (renamed from services/java/com/android/server/wm/BlackFrame.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/DimLayer.java (renamed from services/java/com/android/server/wm/DimLayer.java) | 2 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/DisplayContent.java (renamed from services/java/com/android/server/wm/DisplayContent.java) | 250 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/DisplayMagnifier.java (renamed from services/java/com/android/server/wm/DisplayMagnifier.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/DisplaySettings.java (renamed from services/java/com/android/server/wm/DisplaySettings.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/DragState.java (renamed from services/java/com/android/server/wm/DragState.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/FakeWindowImpl.java (renamed from services/java/com/android/server/wm/FakeWindowImpl.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/FocusedStackFrame.java (renamed from services/java/com/android/server/wm/FocusedStackFrame.java) | 8 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/InputMonitor.java (renamed from services/java/com/android/server/wm/InputMonitor.java) | 5 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/KeyguardDisableHandler.java (renamed from services/java/com/android/server/wm/KeyguardDisableHandler.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/PointerEventDispatcher.java (renamed from services/java/com/android/server/wm/PointerEventDispatcher.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/ScreenRotationAnimation.java (renamed from services/java/com/android/server/wm/ScreenRotationAnimation.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/Session.java (renamed from services/java/com/android/server/wm/Session.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/StackTapPointerEventListener.java (renamed from services/java/com/android/server/wm/StackTapPointerEventListener.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/StartingData.java (renamed from services/java/com/android/server/wm/StartingData.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/StrictModeFlash.java (renamed from services/java/com/android/server/wm/StrictModeFlash.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/Task.java (renamed from services/java/com/android/server/wm/Task.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/TaskGroup.java (renamed from services/java/com/android/server/wm/TaskGroup.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/TaskStack.java (renamed from services/java/com/android/server/wm/TaskStack.java) | 118 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/ViewServer.java (renamed from services/java/com/android/server/wm/ViewServer.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/Watermark.java (renamed from services/java/com/android/server/wm/Watermark.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/WindowAnimator.java (renamed from services/java/com/android/server/wm/WindowAnimator.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java (renamed from services/java/com/android/server/wm/WindowManagerService.java) | 139 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/WindowState.java (renamed from services/java/com/android/server/wm/WindowState.java) | 22 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/WindowStateAnimator.java (renamed from services/java/com/android/server/wm/WindowStateAnimator.java) | 0 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/WindowToken.java (renamed from services/java/com/android/server/wm/WindowToken.java) | 0 | ||||
-rw-r--r-- | services/core/java/service.mk | 6 | ||||
-rw-r--r-- | services/core/jni/Android.mk | 56 | ||||
-rw-r--r-- | services/core/jni/com_android_server_AlarmManagerService.cpp (renamed from services/jni/com_android_server_AlarmManagerService.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_AssetAtlasService.cpp (renamed from services/jni/com_android_server_AssetAtlasService.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_ConsumerIrService.cpp (renamed from services/jni/com_android_server_ConsumerIrService.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_SerialService.cpp (renamed from services/jni/com_android_server_SerialService.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_SystemServer.cpp (renamed from services/jni/com_android_server_SystemServer.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_UsbDeviceManager.cpp (renamed from services/jni/com_android_server_UsbDeviceManager.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_UsbHostManager.cpp (renamed from services/jni/com_android_server_UsbHostManager.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_VibratorService.cpp (renamed from services/jni/com_android_server_VibratorService.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_connectivity_Vpn.cpp (renamed from services/jni/com_android_server_connectivity_Vpn.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_input_InputApplicationHandle.cpp (renamed from services/jni/com_android_server_input_InputApplicationHandle.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_input_InputApplicationHandle.h (renamed from services/jni/com_android_server_input_InputApplicationHandle.h) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_input_InputManagerService.cpp (renamed from services/jni/com_android_server_input_InputManagerService.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_input_InputWindowHandle.cpp (renamed from services/jni/com_android_server_input_InputWindowHandle.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_input_InputWindowHandle.h (renamed from services/jni/com_android_server_input_InputWindowHandle.h) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_lights_LightsService.cpp (renamed from services/jni/com_android_server_LightsService.cpp) | 2 | ||||
-rw-r--r-- | services/core/jni/com_android_server_location_FlpHardwareProvider.cpp (renamed from services/jni/com_android_server_location_FlpHardwareProvider.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_location_GpsLocationProvider.cpp (renamed from services/jni/com_android_server_location_GpsLocationProvider.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_power_PowerManagerService.cpp (renamed from services/jni/com_android_server_power_PowerManagerService.cpp) | 0 | ||||
-rw-r--r-- | services/core/jni/com_android_server_power_PowerManagerService.h (renamed from services/jni/com_android_server_power_PowerManagerService.h) | 0 | ||||
-rw-r--r-- | services/core/jni/onload.cpp (renamed from services/jni/onload.cpp) | 0 | ||||
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java (renamed from services/java/com/android/server/DevicePolicyManagerService.java) | 331 | ||||
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerSystemService.java | 46 | ||||
-rw-r--r-- | services/devicepolicy/java/service.mk | 11 | ||||
-rw-r--r-- | services/java/Android.mk | 18 | ||||
-rw-r--r-- | services/java/com/android/server/AppWidgetService.java | 363 | ||||
-rw-r--r-- | services/java/com/android/server/display/HeadlessDisplayAdapter.java | 73 | ||||
-rw-r--r-- | services/java/com/android/server/print/PrintManagerService.java | 656 | ||||
-rw-r--r-- | services/java/com/android/server/wm/StackBox.java | 414 | ||||
-rw-r--r-- | services/jni/Android.mk | 63 | ||||
-rw-r--r-- | services/print/java/com/android/server/print/PrintManagerService.java | 690 | ||||
-rw-r--r-- | services/print/java/com/android/server/print/RemotePrintService.java (renamed from services/java/com/android/server/print/RemotePrintService.java) | 0 | ||||
-rw-r--r-- | services/print/java/com/android/server/print/RemotePrintSpooler.java (renamed from services/java/com/android/server/print/RemotePrintSpooler.java) | 0 | ||||
-rw-r--r-- | services/print/java/com/android/server/print/UserState.java (renamed from services/java/com/android/server/print/UserState.java) | 0 | ||||
-rw-r--r-- | services/print/java/service.mk | 11 | ||||
-rw-r--r-- | services/tests/Android.mk | 3 |
384 files changed, 5645 insertions, 4504 deletions
diff --git a/Android.mk b/Android.mk index 3a3169cf6475..ade5e385a33b 100644 --- a/Android.mk +++ b/Android.mk @@ -59,6 +59,8 @@ LOCAL_SRC_FILES += \ core/java/android/accounts/IAccountManagerResponse.aidl \ core/java/android/accounts/IAccountAuthenticator.aidl \ core/java/android/accounts/IAccountAuthenticatorResponse.aidl \ + core/java/android/app/IActivityContainer.aidl \ + core/java/android/app/IActivityContainerCallback.aidl \ core/java/android/app/IActivityController.aidl \ core/java/android/app/IActivityPendingResult.aidl \ core/java/android/app/IAlarmManager.aidl \ diff --git a/CleanSpec.mk b/CleanSpec.mk index cfa8be9a13c7..ef3f4aea190a 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -184,7 +184,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/effects/) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/framework-res_intermediates) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrintClient.*) - +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services_intermediates) # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST # ************************************************ diff --git a/api/current.txt b/api/current.txt index 2bd9c054778c..38482423bc2e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3080,6 +3080,14 @@ package android.app { method public void update(android.app.ActivityOptions); } + public class ActivityView extends android.view.ViewGroup { + ctor public ActivityView(android.content.Context); + ctor public ActivityView(android.content.Context, android.util.AttributeSet); + ctor public ActivityView(android.content.Context, android.util.AttributeSet, int); + method protected void onLayout(boolean, int, int, int, int); + method public void startActivity(android.content.Intent); + } + public class AlarmManager { method public void cancel(android.app.PendingIntent); method public void set(int, long, android.app.PendingIntent); @@ -10870,6 +10878,7 @@ package android.hardware.display { method public void registerDisplayListener(android.hardware.display.DisplayManager.DisplayListener, android.os.Handler); method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener); field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION"; + field public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 8; // 0x8 field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2 field public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1; // 0x1 field public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 4; // 0x4 diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 0344d261fd35..89e15d25dd62 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -19,8 +19,9 @@ package com.android.commands.am; import android.app.ActivityManager; -import android.app.ActivityManager.StackBoxInfo; +import android.app.ActivityManager.StackInfo; import android.app.ActivityManagerNative; +import android.app.IActivityContainer; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IInstrumentationWatcher; @@ -31,9 +32,11 @@ import android.content.IIntentReceiver; import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.ResolveInfo; +import android.graphics.Rect; import android.net.Uri; import android.os.Binder; import android.os.Bundle; +import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; @@ -106,11 +109,11 @@ public class Am extends BaseCommand { " am to-intent-uri [INTENT]\n" + " am switch-user <USER_ID>\n" + " am stop-user <USER_ID>\n" + - " am stack create <TASK_ID> <RELATIVE_STACK_BOX_ID> <POSITION> <WEIGHT>\n" + + " am stack start <DISPLAY_ID> <INTENT>\n" + " am stack movetask <TASK_ID> <STACK_ID> [true|false]\n" + - " am stack resize <STACK_ID> <WEIGHT>\n" + - " am stack boxes\n" + - " am stack box <STACK_BOX_ID>\n" + + " am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" + + " am stack list\n" + + " am stack info <STACK_ID>\n" + "\n" + "am start: start an Activity. Options are:\n" + " -D: enable debugging\n" + @@ -204,24 +207,16 @@ public class Am extends BaseCommand { "am stop-user: stop execution of USER_ID, not allowing it to run any\n" + " code until a later explicit switch to it.\n" + "\n" + - "am stack create: create a new stack relative to an existing one.\n" + - " <TASK_ID>: the task to populate the new stack with. Must exist.\n" + - " <RELATIVE_STACK_BOX_ID>: existing stack box's id.\n" + - " <POSITION>: 0: before <RELATIVE_STACK_BOX_ID>, per RTL/LTR configuration,\n" + - " 1: after <RELATIVE_STACK_BOX_ID>, per RTL/LTR configuration,\n" + - " 2: to left of <RELATIVE_STACK_BOX_ID>,\n" + - " 3: to right of <RELATIVE_STACK_BOX_ID>," + - " 4: above <RELATIVE_STACK_BOX_ID>, 5: below <RELATIVE_STACK_BOX_ID>\n" + - " <WEIGHT>: float between 0.2 and 0.8 inclusive.\n" + + "am stack start: start a new activity on <DISPLAY_ID> using <INTENT>.\n" + "\n" + "am stack movetask: move <TASK_ID> from its current stack to the top (true) or" + " bottom (false) of <STACK_ID>.\n" + "\n" + - "am stack resize: change <STACK_ID> relative size to new <WEIGHT>.\n" + + "am stack resize: change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.\n" + "\n" + - "am stack boxes: list the hierarchy of stack boxes and their contents.\n" + + "am stack list: list all of the activity stacks and their sizes.\n" + "\n" + - "am stack box: list the hierarchy of stack boxes rooted at <STACK_BOX_ID>.\n" + + "am stack info: display the information about activity stack <STACK_ID>.\n" + "\n" + "<INTENT> specifications include these flags and arguments:\n" + " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" + @@ -1546,35 +1541,32 @@ public class Am extends BaseCommand { private void runStack() throws Exception { String op = nextArgRequired(); - if (op.equals("create")) { - runStackCreate(); + if (op.equals("start")) { + runStackStart(); } else if (op.equals("movetask")) { runStackMoveTask(); } else if (op.equals("resize")) { - runStackBoxResize(); - } else if (op.equals("boxes")) { - runStackBoxes(); - } else if (op.equals("box")) { - runStackBoxInfo(); + runStackResize(); + } else if (op.equals("list")) { + runStackList(); + } else if (op.equals("info")) { + runStackInfo(); } else { showError("Error: unknown command '" + op + "'"); return; } } - private void runStackCreate() throws Exception { - String taskIdStr = nextArgRequired(); - int taskId = Integer.valueOf(taskIdStr); - String relativeToStr = nextArgRequired(); - int relativeTo = Integer.valueOf(relativeToStr); - String positionStr = nextArgRequired(); - int position = Integer.valueOf(positionStr); - String weightStr = nextArgRequired(); - float weight = Float.valueOf(weightStr); + private void runStackStart() throws Exception { + String displayIdStr = nextArgRequired(); + int displayId = Integer.valueOf(displayIdStr); + Intent intent = makeIntent(UserHandle.USER_CURRENT); try { - int stackId = mAm.createStack(taskId, relativeTo, position, weight); - System.out.println("createStack returned new stackId=" + stackId + "\n\n"); + IBinder homeActivityToken = mAm.getHomeActivityToken(); + IActivityContainer container = mAm.createActivityContainer(homeActivityToken, null); + container.attachToDisplay(displayId); + container.startActivity(intent); } catch (RemoteException e) { } } @@ -1601,34 +1593,40 @@ public class Am extends BaseCommand { } } - private void runStackBoxResize() throws Exception { - String stackBoxIdStr = nextArgRequired(); - int stackBoxId = Integer.valueOf(stackBoxIdStr); - String weightStr = nextArgRequired(); - float weight = Float.valueOf(weightStr); + private void runStackResize() throws Exception { + String stackIdStr = nextArgRequired(); + int stackId = Integer.valueOf(stackIdStr); + String leftStr = nextArgRequired(); + int left = Integer.valueOf(leftStr); + String topStr = nextArgRequired(); + int top = Integer.valueOf(topStr); + String rightStr = nextArgRequired(); + int right = Integer.valueOf(rightStr); + String bottomStr = nextArgRequired(); + int bottom = Integer.valueOf(bottomStr); try { - mAm.resizeStackBox(stackBoxId, weight); + mAm.resizeStack(stackId, new Rect(left, top, right, bottom)); } catch (RemoteException e) { } } - private void runStackBoxes() throws Exception { + private void runStackList() throws Exception { try { - List<StackBoxInfo> stackBoxes = mAm.getStackBoxes(); - for (StackBoxInfo info : stackBoxes) { + List<StackInfo> stacks = mAm.getAllStackInfos(); + for (StackInfo info : stacks) { System.out.println(info); } } catch (RemoteException e) { } } - private void runStackBoxInfo() throws Exception { + private void runStackInfo() throws Exception { try { - String stackBoxIdStr = nextArgRequired(); - int stackBoxId = Integer.valueOf(stackBoxIdStr); - StackBoxInfo stackBoxInfo = mAm.getStackBoxInfo(stackBoxId); - System.out.println(stackBoxInfo); + String stackIdStr = nextArgRequired(); + int stackId = Integer.valueOf(stackIdStr); + StackInfo info = mAm.getStackInfo(stackId); + System.out.println(info); } catch (RemoteException e) { } } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 7ca345993c23..c877cd3ac264 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -1289,106 +1289,15 @@ public class ActivityManager { } /** - * Information you can retrieve about the WindowManager StackBox hierarchy. - * @hide - */ - public static class StackBoxInfo implements Parcelable { - public int stackBoxId; - public float weight; - public boolean vertical; - public Rect bounds; - public StackBoxInfo[] children; - public int stackId; - public StackInfo stack; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(stackBoxId); - dest.writeFloat(weight); - dest.writeInt(vertical ? 1 : 0); - bounds.writeToParcel(dest, flags); - dest.writeInt(stackId); - if (children != null) { - children[0].writeToParcel(dest, flags); - children[1].writeToParcel(dest, flags); - } else { - stack.writeToParcel(dest, flags); - } - } - - public void readFromParcel(Parcel source) { - stackBoxId = source.readInt(); - weight = source.readFloat(); - vertical = source.readInt() == 1; - bounds = Rect.CREATOR.createFromParcel(source); - stackId = source.readInt(); - if (stackId == -1) { - children = new StackBoxInfo[2]; - children[0] = StackBoxInfo.CREATOR.createFromParcel(source); - children[1] = StackBoxInfo.CREATOR.createFromParcel(source); - } else { - stack = StackInfo.CREATOR.createFromParcel(source); - } - } - - public static final Creator<StackBoxInfo> CREATOR = - new Creator<ActivityManager.StackBoxInfo>() { - - @Override - public StackBoxInfo createFromParcel(Parcel source) { - return new StackBoxInfo(source); - } - - @Override - public StackBoxInfo[] newArray(int size) { - return new StackBoxInfo[size]; - } - }; - - public StackBoxInfo() { - } - - public StackBoxInfo(Parcel source) { - readFromParcel(source); - } - - public String toString(String prefix) { - StringBuilder sb = new StringBuilder(256); - sb.append(prefix); sb.append("Box id=" + stackBoxId); sb.append(" weight=" + weight); - sb.append(" vertical=" + vertical); sb.append(" bounds=" + bounds.toShortString()); - sb.append("\n"); - if (children != null) { - sb.append(prefix); sb.append("First child=\n"); - sb.append(children[0].toString(prefix + " ")); - sb.append(prefix); sb.append("Second child=\n"); - sb.append(children[1].toString(prefix + " ")); - } else { - sb.append(prefix); sb.append("Stack=\n"); - sb.append(stack.toString(prefix + " ")); - } - return sb.toString(); - } - - @Override - public String toString() { - return toString(""); - } - } - - /** * Information you can retrieve about an ActivityStack in the system. * @hide */ public static class StackInfo implements Parcelable { public int stackId; - public Rect bounds; + public Rect bounds = new Rect(); public int[] taskIds; public String[] taskNames; + public int displayId; @Override public int describeContents() { @@ -1404,6 +1313,7 @@ public class ActivityManager { dest.writeInt(bounds.bottom); dest.writeIntArray(taskIds); dest.writeStringArray(taskNames); + dest.writeInt(displayId); } public void readFromParcel(Parcel source) { @@ -1412,6 +1322,7 @@ public class ActivityManager { source.readInt(), source.readInt(), source.readInt(), source.readInt()); taskIds = source.createIntArray(); taskNames = source.createStringArray(); + displayId = source.readInt(); } public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() { @@ -1435,7 +1346,9 @@ public class ActivityManager { public String toString(String prefix) { StringBuilder sb = new StringBuilder(256); sb.append(prefix); sb.append("Stack id="); sb.append(stackId); - sb.append(" bounds="); sb.append(bounds.toShortString()); sb.append("\n"); + sb.append(" bounds="); sb.append(bounds.toShortString()); + sb.append(" displayId="); sb.append(displayId); + sb.append("\n"); prefix = prefix + " "; for (int i = 0; i < taskIds.length; ++i) { sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]); diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 74266ccf58a2..7b81713c0fcc 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -16,7 +16,7 @@ package android.app; -import android.app.ActivityManager.StackBoxInfo; +import android.app.ActivityManager.StackInfo; import android.content.ComponentName; import android.content.IIntentReceiver; import android.content.IIntentSender; @@ -31,6 +31,7 @@ import android.content.pm.ParceledListSlice; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.Rect; import android.net.Uri; import android.os.Binder; import android.os.Bundle; @@ -611,18 +612,6 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } - case CREATE_STACK_TRANSACTION: { - data.enforceInterface(IActivityManager.descriptor); - int taskId = data.readInt(); - int relativeStackId = data.readInt(); - int position = data.readInt(); - float weight = data.readFloat(); - int res = createStack(taskId, relativeStackId, position, weight); - reply.writeNoException(); - reply.writeInt(res); - return true; - } - case MOVE_TASK_TO_STACK_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int taskId = data.readInt(); @@ -635,25 +624,26 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM case RESIZE_STACK_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); - int stackBoxId = data.readInt(); + int stackId = data.readInt(); float weight = data.readFloat(); - resizeStackBox(stackBoxId, weight); + Rect r = Rect.CREATOR.createFromParcel(data); + resizeStack(stackId, r); reply.writeNoException(); return true; } - case GET_STACK_BOXES_TRANSACTION: { + case GET_ALL_STACK_INFOS_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); - List<StackBoxInfo> list = getStackBoxes(); + List<StackInfo> list = getAllStackInfos(); reply.writeNoException(); reply.writeTypedList(list); return true; } - case GET_STACK_BOX_INFO_TRANSACTION: { + case GET_STACK_INFO_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); - int stackBoxId = data.readInt(); - StackBoxInfo info = getStackBoxInfo(stackBoxId); + int stackId = data.readInt(); + StackInfo info = getStackInfo(stackId); reply.writeNoException(); if (info != null) { reply.writeInt(1); @@ -2028,6 +2018,45 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } + + case CREATE_ACTIVITY_CONTAINER_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder parentActivityToken = data.readStrongBinder(); + IActivityContainerCallback callback = + (IActivityContainerCallback) data.readStrongBinder(); + IActivityContainer activityContainer = + createActivityContainer(parentActivityToken, callback); + reply.writeNoException(); + if (activityContainer != null) { + reply.writeInt(1); + reply.writeStrongBinder(activityContainer.asBinder()); + } else { + reply.writeInt(0); + } + return true; + } + + case GET_ACTIVITY_CONTAINER_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder activityToken = data.readStrongBinder(); + IActivityContainer activityContainer = getEnclosingActivityContainer(activityToken); + reply.writeNoException(); + if (activityContainer != null) { + reply.writeInt(1); + reply.writeStrongBinder(activityContainer.asBinder()); + } else { + reply.writeInt(0); + } + return true; + } + + case GET_HOME_ACTIVITY_TOKEN_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder homeActivityToken = getHomeActivityToken(); + reply.writeNoException(); + reply.writeStrongBinder(homeActivityToken); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -2715,24 +2744,6 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } @Override - public int createStack(int taskId, int relativeStackBoxId, int position, float weight) - throws RemoteException - { - Parcel data = Parcel.obtain(); - Parcel reply = Parcel.obtain(); - data.writeInterfaceToken(IActivityManager.descriptor); - data.writeInt(taskId); - data.writeInt(relativeStackBoxId); - data.writeInt(position); - data.writeFloat(weight); - mRemote.transact(CREATE_STACK_TRANSACTION, data, reply, 0); - reply.readException(); - int res = reply.readInt(); - data.recycle(); - reply.recycle(); - return res; - } - @Override public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException { Parcel data = Parcel.obtain(); @@ -2747,44 +2758,44 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } @Override - public void resizeStackBox(int stackBoxId, float weight) throws RemoteException + public void resizeStack(int stackBoxId, Rect r) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(stackBoxId); - data.writeFloat(weight); + r.writeToParcel(data, 0); mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); reply.readException(); data.recycle(); reply.recycle(); } @Override - public List<StackBoxInfo> getStackBoxes() throws RemoteException + public List<StackInfo> getAllStackInfos() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); - mRemote.transact(GET_STACK_BOXES_TRANSACTION, data, reply, 0); + mRemote.transact(GET_ALL_STACK_INFOS_TRANSACTION, data, reply, 0); reply.readException(); - ArrayList<StackBoxInfo> list = reply.createTypedArrayList(StackBoxInfo.CREATOR); + ArrayList<StackInfo> list = reply.createTypedArrayList(StackInfo.CREATOR); data.recycle(); reply.recycle(); return list; } @Override - public StackBoxInfo getStackBoxInfo(int stackBoxId) throws RemoteException + public StackInfo getStackInfo(int stackId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); - data.writeInt(stackBoxId); - mRemote.transact(GET_STACK_BOX_INFO_TRANSACTION, data, reply, 0); + data.writeInt(stackId); + mRemote.transact(GET_STACK_INFO_TRANSACTION, data, reply, 0); reply.readException(); int res = reply.readInt(); - StackBoxInfo info = null; + StackInfo info = null; if (res != 0) { - info = StackBoxInfo.CREATOR.createFromParcel(reply); + info = StackInfo.CREATOR.createFromParcel(reply); } data.recycle(); reply.recycle(); @@ -4660,5 +4671,58 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } + public IActivityContainer createActivityContainer(IBinder parentActivityToken, + IActivityContainerCallback callback) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(parentActivityToken); + data.writeStrongBinder((IBinder)callback); + mRemote.transact(CREATE_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0); + reply.readException(); + final int result = reply.readInt(); + final IActivityContainer res; + if (result == 1) { + res = IActivityContainer.Stub.asInterface(reply.readStrongBinder()); + } else { + res = null; + } + data.recycle(); + reply.recycle(); + return res; + } + + public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) + throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(activityToken); + mRemote.transact(GET_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0); + reply.readException(); + final int result = reply.readInt(); + final IActivityContainer res; + if (result == 1) { + res = IActivityContainer.Stub.asInterface(reply.readStrongBinder()); + } else { + res = null; + } + data.recycle(); + reply.recycle(); + return res; + } + + public IBinder getHomeActivityToken() throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + mRemote.transact(GET_HOME_ACTIVITY_TOKEN_TRANSACTION, data, reply, 0); + reply.readException(); + IBinder res = reply.readStrongBinder(); + data.recycle(); + reply.recycle(); + return res; + } + private IBinder mRemote; } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 97baf9a90417..9f21a3603fe9 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2219,15 +2219,27 @@ public final class ActivityThread { ContextImpl appContext = new ContextImpl(); appContext.init(r.packageInfo, r.token, this); appContext.setOuterContext(activity); + Context baseContext = appContext; + + final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); + try { + IActivityContainer container = + ActivityManagerNative.getDefault().getEnclosingActivityContainer(r.token); + final int displayId = + container == null ? Display.DEFAULT_DISPLAY : container.getDisplayId(); + if (displayId > Display.DEFAULT_DISPLAY) { + Display display = dm.getRealDisplay(displayId, r.token); + baseContext = appContext.createDisplayContext(display); + } + } catch (RemoteException e) { + } // For debugging purposes, if the activity's package name contains the value of // the "debug.use-second-display" system property as a substring, then show // its content on a secondary display if there is one. - Context baseContext = appContext; String pkgName = SystemProperties.get("debug.second-display.pkg"); if (pkgName != null && !pkgName.isEmpty() && r.packageInfo.mPackageName.contains(pkgName)) { - DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); for (int displayId : dm.getDisplayIds()) { if (displayId != Display.DEFAULT_DISPLAY) { Display display = dm.getRealDisplay(displayId, r.token); diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java new file mode 100644 index 000000000000..fef4597e4e4e --- /dev/null +++ b/core/java/android/app/ActivityView.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; +import android.graphics.SurfaceTexture; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.Surface; +import android.view.TextureView; +import android.view.TextureView.SurfaceTextureListener; +import android.view.ViewGroup; +import android.view.WindowManager; + +public class ActivityView extends ViewGroup { + private final TextureView mTextureView; + private IActivityContainer mActivityContainer; + private Activity mActivity; + private boolean mAttached; + private int mWidth; + private int mHeight; + + public ActivityView(Context context) { + this(context, null); + } + + public ActivityView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ActivityView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + while (context instanceof ContextWrapper) { + if (context instanceof Activity) { + mActivity = (Activity)context; + break; + } + context = ((ContextWrapper)context).getBaseContext(); + } + if (mActivity == null) { + throw new IllegalStateException("The ActivityView's Context is not an Activity."); + } + + mTextureView = new TextureView(context); + mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener()); + addView(mTextureView); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + mTextureView.layout(l, t, r, b); + } + + @Override + protected void onAttachedToWindow() { + try { + final IBinder token = mActivity.getActivityToken(); + mActivityContainer = + ActivityManagerNative.getDefault().createActivityContainer(token, null); + } catch (RemoteException e) { + throw new IllegalStateException("ActivityView: Unable to create ActivityContainer. " + + e); + } + + final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture(); + if (surfaceTexture != null) { + createActivityView(surfaceTexture); + } + } + + @Override + protected void onDetachedFromWindow() { + if (mActivityContainer != null) { + try { + mActivityContainer.deleteActivityView(); + } catch (RemoteException e) { + } + mActivityContainer = null; + } + mAttached = false; + } + + public void startActivity(Intent intent) { + if (mActivityContainer != null && mAttached) { + try { + mActivityContainer.startActivity(intent); + } catch (RemoteException e) { + throw new IllegalStateException("ActivityView: Unable to startActivity. " + e); + } + } + } + + /** Call when both mActivityContainer and mTextureView's SurfaceTexture are not null */ + private void createActivityView(SurfaceTexture surfaceTexture) { + WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE); + DisplayMetrics metrics = new DisplayMetrics(); + wm.getDefaultDisplay().getMetrics(metrics); + + try { + mActivityContainer.createActivityView(new Surface(surfaceTexture), mWidth, mHeight, + metrics.densityDpi); + } catch (RemoteException e) { + mActivityContainer = null; + throw new IllegalStateException( + "ActivityView: Unable to create ActivityContainer. " + e); + } + mAttached = true; + } + + private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener { + @Override + public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, + int height) { + mWidth = width; + mHeight = height; + if (mActivityContainer != null) { + createActivityView(surfaceTexture); + } + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, + int height) { + } + + @Override + public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { + try { + mActivityContainer.deleteActivityView(); + // TODO: Add binderDied to handle this nullification. + mActivityContainer = null; + } catch (RemoteException r) { + } + mAttached = false; + return false; + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { + + } + + } +} diff --git a/core/java/android/app/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl new file mode 100644 index 000000000000..b03a459a95a4 --- /dev/null +++ b/core/java/android/app/IActivityContainer.aidl @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2013, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.app.IActivityContainerCallback; +import android.content.Intent; +import android.os.IBinder; +import android.view.Surface; + +/** @hide */ +interface IActivityContainer { + void attachToDisplay(int displayId); + int getDisplayId(); + void detachFromDisplay(); + int startActivity(in Intent intent); + void createActivityView(in Surface surface, int width, int height, int density); + void deleteActivityView(); +} diff --git a/core/java/android/app/IActivityContainerCallback.aidl b/core/java/android/app/IActivityContainerCallback.aidl new file mode 100644 index 000000000000..55c2001e90ef --- /dev/null +++ b/core/java/android/app/IActivityContainerCallback.aidl @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2013, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.os.IBinder; + +/** @hide */ +interface IActivityContainerCallback { + oneway void onLastActivityRemoved(IBinder container); +} diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 77c2ea0c1694..3ed3f7bdf20e 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -18,7 +18,7 @@ package android.app; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.RunningServiceInfo; -import android.app.ActivityManager.StackBoxInfo; +import android.app.ActivityManager.StackInfo; import android.content.ComponentName; import android.content.ContentProviderNative; import android.content.IContentProvider; @@ -36,6 +36,7 @@ import android.content.pm.ProviderInfo; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; import android.os.Debug; @@ -117,12 +118,10 @@ public interface IActivityManager extends IInterface { public void moveTaskToBack(int task) throws RemoteException; public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException; public void moveTaskBackwards(int task) throws RemoteException; - public int createStack(int taskId, int relativeStackBoxId, int position, float weight) - throws RemoteException; public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException; - public void resizeStackBox(int stackBoxId, float weight) throws RemoteException; - public List<StackBoxInfo> getStackBoxes() throws RemoteException; - public StackBoxInfo getStackBoxInfo(int stackBoxId) throws RemoteException; + public void resizeStack(int stackId, Rect bounds) throws RemoteException; + public List<StackInfo> getAllStackInfos() throws RemoteException; + public StackInfo getStackInfo(int stackId) throws RemoteException; public void setFocusedStack(int stackId) throws RemoteException; public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException; /* oneway */ @@ -408,6 +407,14 @@ public interface IActivityManager extends IInterface { public void performIdleMaintenance() throws RemoteException; + public IActivityContainer createActivityContainer(IBinder parentActivityToken, + IActivityContainerCallback callback) throws RemoteException; + + public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) + throws RemoteException; + + public IBinder getHomeActivityToken() throws RemoteException; + /* * Private non-Binder interfaces */ @@ -678,12 +685,12 @@ public interface IActivityManager extends IInterface { int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164; int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+165; int HANG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+166; - int CREATE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+167; + int CREATE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+167; int MOVE_TASK_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+168; int RESIZE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+169; - int GET_STACK_BOXES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170; + int GET_ALL_STACK_INFOS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170; int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171; - int GET_STACK_BOX_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172; + int GET_STACK_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172; int CONVERT_FROM_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173; int CONVERT_TO_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+174; int NOTIFY_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+175; @@ -694,4 +701,6 @@ public interface IActivityManager extends IInterface { int RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+180; int GET_PERSISTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+181; int APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+182; + int GET_HOME_ACTIVITY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183; + int GET_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184; } diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index 3efd3c0ede8b..181eb63bce69 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -71,4 +71,14 @@ interface IWallpaperManager { * Returns the desired minimum height for the wallpaper. */ int getHeightHint(); + + /** + * Returns the name of the wallpaper. Private API. + */ + String getName(); + + /** + * Informs the service that wallpaper settings have been restored. Private API. + */ + void settingsRestored(); } diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 093e0e9270ff..a517bc5d71c6 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -115,6 +115,7 @@ public final class DisplayManager { * </p> * * @see #createVirtualDisplay + * @see #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY */ public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1 << 0; @@ -171,6 +172,22 @@ public final class DisplayManager { */ public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 1 << 2; + /** + * Virtual display flag: Only show this display's own content; do not mirror + * the content of another display. + * + * <p> + * This flag is used in conjunction with {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}. + * Ordinarily public virtual displays will automatically mirror the content of the + * default display if they have no windows of their own. When this flag is + * specified, the virtual display will only ever show its own content and + * will be blanked instead if it has no windows. + * </p> + * + * @see #createVirtualDisplay + */ + public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 1 << 3; + /** @hide */ public DisplayManager(Context context) { mContext = context; @@ -429,8 +446,8 @@ public final class DisplayManager { * @param surface The surface to which the content of the virtual display should * be rendered, must be non-null. * @param flags A combination of virtual display flags: - * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION} - * or {@link #VIRTUAL_DISPLAY_FLAG_SECURE}. + * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION}, + * {@link #VIRTUAL_DISPLAY_FLAG_SECURE}, or {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}. * @return The newly created virtual display, or null if the application could * not create the virtual display. * diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index b22d5cf32af5..a06a20b21b07 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -79,9 +79,6 @@ public class SurfaceControl { private final String mName; int mNativeObject; // package visibility only for Surface.java access - private static final boolean HEADLESS = "1".equals( - SystemProperties.get("ro.config.headless", "0")); - /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ /** @@ -232,8 +229,6 @@ public class SurfaceControl { new Throwable()); } - checkHeadless(); - mName = name; mNativeObject = nativeCreate(session, name, w, h, format, flags); if (mNativeObject == 0) { @@ -619,10 +614,4 @@ public class SurfaceControl { } nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers); } - - private static void checkHeadless() { - if (HEADLESS) { - throw new UnsupportedOperationException("Device is headless"); - } - } } diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index 00f4adb911bc..879e58f494c0 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -177,7 +177,8 @@ public final class AccessibilityManager { userId = UserHandle.myUserId(); } IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE); - IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder); + IAccessibilityManager service = iBinder == null + ? null : IAccessibilityManager.Stub.asInterface(iBinder); sInstance = new AccessibilityManager(context, service, userId); } } @@ -197,10 +198,14 @@ public final class AccessibilityManager { mHandler = new MyHandler(context.getMainLooper()); mService = service; mUserId = userId; - + if (mService == null) { + mIsEnabled = false; + } try { - final int stateFlags = mService.addClient(mClient, userId); - setState(stateFlags); + if (mService != null) { + final int stateFlags = mService.addClient(mClient, userId); + setState(stateFlags); + } } catch (RemoteException re) { Log.e(LOG_TAG, "AccessibilityManagerService is dead", re); } @@ -322,14 +327,16 @@ public final class AccessibilityManager { public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() { List<AccessibilityServiceInfo> services = null; try { - services = mService.getInstalledAccessibilityServiceList(mUserId); - if (DEBUG) { - Log.i(LOG_TAG, "Installed AccessibilityServices " + services); + if (mService != null) { + services = mService.getInstalledAccessibilityServiceList(mUserId); + if (DEBUG) { + Log.i(LOG_TAG, "Installed AccessibilityServices " + services); + } } } catch (RemoteException re) { Log.e(LOG_TAG, "Error while obtaining the installed AccessibilityServices. ", re); } - return Collections.unmodifiableList(services); + return services != null ? Collections.unmodifiableList(services) : Collections.EMPTY_LIST; } /** @@ -349,14 +356,16 @@ public final class AccessibilityManager { int feedbackTypeFlags) { List<AccessibilityServiceInfo> services = null; try { - services = mService.getEnabledAccessibilityServiceList(feedbackTypeFlags, mUserId); - if (DEBUG) { - Log.i(LOG_TAG, "Installed AccessibilityServices " + services); + if (mService != null) { + services = mService.getEnabledAccessibilityServiceList(feedbackTypeFlags, mUserId); + if (DEBUG) { + Log.i(LOG_TAG, "Installed AccessibilityServices " + services); + } } } catch (RemoteException re) { Log.e(LOG_TAG, "Error while obtaining the installed AccessibilityServices. ", re); } - return Collections.unmodifiableList(services); + return services != null ? Collections.unmodifiableList(services) : Collections.EMPTY_LIST; } /** @@ -466,6 +475,9 @@ public final class AccessibilityManager { */ public int addAccessibilityInteractionConnection(IWindow windowToken, IAccessibilityInteractionConnection connection) { + if (mService == null) { + return View.NO_ID; + } try { return mService.addAccessibilityInteractionConnection(windowToken, connection, mUserId); } catch (RemoteException re) { @@ -482,7 +494,9 @@ public final class AccessibilityManager { */ public void removeAccessibilityInteractionConnection(IWindow windowToken) { try { - mService.removeAccessibilityInteractionConnection(windowToken); + if (mService != null) { + mService.removeAccessibilityInteractionConnection(windowToken); + } } catch (RemoteException re) { Log.e(LOG_TAG, "Error while removing an accessibility interaction connection. ", re); } diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java index 46541785f468..fe1cf72cb884 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java +++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java @@ -164,8 +164,24 @@ public class ActionMenuPresenter extends BaseMenuPresenter } actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE); + final ActionMenuView menuParent = (ActionMenuView) parent; + final ViewGroup.LayoutParams lp = actionView.getLayoutParams(); + if (!menuParent.checkLayoutParams(lp)) { + actionView.setLayoutParams(menuParent.generateLayoutParams(lp)); + } + return actionView; + } + + @Override + public void bindItemView(final MenuItemImpl item, MenuView.ItemView itemView) { + itemView.initialize(item, 0); + + final ActionMenuView menuView = (ActionMenuView) mMenuView; + final ActionMenuItemView actionItemView = (ActionMenuItemView) itemView; + actionItemView.setItemInvoker(menuView); + if (item.hasSubMenu()) { - actionView.setOnTouchListener(new ForwardingListener(actionView) { + actionItemView.setOnTouchListener(new ForwardingListener(actionItemView) { @Override public ListPopupWindow getPopup() { return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null; @@ -182,24 +198,8 @@ public class ActionMenuPresenter extends BaseMenuPresenter } }); } else { - actionView.setOnTouchListener(null); + actionItemView.setOnTouchListener(null); } - - final ActionMenuView menuParent = (ActionMenuView) parent; - final ViewGroup.LayoutParams lp = actionView.getLayoutParams(); - if (!menuParent.checkLayoutParams(lp)) { - actionView.setLayoutParams(menuParent.generateLayoutParams(lp)); - } - return actionView; - } - - @Override - public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) { - itemView.initialize(item, 0); - - final ActionMenuView menuView = (ActionMenuView) mMenuView; - ActionMenuItemView actionItemView = (ActionMenuItemView) itemView; - actionItemView.setItemInvoker(menuView); } @Override diff --git a/core/java/com/android/server/LocalServices.java b/core/java/com/android/server/LocalServices.java new file mode 100644 index 000000000000..25dcb308b55a --- /dev/null +++ b/core/java/com/android/server/LocalServices.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.util.ArrayMap; + +/** + * This class is used in a similar way as ServiceManager, except the services registered here + * are not Binder objects and are only available in the same process. + * + * Once all services are converted to the SystemService interface, this class can be absorbed + * into SystemServiceManager. + * + * {@hide} + */ +public final class LocalServices { + private LocalServices() {} + + private static final ArrayMap<Class<?>, Object> sLocalServiceObjects = + new ArrayMap<Class<?>, Object>(); + + /** + * Returns a local service instance that implements the specified interface. + * + * @param type The type of service. + * @return The service object. + */ + @SuppressWarnings("unchecked") + public static <T> T getService(Class<T> type) { + synchronized (sLocalServiceObjects) { + return (T) sLocalServiceObjects.get(type); + } + } + + /** + * Adds a service instance of the specified interface to the global registry of local services. + */ + public static <T> void addService(Class<T> type, T service) { + synchronized (sLocalServiceObjects) { + if (sLocalServiceObjects.containsKey(type)) { + throw new IllegalStateException("Overriding service registration"); + } + sLocalServiceObjects.put(type, service); + } + } +} diff --git a/core/java/com/android/server/SystemService.java b/core/java/com/android/server/SystemService.java new file mode 100644 index 000000000000..0356753a22f6 --- /dev/null +++ b/core/java/com/android/server/SystemService.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.content.Context; +import android.os.IBinder; +import android.os.ServiceManager; + +/** + * The base class for services running in the system process. Override and implement + * the lifecycle event callback methods as needed. + * + * The lifecycle of a SystemService: + * + * {@link #onCreate(android.content.Context)} is called to initialize the + * service. + * + * {@link #onStart()} is called to get the service running. It is common + * for services to publish their Binder interface at this point. All required + * dependencies are also assumed to be ready to use. + * + * Then {@link #onBootPhase(int)} is called as many times as there are boot phases + * until {@link #PHASE_BOOT_COMPLETE} is sent, which is the last boot phase. Each phase + * is an opportunity to do special work, like acquiring optional service dependencies, + * waiting to see if SafeMode is enabled, or registering with a service that gets + * started after this one. + * + * NOTE: All lifecycle methods are called from the same thread that created the + * SystemService. + * + * {@hide} + */ +public abstract class SystemService { + /* + * Boot Phases + */ + public static final int PHASE_LOCK_SETTINGS_READY = 480; + public static final int PHASE_SYSTEM_SERVICES_READY = 500; + public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; + public static final int PHASE_BOOT_COMPLETE = 1000; + + private SystemServiceManager mManager; + private Context mContext; + + final void init(Context context, SystemServiceManager manager) { + mContext = context; + mManager = manager; + onCreate(context); + } + + public final boolean isSafeMode() { + return mManager.isSafeMode(); + } + + /** + * Services are not yet available. This is a good place to do setup work that does + * not require other services. + * + * @param context The system context. + */ + public void onCreate(Context context) {} + + /** + * Called when the dependencies listed in the @Service class-annotation are available + * and after the chosen start phase. + * When this method returns, the service should be published. + */ + public abstract void onStart(); + + /** + * Called on each phase of the boot process. Phases before the service's start phase + * (as defined in the @Service annotation) are never received. + * + * @param phase The current boot phase. + */ + public void onBootPhase(int phase) {} + + /** + * Publish the service so it is accessible to other services and apps. + */ + protected final void publishBinderService(String name, IBinder service) { + ServiceManager.addService(name, service); + } + + /** + * Get a binder service by its name. + */ + protected final IBinder getBinderService(String name) { + return ServiceManager.getService(name); + } + + /** + * Publish the service so it is only accessible to the system process. + */ + protected final <T> void publishLocalService(Class<T> type, T service) { + LocalServices.addService(type, service); + } + + /** + * Get a local service by interface. + */ + protected final <T> T getLocalService(Class<T> type) { + return LocalServices.getService(type); + } + + public final Context getContext() { + return mContext; + } + +// /** +// * Called when a new user has been created. If your service deals with multiple users, this +// * method should be overridden. +// * +// * @param userHandle The user that was created. +// */ +// public void onUserCreated(int userHandle) { +// } +// +// /** +// * Called when an existing user has started a new session. If your service deals with multiple +// * users, this method should be overridden. +// * +// * @param userHandle The user who started a new session. +// */ +// public void onUserStarted(int userHandle) { +// } +// +// /** +// * Called when a background user session has entered the foreground. If your service deals with +// * multiple users, this method should be overridden. +// * +// * @param userHandle The user who's session entered the foreground. +// */ +// public void onUserForeground(int userHandle) { +// } +// +// /** +// * Called when a foreground user session has entered the background. If your service deals with +// * multiple users, this method should be overridden; +// * +// * @param userHandle The user who's session entered the background. +// */ +// public void onUserBackground(int userHandle) { +// } +// +// /** +// * Called when a user's active session has stopped. If your service deals with multiple users, +// * this method should be overridden. +// * +// * @param userHandle The user who's session has stopped. +// */ +// public void onUserStopped(int userHandle) { +// } +// +// /** +// * Called when a user has been removed from the system. If your service deals with multiple +// * users, this method should be overridden. +// * +// * @param userHandle The user who has been removed. +// */ +// public void onUserRemoved(int userHandle) { +// } +} diff --git a/core/java/com/android/server/SystemServiceManager.java b/core/java/com/android/server/SystemServiceManager.java new file mode 100644 index 000000000000..e2a6063050e4 --- /dev/null +++ b/core/java/com/android/server/SystemServiceManager.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.content.Context; +import android.util.Log; +import android.util.Slog; + +import java.util.ArrayList; + +/** + * Manages creating, starting, and other lifecycle events of + * {@link com.android.server.SystemService}s. + * + * {@hide} + */ +public class SystemServiceManager { + private static final String TAG = "SystemServiceManager"; + + private final Context mContext; + private boolean mSafeMode; + + // Services that should receive lifecycle events. + private final ArrayList<SystemService> mServices = new ArrayList<SystemService>(); + + private int mCurrentPhase = -1; + + public SystemServiceManager(Context context) { + mContext = context; + } + + public void startService(String className) { + try { + startService(Class.forName(className)); + } catch (ClassNotFoundException cnfe) { + Slog.i(TAG, className + " not available, ignoring."); + } + } + + /** + * Creates and starts a system service. The class must be a subclass of + * {@link com.android.server.SystemService}. + * + * @param serviceClass A Java class that implements the SystemService interface. + * @throws RuntimeException if the service fails to start. + */ + public void startService(Class<?> serviceClass) { + final SystemService serviceInstance = createInstance(serviceClass); + try { + Slog.i(TAG, "Creating " + serviceClass.getSimpleName()); + serviceInstance.init(mContext, this); + } catch (Throwable e) { + throw new RuntimeException("Failed to create service " + serviceClass.getName(), e); + } + + mServices.add(serviceInstance); + + try { + Slog.i(TAG, "Starting " + serviceClass.getSimpleName()); + serviceInstance.onStart(); + } catch (Throwable e) { + throw new RuntimeException("Failed to start service " + serviceClass.getName(), e); + } + } + + /** + * Starts the specified boot phase for all system services that have been started up to + * this point. + * + * @param phase The boot phase to start. + */ + public void startBootPhase(final int phase) { + if (phase <= mCurrentPhase) { + throw new IllegalArgumentException("Next phase must be larger than previous"); + } + mCurrentPhase = phase; + + Slog.i(TAG, "Starting phase " + mCurrentPhase); + + final int serviceLen = mServices.size(); + for (int i = 0; i < serviceLen; i++) { + final SystemService service = mServices.get(i); + try { + service.onBootPhase(mCurrentPhase); + } catch (Throwable e) { + reportWtf("Service " + service.getClass().getName() + + " threw an Exception processing boot phase " + mCurrentPhase, e); + } + } + } + + /** Sets the safe mode flag for services to query. */ + public void setSafeMode(boolean safeMode) { + mSafeMode = safeMode; + } + + /** + * Returns whether we are booting into safe mode. + * @return safe mode flag + */ + public boolean isSafeMode() { + return mSafeMode; + } + + /** + * Outputs the state of this manager to the System log. + */ + public void dump() { + StringBuilder builder = new StringBuilder(); + builder.append("Current phase: ").append(mCurrentPhase).append("\n"); + builder.append("Services:\n"); + final int startedLen = mServices.size(); + for (int i = 0; i < startedLen; i++) { + final SystemService service = mServices.get(i); + builder.append("\t") + .append(service.getClass().getSimpleName()) + .append("\n"); + } + + Slog.e(TAG, builder.toString()); + } + + private SystemService createInstance(Class<?> clazz) { + // Make sure it's a type we expect + if (!SystemService.class.isAssignableFrom(clazz)) { + reportWtf("Class " + clazz.getName() + " does not extend " + + SystemService.class.getName()); + } + + try { + return (SystemService) clazz.newInstance(); + } catch (InstantiationException e) { + reportWtf("Class " + clazz.getName() + " is abstract", e); + } catch (IllegalAccessException e) { + reportWtf("Class " + clazz.getName() + + " must have a public no-arg constructor", e); + } + return null; + } + + private static void reportWtf(String message) { + reportWtf(message, null); + } + + private static void reportWtf(String message, Throwable e) { + Slog.i(TAG, "******************************"); + Log.wtf(TAG, message, e); + + // Make sure we die + throw new RuntimeException(message, e); + } +} diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index b198937df18d..e5461178390b 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2522,7 +2522,7 @@ android:hasCode="false" android:label="@string/android_system_label" android:allowClearUserData="false" - android:backupAgent="com.android.server.SystemBackupAgent" + android:backupAgent="com.android.server.backup.SystemBackupAgent" android:killAfterRestore="false" android:icon="@drawable/ic_launcher_android" android:supportsRtl="true"> diff --git a/core/res/res/values/styles_micro.xml b/core/res/res/values/styles_micro.xml new file mode 100644 index 000000000000..2fd283eb780d --- /dev/null +++ b/core/res/res/values/styles_micro.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <style name="Widget.Micro" parent="Widget.Holo" /> + + <style name="Widget.Micro.TextView"> + <item name="android:fontFamily">sans-serif-condensed</item> + </style> +</resources> diff --git a/core/res/res/values/themes_micro.xml b/core/res/res/values/themes_micro.xml new file mode 100644 index 000000000000..be5fa99d0271 --- /dev/null +++ b/core/res/res/values/themes_micro.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <style name="Theme.Micro" parent="Theme.Holo" /> + + <style name="Theme.Micro.Light" parent="Theme.Holo.Light"/> + <style name="Theme.Micro.Light.NoActionBar" parent="Theme.Holo.Light.NoActionBar"> + <item name="textViewStyle">@android:style/Widget.Micro.TextView</item> + </style> + <style name="Theme.Micro.Light.DarkActionBar" parent="Theme.Holo.Light.DarkActionBar"> + <item name="textViewStyle">@android:style/Widget.Micro.TextView</item> + </style> + +</resources> diff --git a/services/common_time/Android.mk b/libs/common_time/Android.mk index 75eb5281f692..75eb5281f692 100644 --- a/services/common_time/Android.mk +++ b/libs/common_time/Android.mk diff --git a/services/common_time/clock_recovery.cpp b/libs/common_time/clock_recovery.cpp index 3a7c70c3e17d..3a7c70c3e17d 100644 --- a/services/common_time/clock_recovery.cpp +++ b/libs/common_time/clock_recovery.cpp diff --git a/services/common_time/clock_recovery.h b/libs/common_time/clock_recovery.h index b6c87ffaf37e..b6c87ffaf37e 100644 --- a/services/common_time/clock_recovery.h +++ b/libs/common_time/clock_recovery.h diff --git a/services/common_time/common_clock.cpp b/libs/common_time/common_clock.cpp index c9eb3884440d..c9eb3884440d 100644 --- a/services/common_time/common_clock.cpp +++ b/libs/common_time/common_clock.cpp diff --git a/services/common_time/common_clock.h b/libs/common_time/common_clock.h index b786fdceba5f..b786fdceba5f 100644 --- a/services/common_time/common_clock.h +++ b/libs/common_time/common_clock.h diff --git a/services/common_time/common_clock_service.cpp b/libs/common_time/common_clock_service.cpp index 9ca6f3523084..9ca6f3523084 100644 --- a/services/common_time/common_clock_service.cpp +++ b/libs/common_time/common_clock_service.cpp diff --git a/services/common_time/common_clock_service.h b/libs/common_time/common_clock_service.h index bd663f06d43a..bd663f06d43a 100644 --- a/services/common_time/common_clock_service.h +++ b/libs/common_time/common_clock_service.h diff --git a/services/common_time/common_time_config_service.cpp b/libs/common_time/common_time_config_service.cpp index 958561818423..958561818423 100644 --- a/services/common_time/common_time_config_service.cpp +++ b/libs/common_time/common_time_config_service.cpp diff --git a/services/common_time/common_time_config_service.h b/libs/common_time/common_time_config_service.h index 89806dd87e29..89806dd87e29 100644 --- a/services/common_time/common_time_config_service.h +++ b/libs/common_time/common_time_config_service.h diff --git a/services/common_time/common_time_server.cpp b/libs/common_time/common_time_server.cpp index 21e706fa0722..21e706fa0722 100644 --- a/services/common_time/common_time_server.cpp +++ b/libs/common_time/common_time_server.cpp diff --git a/services/common_time/common_time_server.h b/libs/common_time/common_time_server.h index 6e1805086978..6e1805086978 100644 --- a/services/common_time/common_time_server.h +++ b/libs/common_time/common_time_server.h diff --git a/services/common_time/common_time_server_api.cpp b/libs/common_time/common_time_server_api.cpp index e15707181bca..e15707181bca 100644 --- a/services/common_time/common_time_server_api.cpp +++ b/libs/common_time/common_time_server_api.cpp diff --git a/services/common_time/common_time_server_packets.cpp b/libs/common_time/common_time_server_packets.cpp index 9833c37f2519..9833c37f2519 100644 --- a/services/common_time/common_time_server_packets.cpp +++ b/libs/common_time/common_time_server_packets.cpp diff --git a/services/common_time/common_time_server_packets.h b/libs/common_time/common_time_server_packets.h index 57ba8a256308..57ba8a256308 100644 --- a/services/common_time/common_time_server_packets.h +++ b/libs/common_time/common_time_server_packets.h diff --git a/services/common_time/diag_thread.cpp b/libs/common_time/diag_thread.cpp index 4cb955131099..4cb955131099 100644 --- a/services/common_time/diag_thread.cpp +++ b/libs/common_time/diag_thread.cpp diff --git a/services/common_time/diag_thread.h b/libs/common_time/diag_thread.h index c630e0d9b525..c630e0d9b525 100644 --- a/services/common_time/diag_thread.h +++ b/libs/common_time/diag_thread.h diff --git a/services/common_time/main.cpp b/libs/common_time/main.cpp index 49eb30abab66..49eb30abab66 100644 --- a/services/common_time/main.cpp +++ b/libs/common_time/main.cpp diff --git a/services/common_time/utils.cpp b/libs/common_time/utils.cpp index ed2c77ddb3a5..ed2c77ddb3a5 100644 --- a/services/common_time/utils.cpp +++ b/libs/common_time/utils.cpp diff --git a/services/common_time/utils.h b/libs/common_time/utils.h index c28cf0ac33d7..c28cf0ac33d7 100644 --- a/services/common_time/utils.h +++ b/libs/common_time/utils.h diff --git a/services/input/Android.mk b/libs/input/Android.mk index 6e944ef5cc96..6e944ef5cc96 100644 --- a/services/input/Android.mk +++ b/libs/input/Android.mk diff --git a/services/input/EventHub.cpp b/libs/input/EventHub.cpp index fc64656b1745..fc64656b1745 100644 --- a/services/input/EventHub.cpp +++ b/libs/input/EventHub.cpp diff --git a/services/input/EventHub.h b/libs/input/EventHub.h index ae28f016f726..ae28f016f726 100644 --- a/services/input/EventHub.h +++ b/libs/input/EventHub.h diff --git a/services/input/InputApplication.cpp b/libs/input/InputApplication.cpp index a99e637fdf43..a99e637fdf43 100644 --- a/services/input/InputApplication.cpp +++ b/libs/input/InputApplication.cpp diff --git a/services/input/InputApplication.h b/libs/input/InputApplication.h index 1f5504c2d234..1f5504c2d234 100644 --- a/services/input/InputApplication.h +++ b/libs/input/InputApplication.h diff --git a/services/input/InputDispatcher.cpp b/libs/input/InputDispatcher.cpp index 10a639e7aaad..10a639e7aaad 100644 --- a/services/input/InputDispatcher.cpp +++ b/libs/input/InputDispatcher.cpp diff --git a/services/input/InputDispatcher.h b/libs/input/InputDispatcher.h index 190e7b221058..190e7b221058 100644 --- a/services/input/InputDispatcher.h +++ b/libs/input/InputDispatcher.h diff --git a/services/input/InputListener.cpp b/libs/input/InputListener.cpp index 85bb0ed5242e..85bb0ed5242e 100644 --- a/services/input/InputListener.cpp +++ b/libs/input/InputListener.cpp diff --git a/services/input/InputListener.h b/libs/input/InputListener.h index 78ae10f70dfb..78ae10f70dfb 100644 --- a/services/input/InputListener.h +++ b/libs/input/InputListener.h diff --git a/services/input/InputManager.cpp b/libs/input/InputManager.cpp index 6a6547bdf03c..6a6547bdf03c 100644 --- a/services/input/InputManager.cpp +++ b/libs/input/InputManager.cpp diff --git a/services/input/InputManager.h b/libs/input/InputManager.h index a213b2dfaa51..a213b2dfaa51 100644 --- a/services/input/InputManager.h +++ b/libs/input/InputManager.h diff --git a/services/input/InputReader.cpp b/libs/input/InputReader.cpp index 03852a5ffcff..03852a5ffcff 100644 --- a/services/input/InputReader.cpp +++ b/libs/input/InputReader.cpp diff --git a/services/input/InputReader.h b/libs/input/InputReader.h index a8bb63671b60..a8bb63671b60 100644 --- a/services/input/InputReader.h +++ b/libs/input/InputReader.h diff --git a/services/input/InputWindow.cpp b/libs/input/InputWindow.cpp index fe61918e1d86..fe61918e1d86 100644 --- a/services/input/InputWindow.cpp +++ b/libs/input/InputWindow.cpp diff --git a/services/input/InputWindow.h b/libs/input/InputWindow.h index 28fa7ab42d44..28fa7ab42d44 100644 --- a/services/input/InputWindow.h +++ b/libs/input/InputWindow.h diff --git a/services/input/PointerController.cpp b/libs/input/PointerController.cpp index 9af521b7aba2..9af521b7aba2 100644 --- a/services/input/PointerController.cpp +++ b/libs/input/PointerController.cpp diff --git a/services/input/PointerController.h b/libs/input/PointerController.h index 790c0bbd5ca9..790c0bbd5ca9 100644 --- a/services/input/PointerController.h +++ b/libs/input/PointerController.h diff --git a/services/input/SpriteController.cpp b/libs/input/SpriteController.cpp index fd9c66ba04cf..fd9c66ba04cf 100644 --- a/services/input/SpriteController.cpp +++ b/libs/input/SpriteController.cpp diff --git a/services/input/SpriteController.h b/libs/input/SpriteController.h index 75e4843d38dc..75e4843d38dc 100644 --- a/services/input/SpriteController.h +++ b/libs/input/SpriteController.h diff --git a/services/input/tests/Android.mk b/libs/input/tests/Android.mk index 9278f413c3a0..9278f413c3a0 100644 --- a/services/input/tests/Android.mk +++ b/libs/input/tests/Android.mk diff --git a/services/input/tests/InputDispatcher_test.cpp b/libs/input/tests/InputDispatcher_test.cpp index 26b4fab794d8..26b4fab794d8 100644 --- a/services/input/tests/InputDispatcher_test.cpp +++ b/libs/input/tests/InputDispatcher_test.cpp diff --git a/services/input/tests/InputReader_test.cpp b/libs/input/tests/InputReader_test.cpp index f0687324d242..f0687324d242 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/libs/input/tests/InputReader_test.cpp diff --git a/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java b/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java index 6bf4beb0ea57..968976b93a90 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java +++ b/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java @@ -26,7 +26,8 @@ import android.view.LayoutInflater; public class PhoneLayoutInflater extends LayoutInflater { private static final String[] sClassPrefixList = { "android.widget.", - "android.webkit." + "android.webkit.", + "android.app." }; /** diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index c33bd3546aba..f33ab40efecf 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -231,7 +231,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */ boolean mEnableShiftMenuBugReports = false; - boolean mHeadless; boolean mSafeMode; WindowState mStatusBar = null; int mStatusBarHeight; @@ -855,7 +854,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { mContext = context; mWindowManager = windowManager; mWindowManagerFuncs = windowManagerFuncs; - mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); mHandler = new PolicyHandler(); mOrientationListener = new MyOrientationListener(mContext, mHandler); try { @@ -3602,9 +3600,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) { - // do nothing if headless - if (mHeadless) return; - // lid changed state final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED; if (newLidState == mLidState) { @@ -3837,7 +3832,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // the device some other way (which is why we have an exemption here for injected // events). int result; - if ((isScreenOn && !mHeadless) || (isInjected && !isWakeKey)) { + if (isScreenOn || (isInjected && !isWakeKey)) { // When the screen is on or if the key is injected pass the key to the application. result = ACTION_PASS_TO_USER; } else { @@ -4663,10 +4658,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ @Override public void systemReady() { - if (!mHeadless) { - mKeyguardDelegate = new KeyguardServiceDelegate(mContext, null); - mKeyguardDelegate.onSystemReady(); - } + mKeyguardDelegate = new KeyguardServiceDelegate(mContext, null); + mKeyguardDelegate.onSystemReady(); + synchronized (mLock) { updateOrientationListenerLp(); mSystemReady = true; @@ -4693,7 +4687,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ public void showBootMessage(final CharSequence msg, final boolean always) { - if (mHeadless) return; mHandler.post(new Runnable() { @Override public void run() { if (mBootMsgDialog == null) { diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java index 13574624ae26..e5af716e4f71 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java @@ -109,6 +109,9 @@ public class KeyguardServiceDelegate { if (!context.bindServiceAsUser(intent, mKeyguardConnection, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { if (DEBUG) Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS); + mKeyguardState.showing = false; + mKeyguardState.showingAndNotHidden = false; + mKeyguardState.secure = false; } else { if (DEBUG) Log.v(TAG, "*** Keyguard started"); } diff --git a/services/Android.mk b/services/Android.mk new file mode 100644 index 000000000000..80fd35a0e345 --- /dev/null +++ b/services/Android.mk @@ -0,0 +1,49 @@ +LOCAL_PATH:= $(call my-dir) + +# the java library +# ============================================================ +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := + +# TODO: Move this to the product makefiles +REQUIRED_SERVICES := core accessibility appwidget backup devicepolicy print + +include $(patsubst %,$(LOCAL_PATH)/%/java/service.mk,$(REQUIRED_SERVICES)) + +LOCAL_MODULE:= services + +LOCAL_JAVA_LIBRARIES := android.policy conscrypt telephony-common + +#LOCAL_PROGUARD_ENABLED := full +#LOCAL_PROGUARD_FLAG_FILES := proguard.flags + +include $(BUILD_JAVA_LIBRARY) + +include $(BUILD_DROIDDOC) + +# native library +# ============================================================= + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := +LOCAL_SHARED_LIBRARIES := + +# include all the jni subdirs to collect their sources +include $(wildcard $(LOCAL_PATH)/*/jni/Android.mk) + +LOCAL_CFLAGS += -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES + +ifeq ($(WITH_MALLOC_LEAK_CHECK),true) + LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK +endif + +LOCAL_MODULE:= libandroid_servers + +include $(BUILD_SHARED_LIBRARY) + +ifeq (,$(ONE_SHOT_MAKEFILE)) +include $(call all-makefiles-under, $(LOCAL_PATH)) +endif + diff --git a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java index 9e893da02c70..9e893da02c70 100644 --- a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index ccac0d32ea7b..ccac0d32ea7b 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java diff --git a/services/java/com/android/server/accessibility/EventStreamTransformation.java b/services/accessibility/java/com/android/server/accessibility/EventStreamTransformation.java index 8c93e7b4440d..8c93e7b4440d 100644 --- a/services/java/com/android/server/accessibility/EventStreamTransformation.java +++ b/services/accessibility/java/com/android/server/accessibility/EventStreamTransformation.java diff --git a/services/java/com/android/server/accessibility/GestureUtils.java b/services/accessibility/java/com/android/server/accessibility/GestureUtils.java index b68b09f8d0a0..b68b09f8d0a0 100644 --- a/services/java/com/android/server/accessibility/GestureUtils.java +++ b/services/accessibility/java/com/android/server/accessibility/GestureUtils.java diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java index 5f12cf41c1b5..5f12cf41c1b5 100644 --- a/services/java/com/android/server/accessibility/ScreenMagnifier.java +++ b/services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java index 43f12ebedde1..43f12ebedde1 100644 --- a/services/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java diff --git a/services/accessibility/java/service.mk b/services/accessibility/java/service.mk new file mode 100644 index 000000000000..5e8f37578a95 --- /dev/null +++ b/services/accessibility/java/service.mk @@ -0,0 +1,11 @@ +# Include only if the service is required +ifneq ($(findstring accessibility,$(REQUIRED_SERVICES)),) + +SUB_DIR := accessibility/java + +LOCAL_SRC_FILES += \ + $(call all-java-files-under,$(SUB_DIR)) + +#DEFINED_SERVICES += com.android.server.accessibility.AccessibilityManagerService + +endif diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java new file mode 100644 index 000000000000..3378e3da00a1 --- /dev/null +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java @@ -0,0 +1,384 @@ +/* + * Copyright (C) 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. + */ + +package com.android.server.appwidget; + +import android.app.ActivityManager; +import android.appwidget.AppWidgetProviderInfo; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.os.Binder; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.UserHandle; +import android.util.Slog; +import android.util.SparseArray; +import android.widget.RemoteViews; + +import com.android.internal.appwidget.IAppWidgetHost; +import com.android.internal.appwidget.IAppWidgetService; +import com.android.internal.os.BackgroundThread; +import com.android.internal.util.IndentingPrintWriter; +import com.android.server.SystemService; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.List; +import java.util.Locale; + + +/** + * SystemService that publishes an IAppWidgetService. + */ +public class AppWidgetService extends SystemService { + + static final String TAG = "AppWidgetService"; + + Context mContext; + Handler mSaveStateHandler; + + SparseArray<AppWidgetServiceImpl> mAppWidgetServices; + + @Override + public void onCreate(Context context) { + mContext = context; + + mSaveStateHandler = BackgroundThread.getHandler(); + + mAppWidgetServices = new SparseArray<AppWidgetServiceImpl>(5); + AppWidgetServiceImpl primary = new AppWidgetServiceImpl(context, 0, mSaveStateHandler); + mAppWidgetServices.append(0, primary); + } + + @Override + public void onStart() { + publishBinderService(Context.APPWIDGET_SERVICE, mServiceImpl); + } + + @Override + public void onBootPhase(int phase) { + if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { + mServiceImpl.systemRunning(isSafeMode()); + } + } + + private final AppWidgetServiceStub mServiceImpl = new AppWidgetServiceStub(); + + private class AppWidgetServiceStub extends IAppWidgetService.Stub { + + private boolean mSafeMode; + private Locale mLocale; + private PackageManager mPackageManager; + + public void systemRunning(boolean safeMode) { + mSafeMode = safeMode; + + mAppWidgetServices.get(0).systemReady(safeMode); + + // Register for the boot completed broadcast, so we can send the + // ENABLE broacasts. If we try to send them now, they time out, + // because the system isn't ready to handle them yet. + mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, + new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null); + + // Register for configuration changes so we can update the names + // of the widgets when the locale changes. + mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, + new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED), null, null); + + // Register for broadcasts about package install, etc., so we can + // update the provider list. + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_PACKAGE_ADDED); + filter.addAction(Intent.ACTION_PACKAGE_CHANGED); + filter.addAction(Intent.ACTION_PACKAGE_REMOVED); + filter.addDataScheme("package"); + mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, + filter, null, null); + // Register for events related to sdcard installation. + IntentFilter sdFilter = new IntentFilter(); + sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); + sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); + mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, + sdFilter, null, null); + + IntentFilter userFilter = new IntentFilter(); + userFilter.addAction(Intent.ACTION_USER_REMOVED); + userFilter.addAction(Intent.ACTION_USER_STOPPING); + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { + onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL)); + } else if (Intent.ACTION_USER_STOPPING.equals(intent.getAction())) { + onUserStopping(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL)); + } + } + }, userFilter); + } + + @Override + public int allocateAppWidgetId(String packageName, int hostId, int userId) + throws RemoteException { + return getImplForUser(userId).allocateAppWidgetId(packageName, hostId); + } + + @Override + public int[] getAppWidgetIdsForHost(int hostId, int userId) throws RemoteException { + return getImplForUser(userId).getAppWidgetIdsForHost(hostId); + } + + @Override + public void deleteAppWidgetId(int appWidgetId, int userId) throws RemoteException { + getImplForUser(userId).deleteAppWidgetId(appWidgetId); + } + + @Override + public void deleteHost(int hostId, int userId) throws RemoteException { + getImplForUser(userId).deleteHost(hostId); + } + + @Override + public void deleteAllHosts(int userId) throws RemoteException { + getImplForUser(userId).deleteAllHosts(); + } + + @Override + public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options, + int userId) throws RemoteException { + getImplForUser(userId).bindAppWidgetId(appWidgetId, provider, options); + } + + @Override + public boolean bindAppWidgetIdIfAllowed( + String packageName, int appWidgetId, ComponentName provider, Bundle options, + int userId) throws RemoteException { + return getImplForUser(userId).bindAppWidgetIdIfAllowed( + packageName, appWidgetId, provider, options); + } + + @Override + public boolean hasBindAppWidgetPermission(String packageName, int userId) + throws RemoteException { + return getImplForUser(userId).hasBindAppWidgetPermission(packageName); + } + + @Override + public void setBindAppWidgetPermission(String packageName, boolean permission, int userId) + throws RemoteException { + getImplForUser(userId).setBindAppWidgetPermission(packageName, permission); + } + + @Override + public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection, + int userId) throws RemoteException { + getImplForUser(userId).bindRemoteViewsService(appWidgetId, intent, connection); + } + + @Override + public int[] startListening(IAppWidgetHost host, String packageName, int hostId, + List<RemoteViews> updatedViews, int userId) throws RemoteException { + return getImplForUser(userId).startListening(host, packageName, hostId, updatedViews); + } + + public void onUserRemoved(int userId) { + if (userId < 1) return; + synchronized (mAppWidgetServices) { + AppWidgetServiceImpl impl = mAppWidgetServices.get(userId); + mAppWidgetServices.remove(userId); + + if (impl == null) { + AppWidgetServiceImpl.getSettingsFile(userId).delete(); + } else { + impl.onUserRemoved(); + } + } + } + + public void onUserStopping(int userId) { + if (userId < 1) return; + synchronized (mAppWidgetServices) { + AppWidgetServiceImpl impl = mAppWidgetServices.get(userId); + if (impl != null) { + mAppWidgetServices.remove(userId); + impl.onUserStopping(); + } + } + } + + private void checkPermission(int userId) { + int realUserId = ActivityManager.handleIncomingUser( + Binder.getCallingPid(), + Binder.getCallingUid(), + userId, + false, /* allowAll */ + true, /* requireFull */ + this.getClass().getSimpleName(), + this.getClass().getPackage().getName()); + } + + private AppWidgetServiceImpl getImplForUser(int userId) { + checkPermission(userId); + boolean sendInitial = false; + AppWidgetServiceImpl service; + synchronized (mAppWidgetServices) { + service = mAppWidgetServices.get(userId); + if (service == null) { + Slog.i(TAG, "Unable to find AppWidgetServiceImpl for user " + userId + + ", adding"); + // TODO: Verify that it's a valid user + service = new AppWidgetServiceImpl(mContext, userId, mSaveStateHandler); + service.systemReady(mSafeMode); + // Assume that BOOT_COMPLETED was received, as this is a non-primary user. + mAppWidgetServices.append(userId, service); + sendInitial = true; + } + } + if (sendInitial) { + service.sendInitialBroadcasts(); + } + return service; + } + + @Override + public int[] getAppWidgetIds(ComponentName provider, int userId) throws RemoteException { + return getImplForUser(userId).getAppWidgetIds(provider); + } + + @Override + public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId, int userId) + throws RemoteException { + return getImplForUser(userId).getAppWidgetInfo(appWidgetId); + } + + @Override + public RemoteViews getAppWidgetViews(int appWidgetId, int userId) throws RemoteException { + return getImplForUser(userId).getAppWidgetViews(appWidgetId); + } + + @Override + public void updateAppWidgetOptions(int appWidgetId, Bundle options, int userId) { + getImplForUser(userId).updateAppWidgetOptions(appWidgetId, options); + } + + @Override + public Bundle getAppWidgetOptions(int appWidgetId, int userId) { + return getImplForUser(userId).getAppWidgetOptions(appWidgetId); + } + + @Override + public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter, int userId) + throws RemoteException { + return getImplForUser(userId).getInstalledProviders(categoryFilter); + } + + @Override + public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId, int userId) + throws RemoteException { + getImplForUser(userId).notifyAppWidgetViewDataChanged( + appWidgetIds, viewId); + } + + @Override + public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId) + throws RemoteException { + getImplForUser(userId).partiallyUpdateAppWidgetIds( + appWidgetIds, views); + } + + @Override + public void stopListening(int hostId, int userId) throws RemoteException { + getImplForUser(userId).stopListening(hostId); + } + + @Override + public void unbindRemoteViewsService(int appWidgetId, Intent intent, int userId) + throws RemoteException { + getImplForUser(userId).unbindRemoteViewsService( + appWidgetId, intent); + } + + @Override + public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId) + throws RemoteException { + getImplForUser(userId).updateAppWidgetIds(appWidgetIds, views); + } + + @Override + public void updateAppWidgetProvider(ComponentName provider, RemoteViews views, int userId) + throws RemoteException { + getImplForUser(userId).updateAppWidgetProvider(provider, views); + } + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); + + // Dump the state of all the app widget providers + synchronized (mAppWidgetServices) { + IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); + for (int i = 0; i < mAppWidgetServices.size(); i++) { + pw.println("User: " + mAppWidgetServices.keyAt(i)); + ipw.increaseIndent(); + AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i); + service.dump(fd, ipw, args); + ipw.decreaseIndent(); + } + } + } + + BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + // Slog.d(TAG, "received " + action); + if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { + int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); + if (userId >= 0) { + getImplForUser(userId).sendInitialBroadcasts(); + } else { + Slog.w(TAG, "Incorrect user handle supplied in " + intent); + } + } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { + for (int i = 0; i < mAppWidgetServices.size(); i++) { + AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i); + service.onConfigurationChanged(); + } + } else { + int sendingUser = getSendingUserId(); + if (sendingUser == UserHandle.USER_ALL) { + for (int i = 0; i < mAppWidgetServices.size(); i++) { + AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i); + service.onBroadcastReceived(intent); + } + } else { + AppWidgetServiceImpl service = mAppWidgetServices.get(sendingUser); + if (service != null) { + service.onBroadcastReceived(intent); + } + } + } + } + }; + } +} diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 69ae846597f7..98dead312469 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.appwidget; import android.app.AlarmManager; import android.app.AppGlobals; diff --git a/services/appwidget/java/service.mk b/services/appwidget/java/service.mk new file mode 100644 index 000000000000..0e3344682c7f --- /dev/null +++ b/services/appwidget/java/service.mk @@ -0,0 +1,11 @@ +# Include only if the service is required +ifneq ($(findstring appwidget,$(REQUIRED_SERVICES)),) + +SUB_DIR := appwidget/java + +LOCAL_SRC_FILES += \ + $(call all-java-files-under,$(SUB_DIR)) + +#DEFINED_SERVICES += com.android.server.appwidget.AppWidgetService + +endif diff --git a/services/java/com/android/server/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 00bfee78bfbb..c6dc5e63b7b4 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.backup; import android.app.ActivityManagerNative; import android.app.AlarmManager; @@ -83,7 +83,9 @@ import com.android.internal.backup.BackupConstants; import com.android.internal.backup.IBackupTransport; import com.android.internal.backup.IObbBackupService; import com.android.internal.backup.LocalTransport; -import com.android.server.PackageManagerBackupAgent.Metadata; +import com.android.server.EventLogTags; +import com.android.server.SystemService; +import com.android.server.backup.PackageManagerBackupAgent.Metadata; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -135,7 +137,8 @@ import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; -class BackupManagerService extends IBackupManager.Stub { +public class BackupManagerService extends IBackupManager.Stub { + private static final String TAG = "BackupManagerService"; private static final boolean DEBUG = true; private static final boolean MORE_DEBUG = false; @@ -1178,7 +1181,8 @@ class BackupManagerService extends IBackupManager.Stub { // First, on an encrypted device we require matching the device pw final boolean isEncrypted; try { - isEncrypted = (mMountService.getEncryptionState() != MountService.ENCRYPTION_STATE_NONE); + isEncrypted = (mMountService.getEncryptionState() != + IMountService.ENCRYPTION_STATE_NONE); if (isEncrypted) { if (DEBUG) { Slog.i(TAG, "Device encrypted; verifying against device data pw"); @@ -5437,7 +5441,8 @@ class BackupManagerService extends IBackupManager.Stub { boolean isEncrypted; try { - isEncrypted = (mMountService.getEncryptionState() != MountService.ENCRYPTION_STATE_NONE); + isEncrypted = (mMountService.getEncryptionState() != + IMountService.ENCRYPTION_STATE_NONE); if (isEncrypted) Slog.w(TAG, "Device is encrypted; forcing enc password"); } catch (RemoteException e) { // couldn't contact the mount service; fail "safe" and assume encryption @@ -6086,7 +6091,7 @@ class BackupManagerService extends IBackupManager.Stub { } } - // clean up the BackupManagerService side of the bookkeeping + // clean up the BackupManagerImpl side of the bookkeeping // and cancel any pending timeout message mBackupManager.clearRestoreSession(mSession); } diff --git a/services/backup/java/com/android/server/backup/BackupManagerSystemService.java b/services/backup/java/com/android/server/backup/BackupManagerSystemService.java new file mode 100644 index 000000000000..db2c94a9c2c4 --- /dev/null +++ b/services/backup/java/com/android/server/backup/BackupManagerSystemService.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup; + +import android.content.Context; + +import com.android.server.SystemService; + +public class BackupManagerSystemService extends SystemService { + private BackupManagerService mBackupManagerImpl; + + @Override + public void onCreate(Context context) { + mBackupManagerImpl = new BackupManagerService(context); + } + + @Override + public void onStart() { + publishBinderService(Context.BACKUP_SERVICE, mBackupManagerImpl); + } +} + diff --git a/services/java/com/android/server/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java index 77bddb0717ec..495da886fa65 100644 --- a/services/java/com/android/server/PackageManagerBackupAgent.java +++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.backup; import android.app.backup.BackupAgent; import android.app.backup.BackupDataInput; diff --git a/services/java/com/android/server/SystemBackupAgent.java b/services/backup/java/com/android/server/backup/SystemBackupAgent.java index 8cf273dee8cc..26e2e2ac356c 100644 --- a/services/java/com/android/server/SystemBackupAgent.java +++ b/services/backup/java/com/android/server/backup/SystemBackupAgent.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.backup; +import android.app.IWallpaperManager; import android.app.backup.BackupDataInput; import android.app.backup.BackupDataOutput; import android.app.backup.BackupAgentHelper; @@ -26,11 +27,11 @@ import android.app.backup.WallpaperBackupHelper; import android.content.Context; import android.os.Environment; import android.os.ParcelFileDescriptor; +import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.util.Slog; - import java.io.File; import java.io.IOException; @@ -63,16 +64,23 @@ public class SystemBackupAgent extends BackupAgentHelper { public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException { // We only back up the data under the current "wallpaper" schema with metadata - WallpaperManagerService wallpaper = (WallpaperManagerService)ServiceManager.getService( + IWallpaperManager wallpaper = (IWallpaperManager)ServiceManager.getService( Context.WALLPAPER_SERVICE); String[] files = new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO }; String[] keys = new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY }; - if (wallpaper != null && wallpaper.getName() != null && wallpaper.getName().length() > 0) { - // When the wallpaper has a name, back up the info by itself. - // TODO: Don't rely on the innards of the service object like this! - // TODO: Send a delete for any stored wallpaper image in this case? - files = new String[] { WALLPAPER_INFO }; - keys = new String[] { WALLPAPER_INFO_KEY }; + if (wallpaper != null) { + try { + final String wallpaperName = wallpaper.getName(); + if (wallpaperName != null && wallpaperName.length() > 0) { + // When the wallpaper has a name, back up the info by itself. + // TODO: Don't rely on the innards of the service object like this! + // TODO: Send a delete for any stored wallpaper image in this case? + files = new String[] { WALLPAPER_INFO }; + keys = new String[] { WALLPAPER_INFO_KEY }; + } + } catch (RemoteException re) { + Slog.e(TAG, "Couldn't get wallpaper name\n" + re); + } } addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this, files, keys)); super.onBackup(oldState, data, newState); @@ -109,9 +117,15 @@ public class SystemBackupAgent extends BackupAgentHelper { try { super.onRestore(data, appVersionCode, newState); - WallpaperManagerService wallpaper = (WallpaperManagerService)ServiceManager.getService( + IWallpaperManager wallpaper = (IWallpaperManager) ServiceManager.getService( Context.WALLPAPER_SERVICE); - wallpaper.settingsRestored(); + if (wallpaper != null) { + try { + wallpaper.settingsRestored(); + } catch (RemoteException re) { + Slog.e(TAG, "Couldn't restore settings\n" + re); + } + } } catch (IOException ex) { // If there was a failure, delete everything for the wallpaper, this is too aggressive, // but this is hopefully a rare failure. @@ -149,10 +163,16 @@ public class SystemBackupAgent extends BackupAgentHelper { FullBackup.restoreFile(data, size, type, mode, mtime, outFile); if (restoredWallpaper) { - WallpaperManagerService wallpaper = - (WallpaperManagerService)ServiceManager.getService( + IWallpaperManager wallpaper = + (IWallpaperManager)ServiceManager.getService( Context.WALLPAPER_SERVICE); - wallpaper.settingsRestored(); + if (wallpaper != null) { + try { + wallpaper.settingsRestored(); + } catch (RemoteException re) { + Slog.e(TAG, "Couldn't restore settings\n" + re); + } + } } } catch (IOException e) { if (restoredWallpaper) { diff --git a/services/backup/java/service.mk b/services/backup/java/service.mk new file mode 100644 index 000000000000..bd22b95a0610 --- /dev/null +++ b/services/backup/java/service.mk @@ -0,0 +1,11 @@ +# Include only if the service is required +ifneq ($(findstring backup,$(REQUIRED_SERVICES)),) + +SUB_DIR := backup/java + +LOCAL_SRC_FILES += \ + $(call all-java-files-under,$(SUB_DIR)) + +#DEFINED_SERVICES += com.android.server.backup.BackupManagerService + +endif diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 2e1b0af7b099..3cdf170494d4 100644 --- a/services/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -31,6 +31,7 @@ import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.Handler; +import android.os.IBinder; import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; @@ -64,54 +65,51 @@ import static android.app.AlarmManager.ELAPSED_REALTIME; import com.android.internal.util.LocalLog; -class AlarmManagerService extends IAlarmManager.Stub { +class AlarmManagerService extends SystemService { // The threshold for how long an alarm can be late before we print a // warning message. The time duration is in milliseconds. private static final long LATE_ALARM_THRESHOLD = 10 * 1000; private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP; private static final int RTC_MASK = 1 << RTC; - private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP; + private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP; private static final int ELAPSED_REALTIME_MASK = 1 << ELAPSED_REALTIME; - private static final int TIME_CHANGED_MASK = 1 << 16; - private static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK|ELAPSED_REALTIME_WAKEUP_MASK; + static final int TIME_CHANGED_MASK = 1 << 16; + static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK|ELAPSED_REALTIME_WAKEUP_MASK; // Mask for testing whether a given alarm type is wakeup vs non-wakeup - private static final int TYPE_NONWAKEUP_MASK = 0x1; // low bit => non-wakeup - - private static final String TAG = "AlarmManager"; - private static final String ClockReceiver_TAG = "ClockReceiver"; - private static final boolean localLOGV = false; - private static final boolean DEBUG_BATCH = localLOGV || false; - private static final boolean DEBUG_VALIDATE = localLOGV || false; - private static final int ALARM_EVENT = 1; - private static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; + static final int TYPE_NONWAKEUP_MASK = 0x1; // low bit => non-wakeup + + static final String TAG = "AlarmManager"; + static final String ClockReceiver_TAG = "ClockReceiver"; + static final boolean localLOGV = false; + static final boolean DEBUG_BATCH = localLOGV || false; + static final boolean DEBUG_VALIDATE = localLOGV || false; + static final int ALARM_EVENT = 1; + static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; - private static final Intent mBackgroundIntent + static final Intent mBackgroundIntent = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND); - private static final IncreasingTimeOrder sIncreasingTimeOrder = new IncreasingTimeOrder(); + static final IncreasingTimeOrder sIncreasingTimeOrder = new IncreasingTimeOrder(); - private static final boolean WAKEUP_STATS = false; + static final boolean WAKEUP_STATS = false; - private final Context mContext; + final LocalLog mLog = new LocalLog(TAG); - private final LocalLog mLog = new LocalLog(TAG); + final Object mLock = new Object(); - private Object mLock = new Object(); - - private long mNativeData; + long mNativeData; private long mNextWakeup; private long mNextNonWakeup; - private int mBroadcastRefCount = 0; - private PowerManager.WakeLock mWakeLock; - private ArrayList<InFlight> mInFlight = new ArrayList<InFlight>(); - private final AlarmThread mWaitThread = new AlarmThread(); - private final AlarmHandler mHandler = new AlarmHandler(); - private ClockReceiver mClockReceiver; + int mBroadcastRefCount = 0; + PowerManager.WakeLock mWakeLock; + ArrayList<InFlight> mInFlight = new ArrayList<InFlight>(); + final AlarmHandler mHandler = new AlarmHandler(); + ClockReceiver mClockReceiver; private UninstallReceiver mUninstallReceiver; - private final ResultReceiver mResultReceiver = new ResultReceiver(); - private final PendingIntent mTimeTickSender; - private final PendingIntent mDateChangeSender; + final ResultReceiver mResultReceiver = new ResultReceiver(); + PendingIntent mTimeTickSender; + PendingIntent mDateChangeSender; class WakeupEvent { public long when; @@ -125,8 +123,8 @@ class AlarmManagerService extends IAlarmManager.Stub { } } - private final LinkedList<WakeupEvent> mRecentWakeups = new LinkedList<WakeupEvent>(); - private final long RECENT_WAKEUP_PERIOD = 1000L * 60 * 60 * 24; // one day + final LinkedList<WakeupEvent> mRecentWakeups = new LinkedList<WakeupEvent>(); + final long RECENT_WAKEUP_PERIOD = 1000L * 60 * 60 * 24; // one day static final class Batch { long start; // These endpoints are always in ELAPSED @@ -317,9 +315,9 @@ class AlarmManagerService extends IAlarmManager.Stub { } // minimum recurrence period or alarm futurity for us to be able to fuzz it - private static final long MIN_FUZZABLE_INTERVAL = 10000; - private static final BatchTimeOrder sBatchOrder = new BatchTimeOrder(); - private final ArrayList<Batch> mAlarmBatches = new ArrayList<Batch>(); + static final long MIN_FUZZABLE_INTERVAL = 10000; + static final BatchTimeOrder sBatchOrder = new BatchTimeOrder(); + final ArrayList<Batch> mAlarmBatches = new ArrayList<Batch>(); static long convertToElapsed(long when, int type) { final boolean isRtc = (type == RTC || type == RTC_WAKEUP); @@ -403,7 +401,7 @@ class AlarmManagerService extends IAlarmManager.Stub { } } - private static final class InFlight extends Intent { + static final class InFlight extends Intent { final PendingIntent mPendingIntent; final WorkSource mWorkSource; final Pair<String, ComponentName> mTarget; @@ -427,7 +425,7 @@ class AlarmManagerService extends IAlarmManager.Stub { } } - private static final class FilterStats { + static final class FilterStats { final BroadcastStats mBroadcastStats; final Pair<String, ComponentName> mTarget; @@ -443,7 +441,7 @@ class AlarmManagerService extends IAlarmManager.Stub { } } - private static final class BroadcastStats { + static final class BroadcastStats { final String mPackageName; long aggregateTime; @@ -459,47 +457,48 @@ class AlarmManagerService extends IAlarmManager.Stub { } } - private final HashMap<String, BroadcastStats> mBroadcastStats + final HashMap<String, BroadcastStats> mBroadcastStats = new HashMap<String, BroadcastStats>(); - public AlarmManagerService(Context context) { - mContext = context; + @Override + public void onStart() { mNativeData = init(); mNextWakeup = mNextNonWakeup = 0; // We have to set current TimeZone info to kernel // because kernel doesn't keep this after reboot - String tz = SystemProperties.get(TIMEZONE_PROPERTY); - if (tz != null) { - setTimeZone(tz); - } + setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY)); - PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); + PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); - mTimeTickSender = PendingIntent.getBroadcastAsUser(context, 0, + mTimeTickSender = PendingIntent.getBroadcastAsUser(getContext(), 0, new Intent(Intent.ACTION_TIME_TICK).addFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND), 0, UserHandle.ALL); Intent intent = new Intent(Intent.ACTION_DATE_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - mDateChangeSender = PendingIntent.getBroadcastAsUser(context, 0, intent, + mDateChangeSender = PendingIntent.getBroadcastAsUser(getContext(), 0, intent, Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, UserHandle.ALL); // now that we have initied the driver schedule the alarm - mClockReceiver= new ClockReceiver(); + mClockReceiver = new ClockReceiver(); mClockReceiver.scheduleTimeTickEvent(); mClockReceiver.scheduleDateChangedEvent(); mUninstallReceiver = new UninstallReceiver(); if (mNativeData != 0) { - mWaitThread.start(); + AlarmThread waitThread = new AlarmThread(); + waitThread.start(); } else { Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler."); } + + publishBinderService(Context.ALARM_SERVICE, mService); } - + + @Override protected void finalize() throws Throwable { try { close(mNativeData); @@ -508,19 +507,51 @@ class AlarmManagerService extends IAlarmManager.Stub { } } - @Override - public void set(int type, long triggerAtTime, long windowLength, long interval, - PendingIntent operation, WorkSource workSource) { - if (workSource != null) { - mContext.enforceCallingPermission( - android.Manifest.permission.UPDATE_DEVICE_STATS, - "AlarmManager.set"); + void setTimeZoneImpl(String tz) { + if (TextUtils.isEmpty(tz)) { + return; + } + + TimeZone zone = TimeZone.getTimeZone(tz); + // Prevent reentrant calls from stepping on each other when writing + // the time zone property + boolean timeZoneWasChanged = false; + synchronized (this) { + String current = SystemProperties.get(TIMEZONE_PROPERTY); + if (current == null || !current.equals(zone.getID())) { + if (localLOGV) { + Slog.v(TAG, "timezone changed: " + current + ", new=" + zone.getID()); + } + timeZoneWasChanged = true; + SystemProperties.set(TIMEZONE_PROPERTY, zone.getID()); + } + + // Update the kernel timezone information + // Kernel tracks time offsets as 'minutes west of GMT' + int gmtOffset = zone.getOffset(System.currentTimeMillis()); + setKernelTimezone(mNativeData, -(gmtOffset / 60000)); } - set(type, triggerAtTime, windowLength, interval, operation, false, workSource); + TimeZone.setDefault(null); + + if (timeZoneWasChanged) { + Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + intent.putExtra("time-zone", zone.getID()); + getContext().sendBroadcastAsUser(intent, UserHandle.ALL); + } } - public void set(int type, long triggerAtTime, long windowLength, long interval, + void removeImpl(PendingIntent operation) { + if (operation == null) { + return; + } + synchronized (mLock) { + removeLocked(operation); + } + } + + void setImpl(int type, long triggerAtTime, long windowLength, long interval, PendingIntent operation, boolean isStandalone, WorkSource workSource) { if (operation == null) { Slog.w(TAG, "set/setRepeating ignored because there is no intent"); @@ -606,231 +637,64 @@ class AlarmManagerService extends IAlarmManager.Stub { rescheduleKernelAlarmsLocked(); } - private void logBatchesLocked() { - ByteArrayOutputStream bs = new ByteArrayOutputStream(2048); - PrintWriter pw = new PrintWriter(bs); - final long nowRTC = System.currentTimeMillis(); - final long nowELAPSED = SystemClock.elapsedRealtime(); - final int NZ = mAlarmBatches.size(); - for (int iz = 0; iz < NZ; iz++) { - Batch bz = mAlarmBatches.get(iz); - pw.append("Batch "); pw.print(iz); pw.append(": "); pw.println(bz); - dumpAlarmList(pw, bz.alarms, " ", nowELAPSED, nowRTC); - pw.flush(); - Slog.v(TAG, bs.toString()); - bs.reset(); - } - } - - private boolean validateConsistencyLocked() { - if (DEBUG_VALIDATE) { - long lastTime = Long.MIN_VALUE; - final int N = mAlarmBatches.size(); - for (int i = 0; i < N; i++) { - Batch b = mAlarmBatches.get(i); - if (b.start >= lastTime) { - // duplicate start times are okay because of standalone batches - lastTime = b.start; - } else { - Slog.e(TAG, "CONSISTENCY FAILURE: Batch " + i + " is out of order"); - logBatchesLocked(); - return false; - } - } - } - return true; - } - - private Batch findFirstWakeupBatchLocked() { - final int N = mAlarmBatches.size(); - for (int i = 0; i < N; i++) { - Batch b = mAlarmBatches.get(i); - if (b.hasWakeups()) { - return b; + private final IBinder mService = new IAlarmManager.Stub() { + @Override + public void set(int type, long triggerAtTime, long windowLength, long interval, + PendingIntent operation, WorkSource workSource) { + if (workSource != null) { + getContext().enforceCallingPermission( + android.Manifest.permission.UPDATE_DEVICE_STATS, + "AlarmManager.set"); } - } - return null; - } - private void rescheduleKernelAlarmsLocked() { - // Schedule the next upcoming wakeup alarm. If there is a deliverable batch - // prior to that which contains no wakeups, we schedule that as well. - if (mAlarmBatches.size() > 0) { - final Batch firstWakeup = findFirstWakeupBatchLocked(); - final Batch firstBatch = mAlarmBatches.get(0); - if (firstWakeup != null && mNextWakeup != firstWakeup.start) { - mNextWakeup = firstWakeup.start; - setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start); - } - if (firstBatch != firstWakeup && mNextNonWakeup != firstBatch.start) { - mNextNonWakeup = firstBatch.start; - setLocked(ELAPSED_REALTIME, firstBatch.start); - } + setImpl(type, triggerAtTime, windowLength, interval, operation, + false, workSource); } - } - - public void setTime(long millis) { - mContext.enforceCallingOrSelfPermission( - "android.permission.SET_TIME", - "setTime"); - - SystemClock.setCurrentTimeMillis(millis); - } - - public void setTimeZone(String tz) { - mContext.enforceCallingOrSelfPermission( - "android.permission.SET_TIME_ZONE", - "setTimeZone"); - - long oldId = Binder.clearCallingIdentity(); - try { - if (TextUtils.isEmpty(tz)) return; - TimeZone zone = TimeZone.getTimeZone(tz); - // Prevent reentrant calls from stepping on each other when writing - // the time zone property - boolean timeZoneWasChanged = false; - synchronized (this) { - String current = SystemProperties.get(TIMEZONE_PROPERTY); - if (current == null || !current.equals(zone.getID())) { - if (localLOGV) { - Slog.v(TAG, "timezone changed: " + current + ", new=" + zone.getID()); - } - timeZoneWasChanged = true; - SystemProperties.set(TIMEZONE_PROPERTY, zone.getID()); - } - - // Update the kernel timezone information - // Kernel tracks time offsets as 'minutes west of GMT' - int gmtOffset = zone.getOffset(System.currentTimeMillis()); - setKernelTimezone(mNativeData, -(gmtOffset / 60000)); - } - - TimeZone.setDefault(null); - if (timeZoneWasChanged) { - Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra("time-zone", zone.getID()); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL); - } - } finally { - Binder.restoreCallingIdentity(oldId); - } - } - - public void remove(PendingIntent operation) { - if (operation == null) { - return; - } - synchronized (mLock) { - removeLocked(operation); - } - } - - public void removeLocked(PendingIntent operation) { - boolean didRemove = false; - for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { - Batch b = mAlarmBatches.get(i); - didRemove |= b.remove(operation); - if (b.size() == 0) { - mAlarmBatches.remove(i); - } - } + @Override + public void setTime(long millis) { + getContext().enforceCallingOrSelfPermission( + "android.permission.SET_TIME", + "setTime"); - if (didRemove) { - if (DEBUG_BATCH) { - Slog.v(TAG, "remove(operation) changed bounds; rebatching"); - } - rebatchAllAlarmsLocked(true); - rescheduleKernelAlarmsLocked(); + SystemClock.setCurrentTimeMillis(millis); } - } - public void removeLocked(String packageName) { - boolean didRemove = false; - for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { - Batch b = mAlarmBatches.get(i); - didRemove |= b.remove(packageName); - if (b.size() == 0) { - mAlarmBatches.remove(i); + @Override + public void setTimeZone(String tz) { + getContext().enforceCallingOrSelfPermission( + "android.permission.SET_TIME_ZONE", + "setTimeZone"); + + final long oldId = Binder.clearCallingIdentity(); + try { + setTimeZoneImpl(tz); + } finally { + Binder.restoreCallingIdentity(oldId); } } - if (didRemove) { - if (DEBUG_BATCH) { - Slog.v(TAG, "remove(package) changed bounds; rebatching"); - } - rebatchAllAlarmsLocked(true); - rescheduleKernelAlarmsLocked(); - } - } + @Override + public void remove(PendingIntent operation) { + removeImpl(operation); - public void removeUserLocked(int userHandle) { - boolean didRemove = false; - for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { - Batch b = mAlarmBatches.get(i); - didRemove |= b.remove(userHandle); - if (b.size() == 0) { - mAlarmBatches.remove(i); - } } - if (didRemove) { - if (DEBUG_BATCH) { - Slog.v(TAG, "remove(user) changed bounds; rebatching"); + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) + != PackageManager.PERMISSION_GRANTED) { + pw.println("Permission Denial: can't dump AlarmManager from from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid()); + return; } - rebatchAllAlarmsLocked(true); - rescheduleKernelAlarmsLocked(); - } - } - public boolean lookForPackageLocked(String packageName) { - for (int i = 0; i < mAlarmBatches.size(); i++) { - Batch b = mAlarmBatches.get(i); - if (b.hasPackage(packageName)) { - return true; - } + dumpImpl(pw); } - return false; - } + }; - private void setLocked(int type, long when) - { - if (mNativeData != 0) - { - // The kernel never triggers alarms with negative wakeup times - // so we ensure they are positive. - long alarmSeconds, alarmNanoseconds; - if (when < 0) { - alarmSeconds = 0; - alarmNanoseconds = 0; - } else { - alarmSeconds = when / 1000; - alarmNanoseconds = (when % 1000) * 1000 * 1000; - } - - set(mNativeData, type, alarmSeconds, alarmNanoseconds); - } - else - { - Message msg = Message.obtain(); - msg.what = ALARM_EVENT; - - mHandler.removeMessages(ALARM_EVENT); - mHandler.sendMessageAtTime(msg, when); - } - } - - @Override - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - pw.println("Permission Denial: can't dump AlarmManager from from pid=" - + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid()); - return; - } - + void dumpImpl(PrintWriter pw) { synchronized (mLock) { pw.println("Current Alarm Manager state:"); final long nowRTC = System.currentTimeMillis(); @@ -980,6 +844,159 @@ class AlarmManagerService extends IAlarmManager.Stub { } } + private void logBatchesLocked() { + ByteArrayOutputStream bs = new ByteArrayOutputStream(2048); + PrintWriter pw = new PrintWriter(bs); + final long nowRTC = System.currentTimeMillis(); + final long nowELAPSED = SystemClock.elapsedRealtime(); + final int NZ = mAlarmBatches.size(); + for (int iz = 0; iz < NZ; iz++) { + Batch bz = mAlarmBatches.get(iz); + pw.append("Batch "); pw.print(iz); pw.append(": "); pw.println(bz); + dumpAlarmList(pw, bz.alarms, " ", nowELAPSED, nowRTC); + pw.flush(); + Slog.v(TAG, bs.toString()); + bs.reset(); + } + } + + private boolean validateConsistencyLocked() { + if (DEBUG_VALIDATE) { + long lastTime = Long.MIN_VALUE; + final int N = mAlarmBatches.size(); + for (int i = 0; i < N; i++) { + Batch b = mAlarmBatches.get(i); + if (b.start >= lastTime) { + // duplicate start times are okay because of standalone batches + lastTime = b.start; + } else { + Slog.e(TAG, "CONSISTENCY FAILURE: Batch " + i + " is out of order"); + logBatchesLocked(); + return false; + } + } + } + return true; + } + + private Batch findFirstWakeupBatchLocked() { + final int N = mAlarmBatches.size(); + for (int i = 0; i < N; i++) { + Batch b = mAlarmBatches.get(i); + if (b.hasWakeups()) { + return b; + } + } + return null; + } + + void rescheduleKernelAlarmsLocked() { + // Schedule the next upcoming wakeup alarm. If there is a deliverable batch + // prior to that which contains no wakeups, we schedule that as well. + if (mAlarmBatches.size() > 0) { + final Batch firstWakeup = findFirstWakeupBatchLocked(); + final Batch firstBatch = mAlarmBatches.get(0); + if (firstWakeup != null && mNextWakeup != firstWakeup.start) { + mNextWakeup = firstWakeup.start; + setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start); + } + if (firstBatch != firstWakeup && mNextNonWakeup != firstBatch.start) { + mNextNonWakeup = firstBatch.start; + setLocked(ELAPSED_REALTIME, firstBatch.start); + } + } + } + + private void removeLocked(PendingIntent operation) { + boolean didRemove = false; + for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { + Batch b = mAlarmBatches.get(i); + didRemove |= b.remove(operation); + if (b.size() == 0) { + mAlarmBatches.remove(i); + } + } + + if (didRemove) { + if (DEBUG_BATCH) { + Slog.v(TAG, "remove(operation) changed bounds; rebatching"); + } + rebatchAllAlarmsLocked(true); + rescheduleKernelAlarmsLocked(); + } + } + + void removeLocked(String packageName) { + boolean didRemove = false; + for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { + Batch b = mAlarmBatches.get(i); + didRemove |= b.remove(packageName); + if (b.size() == 0) { + mAlarmBatches.remove(i); + } + } + + if (didRemove) { + if (DEBUG_BATCH) { + Slog.v(TAG, "remove(package) changed bounds; rebatching"); + } + rebatchAllAlarmsLocked(true); + rescheduleKernelAlarmsLocked(); + } + } + + void removeUserLocked(int userHandle) { + boolean didRemove = false; + for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { + Batch b = mAlarmBatches.get(i); + didRemove |= b.remove(userHandle); + if (b.size() == 0) { + mAlarmBatches.remove(i); + } + } + + if (didRemove) { + if (DEBUG_BATCH) { + Slog.v(TAG, "remove(user) changed bounds; rebatching"); + } + rebatchAllAlarmsLocked(true); + rescheduleKernelAlarmsLocked(); + } + } + + boolean lookForPackageLocked(String packageName) { + for (int i = 0; i < mAlarmBatches.size(); i++) { + Batch b = mAlarmBatches.get(i); + if (b.hasPackage(packageName)) { + return true; + } + } + return false; + } + + private void setLocked(int type, long when) { + if (mNativeData != 0) { + // The kernel never triggers alarms with negative wakeup times + // so we ensure they are positive. + long alarmSeconds, alarmNanoseconds; + if (when < 0) { + alarmSeconds = 0; + alarmNanoseconds = 0; + } else { + alarmSeconds = when / 1000; + alarmNanoseconds = (when % 1000) * 1000 * 1000; + } + + set(mNativeData, type, alarmSeconds, alarmNanoseconds); + } else { + Message msg = Message.obtain(); + msg.what = ALARM_EVENT; + + mHandler.removeMessages(ALARM_EVENT); + mHandler.sendMessageAtTime(msg, when); + } + } + private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, String prefix, String label, long now) { for (int i=list.size()-1; i>=0; i--) { @@ -1020,7 +1037,7 @@ class AlarmManagerService extends IAlarmManager.Stub { private native int waitForAlarm(long nativeData); private native int setKernelTimezone(long nativeData, int minuteswest); - private void triggerAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED, long nowRTC) { + void triggerAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED, long nowRTC) { // batches are temporally sorted, so we need only pull from the // start of the list until we either empty it or hit a batch // that is not yet deliverable @@ -1166,13 +1183,13 @@ class AlarmManagerService extends IAlarmManager.Stub { if (DEBUG_BATCH) { Slog.v(TAG, "Time changed notification from kernel; rebatching"); } - remove(mTimeTickSender); + removeImpl(mTimeTickSender); rebatchAllAlarms(); mClockReceiver.scheduleTimeTickEvent(); Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + getContext().sendBroadcastAsUser(intent, UserHandle.ALL); } synchronized (mLock) { @@ -1206,7 +1223,7 @@ class AlarmManagerService extends IAlarmManager.Stub { Alarm alarm = triggerList.get(i); try { if (localLOGV) Slog.v(TAG, "sending alarm " + alarm); - alarm.operation.send(mContext, 0, + alarm.operation.send(getContext(), 0, mBackgroundIntent.putExtra( Intent.EXTRA_ALARM_COUNT, alarm.count), mResultReceiver, mHandler); @@ -1248,7 +1265,7 @@ class AlarmManagerService extends IAlarmManager.Stub { if (alarm.repeatInterval > 0) { // This IntentSender is no longer valid, but this // is a repeating alarm, so toss the hoser. - remove(alarm.operation); + removeImpl(alarm.operation); } } catch (RuntimeException e) { Slog.w(TAG, "Failure sending alarm.", e); @@ -1310,7 +1327,7 @@ class AlarmManagerService extends IAlarmManager.Stub { if (alarm.repeatInterval > 0) { // This IntentSender is no longer valid, but this // is a repeating alarm, so toss the hoser. - remove(alarm.operation); + removeImpl(alarm.operation); } } } @@ -1323,7 +1340,7 @@ class AlarmManagerService extends IAlarmManager.Stub { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_TIME_TICK); filter.addAction(Intent.ACTION_DATE_CHANGED); - mContext.registerReceiver(this, filter); + getContext().registerReceiver(this, filter); } @Override @@ -1354,7 +1371,7 @@ class AlarmManagerService extends IAlarmManager.Stub { final long tickEventDelay = nextTime - currentTime; final WorkSource workSource = null; // Let system take blame for time tick events. - set(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 0, + setImpl(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 0, 0, mTimeTickSender, true, workSource); } @@ -1368,7 +1385,7 @@ class AlarmManagerService extends IAlarmManager.Stub { calendar.add(Calendar.DAY_OF_MONTH, 1); final WorkSource workSource = null; // Let system take blame for date change events. - set(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, true, workSource); + setImpl(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, true, workSource); } } @@ -1379,12 +1396,12 @@ class AlarmManagerService extends IAlarmManager.Stub { filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); filter.addDataScheme("package"); - mContext.registerReceiver(this, filter); + getContext().registerReceiver(this, filter); // Register for events related to sdcard installation. IntentFilter sdFilter = new IntentFilter(); sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); sdFilter.addAction(Intent.ACTION_USER_STOPPED); - mContext.registerReceiver(this, sdFilter); + getContext().registerReceiver(this, sdFilter); } @Override diff --git a/services/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index a1a0d47cb019..a1a0d47cb019 100644 --- a/services/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java diff --git a/services/java/com/android/server/AssetAtlasService.java b/services/core/java/com/android/server/AssetAtlasService.java index 26b4652f4c7d..26b4652f4c7d 100644 --- a/services/java/com/android/server/AssetAtlasService.java +++ b/services/core/java/com/android/server/AssetAtlasService.java diff --git a/services/java/com/android/server/AttributeCache.java b/services/core/java/com/android/server/AttributeCache.java index 427dbc091ced..427dbc091ced 100644 --- a/services/java/com/android/server/AttributeCache.java +++ b/services/core/java/com/android/server/AttributeCache.java diff --git a/services/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 5f3f894ca68e..cc9055dd480e 100644 --- a/services/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -19,6 +19,8 @@ package com.android.server; import android.os.BatteryStats; import com.android.internal.app.IBatteryStats; import com.android.server.am.BatteryStatsService; +import com.android.server.lights.Light; +import com.android.server.lights.LightsManager; import android.app.ActivityManagerNative; import android.content.ContentResolver; @@ -134,13 +136,10 @@ public final class BatteryService extends Binder { private boolean mSentLowBatteryBroadcast = false; - private BatteryListener mBatteryPropertiesListener; - private IBatteryPropertiesRegistrar mBatteryPropertiesRegistrar; - - public BatteryService(Context context, LightsService lights) { + public BatteryService(Context context, LightsManager lightsManager) { mContext = context; mHandler = new Handler(true /*async*/); - mLed = new Led(context, lights); + mLed = new Led(context, lightsManager); mBatteryStats = BatteryStatsService.getService(); mCriticalBatteryLevel = mContext.getResources().getInteger( @@ -158,13 +157,11 @@ public final class BatteryService extends Binder { "DEVPATH=/devices/virtual/switch/invalid_charger"); } - mBatteryPropertiesListener = new BatteryListener(); - IBinder b = ServiceManager.getService("batterypropreg"); - mBatteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b); - + final IBatteryPropertiesRegistrar batteryPropertiesRegistrar = + IBatteryPropertiesRegistrar.Stub.asInterface(b); try { - mBatteryPropertiesRegistrar.registerListener(mBatteryPropertiesListener); + batteryPropertiesRegistrar.registerListener(new BatteryListener()); } catch (RemoteException e) { // Should never happen. } @@ -688,7 +685,7 @@ public final class BatteryService extends Binder { }; private final class Led { - private final LightsService.Light mBatteryLight; + private final Light mBatteryLight; private final int mBatteryLowARGB; private final int mBatteryMediumARGB; @@ -696,8 +693,8 @@ public final class BatteryService extends Binder { private final int mBatteryLedOn; private final int mBatteryLedOff; - public Led(Context context, LightsService lights) { - mBatteryLight = lights.getLight(LightsService.LIGHT_ID_BATTERY); + public Led(Context context, LightsManager lights) { + mBatteryLight = lights.getLight(LightsManager.LIGHT_ID_BATTERY); mBatteryLowARGB = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryLowARGB); @@ -723,7 +720,7 @@ public final class BatteryService extends Binder { mBatteryLight.setColor(mBatteryLowARGB); } else { // Flash red when battery is low and not charging - mBatteryLight.setFlashing(mBatteryLowARGB, LightsService.LIGHT_FLASH_TIMED, + mBatteryLight.setFlashing(mBatteryLowARGB, Light.LIGHT_FLASH_TIMED, mBatteryLedOn, mBatteryLedOff); } } else if (status == BatteryManager.BATTERY_STATUS_CHARGING @@ -743,8 +740,14 @@ public final class BatteryService extends Binder { } private final class BatteryListener extends IBatteryPropertiesListener.Stub { + @Override public void batteryPropertiesChanged(BatteryProperties props) { - BatteryService.this.update(props); + final long identity = Binder.clearCallingIdentity(); + try { + BatteryService.this.update(props); + } finally { + Binder.restoreCallingIdentity(identity); + } } } } diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 546324a73e05..546324a73e05 100644 --- a/services/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java diff --git a/services/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java index bce85cee338b..bce85cee338b 100644 --- a/services/java/com/android/server/BootReceiver.java +++ b/services/core/java/com/android/server/BootReceiver.java diff --git a/services/java/com/android/server/BrickReceiver.java b/services/core/java/com/android/server/BrickReceiver.java index cff3805b68d2..cff3805b68d2 100644 --- a/services/java/com/android/server/BrickReceiver.java +++ b/services/core/java/com/android/server/BrickReceiver.java diff --git a/services/java/com/android/server/CertBlacklister.java b/services/core/java/com/android/server/CertBlacklister.java index 8b167d7b0c90..8b167d7b0c90 100644 --- a/services/java/com/android/server/CertBlacklister.java +++ b/services/core/java/com/android/server/CertBlacklister.java diff --git a/services/java/com/android/server/CommonTimeManagementService.java b/services/core/java/com/android/server/CommonTimeManagementService.java index 710fb9d34596..710fb9d34596 100644 --- a/services/java/com/android/server/CommonTimeManagementService.java +++ b/services/core/java/com/android/server/CommonTimeManagementService.java diff --git a/services/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index d42ae3a945db..d42ae3a945db 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java diff --git a/services/java/com/android/server/ConsumerIrService.java b/services/core/java/com/android/server/ConsumerIrService.java index 783dff111443..783dff111443 100644 --- a/services/java/com/android/server/ConsumerIrService.java +++ b/services/core/java/com/android/server/ConsumerIrService.java diff --git a/services/java/com/android/server/CountryDetectorService.java b/services/core/java/com/android/server/CountryDetectorService.java index a478b2f47637..a478b2f47637 100644 --- a/services/java/com/android/server/CountryDetectorService.java +++ b/services/core/java/com/android/server/CountryDetectorService.java diff --git a/services/java/com/android/server/DiskStatsService.java b/services/core/java/com/android/server/DiskStatsService.java index ac25dc58861d..ac25dc58861d 100644 --- a/services/java/com/android/server/DiskStatsService.java +++ b/services/core/java/com/android/server/DiskStatsService.java diff --git a/services/java/com/android/server/DockObserver.java b/services/core/java/com/android/server/DockObserver.java index 4a8bf720aae1..4a8bf720aae1 100644 --- a/services/java/com/android/server/DockObserver.java +++ b/services/core/java/com/android/server/DockObserver.java diff --git a/services/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java index 29b04da9c564..29b04da9c564 100644 --- a/services/java/com/android/server/DropBoxManagerService.java +++ b/services/core/java/com/android/server/DropBoxManagerService.java diff --git a/services/java/com/android/server/EntropyMixer.java b/services/core/java/com/android/server/EntropyMixer.java index cfdbf7d530cd..cfdbf7d530cd 100644 --- a/services/java/com/android/server/EntropyMixer.java +++ b/services/core/java/com/android/server/EntropyMixer.java diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags index 399e7d183658..399e7d183658 100644 --- a/services/java/com/android/server/EventLogTags.logtags +++ b/services/core/java/com/android/server/EventLogTags.logtags diff --git a/services/java/com/android/server/FgThread.java b/services/core/java/com/android/server/FgThread.java index 3b655f2cee93..3b655f2cee93 100644 --- a/services/java/com/android/server/FgThread.java +++ b/services/core/java/com/android/server/FgThread.java diff --git a/services/java/com/android/server/INativeDaemonConnectorCallbacks.java b/services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java index 6fbf713d3f7a..6fbf713d3f7a 100644 --- a/services/java/com/android/server/INativeDaemonConnectorCallbacks.java +++ b/services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java diff --git a/services/java/com/android/server/IdleMaintenanceService.java b/services/core/java/com/android/server/IdleMaintenanceService.java index b0a1aca37d7c..b0a1aca37d7c 100644 --- a/services/java/com/android/server/IdleMaintenanceService.java +++ b/services/core/java/com/android/server/IdleMaintenanceService.java diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index a996dbda5cf5..26424a58061f 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -28,7 +28,7 @@ import com.android.internal.view.IInputMethodClient; import com.android.internal.view.IInputMethodManager; import com.android.internal.view.IInputMethodSession; import com.android.internal.view.InputBindResult; -import com.android.server.EventLogTags; +import com.android.server.statusbar.StatusBarManagerService; import com.android.server.wm.WindowManagerService; import org.xmlpull.v1.XmlPullParser; diff --git a/services/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java index 64b0487fa320..64b0487fa320 100644 --- a/services/java/com/android/server/IntentResolver.java +++ b/services/core/java/com/android/server/IntentResolver.java diff --git a/services/java/com/android/server/IoThread.java b/services/core/java/com/android/server/IoThread.java index 09f2af79c83d..09f2af79c83d 100644 --- a/services/java/com/android/server/IoThread.java +++ b/services/core/java/com/android/server/IoThread.java diff --git a/services/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index eebd1c5e9642..eebd1c5e9642 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java diff --git a/services/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 35e7afad301c..35e7afad301c 100644 --- a/services/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java diff --git a/services/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java index 86f57d124868..86f57d124868 100644 --- a/services/java/com/android/server/MasterClearReceiver.java +++ b/services/core/java/com/android/server/MasterClearReceiver.java diff --git a/services/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 0d535cc7634a..0d535cc7634a 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java index 417d6d81cdf6..417d6d81cdf6 100644 --- a/services/java/com/android/server/NativeDaemonConnector.java +++ b/services/core/java/com/android/server/NativeDaemonConnector.java diff --git a/services/java/com/android/server/NativeDaemonConnectorException.java b/services/core/java/com/android/server/NativeDaemonConnectorException.java index 590bbccdbc5d..590bbccdbc5d 100644 --- a/services/java/com/android/server/NativeDaemonConnectorException.java +++ b/services/core/java/com/android/server/NativeDaemonConnectorException.java diff --git a/services/java/com/android/server/NativeDaemonEvent.java b/services/core/java/com/android/server/NativeDaemonEvent.java index 209515279bf8..209515279bf8 100644 --- a/services/java/com/android/server/NativeDaemonEvent.java +++ b/services/core/java/com/android/server/NativeDaemonEvent.java diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index ad7ec99775a3..ad7ec99775a3 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java diff --git a/services/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java index fddb54e138e2..fddb54e138e2 100644 --- a/services/java/com/android/server/NetworkTimeUpdateService.java +++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java diff --git a/services/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java index 16d2468e7c9d..16d2468e7c9d 100644 --- a/services/java/com/android/server/NsdService.java +++ b/services/core/java/com/android/server/NsdService.java diff --git a/services/java/com/android/server/RandomBlock.java b/services/core/java/com/android/server/RandomBlock.java index 6d6d9010a8d9..6d6d9010a8d9 100644 --- a/services/java/com/android/server/RandomBlock.java +++ b/services/core/java/com/android/server/RandomBlock.java diff --git a/services/java/com/android/server/RecognitionManagerService.java b/services/core/java/com/android/server/RecognitionManagerService.java index c2e749d3382a..c2e749d3382a 100644 --- a/services/java/com/android/server/RecognitionManagerService.java +++ b/services/core/java/com/android/server/RecognitionManagerService.java diff --git a/services/java/com/android/server/SamplingProfilerService.java b/services/core/java/com/android/server/SamplingProfilerService.java index fbf1aa4b8db0..fbf1aa4b8db0 100644 --- a/services/java/com/android/server/SamplingProfilerService.java +++ b/services/core/java/com/android/server/SamplingProfilerService.java diff --git a/services/java/com/android/server/SerialService.java b/services/core/java/com/android/server/SerialService.java index 1abe4588261a..1abe4588261a 100644 --- a/services/java/com/android/server/SerialService.java +++ b/services/core/java/com/android/server/SerialService.java diff --git a/services/java/com/android/server/ServiceWatcher.java b/services/core/java/com/android/server/ServiceWatcher.java index 5c7bfab7ec20..5c7bfab7ec20 100644 --- a/services/java/com/android/server/ServiceWatcher.java +++ b/services/core/java/com/android/server/ServiceWatcher.java diff --git a/services/java/com/android/server/ShutdownActivity.java b/services/core/java/com/android/server/ShutdownActivity.java index be651417150f..be651417150f 100644 --- a/services/java/com/android/server/ShutdownActivity.java +++ b/services/core/java/com/android/server/ShutdownActivity.java diff --git a/services/java/com/android/server/SystemServer.java b/services/core/java/com/android/server/SystemServer.java index a42cbcfe0d64..9ce41b28ff4a 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/core/java/com/android/server/SystemServer.java @@ -17,6 +17,8 @@ package com.android.server; import android.app.ActivityManagerNative; +import android.app.IAlarmManager; +import android.app.INotificationManager; import android.bluetooth.BluetoothAdapter; import android.content.ComponentName; import android.content.ContentResolver; @@ -30,6 +32,7 @@ import android.net.wifi.p2p.WifiP2pService; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; +import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; @@ -51,22 +54,30 @@ import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accounts.AccountManagerService; import com.android.server.am.ActivityManagerService; import com.android.server.am.BatteryStatsService; +import com.android.server.clipboard.ClipboardService; import com.android.server.content.ContentService; import com.android.server.display.DisplayManagerService; import com.android.server.dreams.DreamManagerService; import com.android.server.input.InputManagerService; +import com.android.server.lights.LightsManager; +import com.android.server.lights.LightsService; import com.android.server.media.MediaRouterService; import com.android.server.net.NetworkPolicyManagerService; import com.android.server.net.NetworkStatsService; +import com.android.server.notification.NotificationManagerService; import com.android.server.os.SchedulingPolicyService; import com.android.server.pm.Installer; import com.android.server.pm.PackageManagerService; import com.android.server.pm.UserManagerService; import com.android.server.power.PowerManagerService; import com.android.server.power.ShutdownThread; -import com.android.server.print.PrintManagerService; import com.android.server.search.SearchManagerService; +import com.android.server.statusbar.StatusBarManagerService; +import com.android.server.storage.DeviceStorageMonitorService; +import com.android.server.twilight.TwilightManager; +import com.android.server.twilight.TwilightService; import com.android.server.usb.UsbService; +import com.android.server.wallpaper.WallpaperManagerService; import com.android.server.wifi.WifiService; import com.android.server.wm.WindowManagerService; @@ -84,6 +95,19 @@ class ServerThread { ContentResolver mContentResolver; + /* + * Implementation class names. TODO: Move them to a codegen class or load + * them from the build system somehow. + */ + private static final String BACKUP_MANAGER_SERVICE_CLASS = + "com.android.server.backup.BackupManagerSystemService"; + private static final String DEVICE_POLICY_MANAGER_SERVICE_CLASS = + "com.android.server.devicepolicy.DevicePolicyManagerSystemService"; + private static final String APPWIDGET_SERVICE_CLASS = + "com.android.server.appwidget.AppWidgetService"; + private static final String PRINT_MANAGER_SERVICE_CLASS = + "com.android.server.print.PrintManagerService"; + void reportWtf(String msg, Throwable e) { Slog.w(TAG, "***********************************************"); Log.wtf(TAG, "BOOT FAILURE " + msg, e); @@ -122,17 +146,16 @@ class ServerThread { String factoryTestStr = SystemProperties.get("ro.factorytest"); int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF : Integer.parseInt(factoryTestStr); - final boolean headless = "1".equals(SystemProperties.get("ro.config.headless", "0")); Installer installer = null; AccountManagerService accountManager = null; ContentService contentService = null; - LightsService lights = null; + LightsManager lights = null; PowerManagerService power = null; DisplayManagerService display = null; BatteryService battery = null; VibratorService vibrator = null; - AlarmManagerService alarm = null; + IAlarmManager alarm = null; MountService mountService = null; NetworkManagementService networkManagement = null; NetworkStatsService networkStats = null; @@ -148,8 +171,7 @@ class ServerThread { DockObserver dock = null; UsbService usb = null; SerialService serial = null; - TwilightService twilight = null; - UiModeManagerService uiMode = null; + TwilightManager twilight = null; RecognitionManagerService recognition = null; NetworkTimeUpdateService networkTimeUpdater = null; CommonTimeManagementService commonTimeMgmtService = null; @@ -199,6 +221,8 @@ class ServerThread { Slog.e("System", "************ Failure starting bootstrap service", e); } + final SystemServiceManager systemServiceManager = new SystemServiceManager(context); + boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false); boolean disableMedia = SystemProperties.getBoolean("config.disable_media", false); boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false); @@ -274,8 +298,8 @@ class ServerThread { Slog.i(TAG, "System Content Providers"); ActivityManagerService.installSystemProviders(); - Slog.i(TAG, "Lights Service"); - lights = new LightsService(context); + systemServiceManager.startService(LightsService.class); + lights = LocalServices.getService(LightsManager.class); Slog.i(TAG, "Battery Service"); battery = new BatteryService(context, lights); @@ -291,17 +315,16 @@ class ServerThread { // only initialize the power service after we have started the // lights service, content providers and the battery service. - power.init(context, lights, ActivityManagerService.self(), battery, + power.init(context, lights, battery, BatteryStatsService.getService(), ActivityManagerService.self().getAppOpsService(), display); - Slog.i(TAG, "Alarm Manager"); - alarm = new AlarmManagerService(context); - ServiceManager.addService(Context.ALARM_SERVICE, alarm); + systemServiceManager.startService(AlarmManagerService.class); + alarm = IAlarmManager.Stub.asInterface( + ServiceManager.getService(Context.ALARM_SERVICE)); Slog.i(TAG, "Init Watchdog"); - Watchdog.getInstance().init(context, battery, power, alarm, - ActivityManagerService.self()); + Watchdog.getInstance().init(context, ActivityManagerService.self()); Watchdog.getInstance().addThread(wmHandler, "WindowManager thread"); Slog.i(TAG, "Input Manager"); @@ -344,11 +367,9 @@ class ServerThread { Slog.e("System", "************ Failure starting core service", e); } - DevicePolicyManagerService devicePolicy = null; StatusBarManagerService statusBar = null; + INotificationManager notification = null; InputMethodManagerService imm = null; - AppWidgetService appWidget = null; - NotificationManagerService notification = null; WallpaperManagerService wallpaper = null; LocationManagerService location = null; CountryDetectorService countryDetector = null; @@ -356,7 +377,6 @@ class ServerThread { LockSettingsService lockSettings = null; DreamManagerService dreamy = null; AssetAtlasService atlas = null; - PrintManagerService printManager = null; MediaRouterService mediaRouter = null; // Bring up services needed for UI. @@ -397,7 +417,7 @@ class ServerThread { ActivityManagerNative.getDefault().showBootMessage( context.getResources().getText( com.android.internal.R.string.android_upgrading_starting_apps), - false); + false); } catch (RemoteException e) { } @@ -428,8 +448,7 @@ class ServerThread { try { Slog.i(TAG, "Device Policy"); - devicePolicy = new DevicePolicyManagerService(context); - ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy); + systemServiceManager.startService(DEVICE_POLICY_MANAGER_SERVICE_CLASS); } catch (Throwable e) { reportWtf("starting DevicePolicyService", e); } @@ -567,22 +586,12 @@ class ServerThread { reportWtf("making Content Service ready", e); } - try { - Slog.i(TAG, "Notification Manager"); - notification = new NotificationManagerService(context, statusBar, lights); - ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification); - networkPolicy.bindNotificationManager(notification); - } catch (Throwable e) { - reportWtf("starting Notification Manager", e); - } + systemServiceManager.startService(NotificationManagerService.class); + notification = INotificationManager.Stub.asInterface( + ServiceManager.getService(Context.NOTIFICATION_SERVICE)); + networkPolicy.bindNotificationManager(notification); - try { - Slog.i(TAG, "Device Storage Monitor"); - ServiceManager.addService(DeviceStorageMonitorService.SERVICE, - new DeviceStorageMonitorService(context)); - } catch (Throwable e) { - reportWtf("starting DeviceStorageMonitor service", e); - } + systemServiceManager.startService(DeviceStorageMonitorService.class); if (!disableLocation) { try { @@ -624,10 +633,8 @@ class ServerThread { R.bool.config_enableWallpaperService)) { try { Slog.i(TAG, "Wallpaper Service"); - if (!headless) { - wallpaper = new WallpaperManagerService(context); - ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper); - } + wallpaper = new WallpaperManagerService(context); + ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper); } catch (Throwable e) { reportWtf("starting Wallpaper Service", e); } @@ -683,34 +690,22 @@ class ServerThread { } } - try { - Slog.i(TAG, "Twilight Service"); - twilight = new TwilightService(context); - } catch (Throwable e) { - reportWtf("starting TwilightService", e); - } + systemServiceManager.startService(TwilightService.class); + twilight = LocalServices.getService(TwilightManager.class); - try { - Slog.i(TAG, "UI Mode Manager Service"); - // Listen for UI mode changes - uiMode = new UiModeManagerService(context, twilight); - } catch (Throwable e) { - reportWtf("starting UiModeManagerService", e); - } + systemServiceManager.startService(UiModeManagerService.class); if (!disableNonCoreServices) { try { Slog.i(TAG, "Backup Service"); - ServiceManager.addService(Context.BACKUP_SERVICE, - new BackupManagerService(context)); + systemServiceManager.startService(BACKUP_MANAGER_SERVICE_CLASS); } catch (Throwable e) { Slog.e(TAG, "Failure starting Backup Service", e); } try { Slog.i(TAG, "AppWidget Service"); - appWidget = new AppWidgetService(context); - ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget); + systemServiceManager.startService(APPWIDGET_SERVICE_CLASS); } catch (Throwable e) { reportWtf("starting AppWidget Service", e); } @@ -801,8 +796,7 @@ class ServerThread { try { Slog.i(TAG, "Print Service"); - printManager = new PrintManagerService(context); - ServiceManager.addService(Context.PRINT_SERVICE, printManager); + systemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS); } catch (Throwable e) { reportWtf("starting Print Service", e); } @@ -848,21 +842,10 @@ class ServerThread { } } - if (devicePolicy != null) { - try { - devicePolicy.systemReady(); - } catch (Throwable e) { - reportWtf("making Device Policy Service ready", e); - } - } + // Needed by DevicePolicyManager for initialization + systemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); - if (notification != null) { - try { - notification.systemReady(); - } catch (Throwable e) { - reportWtf("making Notification Service ready", e); - } - } + systemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); try { wm.systemReady(); @@ -911,9 +894,6 @@ class ServerThread { final ConnectivityService connectivityF = connectivity; final DockObserver dockF = dock; final UsbService usbF = usb; - final TwilightService twilightF = twilight; - final UiModeManagerService uiModeF = uiMode; - final AppWidgetService appWidgetF = appWidget; final WallpaperManagerService wallpaperF = wallpaper; final InputMethodManagerService immF = imm; final RecognitionManagerService recognitionF = recognition; @@ -927,7 +907,6 @@ class ServerThread { final AssetAtlasService atlasF = atlas; final InputManagerService inputManagerF = inputManager; final TelephonyRegistry telephonyRegistryF = telephonyRegistry; - final PrintManagerService printManagerF = printManager; final MediaRouterService mediaRouterF = mediaRouter; // We now tell the activity manager it is okay to run third party @@ -944,8 +923,10 @@ class ServerThread { } catch (Throwable e) { reportWtf("observing native crashes", e); } - if (!headless) { + try { startSystemUi(contextF); + } catch (Throwable e) { + reportWtf("starting System UI", e); } try { if (mountServiceF != null) mountServiceF.systemReady(); @@ -988,16 +969,6 @@ class ServerThread { reportWtf("making USB Service ready", e); } try { - if (twilightF != null) twilightF.systemReady(); - } catch (Throwable e) { - reportWtf("makin Twilight Service ready", e); - } - try { - if (uiModeF != null) uiModeF.systemReady(); - } catch (Throwable e) { - reportWtf("making UI Mode Service ready", e); - } - try { if (recognitionF != null) recognitionF.systemReady(); } catch (Throwable e) { reportWtf("making Recognition Service ready", e); @@ -1006,13 +977,9 @@ class ServerThread { // It is now okay to let the various system services start their // third party code... + systemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); try { - if (appWidgetF != null) appWidgetF.systemRunning(safeMode); - } catch (Throwable e) { - reportWtf("Notifying AppWidgetService running", e); - } - try { if (wallpaperF != null) wallpaperF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying WallpaperService running", e); @@ -1072,16 +1039,12 @@ class ServerThread { } try { - if (printManagerF != null) printManagerF.systemRuning(); - } catch (Throwable e) { - reportWtf("Notifying PrintManagerService running", e); - } - - try { if (mediaRouterF != null) mediaRouterF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying MediaRouterService running", e); } + + systemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETE); } }); diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 699d79eb0953..699d79eb0953 100644 --- a/services/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java index 09647674e07f..09647674e07f 100644 --- a/services/java/com/android/server/TextServicesManagerService.java +++ b/services/core/java/com/android/server/TextServicesManagerService.java diff --git a/services/java/com/android/server/TwilightCalculator.java b/services/core/java/com/android/server/TwilightCalculator.java index a5c93b5173d4..a5c93b5173d4 100644 --- a/services/java/com/android/server/TwilightCalculator.java +++ b/services/core/java/com/android/server/TwilightCalculator.java diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index 062be01ab26a..de912dcc1332 100644 --- a/services/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -34,9 +34,9 @@ import android.content.res.Configuration; import android.os.BatteryManager; import android.os.Binder; import android.os.Handler; +import android.os.IBinder; import android.os.PowerManager; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.UserHandle; import android.provider.Settings; import android.service.dreams.Sandman; @@ -47,9 +47,11 @@ import java.io.PrintWriter; import com.android.internal.R; import com.android.internal.app.DisableCarModeActivity; -import com.android.server.TwilightService.TwilightState; +import com.android.server.twilight.TwilightListener; +import com.android.server.twilight.TwilightManager; +import com.android.server.twilight.TwilightState; -final class UiModeManagerService extends IUiModeManager.Stub { +final class UiModeManagerService extends SystemService { private static final String TAG = UiModeManager.class.getSimpleName(); private static final boolean LOG = false; @@ -57,40 +59,36 @@ final class UiModeManagerService extends IUiModeManager.Stub { private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true; private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true; - private final Context mContext; - private final TwilightService mTwilightService; - private final Handler mHandler = new Handler(); - final Object mLock = new Object(); - private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; + private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED; + int mNightMode = UiModeManager.MODE_NIGHT_NO; - private int mNightMode = UiModeManager.MODE_NIGHT_NO; private boolean mCarModeEnabled = false; private boolean mCharging = false; - private final int mDefaultUiModeType; - private final boolean mCarModeKeepsScreenOn; - private final boolean mDeskModeKeepsScreenOn; - private final boolean mTelevision; - + private int mDefaultUiModeType; + private boolean mCarModeKeepsScreenOn; + private boolean mDeskModeKeepsScreenOn; + private boolean mTelevision; private boolean mComputedNightMode; - private int mCurUiMode = 0; - private int mSetUiMode = 0; + int mCurUiMode = 0; + private int mSetUiMode = 0; private boolean mHoldingConfiguration = false; + private Configuration mConfiguration = new Configuration(); + boolean mSystemReady; - private boolean mSystemReady; + private final Handler mHandler = new Handler(); + private TwilightManager mTwilightManager; private NotificationManager mNotificationManager; - private StatusBarManager mStatusBarManager; - private final PowerManager mPowerManager; - private final PowerManager.WakeLock mWakeLock; + private PowerManager.WakeLock mWakeLock; - static Intent buildHomeIntent(String category) { + private static Intent buildHomeIntent(String category) { Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(category); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK @@ -142,28 +140,26 @@ final class UiModeManagerService extends IUiModeManager.Stub { } }; - private final TwilightService.TwilightListener mTwilightListener = - new TwilightService.TwilightListener() { + private final TwilightListener mTwilightListener = new TwilightListener() { @Override public void onTwilightStateChanged() { updateTwilight(); } }; - public UiModeManagerService(Context context, TwilightService twilight) { - mContext = context; - mTwilightService = twilight; - - ServiceManager.addService(Context.UI_MODE_SERVICE, this); - - mContext.registerReceiver(mDockModeReceiver, + @Override + public void onStart() { + final Context context = getContext(); + mTwilightManager = getLocalService(TwilightManager.class); + final PowerManager powerManager = + (PowerManager) context.getSystemService(Context.POWER_SERVICE); + mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); + + context.registerReceiver(mDockModeReceiver, new IntentFilter(Intent.ACTION_DOCK_EVENT)); - mContext.registerReceiver(mBatteryReceiver, + context.registerReceiver(mBatteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); - mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); - mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); - mConfiguration.setToDefaults(); mDefaultUiModeType = context.getResources().getInteger( @@ -175,101 +171,139 @@ final class UiModeManagerService extends IUiModeManager.Stub { mTelevision = context.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEVISION); - mNightMode = Settings.Secure.getInt(mContext.getContentResolver(), + mNightMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.UI_NIGHT_MODE, UiModeManager.MODE_NIGHT_AUTO); - mTwilightService.registerListener(mTwilightListener, mHandler); + mTwilightManager.registerListener(mTwilightListener, mHandler); + + publishBinderService(Context.UI_MODE_SERVICE, mService); } - @Override // Binder call - public void disableCarMode(int flags) { - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mLock) { - setCarModeLocked(false); - if (mSystemReady) { - updateLocked(0, flags); + private final IBinder mService = new IUiModeManager.Stub() { + @Override + public void enableCarMode(int flags) { + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + setCarModeLocked(true); + if (mSystemReady) { + updateLocked(flags, 0); + } } + } finally { + Binder.restoreCallingIdentity(ident); } - } finally { - Binder.restoreCallingIdentity(ident); } - } - @Override // Binder call - public void enableCarMode(int flags) { - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mLock) { - setCarModeLocked(true); - if (mSystemReady) { - updateLocked(flags, 0); + @Override + public void disableCarMode(int flags) { + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + setCarModeLocked(false); + if (mSystemReady) { + updateLocked(0, flags); + } } + } finally { + Binder.restoreCallingIdentity(ident); } - } finally { - Binder.restoreCallingIdentity(ident); } - } - @Override // Binder call - public int getCurrentModeType() { - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mLock) { - return mCurUiMode & Configuration.UI_MODE_TYPE_MASK; + @Override + public int getCurrentModeType() { + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + return mCurUiMode & Configuration.UI_MODE_TYPE_MASK; + } + } finally { + Binder.restoreCallingIdentity(ident); } - } finally { - Binder.restoreCallingIdentity(ident); } - } - @Override // Binder call - public void setNightMode(int mode) { - switch (mode) { - case UiModeManager.MODE_NIGHT_NO: - case UiModeManager.MODE_NIGHT_YES: - case UiModeManager.MODE_NIGHT_AUTO: - break; - default: - throw new IllegalArgumentException("Unknown mode: " + mode); + @Override + public void setNightMode(int mode) { + switch (mode) { + case UiModeManager.MODE_NIGHT_NO: + case UiModeManager.MODE_NIGHT_YES: + case UiModeManager.MODE_NIGHT_AUTO: + break; + default: + throw new IllegalArgumentException("Unknown mode: " + mode); + } + + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + if (isDoingNightModeLocked() && mNightMode != mode) { + Settings.Secure.putInt(getContext().getContentResolver(), + Settings.Secure.UI_NIGHT_MODE, mode); + mNightMode = mode; + updateLocked(0, 0); + } + } + } finally { + Binder.restoreCallingIdentity(ident); + } } - final long ident = Binder.clearCallingIdentity(); - try { + @Override + public int getNightMode() { synchronized (mLock) { - if (isDoingNightModeLocked() && mNightMode != mode) { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.UI_NIGHT_MODE, mode); - mNightMode = mode; - updateLocked(0, 0); - } + return mNightMode; } - } finally { - Binder.restoreCallingIdentity(ident); } - } - @Override // Binder call - public int getNightMode() { + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) + != PackageManager.PERMISSION_GRANTED) { + + pw.println("Permission Denial: can't dump uimode service from from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid()); + return; + } + + dumpImpl(pw); + } + }; + + void dumpImpl(PrintWriter pw) { synchronized (mLock) { - return mNightMode; + pw.println("Current UI Mode Service state:"); + pw.print(" mDockState="); pw.print(mDockState); + pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); + pw.print(" mNightMode="); pw.print(mNightMode); + pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled); + pw.print(" mComputedNightMode="); pw.println(mComputedNightMode); + pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode)); + pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode)); + pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration); + pw.print(" mSystemReady="); pw.println(mSystemReady); + pw.print(" mTwilightService.getCurrentState()="); + pw.println(mTwilightManager.getCurrentState()); } } - void systemReady() { - synchronized (mLock) { - mSystemReady = true; - mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR; - updateComputedNightModeLocked(); - updateLocked(0, 0); + @Override + public void onBootPhase(int phase) { + if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { + synchronized (mLock) { + mSystemReady = true; + mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR; + updateComputedNightModeLocked(); + updateLocked(0, 0); + } } } - private boolean isDoingNightModeLocked() { + boolean isDoingNightModeLocked() { return mCarModeEnabled || mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED; } - private void setCarModeLocked(boolean enabled) { + void setCarModeLocked(boolean enabled) { if (mCarModeEnabled != enabled) { mCarModeEnabled = enabled; } @@ -344,7 +378,7 @@ final class UiModeManagerService extends IUiModeManager.Stub { } } - private void updateLocked(int enableFlags, int disableFlags) { + void updateLocked(int enableFlags, int disableFlags) { String action = null; String oldAction = null; if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) { @@ -359,7 +393,7 @@ final class UiModeManagerService extends IUiModeManager.Stub { adjustStatusBarCarModeLocked(); if (oldAction != null) { - mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL); + getContext().sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL); } mLastBroadcastState = Intent.EXTRA_DOCK_STATE_CAR; action = UiModeManager.ACTION_ENTER_CAR_MODE; @@ -367,7 +401,7 @@ final class UiModeManagerService extends IUiModeManager.Stub { } else if (isDeskDockState(mDockState)) { if (!isDeskDockState(mLastBroadcastState)) { if (oldAction != null) { - mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL); + getContext().sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL); } mLastBroadcastState = mDockState; action = UiModeManager.ACTION_ENTER_DESK_MODE; @@ -393,7 +427,7 @@ final class UiModeManagerService extends IUiModeManager.Stub { Intent intent = new Intent(action); intent.putExtra("enableFlags", enableFlags); intent.putExtra("disableFlags", disableFlags); - mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null, + getContext().sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null, mResultReceiver, null, Activity.RESULT_OK, null, null); // Attempting to make this transition a little more clean, we are going @@ -491,7 +525,7 @@ final class UiModeManagerService extends IUiModeManager.Stub { // activity manager take care of both the start and config // change. Intent homeIntent = buildHomeIntent(category); - if (Sandman.shouldStartDockApp(mContext, homeIntent)) { + if (Sandman.shouldStartDockApp(getContext(), homeIntent)) { try { int result = ActivityManagerNative.getDefault().startActivityWithConfig( null, null, homeIntent, null, null, null, 0, 0, @@ -513,14 +547,15 @@ final class UiModeManagerService extends IUiModeManager.Stub { // If we did not start a dock app, then start dreaming if supported. if (category != null && !dockAppStarted) { - Sandman.startDreamWhenDockedIfAppropriate(mContext); + Sandman.startDreamWhenDockedIfAppropriate(getContext()); } } private void adjustStatusBarCarModeLocked() { + final Context context = getContext(); if (mStatusBarManager == null) { mStatusBarManager = (StatusBarManager) - mContext.getSystemService(Context.STATUS_BAR_SERVICE); + context.getSystemService(Context.STATUS_BAR_SERVICE); } // Fear not: StatusBarManagerService manages a list of requests to disable @@ -536,12 +571,12 @@ final class UiModeManagerService extends IUiModeManager.Stub { if (mNotificationManager == null) { mNotificationManager = (NotificationManager) - mContext.getSystemService(Context.NOTIFICATION_SERVICE); + context.getSystemService(Context.NOTIFICATION_SERVICE); } if (mNotificationManager != null) { if (mCarModeEnabled) { - Intent carModeOffIntent = new Intent(mContext, DisableCarModeActivity.class); + Intent carModeOffIntent = new Intent(context, DisableCarModeActivity.class); Notification n = new Notification(); n.icon = R.drawable.stat_notify_car_mode; @@ -549,10 +584,10 @@ final class UiModeManagerService extends IUiModeManager.Stub { n.flags = Notification.FLAG_ONGOING_EVENT; n.when = 0; n.setLatestEventInfo( - mContext, - mContext.getString(R.string.car_mode_disable_notification_title), - mContext.getString(R.string.car_mode_disable_notification_message), - PendingIntent.getActivityAsUser(mContext, 0, carModeOffIntent, 0, + context, + context.getString(R.string.car_mode_disable_notification_title), + context.getString(R.string.car_mode_disable_notification_message), + PendingIntent.getActivityAsUser(context, 0, carModeOffIntent, 0, null, UserHandle.CURRENT)); mNotificationManager.notifyAsUser(null, R.string.car_mode_disable_notification_title, n, UserHandle.ALL); @@ -563,7 +598,7 @@ final class UiModeManagerService extends IUiModeManager.Stub { } } - private void updateTwilight() { + void updateTwilight() { synchronized (mLock) { if (isDoingNightModeLocked() && mNightMode == UiModeManager.MODE_NIGHT_AUTO) { updateComputedNightModeLocked(); @@ -573,36 +608,11 @@ final class UiModeManagerService extends IUiModeManager.Stub { } private void updateComputedNightModeLocked() { - TwilightState state = mTwilightService.getCurrentState(); + TwilightState state = mTwilightManager.getCurrentState(); if (state != null) { mComputedNightMode = state.isNight(); } } - @Override - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - pw.println("Permission Denial: can't dump uimode service from from pid=" - + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid()); - return; - } - - synchronized (mLock) { - pw.println("Current UI Mode Service state:"); - pw.print(" mDockState="); pw.print(mDockState); - pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); - pw.print(" mNightMode="); pw.print(mNightMode); - pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled); - pw.print(" mComputedNightMode="); pw.println(mComputedNightMode); - pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode)); - pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode)); - pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration); - pw.print(" mSystemReady="); pw.println(mSystemReady); - pw.print(" mTwilightService.getCurrentState()="); - pw.println(mTwilightService.getCurrentState()); - } - } } diff --git a/services/java/com/android/server/UiThread.java b/services/core/java/com/android/server/UiThread.java index 60d73aa6cacb..60d73aa6cacb 100644 --- a/services/java/com/android/server/UiThread.java +++ b/services/core/java/com/android/server/UiThread.java diff --git a/services/java/com/android/server/UpdateLockService.java b/services/core/java/com/android/server/UpdateLockService.java index 0f778cd17f8a..0f778cd17f8a 100644 --- a/services/java/com/android/server/UpdateLockService.java +++ b/services/core/java/com/android/server/UpdateLockService.java diff --git a/services/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index 28eb948d4169..28eb948d4169 100644 --- a/services/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java diff --git a/services/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index e17f42d9f415..b24995382372 100644 --- a/services/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -80,9 +80,6 @@ public class Watchdog extends Thread { final ArrayList<HandlerChecker> mHandlerCheckers = new ArrayList<HandlerChecker>(); final HandlerChecker mMonitorChecker; ContentResolver mResolver; - BatteryService mBattery; - PowerManagerService mPower; - AlarmManagerService mAlarm; ActivityManagerService mActivity; int mPhonePid; @@ -234,13 +231,8 @@ public class Watchdog extends Thread { "i/o thread", DEFAULT_TIMEOUT)); } - public void init(Context context, BatteryService battery, - PowerManagerService power, AlarmManagerService alarm, - ActivityManagerService activity) { + public void init(Context context, ActivityManagerService activity) { mResolver = context.getContentResolver(); - mBattery = battery; - mPower = power; - mAlarm = alarm; mActivity = activity; context.registerReceiver(new RebootRequestReceiver(), diff --git a/services/java/com/android/server/WiredAccessoryManager.java b/services/core/java/com/android/server/WiredAccessoryManager.java index 415fcc126aae..415fcc126aae 100644 --- a/services/java/com/android/server/WiredAccessoryManager.java +++ b/services/core/java/com/android/server/WiredAccessoryManager.java diff --git a/services/java/com/android/server/accounts/AccountAuthenticatorCache.java b/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java index 75523680d335..75523680d335 100644 --- a/services/java/com/android/server/accounts/AccountAuthenticatorCache.java +++ b/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java diff --git a/services/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index aa9849ef5641..aa9849ef5641 100644 --- a/services/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java diff --git a/services/java/com/android/server/accounts/IAccountAuthenticatorCache.java b/services/core/java/com/android/server/accounts/IAccountAuthenticatorCache.java index bb09687720cc..bb09687720cc 100644 --- a/services/java/com/android/server/accounts/IAccountAuthenticatorCache.java +++ b/services/core/java/com/android/server/accounts/IAccountAuthenticatorCache.java diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 17bb3e0f525b..17bb3e0f525b 100644 --- a/services/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 264a809ef0f0..53f064079473 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -28,11 +28,15 @@ import static org.xmlpull.v1.XmlPullParser.START_TAG; import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import android.app.AppOpsManager; +import android.app.IActivityContainer; +import android.app.IActivityContainerCallback; import android.appwidget.AppWidgetManager; +import android.graphics.Rect; import android.util.ArrayMap; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IAppOpsService; +import com.android.internal.app.ProcessMap; import com.android.internal.app.ProcessStats; import com.android.internal.os.BackgroundThread; import com.android.internal.os.BatteryStatsImpl; @@ -45,14 +49,12 @@ import com.android.internal.util.Preconditions; import com.android.server.AppOpsService; import com.android.server.AttributeCache; import com.android.server.IntentResolver; -import com.android.internal.app.ProcessMap; import com.android.server.SystemServer; import com.android.server.Watchdog; import com.android.server.am.ActivityStack.ActivityState; import com.android.server.firewall.IntentFirewall; import com.android.server.pm.UserManagerService; import com.android.server.wm.AppTransition; -import com.android.server.wm.StackBox; import com.android.server.wm.WindowManagerService; import com.google.android.collect.Lists; import com.google.android.collect.Maps; @@ -68,7 +70,6 @@ import org.xmlpull.v1.XmlSerializer; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; -import android.app.ActivityManager.StackBoxInfo; import android.app.ActivityManager.StackInfo; import android.app.ActivityManagerNative; import android.app.ActivityOptions; @@ -331,8 +332,6 @@ public final class ActivityManagerService extends ActivityManagerNative public IntentFirewall mIntentFirewall; - private final boolean mHeadless; - // Whether we should show our dialogs (ANR, crash, etc) or just perform their // default actuion automatically. Important for devices without direct input // devices. @@ -1772,7 +1771,6 @@ public final class ActivityManagerService extends ActivityManagerNative public void setWindowManager(WindowManagerService wm) { mWindowManager = wm; mStackSupervisor.setWindowManager(wm); - wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f); } public void startObservingNativeCrashes() { @@ -1803,7 +1801,7 @@ public final class ActivityManagerService extends ActivityManagerNative m.mFactoryTest = factoryTest; m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface()); - m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper); + m.mStackSupervisor = new ActivityStackSupervisor(m); m.mBatteryStatsService.publish(context); m.mUsageStatsService.publish(context); @@ -1984,8 +1982,6 @@ public final class ActivityManagerService extends ActivityManagerNative mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); - mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); - // User 0 is the first and only user that runs at boot. mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); mUserLru.add(Integer.valueOf(0)); @@ -2853,13 +2849,6 @@ public final class ActivityManagerService extends ActivityManagerNative } boolean startHomeActivityLocked(int userId) { - if (mHeadless) { - // Added because none of the other calls to ensureBootCompleted seem to fire - // when running headless. - ensureBootCompleted(); - return false; - } - if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL && mTopAction == null) { // We are running in factory test mode, but unable to find @@ -2959,7 +2948,7 @@ public final class ActivityManagerService extends ActivityManagerNative intent.setComponent(new ComponentName( ri.activityInfo.packageName, ri.activityInfo.name)); mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, - null, null, 0, 0, 0, null, 0, null, false, null); + null, null, 0, 0, 0, null, 0, null, false, null, null); } } } @@ -3117,7 +3106,7 @@ public final class ActivityManagerService extends ActivityManagerNative // TODO: Switch to user app stacks here. return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, - null, null, options, userId); + null, null, options, userId, null); } @Override @@ -3132,7 +3121,7 @@ public final class ActivityManagerService extends ActivityManagerNative // TODO: Switch to user app stacks here. mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, - res, null, options, UserHandle.getCallingUserId()); + res, null, options, UserHandle.getCallingUserId(), null); return res; } @@ -3147,7 +3136,7 @@ public final class ActivityManagerService extends ActivityManagerNative // TODO: Switch to user app stacks here. int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, - null, null, null, config, options, userId); + null, null, null, config, options, userId, null); return ret; } @@ -3278,7 +3267,7 @@ public final class ActivityManagerService extends ActivityManagerNative int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, - options, false, null); + options, false, null, null); Binder.restoreCallingIdentity(origId); r.finishing = wasFinishing; @@ -3299,7 +3288,7 @@ public final class ActivityManagerService extends ActivityManagerNative // TODO: Switch to user app stacks here. int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, - null, null, null, null, options, userId); + null, null, null, null, options, userId, null); return ret; } @@ -5004,7 +4993,7 @@ public final class ActivityManagerService extends ActivityManagerNative // See if the top visible activity is waiting to run in this process... if (normalMode) { try { - if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) { + if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; } } catch (Exception e) { @@ -7111,23 +7100,40 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public int createStack(int taskId, int relativeStackBoxId, int position, float weight) { + public IBinder getHomeActivityToken() throws RemoteException { enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, - "createStack()"); - if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId + " relStackBoxId=" + - relativeStackBoxId + " position=" + position + " weight=" + weight); + "getHomeActivityToken()"); synchronized (this) { - long ident = Binder.clearCallingIdentity(); - try { - int stackId = mStackSupervisor.createStack(); - mWindowManager.createStack(stackId, relativeStackBoxId, position, weight); - if (taskId > 0) { - moveTaskToStack(taskId, stackId, true); - } - return stackId; - } finally { - Binder.restoreCallingIdentity(ident); + return mStackSupervisor.getHomeActivityToken(); + } + } + + @Override + public IActivityContainer createActivityContainer(IBinder parentActivityToken, + IActivityContainerCallback callback) throws RemoteException { + enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, + "createActivityContainer()"); + synchronized (this) { + if (parentActivityToken == null) { + throw new IllegalArgumentException("parent token must not be null"); } + ActivityRecord r = ActivityRecord.forToken(parentActivityToken); + if (r == null) { + return null; + } + return mStackSupervisor.createActivityContainer(r, callback); + } + } + + @Override + public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) + throws RemoteException { + synchronized (this) { + ActivityStack stack = ActivityRecord.getStackLocked(activityToken); + if (stack != null) { + return stack.mActivityContainer; + } + return null; } } @@ -7152,99 +7158,40 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public void resizeStackBox(int stackBoxId, float weight) { + public void resizeStack(int stackBoxId, Rect bounds) { enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, "resizeStackBox()"); long ident = Binder.clearCallingIdentity(); try { - mWindowManager.resizeStackBox(stackBoxId, weight); + mWindowManager.resizeStack(stackBoxId, bounds); } finally { Binder.restoreCallingIdentity(ident); } } - private ArrayList<StackInfo> getStacks() { - synchronized (this) { - ArrayList<ActivityManager.StackInfo> list = new ArrayList<ActivityManager.StackInfo>(); - ArrayList<ActivityStack> stacks = mStackSupervisor.getStacks(); - for (ActivityStack stack : stacks) { - ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo(); - int stackId = stack.mStackId; - stackInfo.stackId = stackId; - stackInfo.bounds = mWindowManager.getStackBounds(stackId); - ArrayList<TaskRecord> tasks = stack.getAllTasks(); - final int numTasks = tasks.size(); - int[] taskIds = new int[numTasks]; - String[] taskNames = new String[numTasks]; - for (int i = 0; i < numTasks; ++i) { - final TaskRecord task = tasks.get(i); - taskIds[i] = task.taskId; - taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() - : task.realActivity != null ? task.realActivity.flattenToString() - : task.getTopActivity() != null ? task.getTopActivity().packageName - : "unknown"; - } - stackInfo.taskIds = taskIds; - stackInfo.taskNames = taskNames; - list.add(stackInfo); - } - return list; - } - } - - private void addStackInfoToStackBoxInfo(StackBoxInfo stackBoxInfo, List<StackInfo> stackInfos) { - final int stackId = stackBoxInfo.stackId; - if (stackId >= 0) { - for (StackInfo stackInfo : stackInfos) { - if (stackId == stackInfo.stackId) { - stackBoxInfo.stack = stackInfo; - stackInfos.remove(stackInfo); - return; - } - } - } else { - addStackInfoToStackBoxInfo(stackBoxInfo.children[0], stackInfos); - addStackInfoToStackBoxInfo(stackBoxInfo.children[1], stackInfos); - } - } - @Override - public List<StackBoxInfo> getStackBoxes() { + public List<StackInfo> getAllStackInfos() { enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, - "getStackBoxes()"); + "getAllStackInfos()"); long ident = Binder.clearCallingIdentity(); try { - List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos(); synchronized (this) { - List<StackInfo> stackInfos = getStacks(); - for (StackBoxInfo stackBoxInfo : stackBoxInfos) { - addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos); - } + return mStackSupervisor.getAllStackInfosLocked(); } - return stackBoxInfos; } finally { Binder.restoreCallingIdentity(ident); } } @Override - public StackBoxInfo getStackBoxInfo(int stackBoxId) { + public StackInfo getStackInfo(int stackId) { enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, - "getStackBoxInfo()"); + "getStackInfo()"); long ident = Binder.clearCallingIdentity(); try { - List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos(); - StackBoxInfo info = null; synchronized (this) { - List<StackInfo> stackInfos = getStacks(); - for (StackBoxInfo stackBoxInfo : stackBoxInfos) { - addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos); - if (stackBoxInfo.stackBoxId == stackBoxId) { - info = stackBoxInfo; - } - } + return mStackSupervisor.getStackInfoLocked(stackId); } - return info; } finally { Binder.restoreCallingIdentity(ident); } @@ -9500,10 +9447,6 @@ public final class ActivityManagerService extends ActivityManagerNative private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, String stackTrace) { - if (mHeadless) { - Log.e(TAG, "handleAppCrashLocked: " + app.processName); - return false; - } long now = SystemClock.uptimeMillis(); Long crashTime; @@ -14047,9 +13990,6 @@ public final class ActivityManagerService extends ActivityManagerNative */ boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean persistent, boolean initLocale) { - // do nothing if we are headless - if (mHeadless) return true; - int changes = 0; if (values != null) { @@ -14132,18 +14072,21 @@ public final class ActivityManagerService extends ActivityManagerNative boolean kept = true; final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); - if (changes != 0 && starting == null) { - // If the configuration changed, and the caller is not already - // in the process of starting an activity, then find the top - // activity to check if its configuration needs to change. - starting = mainStack.topRunningActivityLocked(null); - } - - if (starting != null) { - kept = mainStack.ensureActivityConfigurationLocked(starting, changes); - // And we need to make sure at this point that all other activities - // are made visible with the correct configuration. - mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); + // mainStack is null during startup. + if (mainStack != null) { + if (changes != 0 && starting == null) { + // If the configuration changed, and the caller is not already + // in the process of starting an activity, then find the top + // activity to check if its configuration needs to change. + starting = mainStack.topRunningActivityLocked(null); + } + + if (starting != null) { + kept = mainStack.ensureActivityConfigurationLocked(starting, changes); + // And we need to make sure at this point that all other activities + // are made visible with the correct configuration. + mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); + } } if (values != null && mWindowManager != null) { diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 49f29fe6c372..b78f24c6a796 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -21,6 +21,7 @@ import com.android.internal.R.styleable; import com.android.internal.app.ResolverActivity; import com.android.server.AttributeCache; import com.android.server.am.ActivityStack.ActivityState; +import com.android.server.am.ActivityStackSupervisor.ActivityContainer; import android.app.ActivityOptions; import android.app.ResultInfo; @@ -138,11 +139,13 @@ final class ActivityRecord { boolean forceNewConfig; // force re-create with new config next time int launchCount; // count of launches since last state long lastLaunchTime; // time of last lauch of this activity + ArrayList<ActivityStack> mChildContainers = new ArrayList<ActivityStack>(); String stringName; // for caching of toString(). private boolean inHistory; // are we in the history stack? final ActivityStackSupervisor mStackSupervisor; + ActivityContainer mInitialActivityContainer; void dump(PrintWriter pw, String prefix) { final long now = SystemClock.uptimeMillis(); @@ -347,7 +350,8 @@ final class ActivityRecord { int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType, ActivityInfo aInfo, Configuration _configuration, ActivityRecord _resultTo, String _resultWho, int _reqCode, - boolean _componentSpecified, ActivityStackSupervisor supervisor) { + boolean _componentSpecified, ActivityStackSupervisor supervisor, + ActivityContainer container) { service = _service; appToken = new Token(this); info = aInfo; @@ -378,6 +382,7 @@ final class ActivityRecord { idle = false; hasBeenLaunched = false; mStackSupervisor = supervisor; + mInitialActivityContainer = container; // This starts out true, since the initial state of an activity // is that we have everything, and we shouldn't never consider it diff --git a/services/java/com/android/server/am/ActivityResult.java b/services/core/java/com/android/server/am/ActivityResult.java index 6d5bdebe4e36..6d5bdebe4e36 100644 --- a/services/java/com/android/server/am/ActivityResult.java +++ b/services/core/java/com/android/server/am/ActivityResult.java diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index e9c78a7a31a7..ef302c4c1bc0 100755 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -39,6 +39,7 @@ import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import com.android.internal.os.BatteryStatsImpl; import com.android.server.Watchdog; import com.android.server.am.ActivityManagerService.ItemMatcher; +import com.android.server.am.ActivityStackSupervisor.ActivityContainer; import com.android.server.wm.AppTransition; import com.android.server.wm.TaskGroup; import com.android.server.wm.WindowManagerService; @@ -52,7 +53,6 @@ import android.app.IThumbnailReceiver; import android.app.ResultInfo; import android.app.ActivityManager.RunningTaskInfo; import android.content.ComponentName; -import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; @@ -139,8 +139,6 @@ final class ActivityStack { final ActivityManagerService mService; final WindowManagerService mWindowManager; - final Context mContext; - /** * The back history of all previous (and possibly still * running) activities. It contains #TaskRecord objects. @@ -229,6 +227,11 @@ final class ActivityStack { int mCurrentUser; final int mStackId; + final ActivityContainer mActivityContainer; + /** The other stacks, in order, on the attached display. Updated at attach/detach time. */ + ArrayList<ActivityStack> mStacks; + /** The attached Display's unique identifier, or -1 if detached */ + int mDisplayId; /** Run all ActivityStacks through this */ final ActivityStackSupervisor mStackSupervisor; @@ -327,14 +330,14 @@ final class ActivityStack { return count; } - ActivityStack(ActivityManagerService service, Context context, Looper looper, int stackId) { - mHandler = new ActivityStackHandler(looper); - mService = service; - mWindowManager = service.mWindowManager; - mStackSupervisor = service.mStackSupervisor; - mContext = context; - mStackId = stackId; - mCurrentUser = service.mCurrentUserId; + ActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer) { + mActivityContainer = activityContainer; + mStackSupervisor = activityContainer.getOuter(); + mService = mStackSupervisor.mService; + mHandler = new ActivityStackHandler(mService.mHandler.getLooper()); + mWindowManager = mService.mWindowManager; + mStackId = activityContainer.mStackId; + mCurrentUser = mService.mCurrentUserId; } boolean okToShow(ActivityRecord r) { @@ -436,25 +439,6 @@ final class ActivityStack { return null; } - boolean containsApp(ProcessRecord app) { - if (app == null) { - return false; - } - for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { - final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; - for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { - final ActivityRecord r = activities.get(activityNdx); - if (r.finishing) { - continue; - } - if (r.app == app) { - return true; - } - } - } - return false; - } - final boolean updateLRUListLocked(ActivityRecord r) { final boolean hadit = mLRUActivities.remove(r); mLRUActivities.add(r); @@ -465,6 +449,25 @@ final class ActivityStack { return mStackId == HOME_STACK_ID; } + final boolean isOnHomeDisplay() { + return isAttached() && + mActivityContainer.mActivityDisplay.mDisplayId == Display.DEFAULT_DISPLAY; + } + + final void moveToFront() { + if (isAttached()) { + if (isOnHomeDisplay()) { + mStackSupervisor.moveHomeStack(isHomeStack()); + } + mStacks.remove(this); + mStacks.add(this); + } + } + + final boolean isAttached() { + return mStacks != null; + } + /** * Returns the top activity in any existing task matching the given * Intent. Returns null if no such task is found. @@ -1264,7 +1267,8 @@ final class ActivityStack { ActivityOptions.abort(options); if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home"); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); - return mStackSupervisor.resumeHomeActivity(prev); + // Only resume home if on home display + return isOnHomeDisplay() && mStackSupervisor.resumeHomeActivity(prev); } next.delayedResume = false; @@ -1287,25 +1291,17 @@ final class ActivityStack { if (prevTask != null && prevTask.mOnTopOfHome && prev.finishing && prev.frontOfTask) { if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); if (prevTask == nextTask) { - ArrayList<ActivityRecord> activities = prevTask.mActivities; - final int numActivities = activities.size(); - for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) { - final ActivityRecord r = activities.get(activityNdx); - // r is usually the same as next, but what if two activities were launched - // before prev finished? - if (!r.finishing) { - r.frontOfTask = true; - break; - } - } + prevTask.setFrontOfTask(); } else if (prevTask != topTask()) { // This task is going away but it was supposed to return to the home task. // Now the task above it has to return to the home task instead. final int taskNdx = mTaskHistory.indexOf(prevTask) + 1; mTaskHistory.get(taskNdx).mOnTopOfHome = true; } else { - if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Launching home next"); - return mStackSupervisor.resumeHomeActivity(prev); + if (DEBUG_STATES && isOnHomeDisplay()) Slog.d(TAG, + "resumeTopActivityLocked: Launching home next"); + // Only resume home if on home display + return isOnHomeDisplay() && mStackSupervisor.resumeHomeActivity(prev); } } @@ -1667,10 +1663,14 @@ final class ActivityStack { private void insertTaskAtTop(TaskRecord task) { // If this is being moved to the top by another activity or being launched from the home // activity, set mOnTopOfHome accordingly. - ActivityStack lastStack = mStackSupervisor.getLastStack(); - final boolean fromHome = lastStack == null ? true : lastStack.isHomeStack(); - if (!isHomeStack() && (fromHome || topTask() != task)) { - task.mOnTopOfHome = fromHome; + if (isOnHomeDisplay()) { + ActivityStack lastStack = mStackSupervisor.getLastStack(); + final boolean fromHome = lastStack.isHomeStack(); + if (!isHomeStack() && (fromHome || topTask() != task)) { + task.mOnTopOfHome = fromHome; + } + } else { + task.mOnTopOfHome = false; } mTaskHistory.remove(task); @@ -1749,9 +1749,9 @@ final class ActivityStack { if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task, new RuntimeException("here").fillInStackTrace()); task.addActivityToTop(r); + task.setFrontOfTask(); r.putInHistory(); - r.frontOfTask = newTask; if (!isHomeStack() || numActivities() > 0) { // We want to show the starting preview window if we are // switching to a new task, or the next activity's process is @@ -2412,15 +2412,12 @@ final class ActivityStack { final ArrayList<ActivityRecord> activities = r.task.mActivities; final int index = activities.indexOf(r); if (index < (activities.size() - 1)) { - ActivityRecord next = activities.get(index+1); - if (r.frontOfTask) { - // The next activity is now the front of the task. - next.frontOfTask = true; - } + r.task.setFrontOfTask(); if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) { // If the caller asked that this activity (and all above it) // be cleared when the task is reset, don't lose that information, // but propagate it up to the next activity. + ActivityRecord next = activities.get(index+1); next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); } } @@ -2599,7 +2596,7 @@ final class ActivityStack { int res = mStackSupervisor.startActivityLocked(srec.app.thread, destIntent, null, aInfo, parent.appToken, null, 0, -1, parent.launchedFromUid, parent.launchedFromPackage, - 0, null, true, null); + 0, null, true, null, null); foundParentInTask = res == ActivityManager.START_SUCCESS; } catch (RemoteException e) { foundParentInTask = false; @@ -3051,7 +3048,7 @@ final class ActivityStack { return; } - mStackSupervisor.moveHomeStack(isHomeStack()); + moveToFront(); // Shift all activities with this task up to the top // of the stack, keeping them in the same internal order. @@ -3160,7 +3157,7 @@ final class ActivityStack { } final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null; - if (task == tr && task.mOnTopOfHome || numTasks <= 1) { + if (task == tr && tr.mOnTopOfHome || numTasks <= 1 && isOnHomeDisplay()) { tr.mOnTopOfHome = false; return mStackSupervisor.resumeHomeActivity(null); } diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 483b4a04390e..3afca668b809 100644 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -34,8 +34,11 @@ import static com.android.server.am.ActivityManagerService.TAG; import android.app.Activity; import android.app.ActivityManager; +import android.app.ActivityManager.StackInfo; import android.app.ActivityOptions; import android.app.AppGlobals; +import android.app.IActivityContainer; +import android.app.IActivityContainerCallback; import android.app.IActivityManager; import android.app.IApplicationThread; import android.app.IThumbnailReceiver; @@ -53,6 +56,11 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Configuration; +import android.graphics.Point; +import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManager.DisplayListener; +import android.hardware.display.DisplayManagerGlobal; +import android.hardware.display.VirtualDisplay; import android.os.Binder; import android.os.Bundle; import android.os.Debug; @@ -68,22 +76,26 @@ import android.os.SystemClock; import android.os.UserHandle; import android.util.EventLog; import android.util.Slog; -import android.util.SparseIntArray; +import android.util.SparseArray; +import android.util.SparseIntArray; +import android.view.Display; +import android.view.DisplayInfo; +import android.view.Surface; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.os.TransferPipe; import com.android.server.am.ActivityManagerService.PendingActivityLaunch; import com.android.server.am.ActivityStack.ActivityState; -import com.android.server.wm.StackBox; import com.android.server.wm.WindowManagerService; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; -public final class ActivityStackSupervisor { +public final class ActivityStackSupervisor implements DisplayListener { static final boolean DEBUG = ActivityManagerService.DEBUG || false; static final boolean DEBUG_ADD_REMOVE = DEBUG || false; static final boolean DEBUG_APP = DEBUG || false; @@ -107,19 +119,23 @@ public final class ActivityStackSupervisor { static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2; static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3; static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4; + static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5; + static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6; + static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7; + + private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay"; // For debugging to make sure the caller when acquiring/releasing our // wake lock is the system process. static final boolean VALIDATE_WAKE_LOCK_CALLER = false; final ActivityManagerService mService; - final Context mContext; - final Looper mLooper; final ActivityStackSupervisorHandler mHandler; /** Short cut */ WindowManagerService mWindowManager; + DisplayManager mDisplayManager; /** Dismiss the keyguard after the next activity is displayed? */ boolean mDismissKeyguardOnNextActivity = false; @@ -134,22 +150,17 @@ public final class ActivityStackSupervisor { /** The current user */ private int mCurrentUser; - /** The stack containing the launcher app */ + /** The stack containing the launcher app. Assumed to always be attached to + * Display.DEFAULT_DISPLAY. */ private ActivityStack mHomeStack; - /** The non-home stack currently receiving input or launching the next activity. If home is - * in front then mHomeStack overrides mFocusedStack. - * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */ + /** The stack currently receiving input or launching the next activity. */ private ActivityStack mFocusedStack; - /** All the non-launcher stacks */ - private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); - - private static final int STACK_STATE_HOME_IN_FRONT = 0; - private static final int STACK_STATE_HOME_TO_BACK = 1; - private static final int STACK_STATE_HOME_IN_BACK = 2; - private static final int STACK_STATE_HOME_TO_FRONT = 3; - private int mStackState = STACK_STATE_HOME_IN_FRONT; + /** If this is the same as mFocusedStack then the activity on the top of the focused stack has + * been resumed. If stacks are changing position this will hold the old stack until the new + * stack becomes resumed after which it will be set to mFocusedStack. */ + private ActivityStack mLastFocusedStack; /** List of activities that are waiting for a new activity to become visible before completing * whatever operation they are supposed to do. */ @@ -206,14 +217,19 @@ public final class ActivityStackSupervisor { /** Stack id of the front stack when user switched, indexed by userId. */ SparseIntArray mUserStackInFront = new SparseIntArray(2); - public ActivityStackSupervisor(ActivityManagerService service, Context context, - Looper looper) { + // TODO: Add listener for removal of references. + /** Mapping from (ActivityStack/TaskStack).mStackId to their current state */ + SparseArray<WeakReference<ActivityContainer>> mActivityContainers = + new SparseArray<WeakReference<ActivityContainer>>(); + + /** Mapping from displayId to display current state */ + private SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<ActivityDisplay>(); + + public ActivityStackSupervisor(ActivityManagerService service) { mService = service; - mContext = context; - mLooper = looper; - PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); + PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE); mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); - mHandler = new ActivityStackSupervisorHandler(looper); + mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper()); if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) { throw new IllegalStateException("Calling must be system uid"); } @@ -223,9 +239,23 @@ public final class ActivityStackSupervisor { } void setWindowManager(WindowManagerService wm) { - mWindowManager = wm; - mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID); - mStacks.add(mHomeStack); + synchronized (mService) { + mWindowManager = wm; + + mDisplayManager = + (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE); + mDisplayManager.registerDisplayListener(this, null); + + Display[] displays = mDisplayManager.getDisplays(); + for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) { + final int displayId = displays[displayNdx].getDisplayId(); + ActivityDisplay activityDisplay = new ActivityDisplay(displayId); + mActivityDisplays.put(displayId, activityDisplay); + } + + createStackOnDisplay(null, HOME_STACK_ID, Display.DEFAULT_DISPLAY); + mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID); + } } void dismissKeyguard() { @@ -237,43 +267,38 @@ public final class ActivityStackSupervisor { } ActivityStack getFocusedStack() { - if (mFocusedStack == null) { - return mHomeStack; - } - switch (mStackState) { - case STACK_STATE_HOME_IN_FRONT: - case STACK_STATE_HOME_TO_FRONT: - return mHomeStack; - case STACK_STATE_HOME_IN_BACK: - case STACK_STATE_HOME_TO_BACK: - default: - return mFocusedStack; - } + return mFocusedStack; } ActivityStack getLastStack() { - switch (mStackState) { - case STACK_STATE_HOME_IN_FRONT: - case STACK_STATE_HOME_TO_BACK: - return mHomeStack; - case STACK_STATE_HOME_TO_FRONT: - case STACK_STATE_HOME_IN_BACK: - default: - return mFocusedStack; - } + return mLastFocusedStack; } + // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the + // top of all visible stacks. boolean isFrontStack(ActivityStack stack) { - return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack()); + ArrayList<ActivityStack> stacks = stack.mStacks; + if (stacks != null && !stacks.isEmpty()) { + return stack == stacks.get(stacks.size() - 1); + } + return false; } void moveHomeStack(boolean toFront) { - final boolean homeInFront = isFrontStack(mHomeStack); - if (homeInFront ^ toFront) { - if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" + - stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ? - STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT)); - mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT; + ArrayList<ActivityStack> stacks = mHomeStack.mStacks; + int topNdx = stacks.size() - 1; + if (topNdx <= 0) { + return; + } + ActivityStack topStack = stacks.get(topNdx); + final boolean homeInFront = topStack == mHomeStack; + if (homeInFront != toFront) { + mLastFocusedStack = topStack; + stacks.remove(mHomeStack); + stacks.add(toFront ? topNdx : 0, mHomeStack); + mFocusedStack = stacks.get(topNdx); + if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: topStack old=" + topStack + " new=" + + mFocusedStack); } } @@ -301,21 +326,29 @@ public final class ActivityStackSupervisor { } TaskRecord anyTaskForIdLocked(int id) { - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - ActivityStack stack = mStacks.get(stackNdx); - TaskRecord task = stack.taskForIdLocked(id); - if (task != null) { - return task; + int numDisplays = mActivityDisplays.size(); + for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + ActivityStack stack = stacks.get(stackNdx); + TaskRecord task = stack.taskForIdLocked(id); + if (task != null) { + return task; + } } } return null; } ActivityRecord isInAnyStackLocked(IBinder token) { - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token); - if (r != null) { - return r; + int numDisplays = mActivityDisplays.size(); + for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityRecord r = stacks.get(stackNdx).isInStackLocked(token); + if (r != null) { + return r; + } } } return null; @@ -340,13 +373,12 @@ public final class ActivityStackSupervisor { } if (stack.removeTask(task) && !stack.isHomeStack()) { if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack); - mStacks.remove(stack); + stack.mActivityContainer.detachLocked(); final int stackId = stack.mStackId; final int nextStackId = mWindowManager.removeStack(stackId); // TODO: Perhaps we need to let the ActivityManager determine the next focus... - if (mFocusedStack == null || mFocusedStack.mStackId == stackId) { - // If this is the last app stack, set mFocusedStack to null. - mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId); + if (stack.isOnHomeDisplay()) { + mFocusedStack = getStack(nextStackId); } } } @@ -366,29 +398,29 @@ public final class ActivityStackSupervisor { return resumedActivity; } - boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception { - boolean didSomething = false; + boolean attachApplicationLocked(ProcessRecord app) throws Exception { final String processName = app.processName; - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (!isFrontStack(stack)) { - continue; - } - ActivityRecord hr = stack.topRunningActivityLocked(null); - if (hr != null) { - if (hr.app == null && app.uid == hr.info.applicationInfo.uid - && processName.equals(hr.processName)) { - try { - if (headless) { - Slog.e(TAG, "Starting activities not supported on headless device: " - + hr); - } else if (realStartActivityLocked(hr, app, true, true)) { - didSomething = true; + boolean didSomething = false; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + if (!isFrontStack(stack)) { + continue; + } + ActivityRecord hr = stack.topRunningActivityLocked(null); + if (hr != null) { + if (hr.app == null && app.uid == hr.info.applicationInfo.uid + && processName.equals(hr.processName)) { + try { + if (realStartActivityLocked(hr, app, true, true)) { + didSomething = true; + } + } catch (Exception e) { + Slog.w(TAG, "Exception in new application when starting activity " + + hr.intent.getComponent().flattenToShortString(), e); + throw e; } - } catch (Exception e) { - Slog.w(TAG, "Exception in new application when starting activity " - + hr.intent.getComponent().flattenToShortString(), e); - throw e; } } } @@ -400,53 +432,52 @@ public final class ActivityStackSupervisor { } boolean allResumedActivitiesIdle() { - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (!isFrontStack(stack)) { - continue; - } - final ActivityRecord resumedActivity = stack.mResumedActivity; - if (resumedActivity == null || !resumedActivity.idle) { - return false; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + if (!isFrontStack(stack)) { + continue; + } + final ActivityRecord resumedActivity = stack.mResumedActivity; + if (resumedActivity == null || !resumedActivity.idle) { + return false; + } } } return true; } boolean allResumedActivitiesComplete() { - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (isFrontStack(stack)) { - final ActivityRecord r = stack.mResumedActivity; - if (r != null && r.state != ActivityState.RESUMED) { - return false; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + if (isFrontStack(stack)) { + final ActivityRecord r = stack.mResumedActivity; + if (r != null && r.state != ActivityState.RESUMED) { + return false; + } } } } // TODO: Not sure if this should check if all Paused are complete too. - switch (mStackState) { - case STACK_STATE_HOME_TO_BACK: - if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" + - stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" + - stackStateToString(STACK_STATE_HOME_IN_BACK)); - mStackState = STACK_STATE_HOME_IN_BACK; - break; - case STACK_STATE_HOME_TO_FRONT: - if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" + - stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" + - stackStateToString(STACK_STATE_HOME_IN_FRONT)); - mStackState = STACK_STATE_HOME_IN_FRONT; - break; - } + if (DEBUG_STACK) Slog.d(TAG, + "allResumedActivitiesComplete: mLastFocusedStack changing from=" + + mLastFocusedStack + " to=" + mFocusedStack); + mLastFocusedStack = mFocusedStack; return true; } boolean allResumedActivitiesVisible() { - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - final ActivityRecord r = stack.mResumedActivity; - if (r != null && (!r.nowVisible || r.waitingVisible)) { - return false; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + final ActivityRecord r = stack.mResumedActivity; + if (r != null && (!r.nowVisible || r.waitingVisible)) { + return false; + } } } return true; @@ -459,13 +490,16 @@ public final class ActivityStackSupervisor { */ boolean pauseBackStacks(boolean userLeaving) { boolean someActivityPaused = false; - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (!isFrontStack(stack) && stack.mResumedActivity != null) { - if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack + - " mResumedActivity=" + stack.mResumedActivity); - stack.startPausingLocked(userLeaving, false); - someActivityPaused = true; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + if (!isFrontStack(stack) && stack.mResumedActivity != null) { + if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack + + " mResumedActivity=" + stack.mResumedActivity); + stack.startPausingLocked(userLeaving, false); + someActivityPaused = true; + } } } return someActivityPaused; @@ -473,17 +507,20 @@ public final class ActivityStackSupervisor { boolean allPausedActivitiesComplete() { boolean pausing = true; - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - final ActivityRecord r = stack.mPausingActivity; - if (r != null && r.state != ActivityState.PAUSED - && r.state != ActivityState.STOPPED - && r.state != ActivityState.STOPPING) { - if (DEBUG_STATES) { - Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state); - pausing = false; - } else { - return false; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + final ActivityRecord r = stack.mPausingActivity; + if (r != null && r.state != ActivityState.PAUSED + && r.state != ActivityState.STOPPED + && r.state != ActivityState.STOPPING) { + if (DEBUG_STATES) { + Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state); + pausing = false; + } else { + return false; + } } } } @@ -525,8 +562,10 @@ public final class ActivityStackSupervisor { return r; } - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); + // Return to the home stack. + final ArrayList<ActivityStack> stacks = mHomeStack.mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); if (stack != focusedStack && isFrontStack(stack)) { r = stack.topRunningActivityLocked(null); if (r != null) { @@ -542,15 +581,19 @@ public final class ActivityStackSupervisor { ActivityRecord r = null; // Gather all of the running tasks for each stack into runningTaskLists. - final int numStacks = mStacks.size(); - ArrayList<RunningTaskInfo>[] runningTaskLists = new ArrayList[numStacks]; - for (int stackNdx = numStacks - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>(); - runningTaskLists[stackNdx] = stackTaskList; - final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList); - if (isFrontStack(stack)) { - r = ar; + ArrayList<ArrayList<RunningTaskInfo>> runningTaskLists = + new ArrayList<ArrayList<RunningTaskInfo>>(); + final int numDisplays = mActivityDisplays.size(); + for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + ArrayList<RunningTaskInfo> stackTaskList = new ArrayList<RunningTaskInfo>(); + runningTaskLists.add(stackTaskList); + final ActivityRecord ar = stack.getTasksLocked(receiver, pending, stackTaskList); + if (r == null && isFrontStack(stack)) { + r = ar; + } } } @@ -559,8 +602,9 @@ public final class ActivityStackSupervisor { while (maxNum > 0) { long mostRecentActiveTime = Long.MIN_VALUE; ArrayList<RunningTaskInfo> selectedStackList = null; - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists[stackNdx]; + final int numTaskLists = runningTaskLists.size(); + for (int stackNdx = 0; stackNdx < numTaskLists; ++stackNdx) { + ArrayList<RunningTaskInfo> stackTaskList = runningTaskLists.get(stackNdx); if (!stackTaskList.isEmpty()) { final long lastActiveTime = stackTaskList.get(0).lastActiveTime; if (lastActiveTime > mostRecentActiveTime) { @@ -630,14 +674,14 @@ public final class ActivityStackSupervisor { void startHomeActivity(Intent intent, ActivityInfo aInfo) { moveHomeToTop(); startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0, - null, false, null); + null, false, null, null); } final int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config, - Bundle options, int userId) { + Bundle options, int userId, IActivityContainer iContainer) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); @@ -651,6 +695,7 @@ public final class ActivityStackSupervisor { ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profileFile, profileFd, userId); + ActivityContainer container = (ActivityContainer)iContainer; synchronized (mService) { int callingPid; if (callingUid >= 0) { @@ -662,7 +707,12 @@ public final class ActivityStackSupervisor { callingPid = callingUid = -1; } - final ActivityStack stack = getFocusedStack(); + final ActivityStack stack; + if (container == null || container.mStack.isOnHomeDisplay()) { + stack = getFocusedStack(); + } else { + stack = container.mStack; + } stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0; if (DEBUG_CONFIGURATION) Slog.v(TAG, @@ -738,9 +788,9 @@ public final class ActivityStackSupervisor { } } - int res = startActivityLocked(caller, intent, resolvedType, - aInfo, resultTo, resultWho, requestCode, callingPid, callingUid, - callingPackage, startFlags, options, componentSpecified, null); + int res = startActivityLocked(caller, intent, resolvedType, aInfo, resultTo, resultWho, + requestCode, callingPid, callingUid, callingPackage, startFlags, options, + componentSpecified, null, container); if (stack.mConfigWillChange) { // If the caller also wants to switch to a new configuration, @@ -855,7 +905,7 @@ public final class ActivityStackSupervisor { } int res = startActivityLocked(caller, intent, resolvedTypes[i], aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage, - 0, theseOptions, componentSpecified, outActivity); + 0, theseOptions, componentSpecified, outActivity, null); if (res < 0) { return res; } @@ -1079,7 +1129,7 @@ public final class ActivityStackSupervisor { Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, - boolean componentSpecified, ActivityRecord[] outActivity) { + boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container) { int err = ActivityManager.START_SUCCESS; ProcessRecord callerApp = null; @@ -1214,8 +1264,8 @@ public final class ActivityStackSupervisor { } ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, - intent, resolvedType, aInfo, mService.mConfiguration, - resultRecord, resultWho, requestCode, componentSpecified, this); + intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, + requestCode, componentSpecified, this, container); if (outActivity != null) { outActivity[0] = r; } @@ -1263,25 +1313,35 @@ public final class ActivityStackSupervisor { if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) { if (task != null) { final ActivityStack taskStack = task.stack; - if (mFocusedStack != taskStack) { - if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, - "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task); - mFocusedStack = taskStack.isHomeStack() ? null : taskStack; - } else { - if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, - "adjustStackFocus: Focused stack already=" + mFocusedStack); + if (taskStack.isOnHomeDisplay()) { + if (mFocusedStack != taskStack) { + if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " + + "focused stack to r=" + r + " task=" + task); + mFocusedStack = taskStack; + } else { + if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, + "adjustStackFocus: Focused stack already=" + mFocusedStack); + } } return taskStack; } - if (mFocusedStack != null) { + final ActivityContainer container = r.mInitialActivityContainer; + if (container != null) { + // The first time put it on the desired stack, after this put on task stack. + r.mInitialActivityContainer = null; + return container.mStack; + } + + if (mFocusedStack != mHomeStack) { if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Have a focused stack=" + mFocusedStack); return mFocusedStack; } - for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) { - ActivityStack stack = mStacks.get(stackNdx); + final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks; + for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = homeDisplayStacks.get(stackNdx); if (!stack.isHomeStack()) { if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting focused stack=" + stack); @@ -1290,9 +1350,8 @@ public final class ActivityStackSupervisor { } } - // Time to create the first app stack for this user. - int stackId = - mService.createStack(-1, HOME_STACK_ID, StackBox.TASK_STACK_GOES_OVER, 1.0f); + // Need to create an app stack for this user. + int stackId = createStackOnDisplay(null, getNextStackId(), Display.DEFAULT_DISPLAY); if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r + " stackId=" + stackId); mFocusedStack = getStack(stackId); @@ -1302,30 +1361,10 @@ public final class ActivityStackSupervisor { } void setFocusedStack(ActivityRecord r) { - if (r == null) { - return; - } - if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) { - if (mStackState != STACK_STATE_HOME_IN_FRONT) { - if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" + - stackStateToString(mStackState) + " new=" + - stackStateToString(STACK_STATE_HOME_TO_FRONT) + - " Callers=" + Debug.getCallers(3)); - mStackState = STACK_STATE_HOME_TO_FRONT; - } - } else { - if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, - "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task + - " Callers=" + Debug.getCallers(3)); - final ActivityStack taskStack = r.task.stack; - mFocusedStack = taskStack.isHomeStack() ? null : taskStack; - if (mStackState != STACK_STATE_HOME_IN_BACK) { - if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" + - stackStateToString(mStackState) + " new=" + - stackStateToString(STACK_STATE_HOME_TO_BACK) + - " Callers=" + Debug.getCallers(3)); - mStackState = STACK_STATE_HOME_TO_BACK; - } + if (r != null) { + final boolean isHomeActivity = + !r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask()); + moveHomeStack(isHomeActivity); } } @@ -1452,7 +1491,7 @@ public final class ActivityStackSupervisor { targetStack.mLastPausedActivity = null; if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack + " from " + intentActivity); - moveHomeStack(targetStack.isHomeStack()); + targetStack.moveToFront(); if (intentActivity.task.intent == null) { // This task was started because of movement of // the activity based on affinity... now that we @@ -1637,15 +1676,9 @@ public final class ActivityStackSupervisor { // We don't need to start a new activity, and // the client said not to do anything if that // is the case, so this is it! - if (r.task == null) Slog.v(TAG, - "startActivityUncheckedLocked: task left null", - new RuntimeException("here").fillInStackTrace()); return ActivityManager.START_RETURN_INTENT_TO_CALLER; } top.deliverNewIntentLocked(callingUid, r.intent); - if (r.task == null) Slog.v(TAG, - "startActivityUncheckedLocked: task left null", - new RuntimeException("here").fillInStackTrace()); return ActivityManager.START_DELIVERED_TO_TOP; } } @@ -1658,9 +1691,6 @@ public final class ActivityStackSupervisor { r.requestCode, Activity.RESULT_CANCELED, null); } ActivityOptions.abort(options); - if (r.task == null) Slog.v(TAG, - "startActivityUncheckedLocked: task left null", - new RuntimeException("here").fillInStackTrace()); return ActivityManager.START_CLASS_NOT_FOUND; } @@ -1671,7 +1701,7 @@ public final class ActivityStackSupervisor { if (r.resultTo == null && !addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { targetStack = adjustStackFocus(r); - moveHomeStack(targetStack.isHomeStack()); + targetStack.moveToFront(); if (reuseTask == null) { r.setTask(targetStack.createTaskRecord(getNextTaskId(), newTaskInfo != null ? newTaskInfo : r.info, @@ -1689,13 +1719,13 @@ public final class ActivityStackSupervisor { == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { // Caller wants to appear on home activity, so before starting // their own activity we will bring home to the front. - r.task.mOnTopOfHome = true; + r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay(); } } } else if (sourceRecord != null) { TaskRecord sourceTask = sourceRecord.task; targetStack = sourceTask.stack; - moveHomeStack(targetStack.isHomeStack()); + targetStack.moveToFront(); if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { // In this case, we are adding the activity to an existing @@ -1749,7 +1779,7 @@ public final class ActivityStackSupervisor { // of a new task... just put it in the top task, though these days // this case should never happen. targetStack = adjustStackFocus(r); - moveHomeStack(targetStack.isHomeStack()); + targetStack.moveToFront(); ActivityRecord prev = targetStack.topActivity(); r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true), @@ -1941,17 +1971,21 @@ public final class ActivityStackSupervisor { boolean handleAppDiedLocked(ProcessRecord app) { boolean hasVisibleActivities = false; - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - hasVisibleActivities |= mStacks.get(stackNdx).handleAppDiedLocked(app); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + hasVisibleActivities |= stacks.get(stackNdx).handleAppDiedLocked(app); + } } return hasVisibleActivities; } void closeSystemDialogsLocked() { - final int numStacks = mStacks.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - stack.closeSystemDialogsLocked(); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + stacks.get(stackNdx).closeSystemDialogsLocked(); + } } } @@ -1964,11 +1998,14 @@ public final class ActivityStackSupervisor { */ boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { boolean didSomething = false; - final int numStacks = mStacks.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { - didSomething = true; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + final int numStacks = stacks.size(); + for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { + didSomething = true; + } } } return didSomething; @@ -1983,15 +2020,18 @@ public final class ActivityStackSupervisor { // we don't blow away the previous app if this activity is being // hosted by the process that is actually still the foreground. ProcessRecord fgApp = null; - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (isFrontStack(stack)) { - if (stack.mResumedActivity != null) { - fgApp = stack.mResumedActivity.app; - } else if (stack.mPausingActivity != null) { - fgApp = stack.mPausingActivity.app; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + if (isFrontStack(stack)) { + if (stack.mResumedActivity != null) { + fgApp = stack.mResumedActivity.app; + } else if (stack.mPausingActivity != null) { + fgApp = stack.mPausingActivity.app; + } + break; } - break; } } @@ -2015,13 +2055,16 @@ public final class ActivityStackSupervisor { targetStack = getFocusedStack(); } boolean result = false; - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (isFrontStack(stack)) { - if (stack == targetStack) { - result = stack.resumeTopActivityLocked(target, targetOptions); - } else { - stack.resumeTopActivityLocked(null); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + if (isFrontStack(stack)) { + if (stack == targetStack) { + result = stack.resumeTopActivityLocked(target, targetOptions); + } else { + stack.resumeTopActivityLocked(null); + } } } } @@ -2029,38 +2072,96 @@ public final class ActivityStackSupervisor { } void finishTopRunningActivityLocked(ProcessRecord app) { - final int numStacks = mStacks.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - stack.finishTopRunningActivityLocked(app); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + final int numStacks = stacks.size(); + for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + stack.finishTopRunningActivityLocked(app); + } } } void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { - if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" + - mStacks.get(stackNdx)); - return; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) { + if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" + + stacks.get(stackNdx)); + return; + } } } } ActivityStack getStack(int stackId) { - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (stack.getStackId() == stackId) { - return stack; + WeakReference<ActivityContainer> weakReference = mActivityContainers.get(stackId); + if (weakReference != null) { + ActivityContainer activityContainer = weakReference.get(); + if (activityContainer != null) { + return activityContainer.mStack; + } else { + mActivityContainers.remove(stackId); } } return null; } ArrayList<ActivityStack> getStacks() { - return new ArrayList<ActivityStack>(mStacks); + ArrayList<ActivityStack> allStacks = new ArrayList<ActivityStack>(); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + allStacks.addAll(mActivityDisplays.valueAt(displayNdx).mStacks); + } + return allStacks; + } + + IBinder getHomeActivityToken() { + final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks(); + for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { + final TaskRecord task = tasks.get(taskNdx); + if (task.isHomeTask()) { + final ArrayList<ActivityRecord> activities = task.mActivities; + for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { + final ActivityRecord r = activities.get(activityNdx); + if (r.isHomeActivity()) { + return r.appToken; + } + } + } + } + return null; + } + + ActivityContainer createActivityContainer(ActivityRecord parentActivity, int stackId, + IActivityContainerCallback callback) { + ActivityContainer activityContainer = new ActivityContainer(parentActivity, stackId, + callback); + mActivityContainers.put(stackId, new WeakReference<ActivityContainer>(activityContainer)); + if (parentActivity != null) { + parentActivity.mChildContainers.add(activityContainer.mStack); + } + return activityContainer; } - int createStack() { + ActivityContainer createActivityContainer(ActivityRecord parentActivity, + IActivityContainerCallback callback) { + return createActivityContainer(parentActivity, getNextStackId(), callback); + } + + private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) { + ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + if (activityDisplay == null) { + return -1; + } + + ActivityContainer activityContainer = + createActivityContainer(parentActivity, stackId, null); + activityContainer.attachToDisplayLocked(activityDisplay); + return stackId; + } + + int getNextStackId() { while (true) { if (++mLastStackId <= HOME_STACK_ID) { mLastStackId = HOME_STACK_ID + 1; @@ -2069,7 +2170,6 @@ public final class ActivityStackSupervisor { break; } } - mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); return mLastStackId; } @@ -2091,15 +2191,18 @@ public final class ActivityStackSupervisor { ActivityRecord findTaskLocked(ActivityRecord r) { if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r); - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (!r.isApplicationActivity() && !stack.isHomeStack()) { - if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack); - continue; - } - final ActivityRecord ar = stack.findTaskLocked(r); - if (ar != null) { - return ar; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + if (!r.isApplicationActivity() && !stack.isHomeStack()) { + if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack); + continue; + } + final ActivityRecord ar = stack.findTaskLocked(r); + if (ar != null) { + return ar; + } } } if (DEBUG_TASKS) Slog.d(TAG, "No task found"); @@ -2107,10 +2210,13 @@ public final class ActivityStackSupervisor { } ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) { - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info); - if (ar != null) { - return ar; + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityRecord ar = stacks.get(stackNdx).findActivityLocked(intent, info); + if (ar != null) { + return ar; + } } } return null; @@ -2138,8 +2244,11 @@ public final class ActivityStackSupervisor { final long endTime = System.currentTimeMillis() + timeout; while (true) { boolean cantShutdown = false; - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked(); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + cantShutdown |= stacks.get(stackNdx).checkReadyForSleepLocked(); + } } if (cantShutdown) { long timeRemaining = endTime - System.currentTimeMillis(); @@ -2170,11 +2279,14 @@ public final class ActivityStackSupervisor { if (mGoingToSleep.isHeld()) { mGoingToSleep.release(); } - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - stack.awakeFromSleepingLocked(); - if (isFrontStack(stack)) { - resumeTopActivitiesLocked(); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + stack.awakeFromSleepingLocked(); + if (isFrontStack(stack)) { + resumeTopActivitiesLocked(); + } } } mGoingToSleepActivities.clear(); @@ -2193,8 +2305,11 @@ public final class ActivityStackSupervisor { if (!mSleepTimeout) { boolean dontSleep = false; - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked(); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + dontSleep |= stacks.get(stackNdx).checkReadyForSleepLocked(); + } } if (mStoppingActivities.size() > 0) { @@ -2217,8 +2332,11 @@ public final class ActivityStackSupervisor { } } - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - mStacks.get(stackNdx).goToSleep(); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + stacks.get(stackNdx).goToSleep(); + } } removeSleepTimeouts(); @@ -2245,37 +2363,45 @@ public final class ActivityStackSupervisor { } void handleAppCrashLocked(ProcessRecord app) { - final int numStacks = mStacks.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - stack.handleAppCrashLocked(app); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + final int numStacks = stacks.size(); + for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + stack.handleAppCrashLocked(app); + } } } void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) { // First the front stacks. In case any are not fullscreen and are in front of home. boolean showHomeBehindStack = false; - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (isFrontStack(stack)) { - showHomeBehindStack = - stack.ensureActivitiesVisibleLocked(starting, configChanges); - } - } - // Now do back stacks. - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - if (!isFrontStack(stack)) { - stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + final int topStackNdx = stacks.size() - 1; + for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + if (stackNdx == topStackNdx) { + // Top stack. + showHomeBehindStack = + stack.ensureActivitiesVisibleLocked(starting, configChanges); + } else { + // Back stack. + stack.ensureActivitiesVisibleLocked(starting, configChanges, + showHomeBehindStack); + } } } } void scheduleDestroyAllActivities(ProcessRecord app, String reason) { - final int numStacks = mStacks.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - stack.scheduleDestroyActivities(app, false, reason); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + final int numStacks = stacks.size(); + for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + stack.scheduleDestroyActivities(app, false, reason); + } } } @@ -2285,8 +2411,13 @@ public final class ActivityStackSupervisor { mCurrentUser = userId; mStartingUsers.add(uss); - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - mStacks.get(stackNdx).switchUserLocked(userId); + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + stack.switchUserLocked(userId); + mWindowManager.moveTaskToTop(stack.topTask().taskId); + } } ActivityStack stack = getStack(restoreStackId); @@ -2294,8 +2425,13 @@ public final class ActivityStackSupervisor { stack = mHomeStack; } final boolean homeInFront = stack.isHomeStack(); - moveHomeStack(homeInFront); - mWindowManager.moveTaskToTop(stack.topTask().taskId); + if (stack.isOnHomeDisplay()) { + moveHomeStack(homeInFront); + mWindowManager.moveTaskToTop(stack.topTask().taskId); + } else { + // Stack was moved to another display while user was swapped out. + resumeHomeActivity(null); + } return homeInFront; } @@ -2340,8 +2476,9 @@ public final class ActivityStackSupervisor { } void validateTopActivitiesLocked() { - for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); + // FIXME +/* for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); final ActivityRecord r = stack.topRunningActivityLocked(null); final ActivityState state = r == null ? ActivityState.DESTROYED : r.state; if (isFrontStack(stack)) { @@ -2371,23 +2508,14 @@ public final class ActivityStackSupervisor { } } } - } - - private static String stackStateToString(int stackState) { - switch (stackState) { - case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT"; - case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK"; - case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK"; - case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT"; - default: return "Unknown stackState=" + stackState; - } +*/ } public void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity="); pw.println(mDismissKeyguardOnNextActivity); pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); - pw.print(" mStackState="); pw.println(stackStateToString(mStackState)); + pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId); pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront); @@ -2416,42 +2544,48 @@ public final class ActivityStackSupervisor { boolean dumpClient, String dumpPackage) { boolean printed = false; boolean needSep = false; - final int numStacks = mStacks.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - final ActivityStack stack = mStacks.get(stackNdx); - StringBuilder stackHeader = new StringBuilder(128); - stackHeader.append(" Stack #"); - stackHeader.append(mStacks.indexOf(stack)); - stackHeader.append(":"); - printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep, - stackHeader.toString()); - printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, - false, dumpPackage, true, " Running activities (most recent first):", null); - - needSep = printed; - boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, - " mPausingActivity: "); - if (pr) { - printed = true; - needSep = false; - } - pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, - " mResumedActivity: "); - if (pr) { - printed = true; - needSep = false; - } - if (dumpAll) { - pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, - " mLastPausedActivity: "); + for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { + ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx); + pw.print("Display #"); pw.println(activityDisplay.mDisplayId); + ArrayList<ActivityStack> stacks = activityDisplay.mStacks; + final int numStacks = stacks.size(); + for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + StringBuilder stackHeader = new StringBuilder(128); + stackHeader.append(" Stack #"); + stackHeader.append(stack.mStackId); + stackHeader.append(":"); + printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, + needSep, stackHeader.toString()); + printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, + !dumpAll, false, dumpPackage, true, + " Running activities (most recent first):", null); + + needSep = printed; + boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep, + " mPausingActivity: "); + if (pr) { + printed = true; + needSep = false; + } + pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, + " mResumedActivity: "); if (pr) { printed = true; - needSep = true; + needSep = false; } - printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, - needSep, " mLastNoHistoryActivity: "); + if (dumpAll) { + pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep, + " mLastPausedActivity: "); + if (pr) { + printed = true; + needSep = true; + } + printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, + needSep, " mLastNoHistoryActivity: "); + } + needSep = printed; } - needSep = printed; } printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, @@ -2581,6 +2715,101 @@ public final class ActivityStackSupervisor { mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT); } + @Override + public void onDisplayAdded(int displayId) { + mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); + } + + @Override + public void onDisplayRemoved(int displayId) { + mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); + } + + @Override + public void onDisplayChanged(int displayId) { + mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); + } + + public void handleDisplayAddedLocked(int displayId) { + boolean newDisplay; + synchronized (mService) { + newDisplay = mActivityDisplays.get(displayId) == null; + if (newDisplay) { + ActivityDisplay activityDisplay = new ActivityDisplay(displayId); + mActivityDisplays.put(displayId, activityDisplay); + } + } + if (newDisplay) { + mWindowManager.onDisplayAdded(displayId); + } + } + + public void handleDisplayRemovedLocked(int displayId) { + synchronized (mService) { + ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + if (activityDisplay != null) { + ArrayList<ActivityStack> stacks = activityDisplay.mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + activityDisplay.detachActivitiesLocked(stacks.get(stackNdx)); + } + mActivityDisplays.remove(displayId); + } + } + mWindowManager.onDisplayRemoved(displayId); + } + + public void handleDisplayChangedLocked(int displayId) { + synchronized (mService) { + ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + if (activityDisplay != null) { + // TODO: Update the bounds. + } + } + mWindowManager.onDisplayChanged(displayId); + } + + StackInfo getStackInfo(ActivityStack stack) { + StackInfo info = new StackInfo(); + mWindowManager.getStackBounds(stack.mStackId, info.bounds); + info.displayId = Display.DEFAULT_DISPLAY; + info.stackId = stack.mStackId; + + ArrayList<TaskRecord> tasks = stack.getAllTasks(); + final int numTasks = tasks.size(); + int[] taskIds = new int[numTasks]; + String[] taskNames = new String[numTasks]; + for (int i = 0; i < numTasks; ++i) { + final TaskRecord task = tasks.get(i); + taskIds[i] = task.taskId; + taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() + : task.realActivity != null ? task.realActivity.flattenToString() + : task.getTopActivity() != null ? task.getTopActivity().packageName + : "unknown"; + } + info.taskIds = taskIds; + info.taskNames = taskNames; + return info; + } + + StackInfo getStackInfoLocked(int stackId) { + ActivityStack stack = getStack(stackId); + if (stack != null) { + return getStackInfo(stack); + } + return null; + } + + ArrayList<StackInfo> getAllStackInfosLocked() { + ArrayList<StackInfo> list = new ArrayList<StackInfo>(); + for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int ndx = stacks.size() - 1; ndx >= 0; --ndx) { + list.add(getStackInfo(stacks.get(ndx))); + } + } + return list; + } + private final class ActivityStackSupervisorHandler extends Handler { public ActivityStackSupervisorHandler(Looper looper) { @@ -2644,7 +2873,203 @@ public final class ActivityStackSupervisor { } } } break; + case HANDLE_DISPLAY_ADDED: { + handleDisplayAddedLocked(msg.arg1); + } break; + case HANDLE_DISPLAY_CHANGED: { + handleDisplayChangedLocked(msg.arg1); + } break; + case HANDLE_DISPLAY_REMOVED: { + handleDisplayRemovedLocked(msg.arg1); + } break; + } + } + } + + class ActivityContainer extends IActivityContainer.Stub { + final int mStackId; + final IActivityContainerCallback mCallback; + final ActivityStack mStack; + final ActivityRecord mParentActivity; + + /** Display this ActivityStack is currently on. Null if not attached to a Display. */ + ActivityDisplay mActivityDisplay; + + ActivityContainer(ActivityRecord parentActivity, int stackId, + IActivityContainerCallback callback) { + synchronized (mService) { + mStackId = stackId; + mStack = new ActivityStack(this); + mParentActivity = parentActivity; + mCallback = callback; } } + + void attachToDisplayLocked(ActivityDisplay activityDisplay) { + mActivityDisplay = activityDisplay; + mStack.mDisplayId = activityDisplay.mDisplayId; + mStack.mStacks = activityDisplay.mStacks; + + activityDisplay.attachActivities(mStack); + mWindowManager.createStack(mStackId, activityDisplay.mDisplayId); + } + + @Override + public void attachToDisplay(int displayId) throws RemoteException { + synchronized (mService) { + ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + if (activityDisplay == null) { + return; + } + attachToDisplayLocked(activityDisplay); + } + } + + @Override + public int getDisplayId() throws RemoteException { + if (mActivityDisplay != null) { + return mActivityDisplay.mDisplayId; + } + return -1; + } + + void detachLocked() { + if (mActivityDisplay != null) { + mActivityDisplay.detachActivitiesLocked(mStack); + mActivityDisplay = null; + mStack.mDisplayId = -1; + mStack.mStacks = null; + } + } + + @Override + public void detachFromDisplay() throws RemoteException { + synchronized (mService) { + detachLocked(); + } + } + + @Override + public final int startActivity(Intent intent) { + mService.enforceNotIsolatedCaller("ActivityContainer"); + int userId = mService.handleIncomingUser(Binder.getCallingPid(), + Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); + // TODO: Switch to user app stacks here. + String mimeType = intent.getType(); + if (mimeType == null && intent.getData() != null + && "content".equals(intent.getData().getScheme())) { + mimeType = mService.getProviderMimeType(intent.getData(), userId); + } + return startActivityMayWait(null, -1, null, intent, mimeType, null, null, 0, 0, null, + null, null, null, null, userId, this); + } + + @Override + public IBinder asBinder() { + return this; + } + + @Override + public void createActivityView(Surface surface, int width, int height, int density) { + DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); + VirtualDisplay virtualDisplay; + long ident = Binder.clearCallingIdentity(); + try { + virtualDisplay = dm.createVirtualDisplay(mService.mContext, + VIRTUAL_DISPLAY_BASE_NAME, width, height, density, surface, + DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | + DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); + } finally { + Binder.restoreCallingIdentity(ident); + } + + final Display display = virtualDisplay.getDisplay(); + final int displayId = display.getDisplayId(); + + mWindowManager.handleDisplayAdded(displayId); + + synchronized (mService) { + ActivityDisplay activityDisplay = new ActivityDisplay(display); + mActivityDisplays.put(displayId, activityDisplay); + attachToDisplayLocked(activityDisplay); + activityDisplay.mVirtualDisplay = virtualDisplay; + } + } + + @Override + public void deleteActivityView() { + synchronized (mService) { + if (!isAttached()) { + return; + } + VirtualDisplay virtualDisplay = mActivityDisplay.mVirtualDisplay; + if (virtualDisplay != null) { + virtualDisplay.release(); + mActivityDisplay.mVirtualDisplay = null; + } + detachLocked(); + } + } + + ActivityStackSupervisor getOuter() { + return ActivityStackSupervisor.this; + } + + boolean isAttached() { + return mActivityDisplay != null; + } + + void getBounds(Point outBounds) { + if (mActivityDisplay != null) { + mActivityDisplay.getBounds(outBounds); + } else { + outBounds.set(0, 0); + } + } + } + + /** Exactly one of these classes per Display in the system. Capable of holding zero or more + * attached {@link ActivityStack}s */ + final class ActivityDisplay { + /** Actual Display this object tracks. */ + final int mDisplayId; + final Display mDisplay; + final DisplayInfo mDisplayInfo = new DisplayInfo(); + + /** All of the stacks on this display. Order matters, topmost stack is in front of all other + * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ + final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); + + /** If this display is for an ActivityView then the VirtualDisplay created for it is stored + * here. */ + VirtualDisplay mVirtualDisplay; + + ActivityDisplay(int displayId) { + this(mDisplayManager.getDisplay(displayId)); + } + + ActivityDisplay(Display display) { + mDisplay = display; + mDisplayId = display.getDisplayId(); + mDisplay.getDisplayInfo(mDisplayInfo); + } + + void attachActivities(ActivityStack stack) { + if (DEBUG_STACK) Slog.v(TAG, "attachActivities: attaching " + stack + " to displayId=" + + mDisplayId); + mStacks.add(stack); + } + + void detachActivitiesLocked(ActivityStack stack) { + if (DEBUG_STACK) Slog.v(TAG, "attachActivities: detaching " + stack + + " from displayId=" + mDisplayId); + mStacks.remove(stack); + } + + void getBounds(Point bounds) { + mDisplay.getDisplayInfo(mDisplayInfo); + bounds.x = mDisplayInfo.appWidth; + bounds.y = mDisplayInfo.appHeight; + } } } diff --git a/services/java/com/android/server/am/AppBindRecord.java b/services/core/java/com/android/server/am/AppBindRecord.java index 06265fd6856d..06265fd6856d 100644 --- a/services/java/com/android/server/am/AppBindRecord.java +++ b/services/core/java/com/android/server/am/AppBindRecord.java diff --git a/services/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java index 0ba62c53dcd9..0ba62c53dcd9 100644 --- a/services/java/com/android/server/am/AppErrorDialog.java +++ b/services/core/java/com/android/server/am/AppErrorDialog.java diff --git a/services/java/com/android/server/am/AppErrorResult.java b/services/core/java/com/android/server/am/AppErrorResult.java index c6a5720b537e..c6a5720b537e 100644 --- a/services/java/com/android/server/am/AppErrorResult.java +++ b/services/core/java/com/android/server/am/AppErrorResult.java diff --git a/services/java/com/android/server/am/AppNotRespondingDialog.java b/services/core/java/com/android/server/am/AppNotRespondingDialog.java index f4c166421c35..f4c166421c35 100644 --- a/services/java/com/android/server/am/AppNotRespondingDialog.java +++ b/services/core/java/com/android/server/am/AppNotRespondingDialog.java diff --git a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java b/services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java index 27865a88da99..27865a88da99 100644 --- a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java +++ b/services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java diff --git a/services/java/com/android/server/am/BackupRecord.java b/services/core/java/com/android/server/am/BackupRecord.java index 5fa7e6a37133..5fa7e6a37133 100644 --- a/services/java/com/android/server/am/BackupRecord.java +++ b/services/core/java/com/android/server/am/BackupRecord.java diff --git a/services/java/com/android/server/am/BaseErrorDialog.java b/services/core/java/com/android/server/am/BaseErrorDialog.java index 6ede8f865065..6ede8f865065 100644 --- a/services/java/com/android/server/am/BaseErrorDialog.java +++ b/services/core/java/com/android/server/am/BaseErrorDialog.java diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 2d596788a829..2d596788a829 100644 --- a/services/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java diff --git a/services/java/com/android/server/am/BroadcastFilter.java b/services/core/java/com/android/server/am/BroadcastFilter.java index 986b8ea3c41f..986b8ea3c41f 100644 --- a/services/java/com/android/server/am/BroadcastFilter.java +++ b/services/core/java/com/android/server/am/BroadcastFilter.java diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index bfb667f8aca0..bfb667f8aca0 100644 --- a/services/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java index b2cfd7a87242..b2cfd7a87242 100644 --- a/services/java/com/android/server/am/BroadcastRecord.java +++ b/services/core/java/com/android/server/am/BroadcastRecord.java diff --git a/services/java/com/android/server/am/CompatModeDialog.java b/services/core/java/com/android/server/am/CompatModeDialog.java index 202cc7cad79d..202cc7cad79d 100644 --- a/services/java/com/android/server/am/CompatModeDialog.java +++ b/services/core/java/com/android/server/am/CompatModeDialog.java diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java index 4d5577bdbd69..4d5577bdbd69 100644 --- a/services/java/com/android/server/am/CompatModePackages.java +++ b/services/core/java/com/android/server/am/CompatModePackages.java diff --git a/services/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java index 423e540229db..423e540229db 100644 --- a/services/java/com/android/server/am/ConnectionRecord.java +++ b/services/core/java/com/android/server/am/ConnectionRecord.java diff --git a/services/java/com/android/server/am/ContentProviderConnection.java b/services/core/java/com/android/server/am/ContentProviderConnection.java index f2c9e2fd2297..f2c9e2fd2297 100644 --- a/services/java/com/android/server/am/ContentProviderConnection.java +++ b/services/core/java/com/android/server/am/ContentProviderConnection.java diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/core/java/com/android/server/am/ContentProviderRecord.java index 646b7d2994de..646b7d2994de 100644 --- a/services/java/com/android/server/am/ContentProviderRecord.java +++ b/services/core/java/com/android/server/am/ContentProviderRecord.java diff --git a/services/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java index 10ea67c34465..10ea67c34465 100644 --- a/services/java/com/android/server/am/CoreSettingsObserver.java +++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java diff --git a/services/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags index d3cc56b53028..d3cc56b53028 100644 --- a/services/java/com/android/server/am/EventLogTags.logtags +++ b/services/core/java/com/android/server/am/EventLogTags.logtags diff --git a/services/java/com/android/server/am/FactoryErrorDialog.java b/services/core/java/com/android/server/am/FactoryErrorDialog.java index f4632c135dfc..f4632c135dfc 100644 --- a/services/java/com/android/server/am/FactoryErrorDialog.java +++ b/services/core/java/com/android/server/am/FactoryErrorDialog.java diff --git a/services/java/com/android/server/am/IntentBindRecord.java b/services/core/java/com/android/server/am/IntentBindRecord.java index 21cf266c62b1..21cf266c62b1 100644 --- a/services/java/com/android/server/am/IntentBindRecord.java +++ b/services/core/java/com/android/server/am/IntentBindRecord.java diff --git a/services/java/com/android/server/am/LaunchWarningWindow.java b/services/core/java/com/android/server/am/LaunchWarningWindow.java index 30c306655af0..30c306655af0 100644 --- a/services/java/com/android/server/am/LaunchWarningWindow.java +++ b/services/core/java/com/android/server/am/LaunchWarningWindow.java diff --git a/services/java/com/android/server/am/NativeCrashListener.java b/services/core/java/com/android/server/am/NativeCrashListener.java index 2c7f1f13098b..2c7f1f13098b 100644 --- a/services/java/com/android/server/am/NativeCrashListener.java +++ b/services/core/java/com/android/server/am/NativeCrashListener.java diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 17f24a928b90..17f24a928b90 100644 --- a/services/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java diff --git a/services/java/com/android/server/am/PendingThumbnailsRecord.java b/services/core/java/com/android/server/am/PendingThumbnailsRecord.java index e4eb4d04c155..e4eb4d04c155 100644 --- a/services/java/com/android/server/am/PendingThumbnailsRecord.java +++ b/services/core/java/com/android/server/am/PendingThumbnailsRecord.java diff --git a/services/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index f5920c8db355..f5920c8db355 100644 --- a/services/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java diff --git a/services/java/com/android/server/am/ProcessMemInfo.java b/services/core/java/com/android/server/am/ProcessMemInfo.java index c94694e7c4b1..c94694e7c4b1 100644 --- a/services/java/com/android/server/am/ProcessMemInfo.java +++ b/services/core/java/com/android/server/am/ProcessMemInfo.java diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 217a8d6159a1..217a8d6159a1 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java index e05fcda70ff0..e05fcda70ff0 100644 --- a/services/java/com/android/server/am/ProcessStatsService.java +++ b/services/core/java/com/android/server/am/ProcessStatsService.java diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/core/java/com/android/server/am/ProviderMap.java index 7da8c48dea35..7da8c48dea35 100644 --- a/services/java/com/android/server/am/ProviderMap.java +++ b/services/core/java/com/android/server/am/ProviderMap.java diff --git a/services/java/com/android/server/am/ReceiverList.java b/services/core/java/com/android/server/am/ReceiverList.java index fa8c1dfc4fda..fa8c1dfc4fda 100644 --- a/services/java/com/android/server/am/ReceiverList.java +++ b/services/core/java/com/android/server/am/ReceiverList.java diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 80e6e9497ece..cb04835dce53 100644 --- a/services/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -18,7 +18,8 @@ package com.android.server.am; import com.android.internal.app.ProcessStats; import com.android.internal.os.BatteryStatsImpl; -import com.android.server.NotificationManagerService; +import com.android.server.LocalServices; +import com.android.server.notification.NotificationManagerInternal; import android.app.INotificationManager; import android.app.Notification; @@ -427,8 +428,8 @@ final class ServiceRecord extends Binder { final Notification localForegroundNoti = foregroundNoti; ams.mHandler.post(new Runnable() { public void run() { - NotificationManagerService nm = - (NotificationManagerService) NotificationManager.getService(); + NotificationManagerInternal nm = LocalServices.getService( + NotificationManagerInternal.class); if (nm == null) { return; } @@ -479,7 +480,7 @@ final class ServiceRecord extends Binder { throw new RuntimeException("icon must be non-zero"); } int[] outId = new int[1]; - nm.enqueueNotificationInternal(localPackageName, localPackageName, + nm.enqueueNotification(localPackageName, localPackageName, appUid, appPid, null, localForegroundId, localForegroundNoti, outId, userId); } catch (RuntimeException e) { diff --git a/services/java/com/android/server/am/StrictModeViolationDialog.java b/services/core/java/com/android/server/am/StrictModeViolationDialog.java index fda1ec130980..fda1ec130980 100644 --- a/services/java/com/android/server/am/StrictModeViolationDialog.java +++ b/services/core/java/com/android/server/am/StrictModeViolationDialog.java diff --git a/services/java/com/android/server/am/TaskAccessInfo.java b/services/core/java/com/android/server/am/TaskAccessInfo.java index 50aeec1172ca..50aeec1172ca 100644 --- a/services/java/com/android/server/am/TaskAccessInfo.java +++ b/services/core/java/com/android/server/am/TaskAccessInfo.java diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 3d568ffb8e07..9740812e654c 100644 --- a/services/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -60,7 +60,8 @@ final class TaskRecord extends ThumbnailHolder { /** Takes on same set of values as ActivityRecord.mActivityType */ private int mTaskType; - /** Launch the home activity when leaving this task. */ + /** Launch the home activity when leaving this task. Will be false for tasks that are not on + * Display.DEFAULT_DISPLAY. */ boolean mOnTopOfHome = false; TaskRecord(int _taskId, ActivityInfo info, Intent _intent) { @@ -159,18 +160,33 @@ final class TaskRecord extends ThumbnailHolder { return null; } + /** Call after activity movement or finish to make sure that frontOfTask is set correctly */ + final void setFrontOfTask() { + boolean foundFront = false; + final int numActivities = mActivities.size(); + for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) { + final ActivityRecord r = mActivities.get(activityNdx); + if (foundFront || r.finishing) { + r.frontOfTask = false; + } else { + r.frontOfTask = true; + // Set frontOfTask false for every following activity. + foundFront = true; + } + } + } + /** - * Reorder the history stack so that the activity at the given index is - * brought to the front. + * Reorder the history stack so that the passed activity is brought to the front. */ final void moveActivityToFrontLocked(ActivityRecord newTop) { if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Removing and adding activity " + newTop + " to stack at top", new RuntimeException("here").fillInStackTrace()); - getTopActivity().frontOfTask = false; mActivities.remove(newTop); mActivities.add(newTop); - newTop.frontOfTask = true; + + setFrontOfTask(); } void addActivityAtBottom(ActivityRecord r) { diff --git a/services/java/com/android/server/am/ThumbnailHolder.java b/services/core/java/com/android/server/am/ThumbnailHolder.java index a6974f56356d..a6974f56356d 100644 --- a/services/java/com/android/server/am/ThumbnailHolder.java +++ b/services/core/java/com/android/server/am/ThumbnailHolder.java diff --git a/services/java/com/android/server/am/UriPermission.java b/services/core/java/com/android/server/am/UriPermission.java index 1f12b74432a3..1f12b74432a3 100644 --- a/services/java/com/android/server/am/UriPermission.java +++ b/services/core/java/com/android/server/am/UriPermission.java diff --git a/services/java/com/android/server/am/UriPermissionOwner.java b/services/core/java/com/android/server/am/UriPermissionOwner.java index 7bbd3bcc2eb9..7bbd3bcc2eb9 100644 --- a/services/java/com/android/server/am/UriPermissionOwner.java +++ b/services/core/java/com/android/server/am/UriPermissionOwner.java diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/core/java/com/android/server/am/UsageStatsService.java index 09cb344531c3..09cb344531c3 100644 --- a/services/java/com/android/server/am/UsageStatsService.java +++ b/services/core/java/com/android/server/am/UsageStatsService.java diff --git a/services/java/com/android/server/am/UserStartedState.java b/services/core/java/com/android/server/am/UserStartedState.java index d3e73d5222a4..d3e73d5222a4 100644 --- a/services/java/com/android/server/am/UserStartedState.java +++ b/services/core/java/com/android/server/am/UserStartedState.java diff --git a/services/java/com/android/server/am/package.html b/services/core/java/com/android/server/am/package.html index c9f96a66ab3b..c9f96a66ab3b 100644 --- a/services/java/com/android/server/am/package.html +++ b/services/core/java/com/android/server/am/package.html diff --git a/services/java/com/android/server/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java index 069ae23f5596..6aa596d9d78e 100644 --- a/services/java/com/android/server/ClipboardService.java +++ b/services/core/java/com/android/server/clipboard/ClipboardService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.clipboard; import android.app.ActivityManagerNative; import android.app.AppGlobals; diff --git a/services/java/com/android/server/connectivity/DataConnectionStats.java b/services/core/java/com/android/server/connectivity/DataConnectionStats.java index 227ab2341012..227ab2341012 100644 --- a/services/java/com/android/server/connectivity/DataConnectionStats.java +++ b/services/core/java/com/android/server/connectivity/DataConnectionStats.java diff --git a/services/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java index a15d678520bc..a15d678520bc 100644 --- a/services/java/com/android/server/connectivity/Nat464Xlat.java +++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java diff --git a/services/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java index 7786fe6e4254..7786fe6e4254 100644 --- a/services/java/com/android/server/connectivity/PacManager.java +++ b/services/core/java/com/android/server/connectivity/PacManager.java diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index adf1dfc10ef5..adf1dfc10ef5 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 2ca2cc507f2e..2ca2cc507f2e 100644 --- a/services/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java diff --git a/services/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index 023bf2b20614..023bf2b20614 100644 --- a/services/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java diff --git a/services/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 71d8d9911f9a..71d8d9911f9a 100644 --- a/services/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java diff --git a/services/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java index 485674782aeb..485674782aeb 100644 --- a/services/java/com/android/server/content/SyncOperation.java +++ b/services/core/java/com/android/server/content/SyncOperation.java diff --git a/services/java/com/android/server/content/SyncQueue.java b/services/core/java/com/android/server/content/SyncQueue.java index 6f3fe6e1d37b..6f3fe6e1d37b 100644 --- a/services/java/com/android/server/content/SyncQueue.java +++ b/services/core/java/com/android/server/content/SyncQueue.java diff --git a/services/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java index 124bc60df10c..124bc60df10c 100644 --- a/services/java/com/android/server/content/SyncStorageEngine.java +++ b/services/core/java/com/android/server/content/SyncStorageEngine.java diff --git a/services/java/com/android/server/display/DisplayAdapter.java b/services/core/java/com/android/server/display/DisplayAdapter.java index b411a0db7184..b411a0db7184 100644 --- a/services/java/com/android/server/display/DisplayAdapter.java +++ b/services/core/java/com/android/server/display/DisplayAdapter.java diff --git a/services/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java index 41611475d9c8..41611475d9c8 100644 --- a/services/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java index 11c5d879b498..11aecddae93f 100644 --- a/services/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java @@ -63,6 +63,7 @@ final class DisplayDeviceInfo { /** * Flag: Indicates that the display device is owned by a particular application * and that no other application should be able to interact with it. + * Should typically be used together with {@link #FLAG_OWN_CONTENT_ONLY}. */ public static final int FLAG_PRIVATE = 1 << 4; @@ -78,6 +79,12 @@ final class DisplayDeviceInfo { public static final int FLAG_PRESENTATION = 1 << 6; /** + * Flag: Only show this display's own content; do not mirror + * the content of another display. + */ + public static final int FLAG_OWN_CONTENT_ONLY = 1 << 7; + + /** * Touch attachment: Display does not receive touch. */ public static final int TOUCH_NONE = 0; @@ -297,6 +304,9 @@ final class DisplayDeviceInfo { if ((flags & FLAG_PRESENTATION) != 0) { msg.append(", FLAG_PRESENTATION"); } + if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) { + msg.append(", FLAG_OWN_CONTENT_ONLY"); + } return msg.toString(); } } diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index bcb677fa455f..12ef65ae6eba 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -31,6 +31,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; @@ -102,7 +103,6 @@ public final class DisplayManagerService extends IDisplayManager.Stub { // Otherwise WFD is enabled according to the value of config_enableWifiDisplay. private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable"; - private static final String SYSTEM_HEADLESS = "ro.config.headless"; private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000; private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1; @@ -116,7 +116,6 @@ public final class DisplayManagerService extends IDisplayManager.Stub { private static final int DISPLAY_BLANK_STATE_UNBLANKED = 2; private final Context mContext; - private final boolean mHeadless; private final DisplayManagerHandler mHandler; private final Handler mUiHandler; private final DisplayAdapterListener mDisplayAdapterListener; @@ -202,8 +201,6 @@ public final class DisplayManagerService extends IDisplayManager.Stub { public DisplayManagerService(Context context, Handler mainHandler) { mContext = context; - mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1"); - mHandler = new DisplayManagerHandler(mainHandler.getLooper()); mUiHandler = UiThread.getHandler(); mDisplayAdapterListener = new DisplayAdapterListener(); @@ -270,15 +267,6 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } /** - * Returns true if the device is headless. - * - * @return True if the device is headless. - */ - public boolean isHeadless() { - return mHeadless; - } - - /** * Registers a display transaction listener to provide the client a chance to * update its surfaces within the same transaction as any display layout updates. * @@ -688,7 +676,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub { if (surface == null) { throw new IllegalArgumentException("surface must not be null"); } - if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { + if (callingUid != Process.SYSTEM_UID && + (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT) != PackageManager.PERMISSION_GRANTED && mContext.checkCallingPermission( @@ -779,13 +768,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub { private void registerDefaultDisplayAdapter() { // Register default display adapter. synchronized (mSyncRoot) { - if (mHeadless) { - registerDisplayAdapterLocked(new HeadlessDisplayAdapter( - mSyncRoot, mContext, mHandler, mDisplayAdapterListener)); - } else { - registerDisplayAdapterLocked(new LocalDisplayAdapter( - mSyncRoot, mContext, mHandler, mDisplayAdapterListener)); - } + registerDisplayAdapterLocked(new LocalDisplayAdapter( + mSyncRoot, mContext, mHandler, mDisplayAdapterListener)); } } @@ -1042,13 +1026,13 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } private void configureDisplayInTransactionLocked(DisplayDevice device) { - DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); - boolean isPrivate = (info.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0; + final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); + final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0; // Find the logical display that the display device is showing. - // Private displays never mirror other displays. + // Certain displays only ever show their own content. LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); - if (!isPrivate) { + if (!ownContent) { if (display != null && !display.hasContentLocked()) { // If the display does not have any content of its own, then // automatically mirror the default logical display contents. @@ -1153,7 +1137,6 @@ public final class DisplayManagerService extends IDisplayManager.Stub { pw.println("DISPLAY MANAGER (dumpsys display)"); synchronized (mSyncRoot) { - pw.println(" mHeadless=" + mHeadless); pw.println(" mOnlyCode=" + mOnlyCore); pw.println(" mSafeMode=" + mSafeMode); pw.println(" mPendingTraversal=" + mPendingTraversal); diff --git a/services/java/com/android/server/display/DisplayTransactionListener.java b/services/core/java/com/android/server/display/DisplayTransactionListener.java index 34eb8f930e9d..34eb8f930e9d 100644 --- a/services/java/com/android/server/display/DisplayTransactionListener.java +++ b/services/core/java/com/android/server/display/DisplayTransactionListener.java diff --git a/services/java/com/android/server/display/DisplayViewport.java b/services/core/java/com/android/server/display/DisplayViewport.java index 5080556a54a3..5080556a54a3 100644 --- a/services/java/com/android/server/display/DisplayViewport.java +++ b/services/core/java/com/android/server/display/DisplayViewport.java diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index cb8f3e20d368..cb8f3e20d368 100644 --- a/services/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 7e357c0c3a7c..7e357c0c3a7c 100644 --- a/services/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java diff --git a/services/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java index 007acf716598..007acf716598 100644 --- a/services/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java diff --git a/services/java/com/android/server/display/OverlayDisplayWindow.java b/services/core/java/com/android/server/display/OverlayDisplayWindow.java index f1dd60a75424..f1dd60a75424 100644 --- a/services/java/com/android/server/display/OverlayDisplayWindow.java +++ b/services/core/java/com/android/server/display/OverlayDisplayWindow.java diff --git a/services/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java index 67b36958a35a..67b36958a35a 100644 --- a/services/java/com/android/server/display/PersistentDataStore.java +++ b/services/core/java/com/android/server/display/PersistentDataStore.java diff --git a/services/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 46d473ce6ba3..95ca0d2b4b43 100644 --- a/services/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -157,8 +157,11 @@ final class VirtualDisplayAdapter extends DisplayAdapter { mInfo.yDpi = mDensityDpi; mInfo.flags = 0; if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) { - mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE | - DisplayDeviceInfo.FLAG_NEVER_BLANK; + mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE + | DisplayDeviceInfo.FLAG_NEVER_BLANK + | DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY; + } else if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) { + mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY; } if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE; diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java index cd57941bcc3e..cd57941bcc3e 100644 --- a/services/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/core/java/com/android/server/display/WifiDisplayController.java index dbb59b269bf5..dbb59b269bf5 100644 --- a/services/java/com/android/server/display/WifiDisplayController.java +++ b/services/core/java/com/android/server/display/WifiDisplayController.java diff --git a/services/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index 85ef33e2742a..85ef33e2742a 100644 --- a/services/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java diff --git a/services/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java index b6e778170d17..b6e778170d17 100644 --- a/services/java/com/android/server/dreams/DreamManagerService.java +++ b/services/core/java/com/android/server/dreams/DreamManagerService.java diff --git a/services/java/com/android/server/firewall/AndFilter.java b/services/core/java/com/android/server/firewall/AndFilter.java index 13551de8a02f..13551de8a02f 100644 --- a/services/java/com/android/server/firewall/AndFilter.java +++ b/services/core/java/com/android/server/firewall/AndFilter.java diff --git a/services/java/com/android/server/firewall/CategoryFilter.java b/services/core/java/com/android/server/firewall/CategoryFilter.java index 246c09630c67..246c09630c67 100644 --- a/services/java/com/android/server/firewall/CategoryFilter.java +++ b/services/core/java/com/android/server/firewall/CategoryFilter.java diff --git a/services/java/com/android/server/firewall/Filter.java b/services/core/java/com/android/server/firewall/Filter.java index 0a124f768f6c..0a124f768f6c 100644 --- a/services/java/com/android/server/firewall/Filter.java +++ b/services/core/java/com/android/server/firewall/Filter.java diff --git a/services/java/com/android/server/firewall/FilterFactory.java b/services/core/java/com/android/server/firewall/FilterFactory.java index dea8b4000ccd..dea8b4000ccd 100644 --- a/services/java/com/android/server/firewall/FilterFactory.java +++ b/services/core/java/com/android/server/firewall/FilterFactory.java diff --git a/services/java/com/android/server/firewall/FilterList.java b/services/core/java/com/android/server/firewall/FilterList.java index d34b2038e5bf..d34b2038e5bf 100644 --- a/services/java/com/android/server/firewall/FilterList.java +++ b/services/core/java/com/android/server/firewall/FilterList.java diff --git a/services/java/com/android/server/firewall/IntentFirewall.java b/services/core/java/com/android/server/firewall/IntentFirewall.java index aaa0b585eddb..aaa0b585eddb 100644 --- a/services/java/com/android/server/firewall/IntentFirewall.java +++ b/services/core/java/com/android/server/firewall/IntentFirewall.java diff --git a/services/java/com/android/server/firewall/NotFilter.java b/services/core/java/com/android/server/firewall/NotFilter.java index 09bf629a0df3..09bf629a0df3 100644 --- a/services/java/com/android/server/firewall/NotFilter.java +++ b/services/core/java/com/android/server/firewall/NotFilter.java diff --git a/services/java/com/android/server/firewall/OrFilter.java b/services/core/java/com/android/server/firewall/OrFilter.java index f6a6f22278e4..f6a6f22278e4 100644 --- a/services/java/com/android/server/firewall/OrFilter.java +++ b/services/core/java/com/android/server/firewall/OrFilter.java diff --git a/services/java/com/android/server/firewall/PortFilter.java b/services/core/java/com/android/server/firewall/PortFilter.java index 84ace553ee78..84ace553ee78 100644 --- a/services/java/com/android/server/firewall/PortFilter.java +++ b/services/core/java/com/android/server/firewall/PortFilter.java diff --git a/services/java/com/android/server/firewall/SenderFilter.java b/services/core/java/com/android/server/firewall/SenderFilter.java index c0eee69b4b0d..c0eee69b4b0d 100644 --- a/services/java/com/android/server/firewall/SenderFilter.java +++ b/services/core/java/com/android/server/firewall/SenderFilter.java diff --git a/services/java/com/android/server/firewall/SenderPermissionFilter.java b/services/core/java/com/android/server/firewall/SenderPermissionFilter.java index caa65f36157a..caa65f36157a 100644 --- a/services/java/com/android/server/firewall/SenderPermissionFilter.java +++ b/services/core/java/com/android/server/firewall/SenderPermissionFilter.java diff --git a/services/java/com/android/server/firewall/StringFilter.java b/services/core/java/com/android/server/firewall/StringFilter.java index 28e99b372d54..28e99b372d54 100644 --- a/services/java/com/android/server/firewall/StringFilter.java +++ b/services/core/java/com/android/server/firewall/StringFilter.java diff --git a/services/java/com/android/server/input/InputApplicationHandle.java b/services/core/java/com/android/server/input/InputApplicationHandle.java index 3cf7edcd6b2e..3cf7edcd6b2e 100644 --- a/services/java/com/android/server/input/InputApplicationHandle.java +++ b/services/core/java/com/android/server/input/InputApplicationHandle.java diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 91786643f7cc..91786643f7cc 100644 --- a/services/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java diff --git a/services/java/com/android/server/input/InputWindowHandle.java b/services/core/java/com/android/server/input/InputWindowHandle.java index 9a70f38ceac7..9a70f38ceac7 100644 --- a/services/java/com/android/server/input/InputWindowHandle.java +++ b/services/core/java/com/android/server/input/InputWindowHandle.java diff --git a/services/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java index 71de776c081c..71de776c081c 100644 --- a/services/java/com/android/server/input/PersistentDataStore.java +++ b/services/core/java/com/android/server/input/PersistentDataStore.java diff --git a/services/core/java/com/android/server/lights/Light.java b/services/core/java/com/android/server/lights/Light.java new file mode 100644 index 000000000000..b496b4c6ce8c --- /dev/null +++ b/services/core/java/com/android/server/lights/Light.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.lights; + +public abstract class Light { + public static final int LIGHT_FLASH_NONE = 0; + public static final int LIGHT_FLASH_TIMED = 1; + public static final int LIGHT_FLASH_HARDWARE = 2; + + /** + * Light brightness is managed by a user setting. + */ + public static final int BRIGHTNESS_MODE_USER = 0; + + /** + * Light brightness is managed by a light sensor. + */ + public static final int BRIGHTNESS_MODE_SENSOR = 1; + + public abstract void setBrightness(int brightness); + public abstract void setBrightness(int brightness, int brightnessMode); + public abstract void setColor(int color); + public abstract void setFlashing(int color, int mode, int onMS, int offMS); + public abstract void pulse(); + public abstract void pulse(int color, int onMS); + public abstract void turnOff(); +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/lights/LightsManager.java b/services/core/java/com/android/server/lights/LightsManager.java new file mode 100644 index 000000000000..2f20509dddf5 --- /dev/null +++ b/services/core/java/com/android/server/lights/LightsManager.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.lights; + +public abstract class LightsManager { + public static final int LIGHT_ID_BACKLIGHT = 0; + public static final int LIGHT_ID_KEYBOARD = 1; + public static final int LIGHT_ID_BUTTONS = 2; + public static final int LIGHT_ID_BATTERY = 3; + public static final int LIGHT_ID_NOTIFICATIONS = 4; + public static final int LIGHT_ID_ATTENTION = 5; + public static final int LIGHT_ID_BLUETOOTH = 6; + public static final int LIGHT_ID_WIFI = 7; + public static final int LIGHT_ID_COUNT = 8; + + public abstract Light getLight(int id); +} diff --git a/services/java/com/android/server/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java index a1d655bd4181..62dc0901bb45 100644 --- a/services/java/com/android/server/LightsService.java +++ b/services/core/java/com/android/server/lights/LightsService.java @@ -14,59 +14,38 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.lights; + +import com.android.server.SystemService; import android.content.Context; import android.content.pm.PackageManager; import android.os.Handler; import android.os.IHardwareService; -import android.os.ServiceManager; import android.os.Message; import android.util.Slog; import java.io.FileInputStream; import java.io.FileOutputStream; -public class LightsService { - private static final String TAG = "LightsService"; - private static final boolean DEBUG = false; - - public static final int LIGHT_ID_BACKLIGHT = 0; - public static final int LIGHT_ID_KEYBOARD = 1; - public static final int LIGHT_ID_BUTTONS = 2; - public static final int LIGHT_ID_BATTERY = 3; - public static final int LIGHT_ID_NOTIFICATIONS = 4; - public static final int LIGHT_ID_ATTENTION = 5; - public static final int LIGHT_ID_BLUETOOTH = 6; - public static final int LIGHT_ID_WIFI = 7; - public static final int LIGHT_ID_COUNT = 8; - - public static final int LIGHT_FLASH_NONE = 0; - public static final int LIGHT_FLASH_TIMED = 1; - public static final int LIGHT_FLASH_HARDWARE = 2; - - /** - * Light brightness is managed by a user setting. - */ - public static final int BRIGHTNESS_MODE_USER = 0; - - /** - * Light brightness is managed by a light sensor. - */ - public static final int BRIGHTNESS_MODE_SENSOR = 1; +public class LightsService extends SystemService { + static final String TAG = "LightsService"; + static final boolean DEBUG = false; - private final Light mLights[] = new Light[LIGHT_ID_COUNT]; + final LightImpl mLights[] = new LightImpl[LightsManager.LIGHT_ID_COUNT]; - public final class Light { + private final class LightImpl extends Light { - private Light(int id) { + private LightImpl(int id) { mId = id; } + @Override public void setBrightness(int brightness) { setBrightness(brightness, BRIGHTNESS_MODE_USER); } + @Override public void setBrightness(int brightness, int brightnessMode) { synchronized (this) { int color = brightness & 0x000000ff; @@ -75,23 +54,26 @@ public class LightsService { } } + @Override public void setColor(int color) { synchronized (this) { setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, 0); } } + @Override public void setFlashing(int color, int mode, int onMS, int offMS) { synchronized (this) { setLightLocked(color, mode, onMS, offMS, BRIGHTNESS_MODE_USER); } } - + @Override public void pulse() { pulse(0x00ffffff, 7); } + @Override public void pulse(int color, int onMS) { synchronized (this) { if (mColor == 0 && !mFlashing) { @@ -101,6 +83,7 @@ public class LightsService { } } + @Override public void turnOff() { synchronized (this) { setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0); @@ -153,9 +136,10 @@ public class LightsService { } public void setFlashlightEnabled(boolean on) { - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT) + final Context context = getContext(); + if (context.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT) != PackageManager.PERMISSION_GRANTED && - mContext.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST) + context.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires FLASHLIGHT or HARDWARE_TEST permission"); } @@ -172,31 +156,41 @@ public class LightsService { } }; - LightsService(Context context) { - + @Override + public void onCreate(Context context) { mNativePointer = init_native(); - mContext = context; - - ServiceManager.addService("hardware", mLegacyFlashlightHack); - for (int i = 0; i < LIGHT_ID_COUNT; i++) { - mLights[i] = new Light(i); + for (int i = 0; i < LightsManager.LIGHT_ID_COUNT; i++) { + mLights[i] = new LightImpl(i); } } + @Override + public void onStart() { + publishBinderService("hardware", mLegacyFlashlightHack); + publishLocalService(LightsManager.class, mService); + } + + private final LightsManager mService = new LightsManager() { + @Override + public com.android.server.lights.Light getLight(int id) { + if (id < LIGHT_ID_COUNT) { + return mLights[id]; + } else { + return null; + } + } + }; + protected void finalize() throws Throwable { finalize_native(mNativePointer); super.finalize(); } - public Light getLight(int id) { - return mLights[id]; - } - private Handler mH = new Handler() { @Override public void handleMessage(Message msg) { - Light light = (Light)msg.obj; + LightImpl light = (LightImpl)msg.obj; light.stopFlashing(); } }; @@ -204,10 +198,8 @@ public class LightsService { private static native long init_native(); private static native void finalize_native(long ptr); - private static native void setLight_native(long ptr, int light, int color, int mode, + static native void setLight_native(long ptr, int light, int color, int mode, int onMS, int offMS, int brightnessMode); - private final Context mContext; - private long mNativePointer; } diff --git a/services/java/com/android/server/location/ComprehensiveCountryDetector.java b/services/core/java/com/android/server/location/ComprehensiveCountryDetector.java index 354858b15368..354858b15368 100644 --- a/services/java/com/android/server/location/ComprehensiveCountryDetector.java +++ b/services/core/java/com/android/server/location/ComprehensiveCountryDetector.java diff --git a/services/java/com/android/server/location/CountryDetectorBase.java b/services/core/java/com/android/server/location/CountryDetectorBase.java index 8326ef949858..8326ef949858 100644 --- a/services/java/com/android/server/location/CountryDetectorBase.java +++ b/services/core/java/com/android/server/location/CountryDetectorBase.java diff --git a/services/java/com/android/server/location/FlpHardwareProvider.java b/services/core/java/com/android/server/location/FlpHardwareProvider.java index fab84a85ae0c..fab84a85ae0c 100644 --- a/services/java/com/android/server/location/FlpHardwareProvider.java +++ b/services/core/java/com/android/server/location/FlpHardwareProvider.java diff --git a/services/java/com/android/server/location/FusedLocationHardwareSecure.java b/services/core/java/com/android/server/location/FusedLocationHardwareSecure.java index 389bd2477c84..389bd2477c84 100644 --- a/services/java/com/android/server/location/FusedLocationHardwareSecure.java +++ b/services/core/java/com/android/server/location/FusedLocationHardwareSecure.java diff --git a/services/java/com/android/server/location/FusedProxy.java b/services/core/java/com/android/server/location/FusedProxy.java index f7fac774c979..f7fac774c979 100644 --- a/services/java/com/android/server/location/FusedProxy.java +++ b/services/core/java/com/android/server/location/FusedProxy.java diff --git a/services/java/com/android/server/location/GeocoderProxy.java b/services/core/java/com/android/server/location/GeocoderProxy.java index 5d4a7701fbfb..5d4a7701fbfb 100644 --- a/services/java/com/android/server/location/GeocoderProxy.java +++ b/services/core/java/com/android/server/location/GeocoderProxy.java diff --git a/services/java/com/android/server/location/GeofenceManager.java b/services/core/java/com/android/server/location/GeofenceManager.java index e24bf7620fe3..e24bf7620fe3 100644 --- a/services/java/com/android/server/location/GeofenceManager.java +++ b/services/core/java/com/android/server/location/GeofenceManager.java diff --git a/services/java/com/android/server/location/GeofenceProxy.java b/services/core/java/com/android/server/location/GeofenceProxy.java index bbc1f472387f..bbc1f472387f 100644 --- a/services/java/com/android/server/location/GeofenceProxy.java +++ b/services/core/java/com/android/server/location/GeofenceProxy.java diff --git a/services/java/com/android/server/location/GeofenceState.java b/services/core/java/com/android/server/location/GeofenceState.java index 3ebe20a7e8e6..3ebe20a7e8e6 100644 --- a/services/java/com/android/server/location/GeofenceState.java +++ b/services/core/java/com/android/server/location/GeofenceState.java diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java index 9c76c19051e8..9c76c19051e8 100644 --- a/services/java/com/android/server/location/GpsLocationProvider.java +++ b/services/core/java/com/android/server/location/GpsLocationProvider.java diff --git a/services/java/com/android/server/location/GpsXtraDownloader.java b/services/core/java/com/android/server/location/GpsXtraDownloader.java index e4200736fd8e..e4200736fd8e 100644 --- a/services/java/com/android/server/location/GpsXtraDownloader.java +++ b/services/core/java/com/android/server/location/GpsXtraDownloader.java diff --git a/services/java/com/android/server/location/LocationBasedCountryDetector.java b/services/core/java/com/android/server/location/LocationBasedCountryDetector.java index 03db621c03a8..03db621c03a8 100644 --- a/services/java/com/android/server/location/LocationBasedCountryDetector.java +++ b/services/core/java/com/android/server/location/LocationBasedCountryDetector.java diff --git a/services/java/com/android/server/location/LocationBlacklist.java b/services/core/java/com/android/server/location/LocationBlacklist.java index 6f22689320ca..6f22689320ca 100644 --- a/services/java/com/android/server/location/LocationBlacklist.java +++ b/services/core/java/com/android/server/location/LocationBlacklist.java diff --git a/services/java/com/android/server/location/LocationFudger.java b/services/core/java/com/android/server/location/LocationFudger.java index 2a68743c578d..2a68743c578d 100644 --- a/services/java/com/android/server/location/LocationFudger.java +++ b/services/core/java/com/android/server/location/LocationFudger.java diff --git a/services/java/com/android/server/location/LocationProviderInterface.java b/services/core/java/com/android/server/location/LocationProviderInterface.java index 6f0923233e19..6f0923233e19 100644 --- a/services/java/com/android/server/location/LocationProviderInterface.java +++ b/services/core/java/com/android/server/location/LocationProviderInterface.java diff --git a/services/java/com/android/server/location/LocationProviderProxy.java b/services/core/java/com/android/server/location/LocationProviderProxy.java index 14db862065e3..14db862065e3 100644 --- a/services/java/com/android/server/location/LocationProviderProxy.java +++ b/services/core/java/com/android/server/location/LocationProviderProxy.java diff --git a/services/java/com/android/server/location/MockProvider.java b/services/core/java/com/android/server/location/MockProvider.java index 36c43ff1ce1d..36c43ff1ce1d 100644 --- a/services/java/com/android/server/location/MockProvider.java +++ b/services/core/java/com/android/server/location/MockProvider.java diff --git a/services/java/com/android/server/location/PassiveProvider.java b/services/core/java/com/android/server/location/PassiveProvider.java index 71bae07680a3..71bae07680a3 100644 --- a/services/java/com/android/server/location/PassiveProvider.java +++ b/services/core/java/com/android/server/location/PassiveProvider.java diff --git a/services/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java index f91ea8c03a39..f91ea8c03a39 100644 --- a/services/java/com/android/server/media/MediaRouterService.java +++ b/services/core/java/com/android/server/media/MediaRouterService.java diff --git a/services/java/com/android/server/media/RemoteDisplayProviderProxy.java b/services/core/java/com/android/server/media/RemoteDisplayProviderProxy.java index a5fe9f2ceb39..a5fe9f2ceb39 100644 --- a/services/java/com/android/server/media/RemoteDisplayProviderProxy.java +++ b/services/core/java/com/android/server/media/RemoteDisplayProviderProxy.java diff --git a/services/java/com/android/server/media/RemoteDisplayProviderWatcher.java b/services/core/java/com/android/server/media/RemoteDisplayProviderWatcher.java index 6a5f563683a3..6a5f563683a3 100644 --- a/services/java/com/android/server/media/RemoteDisplayProviderWatcher.java +++ b/services/core/java/com/android/server/media/RemoteDisplayProviderWatcher.java diff --git a/services/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java index a2e9d6768696..a2e9d6768696 100644 --- a/services/java/com/android/server/net/LockdownVpnTracker.java +++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java diff --git a/services/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java index 397f9f41d8a0..397f9f41d8a0 100644 --- a/services/java/com/android/server/net/NetworkIdentitySet.java +++ b/services/core/java/com/android/server/net/NetworkIdentitySet.java diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index eb7cc4c89e4d..eb7cc4c89e4d 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java diff --git a/services/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java index 475482f6dd0b..475482f6dd0b 100644 --- a/services/java/com/android/server/net/NetworkStatsCollection.java +++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java diff --git a/services/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java index cea084b51849..cea084b51849 100644 --- a/services/java/com/android/server/net/NetworkStatsRecorder.java +++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 5d6adc22685e..5d6adc22685e 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java new file mode 100644 index 000000000000..df2aaca49eca --- /dev/null +++ b/services/core/java/com/android/server/notification/NotificationDelegate.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2013, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.notification; + +public interface NotificationDelegate { + void onSetDisabled(int status); + void onClearAll(); + void onNotificationClick(String pkg, String tag, int id); + void onNotificationClear(String pkg, String tag, int id); + void onNotificationError(String pkg, String tag, int id, + int uid, int initialPid, String message); + void onPanelRevealed(); +} diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java new file mode 100644 index 000000000000..92ffdccb50f0 --- /dev/null +++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java @@ -0,0 +1,8 @@ +package com.android.server.notification; + +import android.app.Notification; + +public interface NotificationManagerInternal { + void enqueueNotification(String pkg, String basePkg, int callingUid, int callingPid, + String tag, int id, Notification notification, int[] idReceived, int userId); +} diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 04386759df50..db4cf31d7dad 100644 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.notification; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_TAG; @@ -47,7 +47,6 @@ import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Bitmap; import android.media.AudioManager; -import android.media.IAudioService; import android.media.IRingtonePlayer; import android.net.Uri; import android.os.Binder; @@ -56,9 +55,7 @@ import android.os.IBinder; import android.os.Message; import android.os.Process; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.UserHandle; -import android.os.UserManager; import android.os.Vibrator; import android.provider.Settings; import android.service.notification.INotificationListener; @@ -78,6 +75,12 @@ import android.widget.Toast; import com.android.internal.R; import com.android.internal.notification.NotificationScorer; +import com.android.server.EventLogTags; +import com.android.server.statusbar.StatusBarManagerInternal; +import com.android.server.SystemService; +import com.android.server.lights.Light; +import com.android.server.lights.LightsManager; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -99,66 +102,61 @@ import java.util.Set; import libcore.io.IoUtils; - /** {@hide} */ -public class NotificationManagerService extends INotificationManager.Stub -{ - private static final String TAG = "NotificationService"; - private static final boolean DBG = false; +public class NotificationManagerService extends SystemService { + static final String TAG = "NotificationService"; + static final boolean DBG = false; - private static final int MAX_PACKAGE_NOTIFICATIONS = 50; + static final int MAX_PACKAGE_NOTIFICATIONS = 50; // message codes - private static final int MESSAGE_TIMEOUT = 2; + static final int MESSAGE_TIMEOUT = 2; - private static final int LONG_DELAY = 3500; // 3.5 seconds - private static final int SHORT_DELAY = 2000; // 2 seconds + static final int LONG_DELAY = 3500; // 3.5 seconds + static final int SHORT_DELAY = 2000; // 2 seconds - private static final long[] DEFAULT_VIBRATE_PATTERN = {0, 250, 250, 250}; - private static final int VIBRATE_PATTERN_MAXLEN = 8 * 2 + 1; // up to eight bumps + static final long[] DEFAULT_VIBRATE_PATTERN = {0, 250, 250, 250}; + static final int VIBRATE_PATTERN_MAXLEN = 8 * 2 + 1; // up to eight bumps - private static final int DEFAULT_STREAM_TYPE = AudioManager.STREAM_NOTIFICATION; - private static final boolean SCORE_ONGOING_HIGHER = false; + static final int DEFAULT_STREAM_TYPE = AudioManager.STREAM_NOTIFICATION; + static final boolean SCORE_ONGOING_HIGHER = false; - private static final int JUNK_SCORE = -1000; - private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; - private static final int SCORE_DISPLAY_THRESHOLD = Notification.PRIORITY_MIN * NOTIFICATION_PRIORITY_MULTIPLIER; + static final int JUNK_SCORE = -1000; + static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; + static final int SCORE_DISPLAY_THRESHOLD = Notification.PRIORITY_MIN * NOTIFICATION_PRIORITY_MULTIPLIER; // Notifications with scores below this will not interrupt the user, either via LED or // sound or vibration - private static final int SCORE_INTERRUPTION_THRESHOLD = + static final int SCORE_INTERRUPTION_THRESHOLD = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER; - private static final boolean ENABLE_BLOCKED_NOTIFICATIONS = true; - private static final boolean ENABLE_BLOCKED_TOASTS = true; + static final boolean ENABLE_BLOCKED_NOTIFICATIONS = true; + static final boolean ENABLE_BLOCKED_TOASTS = true; - private static final String ENABLED_NOTIFICATION_LISTENERS_SEPARATOR = ":"; + static final String ENABLED_NOTIFICATION_LISTENERS_SEPARATOR = ":"; - final Context mContext; - final IActivityManager mAm; - final UserManager mUserManager; - final IBinder mForegroundToken = new Binder(); + private IActivityManager mAm; + AudioManager mAudioManager; + StatusBarManagerInternal mStatusBar; + Vibrator mVibrator; + final IBinder mForegroundToken = new Binder(); private WorkerHandler mHandler; - private StatusBarManagerService mStatusBar; - private LightsService.Light mNotificationLight; - private LightsService.Light mAttentionLight; + private Light mNotificationLight; + Light mAttentionLight; private int mDefaultNotificationColor; private int mDefaultNotificationLedOn; - private int mDefaultNotificationLedOff; + private int mDefaultNotificationLedOff; private long[] mDefaultVibrationPattern; - private long[] mFallbackVibrationPattern; - - private boolean mSystemReady; - private int mDisabledNotifications; - private NotificationRecord mSoundNotification; - private NotificationRecord mVibrateNotification; + private long[] mFallbackVibrationPattern; + boolean mSystemReady; - private IAudioService mAudioService; - private Vibrator mVibrator; + int mDisabledNotifications; + NotificationRecord mSoundNotification; + NotificationRecord mVibrateNotification; // for enabling and disabling notification pulse behavior private boolean mScreenOn = true; @@ -166,15 +164,15 @@ public class NotificationManagerService extends INotificationManager.Stub private boolean mNotificationPulseEnabled; // used as a mutex for access to all active notifications & listeners - private final ArrayList<NotificationRecord> mNotificationList = + final ArrayList<NotificationRecord> mNotificationList = new ArrayList<NotificationRecord>(); - private ArrayList<ToastRecord> mToastQueue; + final ArrayList<ToastRecord> mToastQueue = new ArrayList<ToastRecord>(); - private ArrayList<NotificationRecord> mLights = new ArrayList<NotificationRecord>(); - private NotificationRecord mLedNotification; + ArrayList<NotificationRecord> mLights = new ArrayList<NotificationRecord>(); + NotificationRecord mLedNotification; - private final AppOpsManager mAppOps; + private AppOpsManager mAppOps; // contains connections to all connected listeners, including app services // and system listeners @@ -202,9 +200,9 @@ public class NotificationManagerService extends INotificationManager.Stub private static final String TAG_PACKAGE = "package"; private static final String ATTR_NAME = "name"; - private final ArrayList<NotificationScorer> mScorers = new ArrayList<NotificationScorer>(); + final ArrayList<NotificationScorer> mScorers = new ArrayList<NotificationScorer>(); - private class NotificationListenerInfo implements DeathRecipient { + private class NotificationListenerInfo implements IBinder.DeathRecipient { INotificationListener listener; ComponentName component; int userid; @@ -262,7 +260,7 @@ public class NotificationManagerService extends INotificationManager.Stub public void binderDied() { if (connection == null) { // This is not a service; it won't be recreated. We can give up this connection. - unregisterListener(this.listener, this.userid); + unregisterListenerImpl(this.listener, this.userid); } } @@ -400,12 +398,14 @@ public class NotificationManagerService extends INotificationManager.Stub tag = parser.getName(); if (type == START_TAG) { if (TAG_BODY.equals(tag)) { - version = Integer.parseInt(parser.getAttributeValue(null, ATTR_VERSION)); + version = Integer.parseInt( + parser.getAttributeValue(null, ATTR_VERSION)); } else if (TAG_BLOCKED_PKGS.equals(tag)) { while ((type = parser.next()) != END_DOCUMENT) { tag = parser.getName(); if (TAG_PACKAGE.equals(tag)) { - mBlockedPackages.add(parser.getAttributeValue(null, ATTR_NAME)); + mBlockedPackages.add( + parser.getAttributeValue(null, ATTR_NAME)); } else if (TAG_BLOCKED_PKGS.equals(tag) && type == END_TAG) { break; } @@ -428,15 +428,6 @@ public class NotificationManagerService extends INotificationManager.Stub } } - /** - * Use this when you just want to know if notifications are OK for this package. - */ - public boolean areNotificationsEnabledForPackage(String pkg, int uid) { - checkCallerIsSystem(); - return (mAppOps.checkOpNoThrow(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg) - == AppOpsManager.MODE_ALLOWED); - } - /** Use this when you actually want to post a notification or toast. * * Unchecked. Not exposed via Binder, but can be called in the course of enqueue*(). @@ -450,21 +441,6 @@ public class NotificationManagerService extends INotificationManager.Stub return true; } - public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) { - checkCallerIsSystem(); - - Slog.v(TAG, (enabled?"en":"dis") + "abling notifications for " + pkg); - - mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg, - enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED); - - // Now, cancel any outstanding notifications that are part of a just-disabled app - if (ENABLE_BLOCKED_NOTIFICATIONS && !enabled) { - cancelAllNotificationsInt(pkg, 0, 0, true, UserHandle.getUserId(uid)); - } - } - - private static String idDebugString(Context baseContext, String packageName, int id) { Context c = null; @@ -490,57 +466,6 @@ public class NotificationManagerService extends INotificationManager.Stub } } - /** - * System-only API for getting a list of current (i.e. not cleared) notifications. - * - * Requires ACCESS_NOTIFICATIONS which is signature|system. - */ - @Override - public StatusBarNotification[] getActiveNotifications(String callingPkg) { - // enforce() will ensure the calling uid has the correct permission - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NOTIFICATIONS, - "NotificationManagerService.getActiveNotifications"); - - StatusBarNotification[] tmp = null; - int uid = Binder.getCallingUid(); - - // noteOp will check to make sure the callingPkg matches the uid - if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg) - == AppOpsManager.MODE_ALLOWED) { - synchronized (mNotificationList) { - tmp = new StatusBarNotification[mNotificationList.size()]; - final int N = mNotificationList.size(); - for (int i=0; i<N; i++) { - tmp[i] = mNotificationList.get(i).sbn; - } - } - } - return tmp; - } - - /** - * System-only API for getting a list of recent (cleared, no longer shown) notifications. - * - * Requires ACCESS_NOTIFICATIONS which is signature|system. - */ - @Override - public StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count) { - // enforce() will ensure the calling uid has the correct permission - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NOTIFICATIONS, - "NotificationManagerService.getHistoricalNotifications"); - - StatusBarNotification[] tmp = null; - int uid = Binder.getCallingUid(); - - // noteOp will check to make sure the callingPkg matches the uid - if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg) - == AppOpsManager.MODE_ALLOWED) { - synchronized (mArchive) { - tmp = mArchive.getArray(count); - } - } - return tmp; - } /** * Remove notification access for any services that no longer exist. @@ -548,12 +473,12 @@ public class NotificationManagerService extends INotificationManager.Stub void disableNonexistentListeners() { int currentUser = ActivityManager.getCurrentUser(); String flatIn = Settings.Secure.getStringForUser( - mContext.getContentResolver(), + getContext().getContentResolver(), Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, currentUser); if (!TextUtils.isEmpty(flatIn)) { if (DBG) Slog.v(TAG, "flat before: " + flatIn); - PackageManager pm = mContext.getPackageManager(); + PackageManager pm = getContext().getPackageManager(); List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser( new Intent(NotificationListenerService.SERVICE_INTERFACE), PackageManager.GET_SERVICES | PackageManager.GET_META_DATA, @@ -589,7 +514,7 @@ public class NotificationManagerService extends INotificationManager.Stub } if (DBG) Slog.v(TAG, "flat after: " + flatOut); if (!flatIn.equals(flatOut)) { - Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.putStringForUser(getContext().getContentResolver(), Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, flatOut, currentUser); } @@ -603,7 +528,7 @@ public class NotificationManagerService extends INotificationManager.Stub void rebindListenerServices() { final int currentUser = ActivityManager.getCurrentUser(); String flat = Settings.Secure.getStringForUser( - mContext.getContentResolver(), + getContext().getContentResolver(), Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, currentUser); @@ -652,28 +577,6 @@ public class NotificationManagerService extends INotificationManager.Stub } } - /** - * Register a listener binder directly with the notification manager. - * - * Only works with system callers. Apps should extend - * {@link android.service.notification.NotificationListenerService}. - */ - @Override - public void registerListener(final INotificationListener listener, - final ComponentName component, final int userid) { - checkCallerIsSystem(); - - synchronized (mNotificationList) { - try { - NotificationListenerInfo info - = new NotificationListenerInfo(listener, component, userid, true); - listener.asBinder().linkToDeath(info, 0); - mListeners.add(info); - } catch (RemoteException e) { - // already dead - } - } - } /** * Version of registerListener that takes the name of a @@ -703,7 +606,7 @@ public class NotificationManagerService extends INotificationManager.Stub if (DBG) Slog.v(TAG, " disconnecting old listener: " + info.listener); mListeners.remove(i); if (info.connection != null) { - mContext.unbindService(info.connection); + getContext().unbindService(info.connection); } } } @@ -713,21 +616,25 @@ public class NotificationManagerService extends INotificationManager.Stub intent.putExtra(Intent.EXTRA_CLIENT_LABEL, R.string.notification_listener_binding_label); - intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( - mContext, 0, new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS), 0)); + + final PendingIntent pendingIntent = PendingIntent.getActivity( + getContext(), 0, new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS), 0); + intent.putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent); try { if (DBG) Slog.v(TAG, "binding: " + intent); - if (!mContext.bindServiceAsUser(intent, + if (!getContext().bindServiceAsUser(intent, new ServiceConnection() { INotificationListener mListener; + @Override public void onServiceConnected(ComponentName name, IBinder service) { synchronized (mNotificationList) { mServicesBinding.remove(servicesBindingTag); try { mListener = INotificationListener.Stub.asInterface(service); - NotificationListenerInfo info = new NotificationListenerInfo( + NotificationListenerInfo info + = new NotificationListenerInfo( mListener, name, userid, this); service.linkToDeath(info, 0); mListeners.add(info); @@ -756,28 +663,6 @@ public class NotificationManagerService extends INotificationManager.Stub } } - /** - * Remove a listener binder directly - */ - @Override - public void unregisterListener(INotificationListener listener, int userid) { - // no need to check permissions; if your listener binder is in the list, - // that's proof that you had permission to add it in the first place - - synchronized (mNotificationList) { - final int N = mListeners.size(); - for (int i=N-1; i>=0; i--) { - final NotificationListenerInfo info = mListeners.get(i); - if (info.listener.asBinder() == listener.asBinder() - && info.userid == userid) { - mListeners.remove(i); - if (info.connection != null) { - mContext.unbindService(info.connection); - } - } - } - } - } /** * Remove a listener service for the given user by ComponentName @@ -794,7 +679,7 @@ public class NotificationManagerService extends INotificationManager.Stub mListeners.remove(i); if (info.connection != null) { try { - mContext.unbindService(info.connection); + getContext().unbindService(info.connection); } catch (IllegalArgumentException ex) { // something happened to the service: we think we have a connection // but it's bogus. @@ -809,7 +694,7 @@ public class NotificationManagerService extends INotificationManager.Stub /** * asynchronously notify all listeners about a new notification */ - private void notifyPostedLocked(NotificationRecord n) { + void notifyPostedLocked(NotificationRecord n) { // make a copy in case changes are made to the underlying Notification object final StatusBarNotification sbn = n.sbn.clone(); for (final NotificationListenerInfo info : mListeners) { @@ -824,7 +709,7 @@ public class NotificationManagerService extends INotificationManager.Stub /** * asynchronously notify all listeners about a removed notification */ - private void notifyRemovedLocked(NotificationRecord n) { + void notifyRemovedLocked(NotificationRecord n) { // make a copy in case changes are made to the underlying Notification object // NOTE: this copy is lightweight: it doesn't include heavyweight parts of the notification final StatusBarNotification sbn_light = n.sbn.cloneLight(); @@ -850,66 +735,7 @@ public class NotificationManagerService extends INotificationManager.Stub throw new SecurityException("Disallowed call from unknown listener: " + listener); } - /** - * Allow an INotificationListener to simulate a "clear all" operation. - * - * {@see com.android.server.StatusBarManagerService.NotificationCallbacks#onClearAllNotifications} - * - * @param token The binder for the listener, to check that the caller is allowed - */ - public void cancelAllNotificationsFromListener(INotificationListener token) { - NotificationListenerInfo info = checkListenerToken(token); - long identity = Binder.clearCallingIdentity(); - try { - cancelAll(info.userid); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - /** - * Allow an INotificationListener to simulate clearing (dismissing) a single notification. - * - * {@see com.android.server.StatusBarManagerService.NotificationCallbacks#onNotificationClear} - * - * @param token The binder for the listener, to check that the caller is allowed - */ - public void cancelNotificationFromListener(INotificationListener token, String pkg, String tag, int id) { - NotificationListenerInfo info = checkListenerToken(token); - long identity = Binder.clearCallingIdentity(); - try { - cancelNotification(pkg, tag, id, 0, - Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE, - true, - info.userid); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - /** - * Allow an INotificationListener to request the list of outstanding notifications seen by - * the current user. Useful when starting up, after which point the listener callbacks should - * be used. - * - * @param token The binder for the listener, to check that the caller is allowed - */ - public StatusBarNotification[] getActiveNotificationsFromListener(INotificationListener token) { - NotificationListenerInfo info = checkListenerToken(token); - - StatusBarNotification[] result = new StatusBarNotification[0]; - ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>(); - synchronized (mNotificationList) { - final int N = mNotificationList.size(); - for (int i=0; i<N; i++) { - StatusBarNotification sbn = mNotificationList.get(i).sbn; - if (info.enabledAndUserMatches(sbn)) { - list.add(sbn); - } - } - } - return list.toArray(result); - } // -- end of listener APIs -- @@ -992,8 +818,8 @@ public class NotificationManagerService extends INotificationManager.Stub return String.format( "NotificationRecord(0x%08x: pkg=%s user=%s id=%d tag=%s score=%d: %s)", System.identityHashCode(this), - this.sbn.getPackageName(), this.sbn.getUser(), this.sbn.getId(), this.sbn.getTag(), - this.sbn.getScore(), this.sbn.getNotification()); + this.sbn.getPackageName(), this.sbn.getUser(), this.sbn.getId(), + this.sbn.getTag(), this.sbn.getScore(), this.sbn.getNotification()); } } @@ -1031,9 +857,9 @@ public class NotificationManagerService extends INotificationManager.Stub } } - private StatusBarManagerService.NotificationCallbacks mNotificationCallbacks - = new StatusBarManagerService.NotificationCallbacks() { + private final NotificationDelegate mNotificationDelegate = new NotificationDelegate() { + @Override public void onSetDisabled(int status) { synchronized (mNotificationList) { mDisabledNotifications = status; @@ -1041,7 +867,7 @@ public class NotificationManagerService extends INotificationManager.Stub // cancel whatever's going on long identity = Binder.clearCallingIdentity(); try { - final IRingtonePlayer player = mAudioService.getRingtonePlayer(); + final IRingtonePlayer player = mAudioManager.getRingtonePlayer(); if (player != null) { player.stopAsync(); } @@ -1060,12 +886,14 @@ public class NotificationManagerService extends INotificationManager.Stub } } + @Override public void onClearAll() { // XXX to be totally correct, the caller should tell us which user // this is for. cancelAll(ActivityManager.getCurrentUser()); } + @Override public void onNotificationClick(String pkg, String tag, int id) { // XXX to be totally correct, the caller should tell us which user // this is for. @@ -1074,6 +902,7 @@ public class NotificationManagerService extends INotificationManager.Stub ActivityManager.getCurrentUser()); } + @Override public void onNotificationClear(String pkg, String tag, int id) { // XXX to be totally correct, the caller should tell us which user // this is for. @@ -1082,6 +911,7 @@ public class NotificationManagerService extends INotificationManager.Stub true, ActivityManager.getCurrentUser()); } + @Override public void onPanelRevealed() { synchronized (mNotificationList) { // sound @@ -1089,7 +919,7 @@ public class NotificationManagerService extends INotificationManager.Stub long identity = Binder.clearCallingIdentity(); try { - final IRingtonePlayer player = mAudioService.getRingtonePlayer(); + final IRingtonePlayer player = mAudioManager.getRingtonePlayer(); if (player != null) { player.stopAsync(); } @@ -1114,6 +944,7 @@ public class NotificationManagerService extends INotificationManager.Stub } } + @Override public void onNotificationError(String pkg, String tag, int id, int uid, int initialPid, String message) { Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id @@ -1168,7 +999,7 @@ public class NotificationManagerService extends INotificationManager.Stub if (packageChanged) { // We cancel notifications for packages which have just been disabled try { - final int enabled = mContext.getPackageManager() + final int enabled = getContext().getPackageManager() .getApplicationEnabledSetting(pkgName); if (enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED || enabled == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) { @@ -1244,7 +1075,7 @@ public class NotificationManagerService extends INotificationManager.Stub } void observe() { - ContentResolver resolver = mContext.getContentResolver(); + ContentResolver resolver = getContext().getContentResolver(); resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, false, this, UserHandle.USER_ALL); resolver.registerContentObserver(ENABLED_NOTIFICATION_LISTENERS_URI, @@ -1257,7 +1088,7 @@ public class NotificationManagerService extends INotificationManager.Stub } public void update(Uri uri) { - ContentResolver resolver = mContext.getContentResolver(); + ContentResolver resolver = getContext().getContentResolver(); if (uri == null || NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) { boolean pulseEnabled = Settings.System.getInt(resolver, Settings.System.NOTIFICATION_LIGHT_PULSE, 0) != 0; @@ -1287,28 +1118,24 @@ public class NotificationManagerService extends INotificationManager.Stub return out; } - NotificationManagerService(Context context, StatusBarManagerService statusBar, - LightsService lights) - { - super(); - mContext = context; - mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE); + @Override + public void onStart() { mAm = ActivityManagerNative.getDefault(); - mUserManager = (UserManager)context.getSystemService(Context.USER_SERVICE); - mToastQueue = new ArrayList<ToastRecord>(); - mHandler = new WorkerHandler(); + mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); + mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE); - mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); + mHandler = new WorkerHandler(); importOldBlockDb(); - mStatusBar = statusBar; - statusBar.setNotificationCallbacks(mNotificationCallbacks); + mStatusBar = getLocalService(StatusBarManagerInternal.class); + mStatusBar.setNotificationDelegate(mNotificationDelegate); - mNotificationLight = lights.getLight(LightsService.LIGHT_ID_NOTIFICATIONS); - mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION); + final LightsManager lights = getLocalService(LightsManager.class); + mNotificationLight = lights.getLight(LightsManager.LIGHT_ID_NOTIFICATIONS); + mAttentionLight = lights.getLight(LightsManager.LIGHT_ID_ATTENTION); - Resources resources = mContext.getResources(); + Resources resources = getContext().getResources(); mDefaultNotificationColor = resources.getColor( R.color.config_defaultNotificationColor); mDefaultNotificationLedOn = resources.getInteger( @@ -1330,7 +1157,7 @@ public class NotificationManagerService extends INotificationManager.Stub // After that, including subsequent boots, init with notifications turned on. // This works on the first boot because the setup wizard will toggle this // flag at least once and we'll go back to 0 after that. - if (0 == Settings.Global.getInt(mContext.getContentResolver(), + if (0 == Settings.Global.getInt(getContext().getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0)) { mDisabledNotifications = StatusBarManager.DISABLE_NOTIFICATION_ALERTS; } @@ -1343,7 +1170,7 @@ public class NotificationManagerService extends INotificationManager.Stub filter.addAction(Intent.ACTION_USER_PRESENT); filter.addAction(Intent.ACTION_USER_STOPPED); filter.addAction(Intent.ACTION_USER_SWITCHED); - mContext.registerReceiver(mIntentReceiver, filter); + getContext().registerReceiver(mIntentReceiver, filter); IntentFilter pkgFilter = new IntentFilter(); pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED); pkgFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); @@ -1351,9 +1178,9 @@ public class NotificationManagerService extends INotificationManager.Stub pkgFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); pkgFilter.addDataScheme("package"); - mContext.registerReceiver(mIntentReceiver, pkgFilter); + getContext().registerReceiver(mIntentReceiver, pkgFilter); IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); - mContext.registerReceiver(mIntentReceiver, sdFilter); + getContext().registerReceiver(mIntentReceiver, sdFilter); mSettingsObserver = new SettingsObserver(mHandler); mSettingsObserver.observe(); @@ -1363,9 +1190,9 @@ public class NotificationManagerService extends INotificationManager.Stub R.array.config_notificationScorers); for (String scorerName : notificationScorerNames) { try { - Class<?> scorerClass = mContext.getClassLoader().loadClass(scorerName); + Class<?> scorerClass = getContext().getClassLoader().loadClass(scorerName); NotificationScorer scorer = (NotificationScorer) scorerClass.newInstance(); - scorer.initialize(mContext); + scorer.initialize(getContext()); mScorers.add(scorer); } catch (ClassNotFoundException e) { Slog.w(TAG, "Couldn't find scorer " + scorerName + ".", e); @@ -1375,6 +1202,9 @@ public class NotificationManagerService extends INotificationManager.Stub Slog.w(TAG, "Problem accessing scorer " + scorerName + ".", e); } } + + publishBinderService(Context.NOTIFICATION_SERVICE, mService); + publishLocalService(NotificationManagerInternal.class, mInternalService); } /** @@ -1383,12 +1213,12 @@ public class NotificationManagerService extends INotificationManager.Stub private void importOldBlockDb() { loadBlockDb(); - PackageManager pm = mContext.getPackageManager(); + PackageManager pm = getContext().getPackageManager(); for (String pkg : mBlockedPackages) { PackageInfo info = null; try { info = pm.getPackageInfo(pkg, 0); - setNotificationsEnabledForPackage(pkg, info.applicationInfo.uid, false); + setNotificationsEnabledForPackageImpl(pkg, info.applicationInfo.uid, false); } catch (NameNotFoundException e) { // forget you } @@ -1399,244 +1229,421 @@ public class NotificationManagerService extends INotificationManager.Stub } } - void systemReady() { - mAudioService = IAudioService.Stub.asInterface( - ServiceManager.getService(Context.AUDIO_SERVICE)); + @Override + public void onBootPhase(int phase) { + if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { + // no beeping until we're basically done booting + mSystemReady = true; - // no beeping until we're basically done booting - mSystemReady = true; + // Grab our optional AudioService + mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); - // make sure our listener services are properly bound - rebindListenerServices(); + // make sure our listener services are properly bound + rebindListenerServices(); + } } - // Toasts - // ============================================================================ - public void enqueueToast(String pkg, ITransientNotification callback, int duration) - { - if (DBG) Slog.i(TAG, "enqueueToast pkg=" + pkg + " callback=" + callback + " duration=" + duration); + void setNotificationsEnabledForPackageImpl(String pkg, int uid, boolean enabled) { + Slog.v(TAG, (enabled?"en":"dis") + "abling notifications for " + pkg); + + mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg, + enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED); - if (pkg == null || callback == null) { - Slog.e(TAG, "Not doing toast. pkg=" + pkg + " callback=" + callback); - return ; + // Now, cancel any outstanding notifications that are part of a just-disabled app + if (ENABLE_BLOCKED_NOTIFICATIONS && !enabled) { + cancelAllNotificationsInt(pkg, 0, 0, true, UserHandle.getUserId(uid)); } + } - final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg)); + private final IBinder mService = new INotificationManager.Stub() { + // Toasts + // ============================================================================ - if (ENABLE_BLOCKED_TOASTS && !noteNotificationOp(pkg, Binder.getCallingUid())) { - if (!isSystemToast) { - Slog.e(TAG, "Suppressing toast from package " + pkg + " by user request."); - return; + @Override + public void enqueueToast(String pkg, ITransientNotification callback, int duration) + { + if (DBG) { + Slog.i(TAG, "enqueueToast pkg=" + pkg + " callback=" + callback + + " duration=" + duration); } - } - synchronized (mToastQueue) { - int callingPid = Binder.getCallingPid(); - long callingId = Binder.clearCallingIdentity(); - try { - ToastRecord record; - int index = indexOfToastLocked(pkg, callback); - // If it's already in the queue, we update it in place, we don't - // move it to the end of the queue. - if (index >= 0) { - record = mToastQueue.get(index); - record.update(duration); - } else { - // Limit the number of toasts that any given package except the android - // package can enqueue. Prevents DOS attacks and deals with leaks. - if (!isSystemToast) { - int count = 0; - final int N = mToastQueue.size(); - for (int i=0; i<N; i++) { - final ToastRecord r = mToastQueue.get(i); - if (r.pkg.equals(pkg)) { - count++; - if (count >= MAX_PACKAGE_NOTIFICATIONS) { - Slog.e(TAG, "Package has already posted " + count - + " toasts. Not showing more. Package=" + pkg); - return; + if (pkg == null || callback == null) { + Slog.e(TAG, "Not doing toast. pkg=" + pkg + " callback=" + callback); + return ; + } + + final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg)); + + if (ENABLE_BLOCKED_TOASTS && !noteNotificationOp(pkg, Binder.getCallingUid())) { + if (!isSystemToast) { + Slog.e(TAG, "Suppressing toast from package " + pkg + " by user request."); + return; + } + } + + synchronized (mToastQueue) { + int callingPid = Binder.getCallingPid(); + long callingId = Binder.clearCallingIdentity(); + try { + ToastRecord record; + int index = indexOfToastLocked(pkg, callback); + // If it's already in the queue, we update it in place, we don't + // move it to the end of the queue. + if (index >= 0) { + record = mToastQueue.get(index); + record.update(duration); + } else { + // Limit the number of toasts that any given package except the android + // package can enqueue. Prevents DOS attacks and deals with leaks. + if (!isSystemToast) { + int count = 0; + final int N = mToastQueue.size(); + for (int i=0; i<N; i++) { + final ToastRecord r = mToastQueue.get(i); + if (r.pkg.equals(pkg)) { + count++; + if (count >= MAX_PACKAGE_NOTIFICATIONS) { + Slog.e(TAG, "Package has already posted " + count + + " toasts. Not showing more. Package=" + pkg); + return; + } } - } + } } + + record = new ToastRecord(callingPid, pkg, callback, duration); + mToastQueue.add(record); + index = mToastQueue.size() - 1; + keepProcessAliveLocked(callingPid); + } + // If it's at index 0, it's the current toast. It doesn't matter if it's + // new or just been updated. Call back and tell it to show itself. + // If the callback fails, this will remove it from the list, so don't + // assume that it's valid after this. + if (index == 0) { + showNextToastLocked(); } + } finally { + Binder.restoreCallingIdentity(callingId); + } + } + } + + @Override + public void cancelToast(String pkg, ITransientNotification callback) { + Slog.i(TAG, "cancelToast pkg=" + pkg + " callback=" + callback); + + if (pkg == null || callback == null) { + Slog.e(TAG, "Not cancelling notification. pkg=" + pkg + " callback=" + callback); + return ; + } - record = new ToastRecord(callingPid, pkg, callback, duration); - mToastQueue.add(record); - index = mToastQueue.size() - 1; - keepProcessAliveLocked(callingPid); + synchronized (mToastQueue) { + long callingId = Binder.clearCallingIdentity(); + try { + int index = indexOfToastLocked(pkg, callback); + if (index >= 0) { + cancelToastLocked(index); + } else { + Slog.w(TAG, "Toast already cancelled. pkg=" + pkg + + " callback=" + callback); + } + } finally { + Binder.restoreCallingIdentity(callingId); } - // If it's at index 0, it's the current toast. It doesn't matter if it's - // new or just been updated. Call back and tell it to show itself. - // If the callback fails, this will remove it from the list, so don't - // assume that it's valid after this. - if (index == 0) { - showNextToastLocked(); + } + } + + @Override + public void enqueueNotificationWithTag(String pkg, String basePkg, String tag, int id, + Notification notification, int[] idOut, int userId) throws RemoteException { + enqueueNotificationInternal(pkg, basePkg, Binder.getCallingUid(), + Binder.getCallingPid(), tag, id, notification, idOut, userId); + } + + @Override + public void cancelNotificationWithTag(String pkg, String tag, int id, int userId) { + checkCallerIsSystemOrSameApp(pkg); + userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), + Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg); + // Don't allow client applications to cancel foreground service notis. + cancelNotification(pkg, tag, id, 0, + Binder.getCallingUid() == Process.SYSTEM_UID + ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId); + } + + @Override + public void cancelAllNotifications(String pkg, int userId) { + checkCallerIsSystemOrSameApp(pkg); + + userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), + Binder.getCallingUid(), userId, true, false, "cancelAllNotifications", pkg); + + // Calling from user space, don't allow the canceling of actively + // running foreground services. + cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId); + } + + @Override + public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) { + checkCallerIsSystem(); + + setNotificationsEnabledForPackageImpl(pkg, uid, enabled); + } + + /** + * Use this when you just want to know if notifications are OK for this package. + */ + @Override + public boolean areNotificationsEnabledForPackage(String pkg, int uid) { + checkCallerIsSystem(); + return (mAppOps.checkOpNoThrow(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg) + == AppOpsManager.MODE_ALLOWED); + } + + /** + * System-only API for getting a list of current (i.e. not cleared) notifications. + * + * Requires ACCESS_NOTIFICATIONS which is signature|system. + */ + @Override + public StatusBarNotification[] getActiveNotifications(String callingPkg) { + // enforce() will ensure the calling uid has the correct permission + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.ACCESS_NOTIFICATIONS, + "NotificationManagerService.getActiveNotifications"); + + StatusBarNotification[] tmp = null; + int uid = Binder.getCallingUid(); + + // noteOp will check to make sure the callingPkg matches the uid + if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg) + == AppOpsManager.MODE_ALLOWED) { + synchronized (mNotificationList) { + tmp = new StatusBarNotification[mNotificationList.size()]; + final int N = mNotificationList.size(); + for (int i=0; i<N; i++) { + tmp[i] = mNotificationList.get(i).sbn; + } } - } finally { - Binder.restoreCallingIdentity(callingId); } + return tmp; } - } - public void cancelToast(String pkg, ITransientNotification callback) { - Slog.i(TAG, "cancelToast pkg=" + pkg + " callback=" + callback); + /** + * System-only API for getting a list of recent (cleared, no longer shown) notifications. + * + * Requires ACCESS_NOTIFICATIONS which is signature|system. + */ + @Override + public StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count) { + // enforce() will ensure the calling uid has the correct permission + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.ACCESS_NOTIFICATIONS, + "NotificationManagerService.getHistoricalNotifications"); + + StatusBarNotification[] tmp = null; + int uid = Binder.getCallingUid(); + + // noteOp will check to make sure the callingPkg matches the uid + if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg) + == AppOpsManager.MODE_ALLOWED) { + synchronized (mArchive) { + tmp = mArchive.getArray(count); + } + } + return tmp; + } - if (pkg == null || callback == null) { - Slog.e(TAG, "Not cancelling notification. pkg=" + pkg + " callback=" + callback); - return ; + /** + * Register a listener binder directly with the notification manager. + * + * Only works with system callers. Apps should extend + * {@link android.service.notification.NotificationListenerService}. + */ + @Override + public void registerListener(final INotificationListener listener, + final ComponentName component, final int userid) { + checkCallerIsSystem(); + registerListenerImpl(listener, component, userid); } - synchronized (mToastQueue) { - long callingId = Binder.clearCallingIdentity(); + /** + * Remove a listener binder directly + */ + @Override + public void unregisterListener(INotificationListener listener, int userid) { + // no need to check permissions; if your listener binder is in the list, + // that's proof that you had permission to add it in the first place + unregisterListenerImpl(listener, userid); + } + + /** + * Allow an INotificationListener to simulate a "clear all" operation. + * + * {@see com.android.server.StatusBarManagerService.NotificationCallbacks#onClearAllNotifications} + * + * @param token The binder for the listener, to check that the caller is allowed + */ + @Override + public void cancelAllNotificationsFromListener(INotificationListener token) { + NotificationListenerInfo info = checkListenerToken(token); + long identity = Binder.clearCallingIdentity(); try { - int index = indexOfToastLocked(pkg, callback); - if (index >= 0) { - cancelToastLocked(index); - } else { - Slog.w(TAG, "Toast already cancelled. pkg=" + pkg + " callback=" + callback); - } + cancelAll(info.userid); } finally { - Binder.restoreCallingIdentity(callingId); + Binder.restoreCallingIdentity(identity); } } - } - private void showNextToastLocked() { - ToastRecord record = mToastQueue.get(0); - while (record != null) { - if (DBG) Slog.d(TAG, "Show pkg=" + record.pkg + " callback=" + record.callback); + /** + * Allow an INotificationListener to simulate clearing (dismissing) a single notification. + * + * {@see com.android.server.StatusBarManagerService.NotificationCallbacks#onNotificationClear} + * + * @param token The binder for the listener, to check that the caller is allowed + */ + @Override + public void cancelNotificationFromListener(INotificationListener token, String pkg, + String tag, int id) { + NotificationListenerInfo info = checkListenerToken(token); + long identity = Binder.clearCallingIdentity(); try { - record.callback.show(); - scheduleTimeoutLocked(record); - return; - } catch (RemoteException e) { - Slog.w(TAG, "Object died trying to show notification " + record.callback - + " in package " + record.pkg); - // remove it from the list and let the process die - int index = mToastQueue.indexOf(record); - if (index >= 0) { - mToastQueue.remove(index); - } - keepProcessAliveLocked(record.pid); - if (mToastQueue.size() > 0) { - record = mToastQueue.get(0); - } else { - record = null; + cancelNotification(pkg, tag, id, 0, + Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE, + true, + info.userid); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + /** + * Allow an INotificationListener to request the list of outstanding notifications seen by + * the current user. Useful when starting up, after which point the listener callbacks + * should be used. + * + * @param token The binder for the listener, to check that the caller is allowed + */ + @Override + public StatusBarNotification[] getActiveNotificationsFromListener( + INotificationListener token) { + NotificationListenerInfo info = checkListenerToken(token); + + StatusBarNotification[] result = new StatusBarNotification[0]; + ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>(); + synchronized (mNotificationList) { + final int N = mNotificationList.size(); + for (int i=0; i<N; i++) { + StatusBarNotification sbn = mNotificationList.get(i).sbn; + if (info.enabledAndUserMatches(sbn)) { + list.add(sbn); + } } } + return list.toArray(result); } - } - private void cancelToastLocked(int index) { - ToastRecord record = mToastQueue.get(index); - try { - record.callback.hide(); - } catch (RemoteException e) { - Slog.w(TAG, "Object died trying to hide notification " + record.callback - + " in package " + record.pkg); - // don't worry about this, we're about to remove it from - // the list anyway + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) + != PackageManager.PERMISSION_GRANTED) { + pw.println("Permission Denial: can't dump NotificationManager from from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid()); + return; + } + + dumpImpl(pw); } - mToastQueue.remove(index); - keepProcessAliveLocked(record.pid); - if (mToastQueue.size() > 0) { - // Show the next one. If the callback fails, this will remove - // it from the list, so don't assume that the list hasn't changed - // after this point. - showNextToastLocked(); + }; + + void dumpImpl(PrintWriter pw) { + pw.println("Current Notification Manager state:"); + + pw.println(" Listeners (" + mEnabledListenersForCurrentUser.size() + + ") enabled for current user:"); + for (ComponentName cmpt : mEnabledListenersForCurrentUser) { + pw.println(" " + cmpt); } - } - private void scheduleTimeoutLocked(ToastRecord r) - { - mHandler.removeCallbacksAndMessages(r); - Message m = Message.obtain(mHandler, MESSAGE_TIMEOUT, r); - long delay = r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY; - mHandler.sendMessageDelayed(m, delay); - } + pw.println(" Live listeners (" + mListeners.size() + "):"); + for (NotificationListenerInfo info : mListeners) { + pw.println(" " + info.component + + " (user " + info.userid + "): " + info.listener + + (info.isSystem?" SYSTEM":"")); + } + + int N; - private void handleTimeout(ToastRecord record) - { - if (DBG) Slog.d(TAG, "Timeout pkg=" + record.pkg + " callback=" + record.callback); synchronized (mToastQueue) { - int index = indexOfToastLocked(record.pkg, record.callback); - if (index >= 0) { - cancelToastLocked(index); + N = mToastQueue.size(); + if (N > 0) { + pw.println(" Toast Queue:"); + for (int i=0; i<N; i++) { + mToastQueue.get(i).dump(pw, " "); + } + pw.println(" "); } + } - } - // lock on mToastQueue - private int indexOfToastLocked(String pkg, ITransientNotification callback) - { - IBinder cbak = callback.asBinder(); - ArrayList<ToastRecord> list = mToastQueue; - int len = list.size(); - for (int i=0; i<len; i++) { - ToastRecord r = list.get(i); - if (r.pkg.equals(pkg) && r.callback.asBinder() == cbak) { - return i; + synchronized (mNotificationList) { + N = mNotificationList.size(); + if (N > 0) { + pw.println(" Notification List:"); + for (int i=0; i<N; i++) { + mNotificationList.get(i).dump(pw, " ", getContext()); + } + pw.println(" "); } - } - return -1; - } - // lock on mToastQueue - private void keepProcessAliveLocked(int pid) - { - int toastCount = 0; // toasts from this pid - ArrayList<ToastRecord> list = mToastQueue; - int N = list.size(); - for (int i=0; i<N; i++) { - ToastRecord r = list.get(i); - if (r.pid == pid) { - toastCount++; + N = mLights.size(); + if (N > 0) { + pw.println(" Lights List:"); + for (int i=0; i<N; i++) { + pw.println(" " + mLights.get(i)); + } + pw.println(" "); } - } - try { - mAm.setProcessForeground(mForegroundToken, pid, toastCount > 0); - } catch (RemoteException e) { - // Shouldn't happen. - } - } - private final class WorkerHandler extends Handler - { - @Override - public void handleMessage(Message msg) - { - switch (msg.what) - { - case MESSAGE_TIMEOUT: - handleTimeout((ToastRecord)msg.obj); + pw.println(" mSoundNotification=" + mSoundNotification); + pw.println(" mVibrateNotification=" + mVibrateNotification); + pw.println(" mDisabledNotifications=0x" + + Integer.toHexString(mDisabledNotifications)); + pw.println(" mSystemReady=" + mSystemReady); + pw.println(" mArchive=" + mArchive.toString()); + Iterator<StatusBarNotification> iter = mArchive.descendingIterator(); + int i=0; + while (iter.hasNext()) { + pw.println(" " + iter.next()); + if (++i >= 5) { + if (iter.hasNext()) pw.println(" ..."); break; + } } - } - } - - // Notifications - // ============================================================================ - public void enqueueNotificationWithTag(String pkg, String basePkg, String tag, int id, - Notification notification, int[] idOut, int userId) - { - enqueueNotificationInternal(pkg, basePkg, Binder.getCallingUid(), Binder.getCallingPid(), - tag, id, notification, idOut, userId); - } - - private final static int clamp(int x, int low, int high) { - return (x < low) ? low : ((x > high) ? high : x); + } } - // Not exposed via Binder; for system use only (otherwise malicious apps could spoof the - // uid/pid of another application) + /** + * The private API only accessible to the system process. + */ + private final NotificationManagerInternal mInternalService = new NotificationManagerInternal() { + @Override + public void enqueueNotification(String pkg, String basePkg, int callingUid, int callingPid, + String tag, int id, Notification notification, int[] idReceived, int userId) { + enqueueNotificationInternal(pkg, basePkg, callingUid, callingPid, tag, id, notification, + idReceived, userId); + } + }; - public void enqueueNotificationInternal(final String pkg, String basePkg, final int callingUid, + void enqueueNotificationInternal(final String pkg, String basePkg, final int callingUid, final int callingPid, final String tag, final int id, final Notification notification, - int[] idOut, int incomingUserId) - { + int[] idOut, int incomingUserId) { if (DBG) { - Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification); + Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + + " notification=" + notification); } checkCallerIsSystemOrSameApp(pkg); final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg)); @@ -1787,23 +1794,21 @@ public class NotificationManagerService extends INotificationManager.Stub if (notification.icon != 0) { if (old != null && old.statusBarKey != null) { r.statusBarKey = old.statusBarKey; - long identity = Binder.clearCallingIdentity(); + final long identity = Binder.clearCallingIdentity(); try { mStatusBar.updateNotification(r.statusBarKey, n); - } - finally { + } finally { Binder.restoreCallingIdentity(identity); } } else { - long identity = Binder.clearCallingIdentity(); + final long identity = Binder.clearCallingIdentity(); try { r.statusBarKey = mStatusBar.addNotification(n); if ((n.getNotification().flags & Notification.FLAG_SHOW_LIGHTS) != 0 && canInterrupt) { mAttentionLight.pulse(); } - } - finally { + } finally { Binder.restoreCallingIdentity(identity); } } @@ -1816,33 +1821,32 @@ public class NotificationManagerService extends INotificationManager.Stub } else { Slog.e(TAG, "Not posting notification with icon==0: " + notification); if (old != null && old.statusBarKey != null) { - long identity = Binder.clearCallingIdentity(); + final long identity = Binder.clearCallingIdentity(); try { mStatusBar.removeNotification(old.statusBarKey); - } - finally { + } finally { Binder.restoreCallingIdentity(identity); } notifyRemovedLocked(r); } // ATTENTION: in a future release we will bail out here - // so that we do not play sounds, show lights, etc. for invalid notifications + // so that we do not play sounds, show lights, etc. for invalid + // notifications Slog.e(TAG, "WARNING: In a future release this will crash the app: " + n.getPackageName()); } // If we're not supposed to beep, vibrate, etc. then don't. - if (((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0) + if (((mDisabledNotifications + & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0) && (!(old != null && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 )) && (r.getUserId() == UserHandle.USER_ALL || (r.getUserId() == userId && r.getUserId() == currentUser)) && canInterrupt - && mSystemReady) { - - final AudioManager audioManager = (AudioManager) mContext - .getSystemService(Context.AUDIO_SERVICE); + && mSystemReady + && mAudioManager != null) { // sound @@ -1861,7 +1865,7 @@ public class NotificationManagerService extends INotificationManager.Stub soundUri = Settings.System.DEFAULT_NOTIFICATION_URI; // check to see if the default notification sound is silent - ContentResolver resolver = mContext.getContentResolver(); + ContentResolver resolver = getContext().getContentResolver(); hasValidSound = Settings.System.getString(resolver, Settings.System.NOTIFICATION_SOUND) != null; } else if (notification.sound != null) { @@ -1870,7 +1874,8 @@ public class NotificationManagerService extends INotificationManager.Stub } if (hasValidSound) { - boolean looping = (notification.flags & Notification.FLAG_INSISTENT) != 0; + boolean looping = + (notification.flags & Notification.FLAG_INSISTENT) != 0; int audioStreamType; if (notification.audioStreamType >= 0) { audioStreamType = notification.audioStreamType; @@ -1880,11 +1885,12 @@ public class NotificationManagerService extends INotificationManager.Stub mSoundNotification = r; // do not play notifications if stream volume is 0 (typically because // ringer mode is silent) or if there is a user of exclusive audio focus - if ((audioManager.getStreamVolume(audioStreamType) != 0) - && !audioManager.isAudioFocusExclusive()) { + if ((mAudioManager.getStreamVolume(audioStreamType) != 0) + && !mAudioManager.isAudioFocusExclusive()) { final long identity = Binder.clearCallingIdentity(); try { - final IRingtonePlayer player = mAudioService.getRingtonePlayer(); + final IRingtonePlayer player = + mAudioManager.getRingtonePlayer(); if (player != null) { player.playAsync(soundUri, user, looping, audioStreamType); } @@ -1904,7 +1910,7 @@ public class NotificationManagerService extends INotificationManager.Stub final boolean convertSoundToVibration = !hasCustomVibrate && hasValidSound - && (audioManager.getRingerMode() + && (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE); // The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback. @@ -1912,7 +1918,7 @@ public class NotificationManagerService extends INotificationManager.Stub (notification.defaults & Notification.DEFAULT_VIBRATE) != 0; if ((useDefaultVibrate || convertSoundToVibration || hasCustomVibrate) - && !(audioManager.getRingerMode() + && !(mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT)) { mVibrateNotification = r; @@ -1966,8 +1972,158 @@ public class NotificationManagerService extends INotificationManager.Stub idOut[0] = id; } - private void sendAccessibilityEvent(Notification notification, CharSequence packageName) { - AccessibilityManager manager = AccessibilityManager.getInstance(mContext); + void registerListenerImpl(final INotificationListener listener, + final ComponentName component, final int userid) { + synchronized (mNotificationList) { + try { + NotificationListenerInfo info + = new NotificationListenerInfo(listener, component, userid, true); + listener.asBinder().linkToDeath(info, 0); + mListeners.add(info); + } catch (RemoteException e) { + // already dead + } + } + } + + void unregisterListenerImpl(final INotificationListener listener, final int userid) { + synchronized (mNotificationList) { + final int N = mListeners.size(); + for (int i=N-1; i>=0; i--) { + final NotificationListenerInfo info = mListeners.get(i); + if (info.listener.asBinder() == listener.asBinder() + && info.userid == userid) { + mListeners.remove(i); + if (info.connection != null) { + getContext().unbindService(info.connection); + } + } + } + } + } + + void showNextToastLocked() { + ToastRecord record = mToastQueue.get(0); + while (record != null) { + if (DBG) Slog.d(TAG, "Show pkg=" + record.pkg + " callback=" + record.callback); + try { + record.callback.show(); + scheduleTimeoutLocked(record); + return; + } catch (RemoteException e) { + Slog.w(TAG, "Object died trying to show notification " + record.callback + + " in package " + record.pkg); + // remove it from the list and let the process die + int index = mToastQueue.indexOf(record); + if (index >= 0) { + mToastQueue.remove(index); + } + keepProcessAliveLocked(record.pid); + if (mToastQueue.size() > 0) { + record = mToastQueue.get(0); + } else { + record = null; + } + } + } + } + + void cancelToastLocked(int index) { + ToastRecord record = mToastQueue.get(index); + try { + record.callback.hide(); + } catch (RemoteException e) { + Slog.w(TAG, "Object died trying to hide notification " + record.callback + + " in package " + record.pkg); + // don't worry about this, we're about to remove it from + // the list anyway + } + mToastQueue.remove(index); + keepProcessAliveLocked(record.pid); + if (mToastQueue.size() > 0) { + // Show the next one. If the callback fails, this will remove + // it from the list, so don't assume that the list hasn't changed + // after this point. + showNextToastLocked(); + } + } + + private void scheduleTimeoutLocked(ToastRecord r) + { + mHandler.removeCallbacksAndMessages(r); + Message m = Message.obtain(mHandler, MESSAGE_TIMEOUT, r); + long delay = r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY; + mHandler.sendMessageDelayed(m, delay); + } + + private void handleTimeout(ToastRecord record) + { + if (DBG) Slog.d(TAG, "Timeout pkg=" + record.pkg + " callback=" + record.callback); + synchronized (mToastQueue) { + int index = indexOfToastLocked(record.pkg, record.callback); + if (index >= 0) { + cancelToastLocked(index); + } + } + } + + // lock on mToastQueue + int indexOfToastLocked(String pkg, ITransientNotification callback) + { + IBinder cbak = callback.asBinder(); + ArrayList<ToastRecord> list = mToastQueue; + int len = list.size(); + for (int i=0; i<len; i++) { + ToastRecord r = list.get(i); + if (r.pkg.equals(pkg) && r.callback.asBinder() == cbak) { + return i; + } + } + return -1; + } + + // lock on mToastQueue + void keepProcessAliveLocked(int pid) + { + int toastCount = 0; // toasts from this pid + ArrayList<ToastRecord> list = mToastQueue; + int N = list.size(); + for (int i=0; i<N; i++) { + ToastRecord r = list.get(i); + if (r.pid == pid) { + toastCount++; + } + } + try { + mAm.setProcessForeground(mForegroundToken, pid, toastCount > 0); + } catch (RemoteException e) { + // Shouldn't happen. + } + } + + private final class WorkerHandler extends Handler + { + @Override + public void handleMessage(Message msg) + { + switch (msg.what) + { + case MESSAGE_TIMEOUT: + handleTimeout((ToastRecord)msg.obj); + break; + } + } + } + + + // Notifications + // ============================================================================ + static int clamp(int x, int low, int high) { + return (x < low) ? low : ((x > high) ? high : x); + } + + void sendAccessibilityEvent(Notification notification, CharSequence packageName) { + AccessibilityManager manager = AccessibilityManager.getInstance(getContext()); if (!manager.isEnabled()) { return; } @@ -2001,11 +2157,10 @@ public class NotificationManagerService extends INotificationManager.Stub // status bar if (r.getNotification().icon != 0) { - long identity = Binder.clearCallingIdentity(); + final long identity = Binder.clearCallingIdentity(); try { mStatusBar.removeNotification(r.statusBarKey); - } - finally { + } finally { Binder.restoreCallingIdentity(identity); } r.statusBarKey = null; @@ -2017,7 +2172,7 @@ public class NotificationManagerService extends INotificationManager.Stub mSoundNotification = null; final long identity = Binder.clearCallingIdentity(); try { - final IRingtonePlayer player = mAudioService.getRingtonePlayer(); + final IRingtonePlayer player = mAudioManager.getRingtonePlayer(); if (player != null) { player.stopAsync(); } @@ -2053,7 +2208,7 @@ public class NotificationManagerService extends INotificationManager.Stub * Cancels a notification ONLY if it has all of the {@code mustHaveFlags} * and none of the {@code mustNotHaveFlags}. */ - private void cancelNotification(final String pkg, final String tag, final int id, + void cancelNotification(final String pkg, final String tag, final int id, final int mustHaveFlags, final int mustNotHaveFlags, final boolean sendDelete, final int userId) { // In enqueueNotificationInternal notifications are added by scheduling the @@ -2146,26 +2301,7 @@ public class NotificationManagerService extends INotificationManager.Stub } } - public void cancelNotificationWithTag(String pkg, String tag, int id, int userId) { - checkCallerIsSystemOrSameApp(pkg); - userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg); - // Don't allow client applications to cancel foreground service notis. - cancelNotification(pkg, tag, id, 0, - Binder.getCallingUid() == Process.SYSTEM_UID - ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId); - } - - public void cancelAllNotifications(String pkg, int userId) { - checkCallerIsSystemOrSameApp(pkg); - - userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), userId, true, false, "cancelAllNotifications", pkg); - // Calling from user space, don't allow the canceling of actively - // running foreground services. - cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId); - } // Return true if the UID is a system or phone UID and therefore should not have // any notifications or toasts blocked. @@ -2225,7 +2361,7 @@ public class NotificationManagerService extends INotificationManager.Stub } // lock on mNotificationList - private void updateLightsLocked() + void updateLightsLocked() { // handle notification lights if (mLedNotification == null) { @@ -2251,14 +2387,14 @@ public class NotificationManagerService extends INotificationManager.Stub } if (mNotificationPulseEnabled) { // pulse repeatedly - mNotificationLight.setFlashing(ledARGB, LightsService.LIGHT_FLASH_TIMED, + mNotificationLight.setFlashing(ledARGB, Light.LIGHT_FLASH_TIMED, ledOnMS, ledOffMS); } } } // lock on mNotificationList - private int indexOfNotificationLocked(String pkg, String tag, int id, int userId) + int indexOfNotificationLocked(String pkg, String tag, int id, int userId) { ArrayList<NotificationRecord> list = mNotificationList; final int len = list.size(); @@ -2288,81 +2424,4 @@ public class NotificationManagerService extends INotificationManager.Stub updateLightsLocked(); } } - - // ====================================================================== - @Override - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - pw.println("Permission Denial: can't dump NotificationManager from from pid=" - + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid()); - return; - } - - pw.println("Current Notification Manager state:"); - - pw.println(" Listeners (" + mEnabledListenersForCurrentUser.size() - + ") enabled for current user:"); - for (ComponentName cmpt : mEnabledListenersForCurrentUser) { - pw.println(" " + cmpt); - } - - pw.println(" Live listeners (" + mListeners.size() + "):"); - for (NotificationListenerInfo info : mListeners) { - pw.println(" " + info.component - + " (user " + info.userid + "): " + info.listener - + (info.isSystem?" SYSTEM":"")); - } - - int N; - - synchronized (mToastQueue) { - N = mToastQueue.size(); - if (N > 0) { - pw.println(" Toast Queue:"); - for (int i=0; i<N; i++) { - mToastQueue.get(i).dump(pw, " "); - } - pw.println(" "); - } - - } - - synchronized (mNotificationList) { - N = mNotificationList.size(); - if (N > 0) { - pw.println(" Notification List:"); - for (int i=0; i<N; i++) { - mNotificationList.get(i).dump(pw, " ", mContext); - } - pw.println(" "); - } - - N = mLights.size(); - if (N > 0) { - pw.println(" Lights List:"); - for (int i=0; i<N; i++) { - pw.println(" " + mLights.get(i)); - } - pw.println(" "); - } - - pw.println(" mSoundNotification=" + mSoundNotification); - pw.println(" mVibrateNotification=" + mVibrateNotification); - pw.println(" mDisabledNotifications=0x" + Integer.toHexString(mDisabledNotifications)); - pw.println(" mSystemReady=" + mSystemReady); - pw.println(" mArchive=" + mArchive.toString()); - Iterator<StatusBarNotification> iter = mArchive.descendingIterator(); - int i=0; - while (iter.hasNext()) { - pw.println(" " + iter.next()); - if (++i >= 5) { - if (iter.hasNext()) pw.println(" ..."); - break; - } - } - - } - } } diff --git a/services/java/com/android/server/os/SchedulingPolicyService.java b/services/core/java/com/android/server/os/SchedulingPolicyService.java index c0123bf1b0f5..c0123bf1b0f5 100644 --- a/services/java/com/android/server/os/SchedulingPolicyService.java +++ b/services/core/java/com/android/server/os/SchedulingPolicyService.java diff --git a/services/java/com/android/server/pm/BasePermission.java b/services/core/java/com/android/server/pm/BasePermission.java index 4f27408a6fff..4f27408a6fff 100644 --- a/services/java/com/android/server/pm/BasePermission.java +++ b/services/core/java/com/android/server/pm/BasePermission.java diff --git a/services/java/com/android/server/pm/GrantedPermissions.java b/services/core/java/com/android/server/pm/GrantedPermissions.java index 14258a46a564..14258a46a564 100644 --- a/services/java/com/android/server/pm/GrantedPermissions.java +++ b/services/core/java/com/android/server/pm/GrantedPermissions.java diff --git a/services/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index 0d2b50316366..0d2b50316366 100644 --- a/services/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java diff --git a/services/java/com/android/server/pm/KeySetManager.java b/services/core/java/com/android/server/pm/KeySetManager.java index 66dc1d13c0e1..66dc1d13c0e1 100644 --- a/services/java/com/android/server/pm/KeySetManager.java +++ b/services/core/java/com/android/server/pm/KeySetManager.java diff --git a/services/java/com/android/server/pm/PackageKeySetData.java b/services/core/java/com/android/server/pm/PackageKeySetData.java index cb60621a851d..cb60621a851d 100644 --- a/services/java/com/android/server/pm/PackageKeySetData.java +++ b/services/core/java/com/android/server/pm/PackageKeySetData.java diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5761f6c07adb..b11ebf5bd5d5 100755 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -38,10 +38,10 @@ import com.android.internal.content.PackageHelper; import com.android.internal.util.FastPrintWriter; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; -import com.android.server.DeviceStorageMonitorService; import com.android.server.EventLogTags; import com.android.server.IntentResolver; +import com.android.server.LocalServices; import com.android.server.Watchdog; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -92,6 +92,7 @@ import android.content.pm.VerificationParams; import android.content.pm.VerifierDeviceIdentity; import android.content.pm.VerifierInfo; import android.content.res.Resources; +import android.hardware.display.DisplayManager; import android.net.Uri; import android.os.Binder; import android.os.Build; @@ -127,7 +128,6 @@ import android.util.Slog; import android.util.SparseArray; import android.util.Xml; import android.view.Display; -import android.view.WindowManager; import java.io.BufferedOutputStream; import java.io.File; @@ -162,6 +162,7 @@ import libcore.io.Libcore; import libcore.io.StructStat; import com.android.internal.R; +import com.android.server.storage.DeviceStorageMonitorInternal; /** * Keep track of all those .apks everywhere. @@ -1067,6 +1068,12 @@ public class PackageManagerService extends IPackageManager.Stub { return res; } + private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { + DisplayManager displayManager = (DisplayManager) context.getSystemService( + Context.DISPLAY_SERVICE); + displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); + } + public PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore) { EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, @@ -1114,9 +1121,7 @@ public class PackageManagerService extends IPackageManager.Stub { mInstaller = installer; - WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); - Display d = wm.getDefaultDisplay(); - d.getMetrics(mMetrics); + getDefaultDisplayMetrics(context, mMetrics); synchronized (mInstallLock) { // writer @@ -7339,6 +7344,15 @@ public class PackageManagerService extends IPackageManager.Stub { return pkgLite.recommendedInstallLocation; } + private long getMemoryLowThreshold() { + final DeviceStorageMonitorInternal + dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); + if (dsm == null) { + return 0L; + } + return dsm.getMemoryLowThreshold(); + } + /* * Invoke remote method to get package information and install * location values. Override install location based on default @@ -7356,15 +7370,9 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; } else { - final long lowThreshold; - - final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager - .getService(DeviceStorageMonitorService.SERVICE); - if (dsm == null) { + final long lowThreshold = getMemoryLowThreshold(); + if (lowThreshold == 0L) { Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); - lowThreshold = 0L; - } else { - lowThreshold = dsm.getMemoryLowThreshold(); } try { @@ -7922,8 +7930,8 @@ public class PackageManagerService extends IPackageManager.Stub { boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { final long lowThreshold; - final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager - .getService(DeviceStorageMonitorService.SERVICE); + final DeviceStorageMonitorInternal + dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); if (dsm == null) { Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); lowThreshold = 0L; @@ -9738,10 +9746,10 @@ public class PackageManagerService extends IPackageManager.Stub { clearExternalStorageDataSync(packageName, userId, true); if (succeeded) { // invoke DeviceStorageMonitor's update method to clear any notifications - DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) - ServiceManager.getService(DeviceStorageMonitorService.SERVICE); + DeviceStorageMonitorInternal + dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); if (dsm != null) { - dsm.updateMemory(); + dsm.checkMemory(); } } if(observer != null) { @@ -11566,12 +11574,17 @@ public class PackageManagerService extends IPackageManager.Stub { return true; } + @Override public boolean isStorageLow() { final long token = Binder.clearCallingIdentity(); try { - final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager - .getService(DeviceStorageMonitorService.SERVICE); - return dsm.isMemoryLow(); + final DeviceStorageMonitorInternal + dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); + if (dsm != null) { + return dsm.isMemoryLow(); + } else { + return false; + } } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java index b4478610509d..b4478610509d 100644 --- a/services/java/com/android/server/pm/PackageSetting.java +++ b/services/core/java/com/android/server/pm/PackageSetting.java diff --git a/services/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index 7747c8f9ecdf..7747c8f9ecdf 100644 --- a/services/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java diff --git a/services/java/com/android/server/pm/PackageSignatures.java b/services/core/java/com/android/server/pm/PackageSignatures.java index 9a20be7c8d76..9a20be7c8d76 100644 --- a/services/java/com/android/server/pm/PackageSignatures.java +++ b/services/core/java/com/android/server/pm/PackageSignatures.java diff --git a/services/java/com/android/server/pm/PackageVerificationResponse.java b/services/core/java/com/android/server/pm/PackageVerificationResponse.java index b2ae0dd433da..b2ae0dd433da 100644 --- a/services/java/com/android/server/pm/PackageVerificationResponse.java +++ b/services/core/java/com/android/server/pm/PackageVerificationResponse.java diff --git a/services/java/com/android/server/pm/PackageVerificationState.java b/services/core/java/com/android/server/pm/PackageVerificationState.java index 3214e8895fd5..3214e8895fd5 100644 --- a/services/java/com/android/server/pm/PackageVerificationState.java +++ b/services/core/java/com/android/server/pm/PackageVerificationState.java diff --git a/services/java/com/android/server/pm/PendingPackage.java b/services/core/java/com/android/server/pm/PendingPackage.java index c17cc46dbfb5..c17cc46dbfb5 100644 --- a/services/java/com/android/server/pm/PendingPackage.java +++ b/services/core/java/com/android/server/pm/PendingPackage.java diff --git a/services/java/com/android/server/pm/PreferredActivity.java b/services/core/java/com/android/server/pm/PreferredActivity.java index f93ba2fe9c59..89169264b0b6 100644 --- a/services/java/com/android/server/pm/PreferredActivity.java +++ b/services/core/java/com/android/server/pm/PreferredActivity.java @@ -17,7 +17,6 @@ package com.android.server.pm; import com.android.internal.util.XmlUtils; -import com.android.server.PreferredComponent; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; diff --git a/services/java/com/android/server/PreferredComponent.java b/services/core/java/com/android/server/pm/PreferredComponent.java index a7af252ca2ed..f437372e31a0 100644 --- a/services/java/com/android/server/PreferredComponent.java +++ b/services/core/java/com/android/server/pm/PreferredComponent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.pm; import com.android.internal.util.XmlUtils; diff --git a/services/java/com/android/server/pm/PreferredIntentResolver.java b/services/core/java/com/android/server/pm/PreferredIntentResolver.java index bce24d7b8817..bce24d7b8817 100644 --- a/services/java/com/android/server/pm/PreferredIntentResolver.java +++ b/services/core/java/com/android/server/pm/PreferredIntentResolver.java diff --git a/services/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java index 1d68afa546e8..1d68afa546e8 100644 --- a/services/java/com/android/server/pm/SELinuxMMAC.java +++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java diff --git a/services/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index e59940950136..e59940950136 100644 --- a/services/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java diff --git a/services/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java index ca1eeea69745..ca1eeea69745 100644 --- a/services/java/com/android/server/pm/SharedUserSetting.java +++ b/services/core/java/com/android/server/pm/SharedUserSetting.java diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index c33134a24d19..c33134a24d19 100644 --- a/services/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java diff --git a/services/java/com/android/server/power/DisplayBlanker.java b/services/core/java/com/android/server/power/DisplayBlanker.java index 6072053f96f2..6072053f96f2 100644 --- a/services/java/com/android/server/power/DisplayBlanker.java +++ b/services/core/java/com/android/server/power/DisplayBlanker.java diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/core/java/com/android/server/power/DisplayPowerController.java index 60d44c78e5b6..b8a78e34b1a1 100644 --- a/services/java/com/android/server/power/DisplayPowerController.java +++ b/services/core/java/com/android/server/power/DisplayPowerController.java @@ -16,10 +16,11 @@ package com.android.server.power; -import com.android.server.LightsService; -import com.android.server.TwilightService; -import com.android.server.TwilightService.TwilightState; +import com.android.server.lights.LightsManager; +import com.android.server.twilight.TwilightListener; +import com.android.server.twilight.TwilightManager; import com.android.server.display.DisplayManagerService; +import com.android.server.twilight.TwilightState; import android.animation.Animator; import android.animation.ObjectAnimator; @@ -179,10 +180,10 @@ final class DisplayPowerController { private Handler mCallbackHandler; // The lights service. - private final LightsService mLights; + private final LightsManager mLights; // The twilight service. - private final TwilightService mTwilight; + private final TwilightManager mTwilight; // The display manager. private final DisplayManagerService mDisplayManager; @@ -351,7 +352,7 @@ final class DisplayPowerController { * Creates the display power controller. */ public DisplayPowerController(Looper looper, Context context, Notifier notifier, - LightsService lights, TwilightService twilight, SensorManager sensorManager, + LightsManager lights, TwilightManager twilight, SensorManager sensorManager, DisplayManagerService displayManager, SuspendBlocker displaySuspendBlocker, DisplayBlanker displayBlanker, Callbacks callbacks, Handler callbackHandler) { @@ -528,7 +529,7 @@ final class DisplayPowerController { private void initialize() { mPowerState = new DisplayPowerState( new ElectronBeam(mDisplayManager), mDisplayBlanker, - mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT)); + mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT)); mElectronBeamOnAnimator = ObjectAnimator.ofFloat( mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f); @@ -1368,8 +1369,7 @@ final class DisplayPowerController { } }; - private final TwilightService.TwilightListener mTwilightListener = - new TwilightService.TwilightListener() { + private final TwilightListener mTwilightListener = new TwilightListener() { @Override public void onTwilightStateChanged() { mTwilightChanged = true; diff --git a/services/java/com/android/server/power/DisplayPowerRequest.java b/services/core/java/com/android/server/power/DisplayPowerRequest.java index 22f17d77ef71..22f17d77ef71 100644 --- a/services/java/com/android/server/power/DisplayPowerRequest.java +++ b/services/core/java/com/android/server/power/DisplayPowerRequest.java diff --git a/services/java/com/android/server/power/DisplayPowerState.java b/services/core/java/com/android/server/power/DisplayPowerState.java index fa318f8b6198..42af4b48bde9 100644 --- a/services/java/com/android/server/power/DisplayPowerState.java +++ b/services/core/java/com/android/server/power/DisplayPowerState.java @@ -16,7 +16,7 @@ package com.android.server.power; -import com.android.server.LightsService; +import com.android.server.lights.Light; import android.os.AsyncTask; import android.os.Handler; @@ -56,7 +56,7 @@ final class DisplayPowerState { private final Choreographer mChoreographer; private final ElectronBeam mElectronBeam; private final DisplayBlanker mDisplayBlanker; - private final LightsService.Light mBacklight; + private final Light mBacklight; private final PhotonicModulator mPhotonicModulator; private boolean mScreenOn; @@ -72,7 +72,7 @@ final class DisplayPowerState { private Runnable mCleanListener; public DisplayPowerState(ElectronBeam electronBean, - DisplayBlanker displayBlanker, LightsService.Light backlight) { + DisplayBlanker displayBlanker, Light backlight) { mHandler = new Handler(true /*async*/); mChoreographer = Choreographer.getInstance(); mElectronBeam = electronBean; diff --git a/services/java/com/android/server/power/ElectronBeam.java b/services/core/java/com/android/server/power/ElectronBeam.java index 729bd1669e83..729bd1669e83 100644 --- a/services/java/com/android/server/power/ElectronBeam.java +++ b/services/core/java/com/android/server/power/ElectronBeam.java diff --git a/services/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index 264e2e9c3b15..264e2e9c3b15 100644 --- a/services/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index da9548f7266e..13f55e2e4c54 100644 --- a/services/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -20,10 +20,11 @@ import com.android.internal.app.IAppOpsService; import com.android.internal.app.IBatteryStats; import com.android.server.BatteryService; import com.android.server.EventLogTags; -import com.android.server.LightsService; -import com.android.server.TwilightService; +import com.android.server.lights.LightsService; +import com.android.server.lights.Light; +import com.android.server.lights.LightsManager; +import com.android.server.twilight.TwilightManager; import com.android.server.Watchdog; -import com.android.server.am.ActivityManagerService; import com.android.server.display.DisplayManagerService; import com.android.server.dreams.DreamManagerService; @@ -168,7 +169,7 @@ public final class PowerManagerService extends IPowerManager.Stub private static final int DREAM_BATTERY_LEVEL_DRAIN_CUTOFF = 5; private Context mContext; - private LightsService mLightsService; + private LightsManager mLightsManager; private BatteryService mBatteryService; private DisplayManagerService mDisplayManagerService; private IBatteryStats mBatteryStats; @@ -181,7 +182,7 @@ public final class PowerManagerService extends IPowerManager.Stub private WirelessChargerDetector mWirelessChargerDetector; private SettingsObserver mSettingsObserver; private DreamManagerService mDreamManager; - private LightsService.Light mAttentionLight; + private Light mAttentionLight; private final Object mLock = new Object(); @@ -396,11 +397,11 @@ public final class PowerManagerService extends IPowerManager.Stub * Initialize the power manager. * Must be called before any other functions within the power manager are called. */ - public void init(Context context, LightsService ls, - ActivityManagerService am, BatteryService bs, IBatteryStats bss, + public void init(Context context, LightsManager ls, + BatteryService bs, IBatteryStats bss, IAppOpsService appOps, DisplayManagerService dm) { mContext = context; - mLightsService = ls; + mLightsManager = ls; mBatteryService = bs; mBatteryStats = bss; mAppOps = appOps; @@ -427,12 +428,12 @@ public final class PowerManagerService extends IPowerManager.Stub } } - public void systemReady(TwilightService twilight, DreamManagerService dreamManager) { + public void systemReady(TwilightManager twilight, DreamManagerService dreamManager) { synchronized (mLock) { mSystemReady = true; mDreamManager = dreamManager; - PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); + PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting(); mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting(); mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting(); @@ -448,7 +449,7 @@ public final class PowerManagerService extends IPowerManager.Stub // The display power controller runs on the power manager service's // own handler thread to ensure timely operation. mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(), - mContext, mNotifier, mLightsService, twilight, sensorManager, + mContext, mNotifier, mLightsManager, twilight, sensorManager, mDisplayManagerService, mDisplaySuspendBlocker, mDisplayBlanker, mDisplayPowerControllerCallbacks, mHandler); @@ -456,7 +457,7 @@ public final class PowerManagerService extends IPowerManager.Stub createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"), mHandler); mSettingsObserver = new SettingsObserver(mHandler); - mAttentionLight = mLightsService.getLight(LightsService.LIGHT_ID_ATTENTION); + mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION); // Register for broadcasts from other components of the system. IntentFilter filter = new IntentFilter(); @@ -2061,7 +2062,7 @@ public final class PowerManagerService extends IPowerManager.Stub } private void setAttentionLightInternal(boolean on, int color) { - LightsService.Light light; + Light light; synchronized (mLock) { if (!mSystemReady) { return; @@ -2070,7 +2071,7 @@ public final class PowerManagerService extends IPowerManager.Stub } // Control light outside of lock. - light.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0); + light.setFlashing(color, Light.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0); } /** diff --git a/services/java/com/android/server/power/RampAnimator.java b/services/core/java/com/android/server/power/RampAnimator.java index 4a4f0801240e..4a4f0801240e 100644 --- a/services/java/com/android/server/power/RampAnimator.java +++ b/services/core/java/com/android/server/power/RampAnimator.java diff --git a/services/java/com/android/server/power/ScreenOnBlocker.java b/services/core/java/com/android/server/power/ScreenOnBlocker.java index dbbbc6d2ab20..dbbbc6d2ab20 100644 --- a/services/java/com/android/server/power/ScreenOnBlocker.java +++ b/services/core/java/com/android/server/power/ScreenOnBlocker.java diff --git a/services/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java index 88a27f5f74dd..88a27f5f74dd 100644 --- a/services/java/com/android/server/power/ShutdownThread.java +++ b/services/core/java/com/android/server/power/ShutdownThread.java diff --git a/services/java/com/android/server/power/SuspendBlocker.java b/services/core/java/com/android/server/power/SuspendBlocker.java index 70b278a6f2df..70b278a6f2df 100644 --- a/services/java/com/android/server/power/SuspendBlocker.java +++ b/services/core/java/com/android/server/power/SuspendBlocker.java diff --git a/services/java/com/android/server/power/WirelessChargerDetector.java b/services/core/java/com/android/server/power/WirelessChargerDetector.java index 38f5d7740842..38f5d7740842 100644 --- a/services/java/com/android/server/power/WirelessChargerDetector.java +++ b/services/core/java/com/android/server/power/WirelessChargerDetector.java diff --git a/services/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java index b5d81d1a10fd..b5d81d1a10fd 100644 --- a/services/java/com/android/server/search/SearchManagerService.java +++ b/services/core/java/com/android/server/search/SearchManagerService.java diff --git a/services/java/com/android/server/search/Searchables.java b/services/core/java/com/android/server/search/Searchables.java index 0ffbb7d0aa59..0ffbb7d0aa59 100644 --- a/services/java/com/android/server/search/Searchables.java +++ b/services/core/java/com/android/server/search/Searchables.java diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java new file mode 100644 index 000000000000..4f7518966681 --- /dev/null +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2013, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.statusbar; + +import com.android.server.notification.NotificationDelegate; + +import android.os.IBinder; +import android.service.notification.StatusBarNotification; + +public interface StatusBarManagerInternal { + void setNotificationDelegate(NotificationDelegate delegate); + IBinder addNotification(StatusBarNotification notification); + void updateNotification(IBinder key, StatusBarNotification notification); + void removeNotification(IBinder key); +} diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index f207c08c579c..2ae467eabdd1 100644 --- a/services/java/com/android/server/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -14,26 +14,28 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.statusbar; import android.app.StatusBarManager; +import android.os.Binder; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; -import android.os.Binder; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.UserHandle; import android.util.Slog; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIconList; +import com.android.server.LocalServices; +import com.android.server.notification.NotificationDelegate; import com.android.server.wm.WindowManagerService; import java.io.FileDescriptor; @@ -51,31 +53,31 @@ import java.util.Map; public class StatusBarManagerService extends IStatusBarService.Stub implements WindowManagerService.OnHardKeyboardStatusChangeListener { - static final String TAG = "StatusBarManagerService"; - static final boolean SPEW = false; - - final Context mContext; - final WindowManagerService mWindowManager; - Handler mHandler = new Handler(); - NotificationCallbacks mNotificationCallbacks; - volatile IStatusBar mBar; - StatusBarIconList mIcons = new StatusBarIconList(); - HashMap<IBinder,StatusBarNotification> mNotifications + private static final String TAG = "StatusBarManagerService"; + private static final boolean SPEW = false; + + private final Context mContext; + private final WindowManagerService mWindowManager; + private Handler mHandler = new Handler(); + private NotificationDelegate mNotificationDelegate; + private volatile IStatusBar mBar; + private StatusBarIconList mIcons = new StatusBarIconList(); + private HashMap<IBinder,StatusBarNotification> mNotifications = new HashMap<IBinder,StatusBarNotification>(); // for disabling the status bar - final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>(); - IBinder mSysUiVisToken = new Binder(); - int mDisabled = 0; + private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>(); + private IBinder mSysUiVisToken = new Binder(); + private int mDisabled = 0; - Object mLock = new Object(); + private Object mLock = new Object(); // encompasses lights-out mode and other flags defined on View - int mSystemUiVisibility = 0; - boolean mMenuVisible = false; - int mImeWindowVis = 0; - int mImeBackDisposition; - IBinder mImeToken = null; - int mCurrentUserId; + private int mSystemUiVisibility = 0; + private boolean mMenuVisible = false; + private int mImeWindowVis = 0; + private int mImeBackDisposition; + private IBinder mImeToken = null; + private int mCurrentUserId; private class DisableRecord implements IBinder.DeathRecipient { int userId; @@ -90,16 +92,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } - public interface NotificationCallbacks { - void onSetDisabled(int status); - void onClearAll(); - void onNotificationClick(String pkg, String tag, int id); - void onNotificationClear(String pkg, String tag, int id); - void onPanelRevealed(); - void onNotificationError(String pkg, String tag, int id, - int uid, int initialPid, String message); - } - /** * Construct the service, add the status bar view to the window manager */ @@ -110,15 +102,74 @@ public class StatusBarManagerService extends IStatusBarService.Stub final Resources res = context.getResources(); mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons)); - } - public void setNotificationCallbacks(NotificationCallbacks listener) { - mNotificationCallbacks = listener; + LocalServices.addService(StatusBarManagerInternal.class, mInternalService); } + /** + * Private API used by NotificationManagerService. + */ + private final StatusBarManagerInternal mInternalService = new StatusBarManagerInternal() { + @Override + public void setNotificationDelegate(NotificationDelegate delegate) { + synchronized (mNotifications) { + mNotificationDelegate = delegate; + } + } + + @Override + public IBinder addNotification(StatusBarNotification notification) { + synchronized (mNotifications) { + IBinder key = new Binder(); + mNotifications.put(key, notification); + if (mBar != null) { + try { + mBar.addNotification(key, notification); + } catch (RemoteException ex) { + } + } + return key; + } + } + + @Override + public void updateNotification(IBinder key, StatusBarNotification notification) { + synchronized (mNotifications) { + if (!mNotifications.containsKey(key)) { + throw new IllegalArgumentException("updateNotification key not found: " + key); + } + mNotifications.put(key, notification); + if (mBar != null) { + try { + mBar.updateNotification(key, notification); + } catch (RemoteException ex) { + } + } + } + } + + @Override + public void removeNotification(IBinder key) { + synchronized (mNotifications) { + final StatusBarNotification n = mNotifications.remove(key); + if (n == null) { + Slog.e(TAG, "removeNotification key not found: " + key); + return; + } + if (mBar != null) { + try { + mBar.removeNotification(key); + } catch (RemoteException ex) { + } + } + } + } + }; + // ================================================================================ // From IStatusBarService // ================================================================================ + @Override public void expandNotificationsPanel() { enforceExpandStatusBar(); @@ -130,6 +181,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + @Override public void collapsePanels() { enforceExpandStatusBar(); @@ -141,6 +193,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + @Override public void expandSettingsPanel() { enforceExpandStatusBar(); @@ -152,6 +205,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + @Override public void disable(int what, IBinder token, String pkg) { disableInternal(mCurrentUserId, what, token, pkg); } @@ -177,7 +231,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub mDisabled = net; mHandler.post(new Runnable() { public void run() { - mNotificationCallbacks.onSetDisabled(net); + mNotificationDelegate.onSetDisabled(net); } }); if (mBar != null) { @@ -189,6 +243,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + @Override public void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription) { enforceStatusBar(); @@ -214,6 +269,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + @Override public void setIconVisibility(String slot, boolean visible) { enforceStatusBar(); @@ -241,6 +297,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + @Override public void removeIcon(String slot) { enforceStatusBar(); @@ -265,6 +322,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub * Hide or show the on-screen Menu key. Only call this from the window manager, typically in * response to a window with FLAG_NEEDS_MENU_KEY set. */ + @Override public void topAppWindowChanged(final boolean menuVisible) { enforceStatusBar(); @@ -285,6 +343,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + @Override public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition) { enforceStatusBar(); @@ -312,6 +371,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + @Override public void setSystemUiVisibility(int vis, int mask) { // also allows calls from window manager which is in this process. enforceStatusBarService(); @@ -344,6 +404,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + @Override public void setHardKeyboardEnabled(final boolean enabled) { mHandler.post(new Runnable() { public void run() { @@ -426,6 +487,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub // ================================================================================ // Callbacks from the status bar service. // ================================================================================ + @Override public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList, List<IBinder> notificationKeys, List<StatusBarNotification> notifications, int switches[], List<IBinder> binders) { @@ -458,86 +520,64 @@ public class StatusBarManagerService extends IStatusBarService.Stub * The status bar service should call this each time the user brings the panel from * invisible to visible in order to clear the notification light. */ + @Override public void onPanelRevealed() { enforceStatusBarService(); - - // tell the notification manager to turn off the lights. - mNotificationCallbacks.onPanelRevealed(); + long identity = Binder.clearCallingIdentity(); + try { + // tell the notification manager to turn off the lights. + mNotificationDelegate.onPanelRevealed(); + } finally { + Binder.restoreCallingIdentity(identity); + } } + @Override public void onNotificationClick(String pkg, String tag, int id) { enforceStatusBarService(); - - mNotificationCallbacks.onNotificationClick(pkg, tag, id); + long identity = Binder.clearCallingIdentity(); + try { + mNotificationDelegate.onNotificationClick(pkg, tag, id); + } finally { + Binder.restoreCallingIdentity(identity); + } } + @Override public void onNotificationError(String pkg, String tag, int id, int uid, int initialPid, String message) { enforceStatusBarService(); - - // WARNING: this will call back into us to do the remove. Don't hold any locks. - mNotificationCallbacks.onNotificationError(pkg, tag, id, uid, initialPid, message); + long identity = Binder.clearCallingIdentity(); + try { + // WARNING: this will call back into us to do the remove. Don't hold any locks. + mNotificationDelegate.onNotificationError(pkg, tag, id, uid, initialPid, message); + } finally { + Binder.restoreCallingIdentity(identity); + } } + @Override public void onNotificationClear(String pkg, String tag, int id) { enforceStatusBarService(); - - mNotificationCallbacks.onNotificationClear(pkg, tag, id); + long identity = Binder.clearCallingIdentity(); + try { + mNotificationDelegate.onNotificationClear(pkg, tag, id); + } finally { + Binder.restoreCallingIdentity(identity); + } } + @Override public void onClearAllNotifications() { enforceStatusBarService(); - - mNotificationCallbacks.onClearAll(); - } - - // ================================================================================ - // Callbacks for NotificationManagerService. - // ================================================================================ - public IBinder addNotification(StatusBarNotification notification) { - synchronized (mNotifications) { - IBinder key = new Binder(); - mNotifications.put(key, notification); - if (mBar != null) { - try { - mBar.addNotification(key, notification); - } catch (RemoteException ex) { - } - } - return key; + long identity = Binder.clearCallingIdentity(); + try { + mNotificationDelegate.onClearAll(); + } finally { + Binder.restoreCallingIdentity(identity); } } - public void updateNotification(IBinder key, StatusBarNotification notification) { - synchronized (mNotifications) { - if (!mNotifications.containsKey(key)) { - throw new IllegalArgumentException("updateNotification key not found: " + key); - } - mNotifications.put(key, notification); - if (mBar != null) { - try { - mBar.updateNotification(key, notification); - } catch (RemoteException ex) { - } - } - } - } - - public void removeNotification(IBinder key) { - synchronized (mNotifications) { - final StatusBarNotification n = mNotifications.remove(key); - if (n == null) { - Slog.e(TAG, "removeNotification key not found: " + key); - return; - } - if (mBar != null) { - try { - mBar.removeNotification(key); - } catch (RemoteException ex) { - } - } - } - } // ================================================================================ // Can be called from any thread diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorInternal.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorInternal.java new file mode 100644 index 000000000000..a91a81b3bffc --- /dev/null +++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorInternal.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2013, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.storage; + +public interface DeviceStorageMonitorInternal { + boolean isMemoryLow(); + long getMemoryLowThreshold(); + void checkMemory(); +} + diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java index 016c561077dc..88050841698f 100644 --- a/services/java/com/android/server/DeviceStorageMonitorService.java +++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java @@ -14,7 +14,10 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.storage; + +import com.android.server.EventLogTags; +import com.android.server.SystemService; import android.app.Notification; import android.app.NotificationManager; @@ -29,8 +32,8 @@ import android.os.Binder; import android.os.Environment; import android.os.FileObserver; import android.os.Handler; +import android.os.IBinder; import android.os.Message; -import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StatFs; @@ -66,13 +69,13 @@ import java.io.PrintWriter; * settings parameter with a default value of 2MB), the free memory is * logged to the event log. */ -public class DeviceStorageMonitorService extends Binder { - private static final String TAG = "DeviceStorageMonitorService"; +public class DeviceStorageMonitorService extends SystemService { + static final String TAG = "DeviceStorageMonitorService"; - private static final boolean DEBUG = false; - private static final boolean localLOGV = false; + static final boolean DEBUG = false; + static final boolean localLOGV = false; - private static final int DEVICE_MEMORY_WHAT = 1; + static final int DEVICE_MEMORY_WHAT = 1; private static final int MONITOR_INTERVAL = 1; //in minutes private static final int LOW_MEMORY_NOTIFICATION_ID = 1; @@ -84,9 +87,8 @@ public class DeviceStorageMonitorService extends Binder { private long mFreeMemAfterLastCacheClear; // on /data private long mLastReportedFreeMem; private long mLastReportedFreeMemTime; - private boolean mLowMemFlag=false; + boolean mLowMemFlag=false; private boolean mMemFullFlag=false; - private Context mContext; private ContentResolver mResolver; private long mTotalMemory; // on /data private StatFs mDataFileStats; @@ -98,19 +100,19 @@ public class DeviceStorageMonitorService extends Binder { private static final File CACHE_PATH = Environment.getDownloadCacheDirectory(); private long mThreadStartTime = -1; - private boolean mClearSucceeded = false; - private boolean mClearingCache; + boolean mClearSucceeded = false; + boolean mClearingCache; private Intent mStorageLowIntent; private Intent mStorageOkIntent; private Intent mStorageFullIntent; private Intent mStorageNotFullIntent; private CachePackageDataObserver mClearCacheObserver; - private final CacheFileDeletedObserver mCacheFileDeletedObserver; + private CacheFileDeletedObserver mCacheFileDeletedObserver; private static final int _TRUE = 1; private static final int _FALSE = 0; // This is the raw threshold that has been set at which we consider // storage to be low. - private long mMemLowThreshold; + long mMemLowThreshold; // This is the threshold at which we start trying to flush caches // to get below the low threshold limit. It is less than the low // threshold; we will allow storage to get a bit beyond the limit @@ -126,13 +128,13 @@ public class DeviceStorageMonitorService extends Binder { /** * This string is used for ServiceManager access to this class. */ - public static final String SERVICE = "devicestoragemonitor"; + static final String SERVICE = "devicestoragemonitor"; /** * Handler that checks the amount of disk space on the device and sends a * notification if the device runs low on disk space */ - Handler mHandler = new Handler() { + private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { //don't handle an invalid message @@ -144,7 +146,7 @@ public class DeviceStorageMonitorService extends Binder { } }; - class CachePackageDataObserver extends IPackageDataObserver.Stub { + private class CachePackageDataObserver extends IPackageDataObserver.Stub { public void onRemoveCompleted(String packageName, boolean succeeded) { mClearSucceeded = succeeded; mClearingCache = false; @@ -154,7 +156,7 @@ public class DeviceStorageMonitorService extends Binder { } } - private final void restatDataDir() { + private void restatDataDir() { try { mDataFileStats.restat(DATA_PATH.getAbsolutePath()); mFreeMem = (long) mDataFileStats.getAvailableBlocks() * @@ -206,7 +208,7 @@ public class DeviceStorageMonitorService extends Binder { } } - private final void clearCache() { + private void clearCache() { if (mClearCacheObserver == null) { // Lazy instantiation mClearCacheObserver = new CachePackageDataObserver(); @@ -223,7 +225,7 @@ public class DeviceStorageMonitorService extends Binder { } } - private final void checkMemory(boolean checkCache) { + void checkMemory(boolean checkCache) { //if the thread that was started to clear cache is still running do nothing till its //finished clearing cache. Ideally this flag could be modified by clearCache // and should be accessed via a lock but even if it does this test will fail now and @@ -300,7 +302,7 @@ public class DeviceStorageMonitorService extends Binder { postCheckMemoryMsg(true, DEFAULT_CHECK_INTERVAL); } - private void postCheckMemoryMsg(boolean clearCache, long delay) { + void postCheckMemoryMsg(boolean clearCache, long delay) { // Remove queued messages mHandler.removeMessages(DEVICE_MEMORY_WHAT); mHandler.sendMessageDelayed(mHandler.obtainMessage(DEVICE_MEMORY_WHAT, @@ -312,10 +314,10 @@ public class DeviceStorageMonitorService extends Binder { * Constructor to run service. initializes the disk space threshold value * and posts an empty message to kickstart the process. */ - public DeviceStorageMonitorService(Context context) { + @Override + public void onCreate(Context context) { mLastReportedFreeMemTime = 0; - mContext = context; - mResolver = mContext.getContentResolver(); + mResolver = context.getContentResolver(); //create StatFs object mDataFileStats = new StatFs(DATA_PATH.getAbsolutePath()); mSystemFileStats = new StatFs(SYSTEM_PATH.getAbsolutePath()); @@ -331,9 +333,12 @@ public class DeviceStorageMonitorService extends Binder { mStorageFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mStorageNotFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL); mStorageNotFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + } + @Override + public void onStart() { // cache storage thresholds - final StorageManager sm = StorageManager.from(context); + final StorageManager sm = StorageManager.from(getContext()); mMemLowThreshold = sm.getStorageLowBytes(DATA_PATH); mMemFullThreshold = sm.getStorageFullBytes(DATA_PATH); @@ -345,6 +350,78 @@ public class DeviceStorageMonitorService extends Binder { mCacheFileDeletedObserver = new CacheFileDeletedObserver(); mCacheFileDeletedObserver.startWatching(); + + publishBinderService(SERVICE, mRemoteService); + publishLocalService(DeviceStorageMonitorInternal.class, mLocalService); + } + + private final DeviceStorageMonitorInternal mLocalService = new DeviceStorageMonitorInternal() { + @Override + public void checkMemory() { + // force an early check + postCheckMemoryMsg(true, 0); + } + + @Override + public boolean isMemoryLow() { + return mLowMemFlag; + } + + @Override + public long getMemoryLowThreshold() { + return mMemLowThreshold; + } + }; + + private final IBinder mRemoteService = new Binder() { + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) + != PackageManager.PERMISSION_GRANTED) { + + pw.println("Permission Denial: can't dump " + SERVICE + " from from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid()); + return; + } + + dumpImpl(pw); + } + }; + + void dumpImpl(PrintWriter pw) { + final Context context = getContext(); + + pw.println("Current DeviceStorageMonitor state:"); + + pw.print(" mFreeMem="); pw.print(Formatter.formatFileSize(context, mFreeMem)); + pw.print(" mTotalMemory="); + pw.println(Formatter.formatFileSize(context, mTotalMemory)); + + pw.print(" mFreeMemAfterLastCacheClear="); + pw.println(Formatter.formatFileSize(context, mFreeMemAfterLastCacheClear)); + + pw.print(" mLastReportedFreeMem="); + pw.print(Formatter.formatFileSize(context, mLastReportedFreeMem)); + pw.print(" mLastReportedFreeMemTime="); + TimeUtils.formatDuration(mLastReportedFreeMemTime, SystemClock.elapsedRealtime(), pw); + pw.println(); + + pw.print(" mLowMemFlag="); pw.print(mLowMemFlag); + pw.print(" mMemFullFlag="); pw.println(mMemFullFlag); + + pw.print(" mClearSucceeded="); pw.print(mClearSucceeded); + pw.print(" mClearingCache="); pw.println(mClearingCache); + + pw.print(" mMemLowThreshold="); + pw.print(Formatter.formatFileSize(context, mMemLowThreshold)); + pw.print(" mMemFullThreshold="); + pw.println(Formatter.formatFileSize(context, mMemFullThreshold)); + + pw.print(" mMemCacheStartTrimThreshold="); + pw.print(Formatter.formatFileSize(context, mMemCacheStartTrimThreshold)); + pw.print(" mMemCacheTrimToThreshold="); + pw.println(Formatter.formatFileSize(context, mMemCacheTrimToThreshold)); } /** @@ -352,7 +429,8 @@ public class DeviceStorageMonitorService extends Binder { * an error dialog indicating low disk space and launch the Installer * application */ - private final void sendNotification() { + private void sendNotification() { + final Context context = getContext(); if(localLOGV) Slog.i(TAG, "Sending low memory notification"); //log the event to event log with the amount of free storage(in bytes) left on the device EventLog.writeEvent(EventLogTags.LOW_STORAGE, mFreeMem); @@ -363,86 +441,58 @@ public class DeviceStorageMonitorService extends Binder { lowMemIntent.putExtra("memory", mFreeMem); lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); NotificationManager mNotificationMgr = - (NotificationManager)mContext.getSystemService( + (NotificationManager)context.getSystemService( Context.NOTIFICATION_SERVICE); - CharSequence title = mContext.getText( + CharSequence title = context.getText( com.android.internal.R.string.low_internal_storage_view_title); - CharSequence details = mContext.getText( + CharSequence details = context.getText( com.android.internal.R.string.low_internal_storage_view_text); - PendingIntent intent = PendingIntent.getActivityAsUser(mContext, 0, lowMemIntent, 0, + PendingIntent intent = PendingIntent.getActivityAsUser(context, 0, lowMemIntent, 0, null, UserHandle.CURRENT); Notification notification = new Notification(); notification.icon = com.android.internal.R.drawable.stat_notify_disk_full; notification.tickerText = title; notification.flags |= Notification.FLAG_NO_CLEAR; - notification.setLatestEventInfo(mContext, title, details, intent); + notification.setLatestEventInfo(context, title, details, intent); mNotificationMgr.notifyAsUser(null, LOW_MEMORY_NOTIFICATION_ID, notification, UserHandle.ALL); - mContext.sendStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL); + context.sendStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL); } /** * Cancels low storage notification and sends OK intent. */ - private final void cancelNotification() { + private void cancelNotification() { + final Context context = getContext(); if(localLOGV) Slog.i(TAG, "Canceling low memory notification"); NotificationManager mNotificationMgr = - (NotificationManager)mContext.getSystemService( + (NotificationManager)context.getSystemService( Context.NOTIFICATION_SERVICE); //cancel notification since memory has been freed mNotificationMgr.cancelAsUser(null, LOW_MEMORY_NOTIFICATION_ID, UserHandle.ALL); - mContext.removeStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL); - mContext.sendBroadcastAsUser(mStorageOkIntent, UserHandle.ALL); + context.removeStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL); + context.sendBroadcastAsUser(mStorageOkIntent, UserHandle.ALL); } /** * Send a notification when storage is full. */ - private final void sendFullNotification() { + private void sendFullNotification() { if(localLOGV) Slog.i(TAG, "Sending memory full notification"); - mContext.sendStickyBroadcastAsUser(mStorageFullIntent, UserHandle.ALL); + getContext().sendStickyBroadcastAsUser(mStorageFullIntent, UserHandle.ALL); } /** * Cancels memory full notification and sends "not full" intent. */ - private final void cancelFullNotification() { + private void cancelFullNotification() { if(localLOGV) Slog.i(TAG, "Canceling memory full notification"); - mContext.removeStickyBroadcastAsUser(mStorageFullIntent, UserHandle.ALL); - mContext.sendBroadcastAsUser(mStorageNotFullIntent, UserHandle.ALL); + getContext().removeStickyBroadcastAsUser(mStorageFullIntent, UserHandle.ALL); + getContext().sendBroadcastAsUser(mStorageNotFullIntent, UserHandle.ALL); } - public void updateMemory() { - int callingUid = getCallingUid(); - if(callingUid != Process.SYSTEM_UID) { - return; - } - // force an early check - postCheckMemoryMsg(true, 0); - } - - /** - * Callable from other things in the system service to obtain the low memory - * threshold. - * - * @return low memory threshold in bytes - */ - public long getMemoryLowThreshold() { - return mMemLowThreshold; - } - - /** - * Callable from other things in the system process to check whether memory - * is low. - * - * @return true is memory is low - */ - public boolean isMemoryLow() { - return mLowMemFlag; - } - - public static class CacheFileDeletedObserver extends FileObserver { + private static class CacheFileDeletedObserver extends FileObserver { public CacheFileDeletedObserver() { super(Environment.getDownloadCacheDirectory().getAbsolutePath(), FileObserver.DELETE); } @@ -452,40 +502,4 @@ public class DeviceStorageMonitorService extends Binder { EventLogTags.writeCacheFileDeleted(path); } } - - @Override - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - - pw.println("Permission Denial: can't dump " + SERVICE + " from from pid=" - + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid()); - return; - } - - pw.println("Current DeviceStorageMonitor state:"); - pw.print(" mFreeMem="); pw.print(Formatter.formatFileSize(mContext, mFreeMem)); - pw.print(" mTotalMemory="); - pw.println(Formatter.formatFileSize(mContext, mTotalMemory)); - pw.print(" mFreeMemAfterLastCacheClear="); - pw.println(Formatter.formatFileSize(mContext, mFreeMemAfterLastCacheClear)); - pw.print(" mLastReportedFreeMem="); - pw.print(Formatter.formatFileSize(mContext, mLastReportedFreeMem)); - pw.print(" mLastReportedFreeMemTime="); - TimeUtils.formatDuration(mLastReportedFreeMemTime, SystemClock.elapsedRealtime(), pw); - pw.println(); - pw.print(" mLowMemFlag="); pw.print(mLowMemFlag); - pw.print(" mMemFullFlag="); pw.println(mMemFullFlag); - pw.print(" mClearSucceeded="); pw.print(mClearSucceeded); - pw.print(" mClearingCache="); pw.println(mClearingCache); - pw.print(" mMemLowThreshold="); - pw.print(Formatter.formatFileSize(mContext, mMemLowThreshold)); - pw.print(" mMemFullThreshold="); - pw.println(Formatter.formatFileSize(mContext, mMemFullThreshold)); - pw.print(" mMemCacheStartTrimThreshold="); - pw.print(Formatter.formatFileSize(mContext, mMemCacheStartTrimThreshold)); - pw.print(" mMemCacheTrimToThreshold="); - pw.println(Formatter.formatFileSize(mContext, mMemCacheTrimToThreshold)); - } } diff --git a/services/core/java/com/android/server/twilight/TwilightListener.java b/services/core/java/com/android/server/twilight/TwilightListener.java new file mode 100644 index 000000000000..29ead445892e --- /dev/null +++ b/services/core/java/com/android/server/twilight/TwilightListener.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.twilight; + +public interface TwilightListener { + void onTwilightStateChanged(); +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/twilight/TwilightManager.java b/services/core/java/com/android/server/twilight/TwilightManager.java new file mode 100644 index 000000000000..b3de58b279af --- /dev/null +++ b/services/core/java/com/android/server/twilight/TwilightManager.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.twilight; + +import android.os.Handler; + +public interface TwilightManager { + void registerListener(TwilightListener listener, Handler handler); + TwilightState getCurrentState(); +} diff --git a/services/java/com/android/server/TwilightService.java b/services/core/java/com/android/server/twilight/TwilightService.java index 0356faa610f5..8feb97b36f46 100644 --- a/services/java/com/android/server/TwilightService.java +++ b/services/core/java/com/android/server/twilight/TwilightService.java @@ -14,7 +14,10 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.twilight; + +import com.android.server.SystemService; +import com.android.server.TwilightCalculator; import android.app.AlarmManager; import android.app.PendingIntent; @@ -34,9 +37,7 @@ import android.text.format.DateUtils; import android.text.format.Time; import android.util.Slog; -import java.text.DateFormat; import java.util.ArrayList; -import java.util.Date; import java.util.Iterator; import libcore.util.Objects; @@ -47,78 +48,88 @@ import libcore.util.Objects; * Used by the UI mode manager and other components to adjust night mode * effects based on sunrise and sunset. */ -public final class TwilightService { - private static final String TAG = "TwilightService"; - - private static final boolean DEBUG = false; - - private static final String ACTION_UPDATE_TWILIGHT_STATE = +public final class TwilightService extends SystemService { + static final String TAG = "TwilightService"; + static final boolean DEBUG = false; + static final String ACTION_UPDATE_TWILIGHT_STATE = "com.android.server.action.UPDATE_TWILIGHT_STATE"; - private final Context mContext; - private final AlarmManager mAlarmManager; - private final LocationManager mLocationManager; - private final LocationHandler mLocationHandler; + final Object mLock = new Object(); - private final Object mLock = new Object(); + AlarmManager mAlarmManager; + LocationManager mLocationManager; + LocationHandler mLocationHandler; - private final ArrayList<TwilightListenerRecord> mListeners = + final ArrayList<TwilightListenerRecord> mListeners = new ArrayList<TwilightListenerRecord>(); - private boolean mSystemReady; + TwilightState mTwilightState; - private TwilightState mTwilightState; + @Override + public void onStart() { + mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); + mLocationManager = (LocationManager) getContext().getSystemService( + Context.LOCATION_SERVICE); + mLocationHandler = new LocationHandler(); - public TwilightService(Context context) { - mContext = context; + IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED); + filter.addAction(Intent.ACTION_TIME_CHANGED); + filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); + filter.addAction(ACTION_UPDATE_TWILIGHT_STATE); + getContext().registerReceiver(mUpdateLocationReceiver, filter); - mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); - mLocationManager = (LocationManager)mContext.getSystemService(Context.LOCATION_SERVICE); - mLocationHandler = new LocationHandler(); + publishLocalService(TwilightManager.class, mService); } - void systemReady() { - synchronized (mLock) { - mSystemReady = true; + private static class TwilightListenerRecord implements Runnable { + private final TwilightListener mListener; + private final Handler mHandler; - IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED); - filter.addAction(Intent.ACTION_TIME_CHANGED); - filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); - filter.addAction(ACTION_UPDATE_TWILIGHT_STATE); - mContext.registerReceiver(mUpdateLocationReceiver, filter); + public TwilightListenerRecord(TwilightListener listener, Handler handler) { + mListener = listener; + mHandler = handler; + } - if (!mListeners.isEmpty()) { - mLocationHandler.enableLocationUpdates(); - } + public void postUpdate() { + mHandler.post(this); } - } - /** - * Gets the current twilight state. - * - * @return The current twilight state, or null if no information is available. - */ - public TwilightState getCurrentState() { - synchronized (mLock) { - return mTwilightState; + @Override + public void run() { + mListener.onTwilightStateChanged(); } + } - /** - * Listens for twilight time. - * - * @param listener The listener. - * @param handler The handler on which to post calls into the listener. - */ - public void registerListener(TwilightListener listener, Handler handler) { - synchronized (mLock) { - mListeners.add(new TwilightListenerRecord(listener, handler)); + private final TwilightManager mService = new TwilightManager() { + /** + * Gets the current twilight state. + * + * @return The current twilight state, or null if no information is available. + */ + @Override + public TwilightState getCurrentState() { + synchronized (mLock) { + return mTwilightState; + } + } - if (mSystemReady && mListeners.size() == 1) { - mLocationHandler.enableLocationUpdates(); + /** + * Listens for twilight time. + * + * @param listener The listener. + */ + @Override + public void registerListener(TwilightListener listener, Handler handler) { + synchronized (mLock) { + mListeners.add(new TwilightListenerRecord(listener, handler)); + + if (mListeners.size() == 1) { + mLocationHandler.enableLocationUpdates(); + } } } - } + }; private void setTwilightState(TwilightState state) { synchronized (mLock) { @@ -128,9 +139,10 @@ public final class TwilightService { } mTwilightState = state; - int count = mListeners.size(); - for (int i = 0; i < count; i++) { - mListeners.get(i).post(); + + final int listenerLen = mListeners.size(); + for (int i = 0; i < listenerLen; i++) { + mListeners.get(i).postUpdate(); } } } @@ -162,124 +174,6 @@ public final class TwilightService { return distance >= totalAccuracy; } - /** - * Describes whether it is day or night. - * This object is immutable. - */ - public static final class TwilightState { - private final boolean mIsNight; - private final long mYesterdaySunset; - private final long mTodaySunrise; - private final long mTodaySunset; - private final long mTomorrowSunrise; - - TwilightState(boolean isNight, - long yesterdaySunset, - long todaySunrise, long todaySunset, - long tomorrowSunrise) { - mIsNight = isNight; - mYesterdaySunset = yesterdaySunset; - mTodaySunrise = todaySunrise; - mTodaySunset = todaySunset; - mTomorrowSunrise = tomorrowSunrise; - } - - /** - * Returns true if it is currently night time. - */ - public boolean isNight() { - return mIsNight; - } - - /** - * Returns the time of yesterday's sunset in the System.currentTimeMillis() timebase, - * or -1 if the sun never sets. - */ - public long getYesterdaySunset() { - return mYesterdaySunset; - } - - /** - * Returns the time of today's sunrise in the System.currentTimeMillis() timebase, - * or -1 if the sun never rises. - */ - public long getTodaySunrise() { - return mTodaySunrise; - } - - /** - * Returns the time of today's sunset in the System.currentTimeMillis() timebase, - * or -1 if the sun never sets. - */ - public long getTodaySunset() { - return mTodaySunset; - } - - /** - * Returns the time of tomorrow's sunrise in the System.currentTimeMillis() timebase, - * or -1 if the sun never rises. - */ - public long getTomorrowSunrise() { - return mTomorrowSunrise; - } - - @Override - public boolean equals(Object o) { - return o instanceof TwilightState && equals((TwilightState)o); - } - - public boolean equals(TwilightState other) { - return other != null - && mIsNight == other.mIsNight - && mYesterdaySunset == other.mYesterdaySunset - && mTodaySunrise == other.mTodaySunrise - && mTodaySunset == other.mTodaySunset - && mTomorrowSunrise == other.mTomorrowSunrise; - } - - @Override - public int hashCode() { - return 0; // don't care - } - - @Override - public String toString() { - DateFormat f = DateFormat.getDateTimeInstance(); - return "{TwilightState: isNight=" + mIsNight - + ", mYesterdaySunset=" + f.format(new Date(mYesterdaySunset)) - + ", mTodaySunrise=" + f.format(new Date(mTodaySunrise)) - + ", mTodaySunset=" + f.format(new Date(mTodaySunset)) - + ", mTomorrowSunrise=" + f.format(new Date(mTomorrowSunrise)) - + "}"; - } - } - - /** - * Listener for changes in twilight state. - */ - public interface TwilightListener { - public void onTwilightStateChanged(); - } - - private static final class TwilightListenerRecord implements Runnable { - private final TwilightListener mListener; - private final Handler mHandler; - - public TwilightListenerRecord(TwilightListener listener, Handler handler) { - mListener = listener; - mHandler = handler; - } - - public void post() { - mHandler.post(this); - } - - @Override - public void run() { - mListener.onTwilightStateChanged(); - } - } - private final class LocationHandler extends Handler { private static final int MSG_ENABLE_LOCATION_UPDATES = 1; private static final int MSG_GET_NEW_LOCATION_UPDATE = 2; @@ -518,11 +412,12 @@ public final class TwilightService { } Intent updateIntent = new Intent(ACTION_UPDATE_TWILIGHT_STATE); - PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, updateIntent, 0); + PendingIntent pendingIntent = PendingIntent.getBroadcast( + getContext(), 0, updateIntent, 0); mAlarmManager.cancel(pendingIntent); mAlarmManager.setExact(AlarmManager.RTC, nextUpdate, pendingIntent); } - }; + } private final BroadcastReceiver mUpdateLocationReceiver = new BroadcastReceiver() { @Override diff --git a/services/core/java/com/android/server/twilight/TwilightState.java b/services/core/java/com/android/server/twilight/TwilightState.java new file mode 100644 index 000000000000..91e24d7d55bf --- /dev/null +++ b/services/core/java/com/android/server/twilight/TwilightState.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.twilight; + +import java.text.DateFormat; +import java.util.Date; + +/** + * Describes whether it is day or night. + * This object is immutable. + */ +public class TwilightState { + private final boolean mIsNight; + private final long mYesterdaySunset; + private final long mTodaySunrise; + private final long mTodaySunset; + private final long mTomorrowSunrise; + + TwilightState(boolean isNight, + long yesterdaySunset, + long todaySunrise, long todaySunset, + long tomorrowSunrise) { + mIsNight = isNight; + mYesterdaySunset = yesterdaySunset; + mTodaySunrise = todaySunrise; + mTodaySunset = todaySunset; + mTomorrowSunrise = tomorrowSunrise; + } + + /** + * Returns true if it is currently night time. + */ + public boolean isNight() { + return mIsNight; + } + + /** + * Returns the time of yesterday's sunset in the System.currentTimeMillis() timebase, + * or -1 if the sun never sets. + */ + public long getYesterdaySunset() { + return mYesterdaySunset; + } + + /** + * Returns the time of today's sunrise in the System.currentTimeMillis() timebase, + * or -1 if the sun never rises. + */ + public long getTodaySunrise() { + return mTodaySunrise; + } + + /** + * Returns the time of today's sunset in the System.currentTimeMillis() timebase, + * or -1 if the sun never sets. + */ + public long getTodaySunset() { + return mTodaySunset; + } + + /** + * Returns the time of tomorrow's sunrise in the System.currentTimeMillis() timebase, + * or -1 if the sun never rises. + */ + public long getTomorrowSunrise() { + return mTomorrowSunrise; + } + + @Override + public boolean equals(Object o) { + return o instanceof TwilightState && equals((TwilightState)o); + } + + public boolean equals(TwilightState other) { + return other != null + && mIsNight == other.mIsNight + && mYesterdaySunset == other.mYesterdaySunset + && mTodaySunrise == other.mTodaySunrise + && mTodaySunset == other.mTodaySunset + && mTomorrowSunrise == other.mTomorrowSunrise; + } + + @Override + public int hashCode() { + return 0; // don't care + } + + @Override + public String toString() { + DateFormat f = DateFormat.getDateTimeInstance(); + return "{TwilightState: isNight=" + mIsNight + + ", mYesterdaySunset=" + f.format(new Date(mYesterdaySunset)) + + ", mTodaySunrise=" + f.format(new Date(mTodaySunrise)) + + ", mTodaySunset=" + f.format(new Date(mTodaySunset)) + + ", mTomorrowSunrise=" + f.format(new Date(mTomorrowSunrise)) + + "}"; + } +} diff --git a/services/java/com/android/server/updates/CarrierProvisioningUrlsInstallReceiver.java b/services/core/java/com/android/server/updates/CarrierProvisioningUrlsInstallReceiver.java index b53fb650c627..b53fb650c627 100644 --- a/services/java/com/android/server/updates/CarrierProvisioningUrlsInstallReceiver.java +++ b/services/core/java/com/android/server/updates/CarrierProvisioningUrlsInstallReceiver.java diff --git a/services/java/com/android/server/updates/CertPinInstallReceiver.java b/services/core/java/com/android/server/updates/CertPinInstallReceiver.java index c03fbc3d0aed..c03fbc3d0aed 100644 --- a/services/java/com/android/server/updates/CertPinInstallReceiver.java +++ b/services/core/java/com/android/server/updates/CertPinInstallReceiver.java diff --git a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java index 9601e9ad7ccb..9601e9ad7ccb 100644 --- a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java +++ b/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java diff --git a/services/java/com/android/server/updates/IntentFirewallInstallReceiver.java b/services/core/java/com/android/server/updates/IntentFirewallInstallReceiver.java index 0b54f92103dd..0b54f92103dd 100644 --- a/services/java/com/android/server/updates/IntentFirewallInstallReceiver.java +++ b/services/core/java/com/android/server/updates/IntentFirewallInstallReceiver.java diff --git a/services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java b/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java index e43081436324..e43081436324 100644 --- a/services/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java +++ b/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java diff --git a/services/java/com/android/server/updates/SmsShortCodesInstallReceiver.java b/services/core/java/com/android/server/updates/SmsShortCodesInstallReceiver.java index 0f14f57cbd5a..0f14f57cbd5a 100644 --- a/services/java/com/android/server/updates/SmsShortCodesInstallReceiver.java +++ b/services/core/java/com/android/server/updates/SmsShortCodesInstallReceiver.java diff --git a/services/java/com/android/server/updates/TZInfoInstallReceiver.java b/services/core/java/com/android/server/updates/TZInfoInstallReceiver.java index 83adbdbd7799..83adbdbd7799 100644 --- a/services/java/com/android/server/updates/TZInfoInstallReceiver.java +++ b/services/core/java/com/android/server/updates/TZInfoInstallReceiver.java diff --git a/services/java/com/android/server/usb/UsbDebuggingManager.java b/services/core/java/com/android/server/usb/UsbDebuggingManager.java index ce953a4b134e..ce953a4b134e 100644 --- a/services/java/com/android/server/usb/UsbDebuggingManager.java +++ b/services/core/java/com/android/server/usb/UsbDebuggingManager.java diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/core/java/com/android/server/usb/UsbDeviceManager.java index 5a60de0f269b..5a60de0f269b 100644 --- a/services/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/core/java/com/android/server/usb/UsbDeviceManager.java diff --git a/services/java/com/android/server/usb/UsbHostManager.java b/services/core/java/com/android/server/usb/UsbHostManager.java index dfaad0bcece9..dfaad0bcece9 100644 --- a/services/java/com/android/server/usb/UsbHostManager.java +++ b/services/core/java/com/android/server/usb/UsbHostManager.java diff --git a/services/java/com/android/server/usb/UsbService.java b/services/core/java/com/android/server/usb/UsbService.java index 36669b1a8178..36669b1a8178 100644 --- a/services/java/com/android/server/usb/UsbService.java +++ b/services/core/java/com/android/server/usb/UsbService.java diff --git a/services/java/com/android/server/usb/UsbSettingsManager.java b/services/core/java/com/android/server/usb/UsbSettingsManager.java index ff4857ba1be8..ff4857ba1be8 100644 --- a/services/java/com/android/server/usb/UsbSettingsManager.java +++ b/services/core/java/com/android/server/usb/UsbSettingsManager.java diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index e6b6b93a1d46..97ea52c0a4a2 100644 --- a/services/java/com/android/server/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.wallpaper; import static android.os.ParcelFileDescriptor.*; @@ -85,8 +85,8 @@ import com.android.internal.content.PackageMonitor; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.JournaledFile; -class WallpaperManagerService extends IWallpaperManager.Stub { - static final String TAG = "WallpaperService"; +public class WallpaperManagerService extends IWallpaperManager.Stub { + static final String TAG = "WallpaperManagerService"; static final boolean DEBUG = false; final Object mLock = new Object[0]; @@ -98,7 +98,6 @@ class WallpaperManagerService extends IWallpaperManager.Stub { static final long MIN_WALLPAPER_CRASH_TIME = 10000; static final String WALLPAPER = "wallpaper"; static final String WALLPAPER_INFO = "wallpaper_info.xml"; - /** * Name of the component used to display bitmap wallpapers from either the gallery or * built-in wallpapers. @@ -505,7 +504,12 @@ class WallpaperManagerService extends IWallpaperManager.Stub { } } - String getName() { + /** Called by SystemBackupAgent */ + public String getName() { + // Verify caller is the system + if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) { + throw new RuntimeException("getName() can only be called from the system process"); + } synchronized (mLock) { return mWallpaperMap.get(0).name; } @@ -1175,7 +1179,11 @@ class WallpaperManagerService extends IWallpaperManager.Stub { } // Called by SystemBackupAgent after files are restored to disk. - void settingsRestored() { + public void settingsRestored() { + // Verify caller is the system + if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) { + throw new RuntimeException("settingsRestored() can only be called from the system process"); + } // TODO: If necessary, make it work for secondary users as well. This currently assumes // restores only to the primary user if (DEBUG) Slog.v(TAG, "settingsRestored"); diff --git a/services/java/com/android/server/wifi/README.txt b/services/core/java/com/android/server/wifi/README.txt index 39e14751ab13..39e14751ab13 100644 --- a/services/java/com/android/server/wifi/README.txt +++ b/services/core/java/com/android/server/wifi/README.txt diff --git a/services/java/com/android/server/wifi/WifiController.java b/services/core/java/com/android/server/wifi/WifiController.java index a3d514e304ca..a3d514e304ca 100644 --- a/services/java/com/android/server/wifi/WifiController.java +++ b/services/core/java/com/android/server/wifi/WifiController.java diff --git a/services/java/com/android/server/wifi/WifiNotificationController.java b/services/core/java/com/android/server/wifi/WifiNotificationController.java index a9206e09b803..a9206e09b803 100644 --- a/services/java/com/android/server/wifi/WifiNotificationController.java +++ b/services/core/java/com/android/server/wifi/WifiNotificationController.java diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/core/java/com/android/server/wifi/WifiService.java index f2efde101565..f2efde101565 100644 --- a/services/java/com/android/server/wifi/WifiService.java +++ b/services/core/java/com/android/server/wifi/WifiService.java diff --git a/services/java/com/android/server/wifi/WifiSettingsStore.java b/services/core/java/com/android/server/wifi/WifiSettingsStore.java index 3ff80616142c..3ff80616142c 100644 --- a/services/java/com/android/server/wifi/WifiSettingsStore.java +++ b/services/core/java/com/android/server/wifi/WifiSettingsStore.java diff --git a/services/java/com/android/server/wifi/WifiTrafficPoller.java b/services/core/java/com/android/server/wifi/WifiTrafficPoller.java index b4985509047c..b4985509047c 100644 --- a/services/java/com/android/server/wifi/WifiTrafficPoller.java +++ b/services/core/java/com/android/server/wifi/WifiTrafficPoller.java diff --git a/services/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 756e06a68d87..756e06a68d87 100644 --- a/services/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java index 3cccf1d534f2..3cccf1d534f2 100644 --- a/services/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index e98014bdea3e..e98014bdea3e 100644 --- a/services/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java diff --git a/services/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java index 5aa266d473bd..5aa266d473bd 100644 --- a/services/java/com/android/server/wm/BlackFrame.java +++ b/services/core/java/com/android/server/wm/BlackFrame.java diff --git a/services/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java index c189ddd86c14..978d5b742ee5 100644 --- a/services/java/com/android/server/wm/DimLayer.java +++ b/services/core/java/com/android/server/wm/DimLayer.java @@ -166,7 +166,7 @@ public class DimLayer { final int dw, dh; final float xPos, yPos; - if (mStack.hasSibling()) { + if (!mStack.isFullscreen()) { dw = mBounds.width(); dh = mBounds.height(); xPos = mBounds.left; diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index d358b4c6ed67..0a070c1402ee 100644 --- a/services/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -21,14 +21,13 @@ import static com.android.server.wm.WindowManagerService.DEBUG_STACK; import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerService.TAG; -import android.app.ActivityManager.StackBoxInfo; import android.graphics.Rect; import android.graphics.Region; -import android.os.Debug; import android.util.EventLog; import android.util.Slog; import android.view.Display; import android.view.DisplayInfo; +import android.view.Surface; import com.android.server.EventLogTags; import java.io.PrintWriter; @@ -74,6 +73,7 @@ class DisplayContent { private final Display mDisplay; Rect mBaseDisplayRect = new Rect(); + Rect mContentRect = new Rect(); // Accessed directly by all users. boolean layoutNeeded; @@ -92,11 +92,12 @@ class DisplayContent { */ final AppTokenList mExitingAppTokens = new AppTokenList(); - /** Array containing the home StackBox and possibly one more which would contain apps. Array + /** Array containing all TaskStacks on this display. Array * is stored in display order with the current bottom stack at 0. */ - private ArrayList<StackBox> mStackBoxes = new ArrayList<StackBox>(); + private ArrayList<TaskStack> mStacks = new ArrayList<TaskStack>(); - /** True when the home StackBox is at the top of mStackBoxes, false otherwise. */ + /** A special TaskStack with id==HOME_STACK_ID that moves to the bottom whenever any TaskStack + * (except a future lockscreen TaskStack) moves to the top. */ private TaskStack mHomeStack = null; /** Detect user tapping outside of current focused stack bounds .*/ @@ -123,13 +124,6 @@ class DisplayContent { display.getDisplayInfo(mDisplayInfo); isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY; mService = service; - - StackBox newBox = new StackBox(service, this, null); - mStackBoxes.add(newBox); - TaskStack newStack = new TaskStack(service, HOME_STACK_ID, this); - newStack.mStackBox = newBox; - newBox.mStack = newStack; - mHomeStack = newStack; } int getDisplayId() { @@ -155,10 +149,6 @@ class DisplayContent { return mDisplay.hasAccess(uid); } - boolean homeOnTop() { - return mStackBoxes.get(0).mStack != mHomeStack; - } - public boolean isPrivate() { return (mDisplay.getFlags() & Display.FLAG_PRIVATE) != 0; } @@ -201,20 +191,39 @@ class DisplayContent { } TaskStack getHomeStack() { + if (mHomeStack == null) { + Slog.e(TAG, "getHomeStack: Returning null from this=" + this); + } return mHomeStack; } void updateDisplayInfo() { + // Save old size. + int oldWidth = mDisplayInfo.logicalWidth; + int oldHeight = mDisplayInfo.logicalHeight; mDisplay.getDisplayInfo(mDisplayInfo); + + for (int i = mStacks.size() - 1; i >= 0; --i) { + final TaskStack stack = mStacks.get(i); + if (!stack.isFullscreen()) { + stack.resizeBounds(oldWidth, oldHeight, mDisplayInfo.logicalWidth, + mDisplayInfo.logicalHeight); + } + } } void getLogicalDisplayRect(Rect out) { updateDisplayInfo(); // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked. + final int orientation = mDisplayInfo.rotation; + boolean rotated = (orientation == Surface.ROTATION_90 + || orientation == Surface.ROTATION_270); + final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth; + final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight; int width = mDisplayInfo.logicalWidth; - int left = (mBaseDisplayWidth - width) / 2; + int left = (physWidth - width) / 2; int height = mDisplayInfo.logicalHeight; - int top = (mBaseDisplayHeight - height) / 2; + int top = (physHeight - height) / 2; out.set(left, top, left + width, top + height); } @@ -227,159 +236,62 @@ class DisplayContent { return count; } - /** Refer to {@link WindowManagerService#createStack(int, int, int, float)} */ - TaskStack createStack(int stackId, int relativeStackBoxId, int position, float weight) { - TaskStack newStack = null; - if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId + " relativeStackBoxId=" - + relativeStackBoxId + " position=" + position + " weight=" + weight); + /** Refer to {@link WindowManagerService#createStack(int, int)} */ + TaskStack createStack(int stackId) { + if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId); + TaskStack newStack = new TaskStack(mService, stackId, this); if (stackId == HOME_STACK_ID) { - if (mStackBoxes.size() != 1) { + if (mHomeStack != null) { throw new IllegalArgumentException("createStack: HOME_STACK_ID (0) not first."); } - newStack = mHomeStack; - } else { - int stackBoxNdx; - for (stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - final StackBox box = mStackBoxes.get(stackBoxNdx); - if (position == StackBox.TASK_STACK_GOES_OVER - || position == StackBox.TASK_STACK_GOES_UNDER) { - // Position indicates a new box is added at top level only. - if (box.contains(relativeStackBoxId)) { - StackBox newBox = new StackBox(mService, this, null); - newStack = new TaskStack(mService, stackId, this); - newStack.mStackBox = newBox; - newBox.mStack = newStack; - final int offset = position == StackBox.TASK_STACK_GOES_OVER ? 1 : 0; - if (DEBUG_STACK) Slog.d(TAG, "createStack: inserting stack at " + - (stackBoxNdx + offset)); - mStackBoxes.add(stackBoxNdx + offset, newBox); - break; - } - } else { - // Remaining position values indicate a box must be split. - newStack = box.split(stackId, relativeStackBoxId, position, weight); - if (newStack != null) { - break; - } - } - } - if (stackBoxNdx < 0) { - throw new IllegalArgumentException("createStack: stackBoxId " + relativeStackBoxId - + " not found."); - } + mHomeStack = newStack; } - if (newStack != null) { - layoutNeeded = true; - } - EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, relativeStackBoxId, position, - (int)(weight * 100 + 0.5)); + mStacks.add(newStack); + layoutNeeded = true; return newStack; } - /** Refer to {@link WindowManagerService#resizeStackBox(int, float)} */ - boolean resizeStack(int stackBoxId, float weight) { - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - final StackBox box = mStackBoxes.get(stackBoxNdx); - if (box.resize(stackBoxId, weight)) { - layoutNeeded = true; - return true; - } - } - return false; - } - - void addStackBox(StackBox box, boolean toTop) { - if (mStackBoxes.size() >= 2) { - throw new RuntimeException("addStackBox: Too many toplevel StackBoxes!"); - } - mStackBoxes.add(toTop ? mStackBoxes.size() : 0, box); + void moveStack(TaskStack stack, boolean toTop) { + mStacks.remove(stack); + mStacks.add(toTop ? mStacks.size() : 0, stack); } - void removeStackBox(StackBox box) { - if (DEBUG_STACK) Slog.d(TAG, "removeStackBox: box=" + box); - final TaskStack stack = box.mStack; - if (stack != null && stack.mStackId == HOME_STACK_ID) { - // Never delete the home stack, even if it is empty. - if (DEBUG_STACK) Slog.d(TAG, "removeStackBox: Not deleting home stack."); - return; - } - mStackBoxes.remove(box); - } - - StackBoxInfo getStackBoxInfo(StackBox box) { - StackBoxInfo info = new StackBoxInfo(); - info.stackBoxId = box.mStackBoxId; - info.weight = box.mWeight; - info.vertical = box.mVertical; - info.bounds = new Rect(box.mBounds); - if (box.mStack != null) { - info.stackId = box.mStack.mStackId; - // ActivityManagerService will fill in the StackInfo. - } else { - info.stackId = -1; - info.children = new StackBoxInfo[2]; - info.children[0] = getStackBoxInfo(box.mFirst); - info.children[1] = getStackBoxInfo(box.mSecond); - } - return info; - } - - ArrayList<StackBoxInfo> getStackBoxInfos() { - ArrayList<StackBoxInfo> list = new ArrayList<StackBoxInfo>(); - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - list.add(getStackBoxInfo(mStackBoxes.get(stackBoxNdx))); - } - return list; - } - - /** - * Move the home StackBox to the top or bottom of mStackBoxes. That is the only place - * it is allowed to be. This is a nop if the home StackBox is already in the correct position. - * @param toTop Move home to the top of mStackBoxes if true, to the bottom if false. - * @return true if a change was made, false otherwise. - */ - boolean moveHomeStackBox(boolean toTop) { - if (DEBUG_STACK) Slog.d(TAG, "moveHomeStackBox: toTop=" + toTop + " Callers=" + - Debug.getCallers(4)); - EventLog.writeEvent(EventLogTags.WM_HOME_STACK_MOVED, toTop ? 1 : 0); - switch (mStackBoxes.size()) { - case 0: throw new RuntimeException("moveHomeStackBox: No home StackBox!"); - case 1: return false; // Only the home StackBox exists. - case 2: - if (homeOnTop() ^ toTop) { - mStackBoxes.add(mStackBoxes.remove(0)); - return true; - } - return false; - default: throw new RuntimeException("moveHomeStackBox: Too many toplevel StackBoxes!"); + TaskStack removeStack(TaskStack stack) { + mStacks.remove(stack); + if (!mStacks.isEmpty()) { + return mStacks.get(mStacks.size() - 1); } + return null; } /** - * Propagate the new bounds to all child stack boxes, applying weights as we move down. + * Propagate the new bounds to all child stacks. * @param contentRect The bounds to apply at the top level. */ - boolean setStackBoxSize(Rect contentRect) { - boolean change = false; - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - change |= mStackBoxes.get(stackBoxNdx).setStackBoxSizes(contentRect, true); - } - return change; + void resize(Rect contentRect) { + mContentRect.set(contentRect); } - Rect getStackBounds(int stackId) { - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - Rect bounds = mStackBoxes.get(stackBoxNdx).getStackBounds(stackId); - if (bounds != null) { - return bounds; + boolean getStackBounds(int stackId, Rect bounds) { + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { + final TaskStack stack = mStacks.get(stackNdx); + if (stackId == stack.mStackId) { + bounds.set(stack.mBounds); + return true; } } - return null; + return false; } int stackIdFromPoint(int x, int y) { - StackBox topBox = mStackBoxes.get(mStackBoxes.size() - 1); - return topBox.stackIdFromPoint(x, y); + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { + final TaskStack stack = mStacks.get(stackNdx); + stack.getBounds(mTmpRect); + if (mTmpRect.contains(x, y)) { + return stack.mStackId; + } + } + return -1; } void setTouchExcludeRegion(TaskStack focusedStack) { @@ -408,48 +320,48 @@ class DisplayContent { } } - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - mStackBoxes.get(stackBoxNdx).switchUserStacks(newUserId); + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { + mStacks.get(stackNdx).switchUser(newUserId); } } void resetAnimationBackgroundAnimator() { - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - mStackBoxes.get(stackBoxNdx).resetAnimationBackgroundAnimator(); + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { + mStacks.get(stackNdx).resetAnimationBackgroundAnimator(); } } boolean animateDimLayers() { boolean result = false; - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - result |= mStackBoxes.get(stackBoxNdx).animateDimLayers(); + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { + result |= mStacks.get(stackNdx).animateDimLayers(); } return result; } void resetDimming() { - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - mStackBoxes.get(stackBoxNdx).resetDimming(); + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { + mStacks.get(stackNdx).resetDimmingTag(); } } boolean isDimming() { boolean result = false; - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - result |= mStackBoxes.get(stackBoxNdx).isDimming(); + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { + result |= mStacks.get(stackNdx).isDimming(); } return result; } void stopDimmingIfNeeded() { - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - mStackBoxes.get(stackBoxNdx).stopDimmingIfNeeded(); + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { + mStacks.get(stackNdx).stopDimmingIfNeeded(); } } void close() { - for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { - mStackBoxes.get(stackBoxNdx).close(); + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { + mStacks.get(stackNdx).close(); } } @@ -477,9 +389,10 @@ class DisplayContent { pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth); pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight); pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded); - for (int boxNdx = 0; boxNdx < mStackBoxes.size(); ++boxNdx) { - pw.print(prefix); pw.print("StackBox #"); pw.println(boxNdx); - mStackBoxes.get(boxNdx).dump(prefix + " ", pw); + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { + final TaskStack stack = mStacks.get(stackNdx); + pw.print(prefix); pw.print("mStacks[" + stackNdx + "]"); pw.println(stack.mStackId); + stack.dump(prefix + " ", pw); } int ndx = numTokens(); if (ndx > 0) { @@ -520,4 +433,9 @@ class DisplayContent { } pw.println(); } + + @Override + public String toString() { + return "Display " + mDisplayId + " info=" + mDisplayInfo + " stacks=" + mStacks; + } } diff --git a/services/java/com/android/server/wm/DisplayMagnifier.java b/services/core/java/com/android/server/wm/DisplayMagnifier.java index 382d7b4a94af..382d7b4a94af 100644 --- a/services/java/com/android/server/wm/DisplayMagnifier.java +++ b/services/core/java/com/android/server/wm/DisplayMagnifier.java diff --git a/services/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java index 34d1a647e10f..34d1a647e10f 100644 --- a/services/java/com/android/server/wm/DisplaySettings.java +++ b/services/core/java/com/android/server/wm/DisplaySettings.java diff --git a/services/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index a73793968f49..a73793968f49 100644 --- a/services/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java diff --git a/services/java/com/android/server/wm/FakeWindowImpl.java b/services/core/java/com/android/server/wm/FakeWindowImpl.java index 5a3471b06215..5a3471b06215 100644 --- a/services/java/com/android/server/wm/FakeWindowImpl.java +++ b/services/core/java/com/android/server/wm/FakeWindowImpl.java diff --git a/services/java/com/android/server/wm/FocusedStackFrame.java b/services/core/java/com/android/server/wm/FocusedStackFrame.java index cc48b867f6df..f1f5fe88cc85 100644 --- a/services/java/com/android/server/wm/FocusedStackFrame.java +++ b/services/core/java/com/android/server/wm/FocusedStackFrame.java @@ -41,7 +41,7 @@ class FocusedStackFrame { private final SurfaceControl mSurfaceControl; private final Surface mSurface = new Surface(); private final Rect mLastBounds = new Rect(); - private final Rect mBounds = new Rect(); + final Rect mBounds = new Rect(); private final Rect mTmpDrawRect = new Rect(); public FocusedStackFrame(Display display, SurfaceSession session) { @@ -131,9 +131,9 @@ class FocusedStackFrame { } } - public void setBounds(Rect bounds) { - if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + bounds); - mBounds.set(bounds); + public void setBounds(TaskStack stack) { + stack.getBounds(mBounds); + if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + mBounds); } public void setLayer(int layer) { diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 3d2ec4577acf..803b9acac3d9 100644 --- a/services/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -58,6 +58,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { private final Object mInputDevicesReadyMonitor = new Object(); private boolean mInputDevicesReady; + Rect mTmpRect = new Rect(); + public InputMonitor(WindowManagerService service) { mService = service; } @@ -175,7 +177,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { if (modal && child.mAppToken != null) { // Limit the outer touch to the activity stack region. flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; - inputWindowHandle.touchableRegion.set(child.getStackBounds()); + child.getStackBounds(mTmpRect); + inputWindowHandle.touchableRegion.set(mTmpRect); } else { // Not modal or full screen modal child.getTouchableRegion(inputWindowHandle.touchableRegion); diff --git a/services/java/com/android/server/wm/KeyguardDisableHandler.java b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java index 859df519169c..859df519169c 100644 --- a/services/java/com/android/server/wm/KeyguardDisableHandler.java +++ b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java diff --git a/services/java/com/android/server/wm/PointerEventDispatcher.java b/services/core/java/com/android/server/wm/PointerEventDispatcher.java index 6b0e4c9f010a..6b0e4c9f010a 100644 --- a/services/java/com/android/server/wm/PointerEventDispatcher.java +++ b/services/core/java/com/android/server/wm/PointerEventDispatcher.java diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index e630737b40b7..e630737b40b7 100644 --- a/services/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java diff --git a/services/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 87cabc9a510b..87cabc9a510b 100644 --- a/services/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java diff --git a/services/java/com/android/server/wm/StackTapPointerEventListener.java b/services/core/java/com/android/server/wm/StackTapPointerEventListener.java index 19d8ab372afe..19d8ab372afe 100644 --- a/services/java/com/android/server/wm/StackTapPointerEventListener.java +++ b/services/core/java/com/android/server/wm/StackTapPointerEventListener.java diff --git a/services/java/com/android/server/wm/StartingData.java b/services/core/java/com/android/server/wm/StartingData.java index 7115b0fd02e5..7115b0fd02e5 100644 --- a/services/java/com/android/server/wm/StartingData.java +++ b/services/core/java/com/android/server/wm/StartingData.java diff --git a/services/java/com/android/server/wm/StrictModeFlash.java b/services/core/java/com/android/server/wm/StrictModeFlash.java index fb5876b65aed..fb5876b65aed 100644 --- a/services/java/com/android/server/wm/StrictModeFlash.java +++ b/services/core/java/com/android/server/wm/StrictModeFlash.java diff --git a/services/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 13fdbc83b2ce..13fdbc83b2ce 100644 --- a/services/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java diff --git a/services/java/com/android/server/wm/TaskGroup.java b/services/core/java/com/android/server/wm/TaskGroup.java index 1f1dd5832d55..1f1dd5832d55 100644 --- a/services/java/com/android/server/wm/TaskGroup.java +++ b/services/core/java/com/android/server/wm/TaskGroup.java diff --git a/services/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index cb29df474874..ef245f9d123a 100644 --- a/services/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -26,8 +26,6 @@ import android.util.Slog; import android.util.TypedValue; import com.android.server.EventLogTags; -import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; - import java.io.PrintWriter; import java.util.ArrayList; @@ -49,8 +47,9 @@ public class TaskStack { * mTaskHistory in the ActivityStack with the same mStackId */ private final ArrayList<Task> mTasks = new ArrayList<Task>(); - /** The StackBox this sits in. */ - StackBox mStackBox; + /** Content limits relative to the DisplayContent this sits in. Empty indicates fullscreen, + * Nonempty is size of this TaskStack but is also used to scale if DisplayContent changes. */ + Rect mBounds = new Rect(); /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */ final DimLayer mDimLayer; @@ -74,6 +73,9 @@ public class TaskStack { mDisplayContent = displayContent; mDimLayer = new DimLayer(service, this); mAnimationBackgroundSurface = new DimLayer(service, this); + // TODO: remove bounds from log, they are always 0. + EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top, + mBounds.right, mBounds.bottom); } DisplayContent getDisplayContent() { @@ -84,12 +86,64 @@ public class TaskStack { return mTasks; } - boolean isHomeStack() { - return mStackId == HOME_STACK_ID; + private void resizeWindows() { + final boolean underStatusBar = mBounds.top == 0; + + final ArrayList<WindowState> resizingWindows = mService.mResizingWindows; + for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { + final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens; + for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { + final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows; + for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { + final WindowState win = windows.get(winNdx); + if (!resizingWindows.contains(win)) { + if (WindowManagerService.DEBUG_RESIZE) Slog.d(TAG, + "setBounds: Resizing " + win); + resizingWindows.add(win); + } + win.mUnderStatusBar = underStatusBar; + } + } + } + } + + boolean setBounds(Rect bounds) { + if (mBounds.equals(bounds)) { + return false; + } + + mDimLayer.setBounds(bounds); + mAnimationBackgroundSurface.setBounds(bounds); + mBounds.set(bounds); + + resizeWindows(); + return true; + } + + void getBounds(Rect out) { + if (mBounds.isEmpty()) { + mDisplayContent.getLogicalDisplayRect(out); + } else { + out.set(mBounds); + } + out.intersect(mDisplayContent.mContentRect); } - boolean hasSibling() { - return mStackBox.mParent != null; + boolean isFullscreen() { + return mBounds.isEmpty(); + } + + void resizeBounds(float oldWidth, float oldHeight, float newWidth, float newHeight) { + if (oldWidth == newWidth && oldHeight == newHeight) { + return; + } + float widthScale = newWidth / oldWidth; + float heightScale = newHeight / oldHeight; + mBounds.left = (int)(mBounds.left * widthScale + 0.5); + mBounds.top = (int)(mBounds.top * heightScale + 0.5); + mBounds.right = (int)(mBounds.right * widthScale + 0.5); + mBounds.bottom = (int)(mBounds.bottom * heightScale + 0.5); + resizeWindows(); } /** @@ -97,9 +151,7 @@ public class TaskStack { * @param task The task to add. * @param toTop Whether to add it to the top or bottom. */ - boolean addTask(Task task, boolean toTop) { - mStackBox.makeDirty(); - + void addTask(Task task, boolean toTop) { int stackNdx; if (!toTop) { stackNdx = 0; @@ -122,20 +174,20 @@ public class TaskStack { task.mStack = this; mDisplayContent.addTask(task, toTop); - return mDisplayContent.moveHomeStackBox(mStackId == HOME_STACK_ID); + mDisplayContent.moveStack(this, true); } - boolean moveTaskToTop(Task task) { + void moveTaskToTop(Task task) { if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToTop: task=" + task + " Callers=" + Debug.getCallers(6)); mTasks.remove(task); - return addTask(task, true); + addTask(task, true); } - boolean moveTaskToBottom(Task task) { + void moveTaskToBottom(Task task) { if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToBottom: task=" + task); mTasks.remove(task); - return addTask(task, false); + addTask(task, false); } /** @@ -145,7 +197,6 @@ public class TaskStack { */ void removeTask(Task task) { if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task); - mStackBox.makeDirty(); mTasks.remove(task); mDisplayContent.removeTask(task); } @@ -154,7 +205,11 @@ public class TaskStack { mAnimationBackgroundSurface.destroySurface(); mDimLayer.destroySurface(); EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId); - return mStackBox.remove(); + TaskStack next = mDisplayContent.removeStack(this); + if (next != null) { + return next.mStackId; + } + return -1; } void resetAnimationBackgroundAnimator() { @@ -259,28 +314,6 @@ public class TaskStack { } } - void setBounds(Rect bounds, boolean underStatusBar) { - mDimLayer.setBounds(bounds); - mAnimationBackgroundSurface.setBounds(bounds); - - final ArrayList<WindowState> resizingWindows = mService.mResizingWindows; - for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { - final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens; - for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { - final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows; - for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { - final WindowState win = windows.get(winNdx); - if (!resizingWindows.contains(win)) { - if (WindowManagerService.DEBUG_RESIZE) Slog.d(TAG, - "setBounds: Resizing " + win); - resizingWindows.add(win); - } - win.mUnderStatusBar = underStatusBar; - } - } - } - } - void switchUser(int userId) { int top = mTasks.size(); for (int taskNdx = 0; taskNdx < top; ++taskNdx) { @@ -293,6 +326,11 @@ public class TaskStack { } } + void close() { + mDimLayer.mDimSurface.destroy(); + mAnimationBackgroundSurface.mDimSurface.destroy(); + } + public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("mStackId="); pw.println(mStackId); for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) { diff --git a/services/java/com/android/server/wm/ViewServer.java b/services/core/java/com/android/server/wm/ViewServer.java index a763e2c724c4..a763e2c724c4 100644 --- a/services/java/com/android/server/wm/ViewServer.java +++ b/services/core/java/com/android/server/wm/ViewServer.java diff --git a/services/java/com/android/server/wm/Watermark.java b/services/core/java/com/android/server/wm/Watermark.java index e226e3d73e47..e226e3d73e47 100644 --- a/services/java/com/android/server/wm/Watermark.java +++ b/services/core/java/com/android/server/wm/Watermark.java diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 91f15f3fb7f1..91f15f3fb7f1 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f9773a6f25cf..e02714beb649 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -45,7 +45,6 @@ import com.android.server.power.PowerManagerService; import com.android.server.power.ShutdownThread; import android.Manifest; -import android.app.ActivityManager.StackBoxInfo; import android.app.ActivityManagerNative; import android.app.IActivityManager; import android.app.StatusBarManager; @@ -293,8 +292,6 @@ public class WindowManagerService extends IWindowManager.Stub final private KeyguardDisableHandler mKeyguardDisableHandler; - private final boolean mHeadless; - final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -734,7 +731,6 @@ public class WindowManagerService extends IWindowManager.Stub com.android.internal.R.bool.config_sf_limitedAlpha); mInputManager = inputManager; // Must be before createDisplayContentLocked. mDisplayManagerService = displayManager; - mHeadless = displayManager.isHeadless(); mDisplaySettings = new DisplaySettings(context); mDisplaySettings.readSettingsLocked(); @@ -3778,10 +3774,8 @@ public class WindowManagerService extends IWindowManager.Stub if (stack == null) { mFocusedStackFrame.setVisibility(false); } else { - final StackBox box = stack.mStackBox; - final Rect bounds = box.mBounds; - final boolean multipleStacks = box.mParent != null; - mFocusedStackFrame.setBounds(bounds); + mFocusedStackFrame.setBounds(stack); + final boolean multipleStacks = !stack.isFullscreen(); mFocusedStackFrame.setVisibility(multipleStacks); } } finally { @@ -4788,10 +4782,14 @@ public class WindowManagerService extends IWindowManager.Stub } final TaskStack stack = task.mStack; final DisplayContent displayContent = task.getDisplayContent(); - final boolean isHomeStackTask = stack.isHomeStack(); - if (isHomeStackTask != displayContent.homeOnTop()) { - // First move the stack itself. - displayContent.moveHomeStackBox(isHomeStackTask); + displayContent.moveStack(stack, true); + if (displayContent.isDefaultDisplay) { + final TaskStack homeStack = displayContent.getHomeStack(); + if (homeStack != stack) { + // When a non-home stack moves to the top, the home stack moves to the + // bottom. + displayContent.moveStack(homeStack, false); + } } stack.moveTaskToTop(task); } @@ -4820,38 +4818,23 @@ public class WindowManagerService extends IWindowManager.Stub } /** - * Create a new TaskStack and place it next to an existing stack. + * Create a new TaskStack and place it on a DisplayContent. * @param stackId The unique identifier of the new stack. - * @param relativeStackBoxId The existing stack that this stack goes before or after. - * @param position One of: - * {@link StackBox#TASK_STACK_GOES_BEFORE} - * {@link StackBox#TASK_STACK_GOES_AFTER} - * {@link StackBox#TASK_STACK_GOES_ABOVE} - * {@link StackBox#TASK_STACK_GOES_BELOW} - * {@link StackBox#TASK_STACK_GOES_UNDER} - * {@link StackBox#TASK_STACK_GOES_OVER} - * @param weight Relative weight for determining how big to make the new TaskStack. + * @param displayId The unique identifier of the DisplayContent. */ - public void createStack(int stackId, int relativeStackBoxId, int position, float weight) { - synchronized (mWindowMap) { - if (position <= StackBox.TASK_STACK_GOES_BELOW && - (weight < STACK_WEIGHT_MIN || weight > STACK_WEIGHT_MAX)) { - throw new IllegalArgumentException( - "createStack: weight must be between " + STACK_WEIGHT_MIN + " and " + - STACK_WEIGHT_MAX + ", weight=" + weight); - } - final int numDisplays = mDisplayContents.size(); - for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { - final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); - TaskStack stack = displayContent.createStack(stackId, relativeStackBoxId, position, - weight); - if (stack != null) { + public void createStack(int stackId, int displayId) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mWindowMap) { + final DisplayContent displayContent = mDisplayContents.get(displayId); + if (displayContent != null) { + TaskStack stack = displayContent.createStack(stackId); mStackIdToStack.put(stackId, stack); performLayoutAndPlaceSurfacesLocked(); - return; } } - Slog.e(TAG, "createStack: Unable to find relativeStackBoxId=" + relativeStackBoxId); + } finally { + Binder.restoreCallingIdentity(origId); } } @@ -4863,7 +4846,9 @@ public class WindowManagerService extends IWindowManager.Stub int nextStackId = stack.remove(); stack.getDisplayContent().layoutNeeded = true; requestTraversalLocked(); - return nextStackId; + if (nextStackId > HOME_STACK_ID) { + return nextStackId; + } } if (DEBUG_STACK) Slog.i(TAG, "removeStack: could not find stackId=" + stackId); } @@ -4880,7 +4865,6 @@ public class WindowManagerService extends IWindowManager.Stub final TaskStack stack = task.mStack; EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask"); stack.removeTask(task); - stack.getDisplayContent().layoutNeeded = true; } } @@ -4898,40 +4882,27 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void resizeStackBox(int stackBoxId, float weight) { - if (weight < STACK_WEIGHT_MIN || weight > STACK_WEIGHT_MAX) { - throw new IllegalArgumentException( - "resizeStack: weight must be between " + STACK_WEIGHT_MIN + " and " + - STACK_WEIGHT_MAX + ", weight=" + weight); - } + public void resizeStack(int stackId, Rect bounds) { synchronized (mWindowMap) { - final int numDisplays = mDisplayContents.size(); - for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { - if (mDisplayContents.valueAt(displayNdx).resizeStack(stackBoxId, weight)) { - performLayoutAndPlaceSurfacesLocked(); - return; - } + final TaskStack stack = mStackIdToStack.get(stackId); + if (stack == null) { + throw new IllegalArgumentException("resizeStack: stackId " + stackId + + " not found."); + } + if (stack.setBounds(bounds)) { + stack.getDisplayContent().layoutNeeded = true; + performLayoutAndPlaceSurfacesLocked(); } } - throw new IllegalArgumentException("resizeStack: stackBoxId " + stackBoxId - + " not found."); } - public ArrayList<StackBoxInfo> getStackBoxInfos() { - synchronized(mWindowMap) { - return getDefaultDisplayContentLocked().getStackBoxInfos(); + public void getStackBounds(int stackId, Rect bounds) { + final TaskStack stack = mStackIdToStack.get(stackId); + if (stack != null) { + stack.getBounds(bounds); + return; } - } - - public Rect getStackBounds(int stackId) { - final int numDisplays = mDisplayContents.size(); - for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { - Rect bounds = mDisplayContents.valueAt(displayNdx).getStackBounds(stackId); - if (bounds != null) { - return bounds; - } - } - return null; + bounds.setEmpty(); } // ------------------------------------------------------------- @@ -5259,7 +5230,7 @@ public class WindowManagerService extends IWindowManager.Stub public void performBootTimeout() { synchronized(mWindowMap) { - if (mDisplayEnabled || mHeadless) { + if (mDisplayEnabled) { return; } Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled"); @@ -5443,7 +5414,6 @@ public class WindowManagerService extends IWindowManager.Stub // only allow disables from pids which have count on, etc. @Override public void showStrictModeViolation(boolean on) { - if (mHeadless) return; int pid = Binder.getCallingPid(); mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid)); } @@ -5589,7 +5559,7 @@ public class WindowManagerService extends IWindowManager.Stub continue; } appWin = ws; - stackBounds.set(ws.getStackBounds()); + ws.getStackBounds(stackBounds); } } @@ -7476,9 +7446,7 @@ public class WindowManagerService extends IWindowManager.Stub } case DO_DISPLAY_ADDED: - synchronized (mWindowMap) { - handleDisplayAddedLocked(msg.arg1); - } + handleDisplayAdded(msg.arg1); break; case DO_DISPLAY_REMOVED: @@ -8218,7 +8186,7 @@ public class WindowManagerService extends IWindowManager.Stub } mPolicy.getContentRectLw(mTmpContentRect); - displayContent.setStackBoxSize(mTmpContentRect); + displayContent.resize(mTmpContentRect); int seq = mLayoutSeq+1; if (seq < 0) seq = 0; @@ -8813,7 +8781,8 @@ public class WindowManagerService extends IWindowManager.Stub if (canBeSeen) { // This function assumes that the contents of the default display are // processed first before secondary displays. - if (w.mDisplayContent.isDefaultDisplay) { + final DisplayContent displayContent = w.mDisplayContent; + if (displayContent.isDefaultDisplay) { // While a dream or keyguard is showing, obscure ordinary application // content on secondary displays (by forcibly enabling mirroring unless // there is other content we want to show) but still allow opaque @@ -9017,6 +8986,10 @@ public class WindowManagerService extends IWindowManager.Stub final int N = windows.size(); for (i=N-1; i>=0; i--) { WindowState w = windows.get(i); + final TaskStack stack = w.getStack(); + if (stack == null) { + continue; + } final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured; @@ -9026,7 +8999,7 @@ public class WindowManagerService extends IWindowManager.Stub handleNotObscuredLocked(w, currentTime, innerDw, innerDh); } - if (!w.getStack().testDimmingTag()) { + if (!stack.testDimmingTag()) { handleFlagDimBehind(w, innerDw, innerDh); } @@ -10810,11 +10783,13 @@ public class WindowManagerService extends IWindowManager.Stub mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0)); } - private void handleDisplayAddedLocked(int displayId) { - final Display display = mDisplayManager.getDisplay(displayId); - if (display != null) { - createDisplayContentLocked(display); - displayReady(displayId); + public void handleDisplayAdded(int displayId) { + synchronized (mWindowMap) { + final Display display = mDisplayManager.getDisplay(displayId); + if (display != null) { + createDisplayContentLocked(display); + displayReady(displayId); + } } } diff --git a/services/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 4d53cea4370d..77a36b81f6e6 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -463,8 +463,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { mHaveFrame = true; TaskStack stack = mAppToken != null ? getStack() : null; - if (stack != null && stack.hasSibling()) { - mContainingFrame.set(getStackBounds(stack)); + if (stack != null && !stack.isFullscreen()) { + getStackBounds(stack, mContainingFrame); if (mUnderStatusBar) { mContainingFrame.top = pf.top; } @@ -717,21 +717,27 @@ final class WindowState implements WindowManagerPolicy.WindowState { if (wtoken != null) { Task task = mService.mTaskIdToTask.get(wtoken.groupId); if (task != null) { - return task.mStack; + if (task.mStack != null) { + return task.mStack; + } + Slog.e(TAG, "getStack: mStack null for task=" + task); + } else { + Slog.e(TAG, "getStack: couldn't find taskId=" + wtoken.groupId); } } return mDisplayContent.getHomeStack(); } - Rect getStackBounds() { - return getStackBounds(getStack()); + void getStackBounds(Rect bounds) { + getStackBounds(getStack(), bounds); } - private Rect getStackBounds(TaskStack stack) { + private void getStackBounds(TaskStack stack, Rect bounds) { if (stack != null) { - return stack.mStackBox.mBounds; + stack.getBounds(bounds); + return; } - return mFrame; + bounds.set(mFrame); } public long getInputDispatchingTimeoutNanos() { diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index c405170da280..c405170da280 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java diff --git a/services/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 22671234c538..22671234c538 100644 --- a/services/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java diff --git a/services/core/java/service.mk b/services/core/java/service.mk new file mode 100644 index 000000000000..4cb411bc4d25 --- /dev/null +++ b/services/core/java/service.mk @@ -0,0 +1,6 @@ +SUB_DIR := core/java + +LOCAL_SRC_FILES += \ + $(call all-java-files-under,$(SUB_DIR)) \ + $(SUB_DIR)/com/android/server/EventLogTags.logtags \ + $(SUB_DIR)/com/android/server/am/EventLogTags.logtags diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk new file mode 100644 index 000000000000..1a3ce639c015 --- /dev/null +++ b/services/core/jni/Android.mk @@ -0,0 +1,56 @@ +# This file is included by the top level services directory to collect source +# files +LOCAL_REL_DIR := core/jni + +LOCAL_SRC_FILES += \ + $(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \ + $(LOCAL_REL_DIR)/com_android_server_AssetAtlasService.cpp \ + $(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \ + $(LOCAL_REL_DIR)/com_android_server_input_InputApplicationHandle.cpp \ + $(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp \ + $(LOCAL_REL_DIR)/com_android_server_input_InputWindowHandle.cpp \ + $(LOCAL_REL_DIR)/com_android_server_lights_LightsService.cpp \ + $(LOCAL_REL_DIR)/com_android_server_power_PowerManagerService.cpp \ + $(LOCAL_REL_DIR)/com_android_server_SerialService.cpp \ + $(LOCAL_REL_DIR)/com_android_server_SystemServer.cpp \ + $(LOCAL_REL_DIR)/com_android_server_UsbDeviceManager.cpp \ + $(LOCAL_REL_DIR)/com_android_server_UsbHostManager.cpp \ + $(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \ + $(LOCAL_REL_DIR)/com_android_server_location_GpsLocationProvider.cpp \ + $(LOCAL_REL_DIR)/com_android_server_location_FlpHardwareProvider.cpp \ + $(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \ + $(LOCAL_REL_DIR)/onload.cpp + +LOCAL_C_INCLUDES += \ + $(JNI_H_INCLUDE) \ + frameworks/base/services \ + frameworks/base/libs \ + frameworks/base/core/jni \ + frameworks/native/services \ + external/skia/include/core \ + libcore/include \ + libcore/include/libsuspend \ + $(call include-path-for, libhardware)/hardware \ + $(call include-path-for, libhardware_legacy)/hardware_legacy \ + +LOCAL_SHARED_LIBRARIES += \ + libandroid_runtime \ + libandroidfw \ + libbinder \ + libcutils \ + liblog \ + libhardware \ + libhardware_legacy \ + libnativehelper \ + libutils \ + libui \ + libinput \ + libinputservice \ + libsensorservice \ + libskia \ + libgui \ + libusbhost \ + libsuspend \ + libEGL \ + libGLESv2 + diff --git a/services/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp index 342515bb3bb0..342515bb3bb0 100644 --- a/services/jni/com_android_server_AlarmManagerService.cpp +++ b/services/core/jni/com_android_server_AlarmManagerService.cpp diff --git a/services/jni/com_android_server_AssetAtlasService.cpp b/services/core/jni/com_android_server_AssetAtlasService.cpp index 885d21eca925..885d21eca925 100644 --- a/services/jni/com_android_server_AssetAtlasService.cpp +++ b/services/core/jni/com_android_server_AssetAtlasService.cpp diff --git a/services/jni/com_android_server_ConsumerIrService.cpp b/services/core/jni/com_android_server_ConsumerIrService.cpp index 004c0aaad445..004c0aaad445 100644 --- a/services/jni/com_android_server_ConsumerIrService.cpp +++ b/services/core/jni/com_android_server_ConsumerIrService.cpp diff --git a/services/jni/com_android_server_SerialService.cpp b/services/core/jni/com_android_server_SerialService.cpp index b889b78cc1f9..b889b78cc1f9 100644 --- a/services/jni/com_android_server_SerialService.cpp +++ b/services/core/jni/com_android_server_SerialService.cpp diff --git a/services/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp index 0625544effdc..0625544effdc 100644 --- a/services/jni/com_android_server_SystemServer.cpp +++ b/services/core/jni/com_android_server_SystemServer.cpp diff --git a/services/jni/com_android_server_UsbDeviceManager.cpp b/services/core/jni/com_android_server_UsbDeviceManager.cpp index 355173384892..355173384892 100644 --- a/services/jni/com_android_server_UsbDeviceManager.cpp +++ b/services/core/jni/com_android_server_UsbDeviceManager.cpp diff --git a/services/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp index f1fa6cf07f60..f1fa6cf07f60 100644 --- a/services/jni/com_android_server_UsbHostManager.cpp +++ b/services/core/jni/com_android_server_UsbHostManager.cpp diff --git a/services/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp index 2b3f74a97184..2b3f74a97184 100644 --- a/services/jni/com_android_server_VibratorService.cpp +++ b/services/core/jni/com_android_server_VibratorService.cpp diff --git a/services/jni/com_android_server_connectivity_Vpn.cpp b/services/core/jni/com_android_server_connectivity_Vpn.cpp index ab8c959f692f..ab8c959f692f 100644 --- a/services/jni/com_android_server_connectivity_Vpn.cpp +++ b/services/core/jni/com_android_server_connectivity_Vpn.cpp diff --git a/services/jni/com_android_server_input_InputApplicationHandle.cpp b/services/core/jni/com_android_server_input_InputApplicationHandle.cpp index f943d168e7d6..f943d168e7d6 100644 --- a/services/jni/com_android_server_input_InputApplicationHandle.cpp +++ b/services/core/jni/com_android_server_input_InputApplicationHandle.cpp diff --git a/services/jni/com_android_server_input_InputApplicationHandle.h b/services/core/jni/com_android_server_input_InputApplicationHandle.h index 89d48c63cf3a..89d48c63cf3a 100644 --- a/services/jni/com_android_server_input_InputApplicationHandle.h +++ b/services/core/jni/com_android_server_input_InputApplicationHandle.h diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 10ad278a8e10..10ad278a8e10 100644 --- a/services/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp diff --git a/services/jni/com_android_server_input_InputWindowHandle.cpp b/services/core/jni/com_android_server_input_InputWindowHandle.cpp index b80183c73b80..b80183c73b80 100644 --- a/services/jni/com_android_server_input_InputWindowHandle.cpp +++ b/services/core/jni/com_android_server_input_InputWindowHandle.cpp diff --git a/services/jni/com_android_server_input_InputWindowHandle.h b/services/core/jni/com_android_server_input_InputWindowHandle.h index 2cfa17d34b83..2cfa17d34b83 100644 --- a/services/jni/com_android_server_input_InputWindowHandle.h +++ b/services/core/jni/com_android_server_input_InputWindowHandle.h diff --git a/services/jni/com_android_server_LightsService.cpp b/services/core/jni/com_android_server_lights_LightsService.cpp index 69793f7c1af9..d51e044c4dbe 100644 --- a/services/jni/com_android_server_LightsService.cpp +++ b/services/core/jni/com_android_server_lights_LightsService.cpp @@ -134,7 +134,7 @@ static JNINativeMethod method_table[] = { int register_android_server_LightsService(JNIEnv *env) { - return jniRegisterNativeMethods(env, "com/android/server/LightsService", + return jniRegisterNativeMethods(env, "com/android/server/lights/LightsService", method_table, NELEM(method_table)); } diff --git a/services/jni/com_android_server_location_FlpHardwareProvider.cpp b/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp index 6c14887ef627..6c14887ef627 100644 --- a/services/jni/com_android_server_location_FlpHardwareProvider.cpp +++ b/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp diff --git a/services/jni/com_android_server_location_GpsLocationProvider.cpp b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp index e9ba116c26bf..e9ba116c26bf 100644 --- a/services/jni/com_android_server_location_GpsLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp diff --git a/services/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp index 151e134ee3ba..151e134ee3ba 100644 --- a/services/jni/com_android_server_power_PowerManagerService.cpp +++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp diff --git a/services/jni/com_android_server_power_PowerManagerService.h b/services/core/jni/com_android_server_power_PowerManagerService.h index 0808b80f18ff..0808b80f18ff 100644 --- a/services/jni/com_android_server_power_PowerManagerService.h +++ b/services/core/jni/com_android_server_power_PowerManagerService.h diff --git a/services/jni/onload.cpp b/services/core/jni/onload.cpp index efc34a2aca41..efc34a2aca41 100644 --- a/services/jni/onload.cpp +++ b/services/core/jni/onload.cpp diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 2bb99d68ed77..af362467aa84 100644 --- a/services/java/com/android/server/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.devicepolicy; import static android.Manifest.permission.MANAGE_CA_CERTIFICATES; @@ -117,7 +117,7 @@ import java.util.Set; */ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - private static final String TAG = "DevicePolicyManagerService"; + private static final String LOG_TAG = "DevicePolicyManagerService"; private static final String DEVICE_POLICIES_XML = "device_policies.xml"; @@ -186,7 +186,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { getSendingUserId()); if (Intent.ACTION_BOOT_COMPLETED.equals(action) || ACTION_EXPIRED_PASSWORD_NOTIFICATION.equals(action)) { - if (DBG) Slog.v(TAG, "Sending password expiration notifications for action " + if (DBG) Slog.v(LOG_TAG, "Sending password expiration notifications for action " + action + " for user " + userHandle); mHandler.post(new Runnable() { public void run() { @@ -218,6 +218,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { }; static class ActiveAdmin { + private static final String TAG_DISABLE_KEYGUARD_FEATURES = "disable-keyguard-features"; + private static final String TAG_DISABLE_CAMERA = "disable-camera"; + private static final String TAG_ENCRYPTION_REQUESTED = "encryption-requested"; + private static final String TAG_PASSWORD_EXPIRATION_DATE = "password-expiration-date"; + private static final String TAG_PASSWORD_EXPIRATION_TIMEOUT = "password-expiration-timeout"; + private static final String TAG_GLOBAL_PROXY_EXCLUSION_LIST = "global-proxy-exclusion-list"; + private static final String TAG_GLOBAL_PROXY_SPEC = "global-proxy-spec"; + private static final String TAG_SPECIFIES_GLOBAL_PROXY = "specifies-global-proxy"; + private static final String TAG_MAX_FAILED_PASSWORD_WIPE = "max-failed-password-wipe"; + private static final String TAG_MAX_TIME_TO_UNLOCK = "max-time-to-unlock"; + private static final String TAG_MIN_PASSWORD_NONLETTER = "min-password-nonletter"; + private static final String TAG_MIN_PASSWORD_SYMBOLS = "min-password-symbols"; + private static final String TAG_MIN_PASSWORD_NUMERIC = "min-password-numeric"; + private static final String TAG_MIN_PASSWORD_LETTERS = "min-password-letters"; + private static final String TAG_MIN_PASSWORD_LOWERCASE = "min-password-lowercase"; + private static final String TAG_MIN_PASSWORD_UPPERCASE = "min-password-uppercase"; + private static final String TAG_PASSWORD_HISTORY_LENGTH = "password-history-length"; + private static final String TAG_MIN_PASSWORD_LENGTH = "min-password-length"; + private static final String ATTR_VALUE = "value"; + private static final String TAG_PASSWORD_QUALITY = "password-quality"; + private static final String TAG_POLICIES = "policies"; + final DeviceAdminInfo info; int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; @@ -281,103 +303,103 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { void writeToXml(XmlSerializer out) throws IllegalArgumentException, IllegalStateException, IOException { - out.startTag(null, "policies"); + out.startTag(null, TAG_POLICIES); info.writePoliciesToXml(out); - out.endTag(null, "policies"); + out.endTag(null, TAG_POLICIES); if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { - out.startTag(null, "password-quality"); - out.attribute(null, "value", Integer.toString(passwordQuality)); - out.endTag(null, "password-quality"); + out.startTag(null, TAG_PASSWORD_QUALITY); + out.attribute(null, ATTR_VALUE, Integer.toString(passwordQuality)); + out.endTag(null, TAG_PASSWORD_QUALITY); if (minimumPasswordLength != DEF_MINIMUM_PASSWORD_LENGTH) { - out.startTag(null, "min-password-length"); - out.attribute(null, "value", Integer.toString(minimumPasswordLength)); - out.endTag(null, "min-password-length"); + out.startTag(null, TAG_MIN_PASSWORD_LENGTH); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordLength)); + out.endTag(null, TAG_MIN_PASSWORD_LENGTH); } if(passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) { - out.startTag(null, "password-history-length"); - out.attribute(null, "value", Integer.toString(passwordHistoryLength)); - out.endTag(null, "password-history-length"); + out.startTag(null, TAG_PASSWORD_HISTORY_LENGTH); + out.attribute(null, ATTR_VALUE, Integer.toString(passwordHistoryLength)); + out.endTag(null, TAG_PASSWORD_HISTORY_LENGTH); } if (minimumPasswordUpperCase != DEF_MINIMUM_PASSWORD_UPPER_CASE) { - out.startTag(null, "min-password-uppercase"); - out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase)); - out.endTag(null, "min-password-uppercase"); + out.startTag(null, TAG_MIN_PASSWORD_UPPERCASE); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordUpperCase)); + out.endTag(null, TAG_MIN_PASSWORD_UPPERCASE); } if (minimumPasswordLowerCase != DEF_MINIMUM_PASSWORD_LOWER_CASE) { - out.startTag(null, "min-password-lowercase"); - out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase)); - out.endTag(null, "min-password-lowercase"); + out.startTag(null, TAG_MIN_PASSWORD_LOWERCASE); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordLowerCase)); + out.endTag(null, TAG_MIN_PASSWORD_LOWERCASE); } if (minimumPasswordLetters != DEF_MINIMUM_PASSWORD_LETTERS) { - out.startTag(null, "min-password-letters"); - out.attribute(null, "value", Integer.toString(minimumPasswordLetters)); - out.endTag(null, "min-password-letters"); + out.startTag(null, TAG_MIN_PASSWORD_LETTERS); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordLetters)); + out.endTag(null, TAG_MIN_PASSWORD_LETTERS); } if (minimumPasswordNumeric != DEF_MINIMUM_PASSWORD_NUMERIC) { - out.startTag(null, "min-password-numeric"); - out.attribute(null, "value", Integer.toString(minimumPasswordNumeric)); - out.endTag(null, "min-password-numeric"); + out.startTag(null, TAG_MIN_PASSWORD_NUMERIC); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordNumeric)); + out.endTag(null, TAG_MIN_PASSWORD_NUMERIC); } if (minimumPasswordSymbols != DEF_MINIMUM_PASSWORD_SYMBOLS) { - out.startTag(null, "min-password-symbols"); - out.attribute(null, "value", Integer.toString(minimumPasswordSymbols)); - out.endTag(null, "min-password-symbols"); + out.startTag(null, TAG_MIN_PASSWORD_SYMBOLS); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordSymbols)); + out.endTag(null, TAG_MIN_PASSWORD_SYMBOLS); } if (minimumPasswordNonLetter > DEF_MINIMUM_PASSWORD_NON_LETTER) { - out.startTag(null, "min-password-nonletter"); - out.attribute(null, "value", Integer.toString(minimumPasswordNonLetter)); - out.endTag(null, "min-password-nonletter"); + out.startTag(null, TAG_MIN_PASSWORD_NONLETTER); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordNonLetter)); + out.endTag(null, TAG_MIN_PASSWORD_NONLETTER); } } if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) { - out.startTag(null, "max-time-to-unlock"); - out.attribute(null, "value", Long.toString(maximumTimeToUnlock)); - out.endTag(null, "max-time-to-unlock"); + out.startTag(null, TAG_MAX_TIME_TO_UNLOCK); + out.attribute(null, ATTR_VALUE, Long.toString(maximumTimeToUnlock)); + out.endTag(null, TAG_MAX_TIME_TO_UNLOCK); } if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) { - out.startTag(null, "max-failed-password-wipe"); - out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe)); - out.endTag(null, "max-failed-password-wipe"); + out.startTag(null, TAG_MAX_FAILED_PASSWORD_WIPE); + out.attribute(null, ATTR_VALUE, Integer.toString(maximumFailedPasswordsForWipe)); + out.endTag(null, TAG_MAX_FAILED_PASSWORD_WIPE); } if (specifiesGlobalProxy) { - out.startTag(null, "specifies-global-proxy"); - out.attribute(null, "value", Boolean.toString(specifiesGlobalProxy)); - out.endTag(null, "specifies_global_proxy"); + out.startTag(null, TAG_SPECIFIES_GLOBAL_PROXY); + out.attribute(null, ATTR_VALUE, Boolean.toString(specifiesGlobalProxy)); + out.endTag(null, TAG_SPECIFIES_GLOBAL_PROXY); if (globalProxySpec != null) { - out.startTag(null, "global-proxy-spec"); - out.attribute(null, "value", globalProxySpec); - out.endTag(null, "global-proxy-spec"); + out.startTag(null, TAG_GLOBAL_PROXY_SPEC); + out.attribute(null, ATTR_VALUE, globalProxySpec); + out.endTag(null, TAG_GLOBAL_PROXY_SPEC); } if (globalProxyExclusionList != null) { - out.startTag(null, "global-proxy-exclusion-list"); - out.attribute(null, "value", globalProxyExclusionList); - out.endTag(null, "global-proxy-exclusion-list"); + out.startTag(null, TAG_GLOBAL_PROXY_EXCLUSION_LIST); + out.attribute(null, ATTR_VALUE, globalProxyExclusionList); + out.endTag(null, TAG_GLOBAL_PROXY_EXCLUSION_LIST); } } if (passwordExpirationTimeout != DEF_PASSWORD_EXPIRATION_TIMEOUT) { - out.startTag(null, "password-expiration-timeout"); - out.attribute(null, "value", Long.toString(passwordExpirationTimeout)); - out.endTag(null, "password-expiration-timeout"); + out.startTag(null, TAG_PASSWORD_EXPIRATION_TIMEOUT); + out.attribute(null, ATTR_VALUE, Long.toString(passwordExpirationTimeout)); + out.endTag(null, TAG_PASSWORD_EXPIRATION_TIMEOUT); } if (passwordExpirationDate != DEF_PASSWORD_EXPIRATION_DATE) { - out.startTag(null, "password-expiration-date"); - out.attribute(null, "value", Long.toString(passwordExpirationDate)); - out.endTag(null, "password-expiration-date"); + out.startTag(null, TAG_PASSWORD_EXPIRATION_DATE); + out.attribute(null, ATTR_VALUE, Long.toString(passwordExpirationDate)); + out.endTag(null, TAG_PASSWORD_EXPIRATION_DATE); } if (encryptionRequested) { - out.startTag(null, "encryption-requested"); - out.attribute(null, "value", Boolean.toString(encryptionRequested)); - out.endTag(null, "encryption-requested"); + out.startTag(null, TAG_ENCRYPTION_REQUESTED); + out.attribute(null, ATTR_VALUE, Boolean.toString(encryptionRequested)); + out.endTag(null, TAG_ENCRYPTION_REQUESTED); } if (disableCamera) { - out.startTag(null, "disable-camera"); - out.attribute(null, "value", Boolean.toString(disableCamera)); - out.endTag(null, "disable-camera"); + out.startTag(null, TAG_DISABLE_CAMERA); + out.attribute(null, ATTR_VALUE, Boolean.toString(disableCamera)); + out.endTag(null, TAG_DISABLE_CAMERA); } if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) { - out.startTag(null, "disable-keyguard-features"); - out.attribute(null, "value", Integer.toString(disabledKeyguardFeatures)); - out.endTag(null, "disable-keyguard-features"); + out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES); + out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures)); + out.endTag(null, TAG_DISABLE_KEYGUARD_FEATURES); } } @@ -391,67 +413,67 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { continue; } String tag = parser.getName(); - if ("policies".equals(tag)) { + if (TAG_POLICIES.equals(tag)) { info.readPoliciesFromXml(parser); - } else if ("password-quality".equals(tag)) { + } else if (TAG_PASSWORD_QUALITY.equals(tag)) { passwordQuality = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-length".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_LENGTH.equals(tag)) { minimumPasswordLength = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("password-history-length".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_PASSWORD_HISTORY_LENGTH.equals(tag)) { passwordHistoryLength = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-uppercase".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_UPPERCASE.equals(tag)) { minimumPasswordUpperCase = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-lowercase".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_LOWERCASE.equals(tag)) { minimumPasswordLowerCase = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-letters".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_LETTERS.equals(tag)) { minimumPasswordLetters = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-numeric".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_NUMERIC.equals(tag)) { minimumPasswordNumeric = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-symbols".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_SYMBOLS.equals(tag)) { minimumPasswordSymbols = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-nonletter".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) { minimumPasswordNonLetter = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("max-time-to-unlock".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) { maximumTimeToUnlock = Long.parseLong( - parser.getAttributeValue(null, "value")); - } else if ("max-failed-password-wipe".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MAX_FAILED_PASSWORD_WIPE.equals(tag)) { maximumFailedPasswordsForWipe = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("specifies-global-proxy".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_SPECIFIES_GLOBAL_PROXY.equals(tag)) { specifiesGlobalProxy = Boolean.parseBoolean( - parser.getAttributeValue(null, "value")); - } else if ("global-proxy-spec".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_GLOBAL_PROXY_SPEC.equals(tag)) { globalProxySpec = - parser.getAttributeValue(null, "value"); - } else if ("global-proxy-exclusion-list".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE); + } else if (TAG_GLOBAL_PROXY_EXCLUSION_LIST.equals(tag)) { globalProxyExclusionList = - parser.getAttributeValue(null, "value"); - } else if ("password-expiration-timeout".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE); + } else if (TAG_PASSWORD_EXPIRATION_TIMEOUT.equals(tag)) { passwordExpirationTimeout = Long.parseLong( - parser.getAttributeValue(null, "value")); - } else if ("password-expiration-date".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_PASSWORD_EXPIRATION_DATE.equals(tag)) { passwordExpirationDate = Long.parseLong( - parser.getAttributeValue(null, "value")); - } else if ("encryption-requested".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_ENCRYPTION_REQUESTED.equals(tag)) { encryptionRequested = Boolean.parseBoolean( - parser.getAttributeValue(null, "value")); - } else if ("disable-camera".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_DISABLE_CAMERA.equals(tag)) { disableCamera = Boolean.parseBoolean( - parser.getAttributeValue(null, "value")); - } else if ("disable-keyguard-features".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) { disabledKeyguardFeatures = Integer.parseInt( - parser.getAttributeValue(null, "value")); + parser.getAttributeValue(null, ATTR_VALUE)); } else { - Slog.w(TAG, "Unknown admin tag: " + tag); + Slog.w(LOG_TAG, "Unknown admin tag: " + tag); } XmlUtils.skipCurrentTag(parser); } @@ -513,7 +535,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void handlePackagesChanged(int userHandle) { boolean removed = false; - if (DBG) Slog.d(TAG, "Handling package changes for user " + userHandle); + if (DBG) Slog.d(LOG_TAG, "Handling package changes for user " + userHandle); DevicePolicyData policy = getUserData(userHandle); IPackageManager pm = AppGlobals.getPackageManager(); for (int i = policy.mAdminList.size() - 1; i >= 0; i--) { @@ -585,7 +607,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { void removeUserData(int userHandle) { synchronized (this) { if (userHandle == UserHandle.USER_OWNER) { - Slog.w(TAG, "Tried to remove device policy file for user 0! Ignoring."); + Slog.w(LOG_TAG, "Tried to remove device policy file for user 0! Ignoring."); return; } DevicePolicyData policy = mUserData.get(userHandle); @@ -595,7 +617,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { File policyFile = new File(Environment.getUserSystemDirectory(userHandle), DEVICE_POLICIES_XML); policyFile.delete(); - Slog.i(TAG, "Removed device policy file " + policyFile.getAbsolutePath()); + Slog.i(LOG_TAG, "Removed device policy file " + policyFile.getAbsolutePath()); } } @@ -792,10 +814,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { return new DeviceAdminInfo(mContext, infos.get(0)); } catch (XmlPullParserException e) { - Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e); + Slog.w(LOG_TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, + e); return null; } catch (IOException e) { - Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e); + Slog.w(LOG_TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, + e); return null; } } @@ -922,7 +946,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ComponentName.unflattenFromString(name), userHandle); if (DBG && (UserHandle.getUserId(dai.getActivityInfo().applicationInfo.uid) != userHandle)) { - Slog.w(TAG, "findAdmin returned an incorrect uid " + Slog.w(LOG_TAG, "findAdmin returned an incorrect uid " + dai.getActivityInfo().applicationInfo.uid + " for user " + userHandle); } @@ -933,7 +957,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { policy.mAdminList.add(ap); } } catch (RuntimeException e) { - Slog.w(TAG, "Failed loading admin " + name, e); + Slog.w(LOG_TAG, "Failed loading admin " + name, e); } } else if ("failed-password-attempts".equals(tag)) { policy.mFailedPasswordAttempts = Integer.parseInt( @@ -962,22 +986,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { parser.getAttributeValue(null, "nonletter")); XmlUtils.skipCurrentTag(parser); } else { - Slog.w(TAG, "Unknown tag: " + tag); + Slog.w(LOG_TAG, "Unknown tag: " + tag); XmlUtils.skipCurrentTag(parser); } } } catch (NullPointerException e) { - Slog.w(TAG, "failed parsing " + file + " " + e); + Slog.w(LOG_TAG, "failed parsing " + file + " " + e); } catch (NumberFormatException e) { - Slog.w(TAG, "failed parsing " + file + " " + e); + Slog.w(LOG_TAG, "failed parsing " + file + " " + e); } catch (XmlPullParserException e) { - Slog.w(TAG, "failed parsing " + file + " " + e); + Slog.w(LOG_TAG, "failed parsing " + file + " " + e); } catch (FileNotFoundException e) { // Don't be noisy, this is normal if we haven't defined any policies. } catch (IOException e) { - Slog.w(TAG, "failed parsing " + file + " " + e); + Slog.w(LOG_TAG, "failed parsing " + file + " " + e); } catch (IndexOutOfBoundsException e) { - Slog.w(TAG, "failed parsing " + file + " " + e); + Slog.w(LOG_TAG, "failed parsing " + file + " " + e); } try { if (stream != null) { @@ -993,7 +1017,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // never normally happen. LockPatternUtils utils = new LockPatternUtils(mContext); if (utils.getActivePasswordQuality() < policy.mActivePasswordQuality) { - Slog.w(TAG, "Active password quality 0x" + Slog.w(LOG_TAG, "Active password quality 0x" + Integer.toHexString(policy.mActivePasswordQuality) + " does not match actual quality 0x" + Integer.toHexString(utils.getActivePasswordQuality())); @@ -1037,7 +1061,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } if (!haveOwner) { - Slog.w(TAG, "Previous password owner " + policy.mPasswordOwner + Slog.w(LOG_TAG, "Previous password owner " + policy.mPasswordOwner + " no longer active; disabling"); policy.mPasswordOwner = -1; } @@ -1057,7 +1081,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long token = Binder.clearCallingIdentity(); try { String value = cameraDisabled ? "1" : "0"; - if (DBG) Slog.v(TAG, "Change in camera state [" + if (DBG) Slog.v(LOG_TAG, "Change in camera state [" + SYSTEM_PROP_DISABLE_CAMERA + "] = " + value); SystemProperties.set(SYSTEM_PROP_DISABLE_CAMERA, value); } finally { @@ -1173,7 +1197,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (this) { long ident = Binder.clearCallingIdentity(); try { - if (!refreshing && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) { + if (!refreshing + && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) { throw new IllegalArgumentException("Admin is already added"); } ActiveAdmin newAdmin = new ActiveAdmin(info); @@ -1443,7 +1468,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ap.passwordExpirationDate = expiration; ap.passwordExpirationTimeout = timeout; if (timeout > 0L) { - Slog.w(TAG, "setPasswordExpiration(): password will expire on " + Slog.w(LOG_TAG, "setPasswordExpiration(): password will expire on " + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT) .format(new Date(expiration))); } @@ -1789,11 +1814,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return true; } return policy.mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null, userHandle) - && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null, userHandle) - && policy.mActivePasswordLetters >= getPasswordMinimumLetters(null, userHandle) - && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(null, userHandle) - && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(null, userHandle) - && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null, userHandle); + && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null, userHandle) + && policy.mActivePasswordLetters >= getPasswordMinimumLetters(null, userHandle) + && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(null, userHandle) + && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(null, userHandle) + && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null, userHandle); } } @@ -1871,7 +1896,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int realQuality = LockPatternUtils.computePasswordQuality(password); if (realQuality < quality && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { - Slog.w(TAG, "resetPassword: password quality 0x" + Slog.w(LOG_TAG, "resetPassword: password quality 0x" + Integer.toHexString(realQuality) + " does not meet required quality 0x" + Integer.toHexString(quality)); @@ -1881,7 +1906,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } int length = getPasswordMinimumLength(null, userHandle); if (password.length() < length) { - Slog.w(TAG, "resetPassword: password length " + password.length() + Slog.w(LOG_TAG, "resetPassword: password length " + password.length() + " does not meet required length " + length); return false; } @@ -1910,40 +1935,40 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } int neededLetters = getPasswordMinimumLetters(null, userHandle); if(letters < neededLetters) { - Slog.w(TAG, "resetPassword: number of letters " + letters + Slog.w(LOG_TAG, "resetPassword: number of letters " + letters + " does not meet required number of letters " + neededLetters); return false; } int neededNumbers = getPasswordMinimumNumeric(null, userHandle); if (numbers < neededNumbers) { - Slog.w(TAG, "resetPassword: number of numerical digits " + numbers + Slog.w(LOG_TAG, "resetPassword: number of numerical digits " + numbers + " does not meet required number of numerical digits " + neededNumbers); return false; } int neededLowerCase = getPasswordMinimumLowerCase(null, userHandle); if (lowercase < neededLowerCase) { - Slog.w(TAG, "resetPassword: number of lowercase letters " + lowercase + Slog.w(LOG_TAG, "resetPassword: number of lowercase letters " + lowercase + " does not meet required number of lowercase letters " + neededLowerCase); return false; } int neededUpperCase = getPasswordMinimumUpperCase(null, userHandle); if (uppercase < neededUpperCase) { - Slog.w(TAG, "resetPassword: number of uppercase letters " + uppercase + Slog.w(LOG_TAG, "resetPassword: number of uppercase letters " + uppercase + " does not meet required number of uppercase letters " + neededUpperCase); return false; } int neededSymbols = getPasswordMinimumSymbols(null, userHandle); if (symbols < neededSymbols) { - Slog.w(TAG, "resetPassword: number of special symbols " + symbols + Slog.w(LOG_TAG, "resetPassword: number of special symbols " + symbols + " does not meet required number of special symbols " + neededSymbols); return false; } int neededNonLetter = getPasswordMinimumNonLetter(null, userHandle); if (nonletter < neededNonLetter) { - Slog.w(TAG, "resetPassword: number of non-letter characters " + nonletter + Slog.w(LOG_TAG, "resetPassword: number of non-letter characters " + nonletter + " does not meet required number of non-letter characters " + neededNonLetter); return false; @@ -1954,7 +1979,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int callingUid = Binder.getCallingUid(); DevicePolicyData policy = getUserData(userHandle); if (policy.mPasswordOwner >= 0 && policy.mPasswordOwner != callingUid) { - Slog.w(TAG, "resetPassword: already set by another uid and not entered by user"); + Slog.w(LOG_TAG, "resetPassword: already set by another uid and not entered by user"); return false; } @@ -2020,7 +2045,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { getIPowerManager().setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs); } catch (RemoteException e) { - Slog.w(TAG, "Failure talking with power manager", e); + Slog.w(LOG_TAG, "Failure talking with power manager", e); } } finally { Binder.restoreCallingIdentity(ident); @@ -2095,10 +2120,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { X509Certificate cert = parseCert(certBuffer); pemCert = Credentials.convertToPem(cert); } catch (CertificateException ce) { - Log.e(TAG, "Problem converting cert", ce); + Log.e(LOG_TAG, "Problem converting cert", ce); return false; } catch (IOException ioe) { - Log.e(TAG, "Problem reading cert", ioe); + Log.e(LOG_TAG, "Problem reading cert", ioe); return false; } try { @@ -2113,7 +2138,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } catch (InterruptedException e1) { - Log.w(TAG, "installCaCertsToKeyChain(): ", e1); + Log.w(LOG_TAG, "installCaCertsToKeyChain(): ", e1); Thread.currentThread().interrupt(); } return false; @@ -2134,10 +2159,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { X509Certificate cert = parseCert(certBuffer); alias = certStore.getCertificateAlias(cert); } catch (CertificateException ce) { - Log.e(TAG, "Problem creating X509Certificate", ce); + Log.e(LOG_TAG, "Problem creating X509Certificate", ce); return; } catch (IOException ioe) { - Log.e(TAG, "Problem reading certificate", ioe); + Log.e(LOG_TAG, "Problem reading certificate", ioe); return; } try { @@ -2146,13 +2171,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { service.deleteCaCertificate(alias); } catch (RemoteException e) { - Log.e(TAG, "from CaCertUninstaller: ", e); + Log.e(LOG_TAG, "from CaCertUninstaller: ", e); } finally { keyChainConnection.close(); keyChainConnection = null; } } catch (InterruptedException ie) { - Log.w(TAG, "CaCertUninstaller: ", ie); + Log.w(LOG_TAG, "CaCertUninstaller: ", ie); Thread.currentThread().interrupt(); } } @@ -2173,7 +2198,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { RecoverySystem.rebootWipeUserData(mContext); } catch (IOException e) { - Slog.w(TAG, "Failed requesting data wipe", e); + Slog.w(LOG_TAG, "Failed requesting data wipe", e); } } } @@ -2264,8 +2289,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (p.mActivePasswordQuality != quality || p.mActivePasswordLength != length || p.mFailedPasswordAttempts != 0 || p.mActivePasswordLetters != letters || p.mActivePasswordUpperCase != uppercase - || p.mActivePasswordLowerCase != lowercase || p.mActivePasswordNumeric != numbers - || p.mActivePasswordSymbols != symbols || p.mActivePasswordNonLetter != nonletter) { + || p.mActivePasswordLowerCase != lowercase + || p.mActivePasswordNumeric != numbers + || p.mActivePasswordSymbols != symbols + || p.mActivePasswordNonLetter != nonletter) { long ident = Binder.clearCallingIdentity(); try { p.mActivePasswordQuality = quality; @@ -2387,7 +2414,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // If the user is not the owner, don't set the global proxy. Fail silently. if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { - Slog.w(TAG, "Only the owner is allowed to set the global proxy. User " + Slog.w(LOG_TAG, "Only the owner is allowed to set the global proxy. User " + userHandle + " is not permitted."); return null; } @@ -2468,7 +2495,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ProxyProperties proxyProperties = new ProxyProperties(data[0], proxyPort, exclusionList); if (!proxyProperties.isValid()) { - Slog.e(TAG, "Invalid proxy properties, ignoring: " + proxyProperties.toString()); + Slog.e(LOG_TAG, "Invalid proxy properties, ignoring: " + proxyProperties.toString()); return; } Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, data[0]); @@ -2494,7 +2521,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Only owner can set storage encryption if (userHandle != UserHandle.USER_OWNER || UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { - Slog.w(TAG, "Only owner is allowed to set storage encryption. User " + Slog.w(LOG_TAG, "Only owner is allowed to set storage encryption. User " + UserHandle.getCallingUserId() + " is not permitted."); return 0; } @@ -2880,7 +2907,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } catch (NameNotFoundException nnfe) { - Slog.w(TAG, "Device Owner package " + packageName + " not installed."); + Slog.w(LOG_TAG, "Device Owner package " + packageName + " not installed."); } return false; } @@ -2905,9 +2932,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mOwnerName = parser.getAttributeValue(null, ATTR_NAME); input.close(); } catch (XmlPullParserException xppe) { - Slog.e(TAG, "Error parsing device-owner file\n" + xppe); + Slog.e(LOG_TAG, "Error parsing device-owner file\n" + xppe); } catch (IOException ioe) { - Slog.e(TAG, "IO Exception when reading device-owner file\n" + ioe); + Slog.e(LOG_TAG, "IO Exception when reading device-owner file\n" + ioe); } } @@ -2935,7 +2962,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.flush(); file.finishWrite(output); } catch (IOException ioe) { - Slog.e(TAG, "IO Exception when writing device-owner file\n" + ioe); + Slog.e(LOG_TAG, "IO Exception when writing device-owner file\n" + ioe); } } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerSystemService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerSystemService.java new file mode 100644 index 000000000000..160aa3954d7f --- /dev/null +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerSystemService.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.devicepolicy; + +import android.content.Context; + +import com.android.server.SystemService; + +/** + * SystemService wrapper for the DevicePolicyManager implementation. Publishes + * Context.DEVICE_POLICY_SERVICE. + */ +public final class DevicePolicyManagerSystemService extends SystemService { + private DevicePolicyManagerService mDevicePolicyManagerImpl; + + @Override + public void onCreate(Context context) { + mDevicePolicyManagerImpl = new DevicePolicyManagerService(context); + } + + @Override + public void onStart() { + publishBinderService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManagerImpl); + } + + @Override + public void onBootPhase(int phase) { + if (phase == PHASE_LOCK_SETTINGS_READY) { + mDevicePolicyManagerImpl.systemReady(); + } + } +}
\ No newline at end of file diff --git a/services/devicepolicy/java/service.mk b/services/devicepolicy/java/service.mk new file mode 100644 index 000000000000..e64cc96dedf8 --- /dev/null +++ b/services/devicepolicy/java/service.mk @@ -0,0 +1,11 @@ +# Include only if the service is required +ifneq ($(findstring devicepolicy,$(REQUIRED_SERVICES)),) + +SUB_DIR := devicepolicy/java + +LOCAL_SRC_FILES += \ + $(call all-java-files-under,$(SUB_DIR)) + +#DEFINED_SERVICES += com.android.server.devicepolicy.DevicePolicyManagerService + +endif diff --git a/services/java/Android.mk b/services/java/Android.mk deleted file mode 100644 index 8c3d0f09197c..000000000000 --- a/services/java/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -# the library -# ============================================================ -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - $(call all-subdir-java-files) \ - com/android/server/EventLogTags.logtags \ - com/android/server/am/EventLogTags.logtags - -LOCAL_MODULE:= services - -LOCAL_JAVA_LIBRARIES := android.policy conscrypt telephony-common - -include $(BUILD_JAVA_LIBRARY) - -include $(BUILD_DROIDDOC) diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java deleted file mode 100644 index 203cca692df0..000000000000 --- a/services/java/com/android/server/AppWidgetService.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright (C) 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. - */ - -package com.android.server; - -import android.app.ActivityManager; -import android.appwidget.AppWidgetProviderInfo; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.os.Binder; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.UserHandle; -import android.util.Slog; -import android.util.SparseArray; -import android.widget.RemoteViews; - -import com.android.internal.appwidget.IAppWidgetHost; -import com.android.internal.appwidget.IAppWidgetService; -import com.android.internal.os.BackgroundThread; -import com.android.internal.util.IndentingPrintWriter; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.List; -import java.util.Locale; - - -/** - * Redirects calls to this service to the instance of the service for the appropriate user. - */ -class AppWidgetService extends IAppWidgetService.Stub -{ - private static final String TAG = "AppWidgetService"; - - Context mContext; - Locale mLocale; - PackageManager mPackageManager; - boolean mSafeMode; - private final Handler mSaveStateHandler; - - private final SparseArray<AppWidgetServiceImpl> mAppWidgetServices; - - AppWidgetService(Context context) { - mContext = context; - - mSaveStateHandler = BackgroundThread.getHandler(); - - mAppWidgetServices = new SparseArray<AppWidgetServiceImpl>(5); - AppWidgetServiceImpl primary = new AppWidgetServiceImpl(context, 0, mSaveStateHandler); - mAppWidgetServices.append(0, primary); - } - - public void systemRunning(boolean safeMode) { - mSafeMode = safeMode; - - mAppWidgetServices.get(0).systemReady(safeMode); - - // Register for the boot completed broadcast, so we can send the - // ENABLE broacasts. If we try to send them now, they time out, - // because the system isn't ready to handle them yet. - mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, - new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null); - - // Register for configuration changes so we can update the names - // of the widgets when the locale changes. - mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, - new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED), null, null); - - // Register for broadcasts about package install, etc., so we can - // update the provider list. - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_PACKAGE_ADDED); - filter.addAction(Intent.ACTION_PACKAGE_CHANGED); - filter.addAction(Intent.ACTION_PACKAGE_REMOVED); - filter.addDataScheme("package"); - mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, - filter, null, null); - // Register for events related to sdcard installation. - IntentFilter sdFilter = new IntentFilter(); - sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); - sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); - mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, - sdFilter, null, null); - - IntentFilter userFilter = new IntentFilter(); - userFilter.addAction(Intent.ACTION_USER_REMOVED); - userFilter.addAction(Intent.ACTION_USER_STOPPING); - mContext.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { - onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, - UserHandle.USER_NULL)); - } else if (Intent.ACTION_USER_STOPPING.equals(intent.getAction())) { - onUserStopping(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, - UserHandle.USER_NULL)); - } - } - }, userFilter); - } - - @Override - public int allocateAppWidgetId(String packageName, int hostId, int userId) - throws RemoteException { - return getImplForUser(userId).allocateAppWidgetId(packageName, hostId); - } - - @Override - public int[] getAppWidgetIdsForHost(int hostId, int userId) throws RemoteException { - return getImplForUser(userId).getAppWidgetIdsForHost(hostId); - } - - @Override - public void deleteAppWidgetId(int appWidgetId, int userId) throws RemoteException { - getImplForUser(userId).deleteAppWidgetId(appWidgetId); - } - - @Override - public void deleteHost(int hostId, int userId) throws RemoteException { - getImplForUser(userId).deleteHost(hostId); - } - - @Override - public void deleteAllHosts(int userId) throws RemoteException { - getImplForUser(userId).deleteAllHosts(); - } - - @Override - public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options, int userId) - throws RemoteException { - getImplForUser(userId).bindAppWidgetId(appWidgetId, provider, options); - } - - @Override - public boolean bindAppWidgetIdIfAllowed( - String packageName, int appWidgetId, ComponentName provider, Bundle options, int userId) - throws RemoteException { - return getImplForUser(userId).bindAppWidgetIdIfAllowed( - packageName, appWidgetId, provider, options); - } - - @Override - public boolean hasBindAppWidgetPermission(String packageName, int userId) - throws RemoteException { - return getImplForUser(userId).hasBindAppWidgetPermission(packageName); - } - - @Override - public void setBindAppWidgetPermission(String packageName, boolean permission, int userId) - throws RemoteException { - getImplForUser(userId).setBindAppWidgetPermission(packageName, permission); - } - - @Override - public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection, - int userId) throws RemoteException { - getImplForUser(userId).bindRemoteViewsService(appWidgetId, intent, connection); - } - - @Override - public int[] startListening(IAppWidgetHost host, String packageName, int hostId, - List<RemoteViews> updatedViews, int userId) throws RemoteException { - return getImplForUser(userId).startListening(host, packageName, hostId, updatedViews); - } - - public void onUserRemoved(int userId) { - if (userId < 1) return; - synchronized (mAppWidgetServices) { - AppWidgetServiceImpl impl = mAppWidgetServices.get(userId); - mAppWidgetServices.remove(userId); - - if (impl == null) { - AppWidgetServiceImpl.getSettingsFile(userId).delete(); - } else { - impl.onUserRemoved(); - } - } - } - - public void onUserStopping(int userId) { - if (userId < 1) return; - synchronized (mAppWidgetServices) { - AppWidgetServiceImpl impl = mAppWidgetServices.get(userId); - if (impl != null) { - mAppWidgetServices.remove(userId); - impl.onUserStopping(); - } - } - } - - private void checkPermission(int userId) { - int realUserId = ActivityManager.handleIncomingUser( - Binder.getCallingPid(), - Binder.getCallingUid(), - userId, - false, /* allowAll */ - true, /* requireFull */ - this.getClass().getSimpleName(), - this.getClass().getPackage().getName()); - } - - private AppWidgetServiceImpl getImplForUser(int userId) { - checkPermission(userId); - boolean sendInitial = false; - AppWidgetServiceImpl service; - synchronized (mAppWidgetServices) { - service = mAppWidgetServices.get(userId); - if (service == null) { - Slog.i(TAG, "Unable to find AppWidgetServiceImpl for user " + userId + ", adding"); - // TODO: Verify that it's a valid user - service = new AppWidgetServiceImpl(mContext, userId, mSaveStateHandler); - service.systemReady(mSafeMode); - // Assume that BOOT_COMPLETED was received, as this is a non-primary user. - mAppWidgetServices.append(userId, service); - sendInitial = true; - } - } - if (sendInitial) { - service.sendInitialBroadcasts(); - } - return service; - } - - @Override - public int[] getAppWidgetIds(ComponentName provider, int userId) throws RemoteException { - return getImplForUser(userId).getAppWidgetIds(provider); - } - - @Override - public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId, int userId) - throws RemoteException { - return getImplForUser(userId).getAppWidgetInfo(appWidgetId); - } - - @Override - public RemoteViews getAppWidgetViews(int appWidgetId, int userId) throws RemoteException { - return getImplForUser(userId).getAppWidgetViews(appWidgetId); - } - - @Override - public void updateAppWidgetOptions(int appWidgetId, Bundle options, int userId) { - getImplForUser(userId).updateAppWidgetOptions(appWidgetId, options); - } - - @Override - public Bundle getAppWidgetOptions(int appWidgetId, int userId) { - return getImplForUser(userId).getAppWidgetOptions(appWidgetId); - } - - @Override - public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter, int userId) - throws RemoteException { - return getImplForUser(userId).getInstalledProviders(categoryFilter); - } - - @Override - public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId, int userId) - throws RemoteException { - getImplForUser(userId).notifyAppWidgetViewDataChanged( - appWidgetIds, viewId); - } - - @Override - public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId) - throws RemoteException { - getImplForUser(userId).partiallyUpdateAppWidgetIds( - appWidgetIds, views); - } - - @Override - public void stopListening(int hostId, int userId) throws RemoteException { - getImplForUser(userId).stopListening(hostId); - } - - @Override - public void unbindRemoteViewsService(int appWidgetId, Intent intent, int userId) - throws RemoteException { - getImplForUser(userId).unbindRemoteViewsService( - appWidgetId, intent); - } - - @Override - public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId) - throws RemoteException { - getImplForUser(userId).updateAppWidgetIds(appWidgetIds, views); - } - - @Override - public void updateAppWidgetProvider(ComponentName provider, RemoteViews views, int userId) - throws RemoteException { - getImplForUser(userId).updateAppWidgetProvider(provider, views); - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); - - // Dump the state of all the app widget providers - synchronized (mAppWidgetServices) { - IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); - for (int i = 0; i < mAppWidgetServices.size(); i++) { - pw.println("User: " + mAppWidgetServices.keyAt(i)); - ipw.increaseIndent(); - AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i); - service.dump(fd, ipw, args); - ipw.decreaseIndent(); - } - } - } - - BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - // Slog.d(TAG, "received " + action); - if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { - int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); - if (userId >= 0) { - getImplForUser(userId).sendInitialBroadcasts(); - } else { - Slog.w(TAG, "Incorrect user handle supplied in " + intent); - } - } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { - for (int i = 0; i < mAppWidgetServices.size(); i++) { - AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i); - service.onConfigurationChanged(); - } - } else { - int sendingUser = getSendingUserId(); - if (sendingUser == UserHandle.USER_ALL) { - for (int i = 0; i < mAppWidgetServices.size(); i++) { - AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i); - service.onBroadcastReceived(intent); - } - } else { - AppWidgetServiceImpl service = mAppWidgetServices.get(sendingUser); - if (service != null) { - service.onBroadcastReceived(intent); - } - } - } - } - }; -} diff --git a/services/java/com/android/server/display/HeadlessDisplayAdapter.java b/services/java/com/android/server/display/HeadlessDisplayAdapter.java deleted file mode 100644 index 7a104d7e5a8a..000000000000 --- a/services/java/com/android/server/display/HeadlessDisplayAdapter.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2012 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.display; - -import android.content.Context; -import android.os.Handler; -import android.util.DisplayMetrics; -import android.view.Display; - -/** - * Provides a fake default display for headless systems. - * <p> - * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock. - * </p> - */ -final class HeadlessDisplayAdapter extends DisplayAdapter { - private static final String TAG = "HeadlessDisplayAdapter"; - - // Called with SyncRoot lock held. - public HeadlessDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, - Context context, Handler handler, Listener listener) { - super(syncRoot, context, handler, listener, TAG); - } - - @Override - public void registerLocked() { - super.registerLocked(); - sendDisplayDeviceEventLocked(new HeadlessDisplayDevice(), DISPLAY_DEVICE_EVENT_ADDED); - } - - private final class HeadlessDisplayDevice extends DisplayDevice { - private DisplayDeviceInfo mInfo; - - public HeadlessDisplayDevice() { - super(HeadlessDisplayAdapter.this, null); - } - - @Override - public DisplayDeviceInfo getDisplayDeviceInfoLocked() { - if (mInfo == null) { - mInfo = new DisplayDeviceInfo(); - mInfo.name = getContext().getResources().getString( - com.android.internal.R.string.display_manager_built_in_display_name); - mInfo.width = 640; - mInfo.height = 480; - mInfo.refreshRate = 60; - mInfo.densityDpi = DisplayMetrics.DENSITY_DEFAULT; - mInfo.xDpi = 160; - mInfo.yDpi = 160; - mInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY - | DisplayDeviceInfo.FLAG_SECURE - | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS; - mInfo.type = Display.TYPE_BUILT_IN; - mInfo.touch = DisplayDeviceInfo.TOUCH_NONE; - } - return mInfo; - } - } -} diff --git a/services/java/com/android/server/print/PrintManagerService.java b/services/java/com/android/server/print/PrintManagerService.java deleted file mode 100644 index 98acc27741fa..000000000000 --- a/services/java/com/android/server/print/PrintManagerService.java +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.print; - -import android.Manifest; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.database.ContentObserver; -import android.net.Uri; -import android.os.Binder; -import android.os.Bundle; -import android.os.Process; -import android.os.RemoteException; -import android.os.UserHandle; -import android.print.IPrintDocumentAdapter; -import android.print.IPrintJobStateChangeListener; -import android.print.IPrintManager; -import android.print.IPrinterDiscoveryObserver; -import android.print.PrintAttributes; -import android.print.PrintJobId; -import android.print.PrintJobInfo; -import android.print.PrinterId; -import android.printservice.PrintServiceInfo; -import android.provider.Settings; -import android.text.TextUtils; -import android.util.SparseArray; - -import com.android.internal.R; -import com.android.internal.content.PackageMonitor; -import com.android.internal.os.BackgroundThread; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -public final class PrintManagerService extends IPrintManager.Stub { - - private static final char COMPONENT_NAME_SEPARATOR = ':'; - - private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME = - "EXTRA_PRINT_SERVICE_COMPONENT_NAME"; - - private final Object mLock = new Object(); - - private final Context mContext; - - private final SparseArray<UserState> mUserStates = new SparseArray<UserState>(); - - private int mCurrentUserId = UserHandle.USER_OWNER; - - public PrintManagerService(Context context) { - mContext = context; - registerContentObservers(); - registerBoradcastReceivers(); - } - - public void systemRuning() { - BackgroundThread.getHandler().post(new Runnable() { - @Override - public void run() { - final UserState userState; - synchronized (mLock) { - userState = getCurrentUserStateLocked(); - userState.updateIfNeededLocked(); - } - // This is the first time we switch to this user after boot, so - // now is the time to remove obsolete print jobs since they - // are from the last boot and no application would query them. - userState.removeObsoletePrintJobs(); - } - }); - } - - @Override - public Bundle print(String printJobName, IPrintDocumentAdapter adapter, - PrintAttributes attributes, String packageName, int appId, int userId) { - final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - String resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - return userState.print(printJobName, adapter, attributes, - resolvedPackageName, resolvedAppId); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public List<PrintJobInfo> getPrintJobInfos(int appId, int userId) { - final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - return userState.getPrintJobInfos(resolvedAppId); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) { - final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - return userState.getPrintJobInfo(printJobId, resolvedAppId); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) { - final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.cancelPrintJob(printJobId, resolvedAppId); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void restartPrintJob(PrintJobId printJobId, int appId, int userId) { - final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.restartPrintJob(printJobId, resolvedAppId); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public List<PrintServiceInfo> getEnabledPrintServices(int userId) { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - return userState.getEnabledPrintServices(); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public List<PrintServiceInfo> getInstalledPrintServices(int userId) { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - return userState.getInstalledPrintServices(); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer, - int userId) { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.createPrinterDiscoverySession(observer); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer, - int userId) { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.destroyPrinterDiscoverySession(observer); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void startPrinterDiscovery(IPrinterDiscoveryObserver observer, - List<PrinterId> priorityList, int userId) { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.startPrinterDiscovery(observer, priorityList); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer, int userId) { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.stopPrinterDiscovery(observer); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void validatePrinters(List<PrinterId> printerIds, int userId) { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.validatePrinters(printerIds); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void startPrinterStateTracking(PrinterId printerId, int userId) { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.startPrinterStateTracking(printerId); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void stopPrinterStateTracking(PrinterId printerId, int userId) { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.stopPrinterStateTracking(printerId); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener, - int appId, int userId) throws RemoteException { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.addPrintJobStateChangeListener(listener, resolvedAppId); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener, - int userId) { - final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); - final UserState userState; - synchronized (mLock) { - userState = getOrCreateUserStateLocked(resolvedUserId); - } - final long identity = Binder.clearCallingIdentity(); - try { - userState.removePrintJobStateChangeListener(listener); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - pw.println("Permission Denial: can't dump PrintManager from from pid=" - + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid()); - return; - } - - synchronized (mLock) { - final long identity = Binder.clearCallingIdentity(); - try { - pw.println("PRINT MANAGER STATE (dumpsys print)"); - final int userStateCount = mUserStates.size(); - for (int i = 0; i < userStateCount; i++) { - UserState userState = mUserStates.valueAt(i); - userState.dump(fd, pw, ""); - pw.println(); - } - } finally { - Binder.restoreCallingIdentity(identity); - } - } - } - - private void registerContentObservers() { - final Uri enabledPrintServicesUri = Settings.Secure.getUriFor( - Settings.Secure.ENABLED_PRINT_SERVICES); - - ContentObserver observer = new ContentObserver(BackgroundThread.getHandler()) { - @Override - public void onChange(boolean selfChange, Uri uri) { - if (enabledPrintServicesUri.equals(uri)) { - synchronized (mLock) { - UserState userState = getCurrentUserStateLocked(); - userState.updateIfNeededLocked(); - } - } - } - }; - - mContext.getContentResolver().registerContentObserver(enabledPrintServicesUri, - false, observer, UserHandle.USER_ALL); - } - - private void registerBoradcastReceivers() { - PackageMonitor monitor = new PackageMonitor() { - @Override - public boolean onPackageChanged(String packageName, int uid, String[] components) { - synchronized (mLock) { - UserState userState = getOrCreateUserStateLocked(getChangingUserId()); - Iterator<ComponentName> iterator = userState.getEnabledServices().iterator(); - while (iterator.hasNext()) { - ComponentName componentName = iterator.next(); - if (packageName.equals(componentName.getPackageName())) { - userState.updateIfNeededLocked(); - return true; - } - } - } - return false; - } - - @Override - public void onPackageRemoved(String packageName, int uid) { - synchronized (mLock) { - UserState userState = getOrCreateUserStateLocked(getChangingUserId()); - Iterator<ComponentName> iterator = userState.getEnabledServices().iterator(); - while (iterator.hasNext()) { - ComponentName componentName = iterator.next(); - if (packageName.equals(componentName.getPackageName())) { - iterator.remove(); - persistComponentNamesToSettingLocked( - Settings.Secure.ENABLED_PRINT_SERVICES, - userState.getEnabledServices(), getChangingUserId()); - userState.updateIfNeededLocked(); - return; - } - } - } - } - - @Override - public boolean onHandleForceStop(Intent intent, String[] stoppedPackages, - int uid, boolean doit) { - synchronized (mLock) { - UserState userState = getOrCreateUserStateLocked(getChangingUserId()); - boolean stoppedSomePackages = false; - Iterator<ComponentName> iterator = userState.getEnabledServices().iterator(); - while (iterator.hasNext()) { - ComponentName componentName = iterator.next(); - String componentPackage = componentName.getPackageName(); - for (String stoppedPackage : stoppedPackages) { - if (componentPackage.equals(stoppedPackage)) { - if (!doit) { - return true; - } - stoppedSomePackages = true; - break; - } - } - } - if (stoppedSomePackages) { - userState.updateIfNeededLocked(); - } - return false; - } - } - - @Override - public void onPackageAdded(String packageName, int uid) { - Intent intent = new Intent(android.printservice.PrintService.SERVICE_INTERFACE); - intent.setPackage(packageName); - - List<ResolveInfo> installedServices = mContext.getPackageManager() - .queryIntentServicesAsUser(intent, PackageManager.GET_SERVICES, - getChangingUserId()); - - if (installedServices == null) { - return; - } - - final int installedServiceCount = installedServices.size(); - for (int i = 0; i < installedServiceCount; i++) { - ServiceInfo serviceInfo = installedServices.get(i).serviceInfo; - ComponentName component = new ComponentName(serviceInfo.packageName, - serviceInfo.name); - String label = serviceInfo.loadLabel(mContext.getPackageManager()).toString(); - showEnableInstalledPrintServiceNotification(component, label, - getChangingUserId()); - } - } - - private void persistComponentNamesToSettingLocked(String settingName, - Set<ComponentName> componentNames, int userId) { - StringBuilder builder = new StringBuilder(); - for (ComponentName componentName : componentNames) { - if (builder.length() > 0) { - builder.append(COMPONENT_NAME_SEPARATOR); - } - builder.append(componentName.flattenToShortString()); - } - Settings.Secure.putStringForUser(mContext.getContentResolver(), - settingName, builder.toString(), userId); - } - }; - - // package changes - monitor.register(mContext, BackgroundThread.getHandler().getLooper(), - UserHandle.ALL, true); - - // user changes - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_USER_SWITCHED); - intentFilter.addAction(Intent.ACTION_USER_REMOVED); - - mContext.registerReceiverAsUser(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (Intent.ACTION_USER_SWITCHED.equals(action)) { - switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); - } else if (Intent.ACTION_USER_REMOVED.equals(action)) { - removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); - } - } - }, UserHandle.ALL, intentFilter, null, BackgroundThread.getHandler()); - } - - private UserState getCurrentUserStateLocked() { - return getOrCreateUserStateLocked(mCurrentUserId); - } - - private UserState getOrCreateUserStateLocked(int userId) { - UserState userState = mUserStates.get(userId); - if (userState == null) { - userState = new UserState(mContext, userId, mLock); - mUserStates.put(userId, userState); - } - return userState; - } - - private void switchUser(int newUserId) { - UserState userState; - synchronized (mLock) { - if (newUserId == mCurrentUserId) { - return; - } - mCurrentUserId = newUserId; - userState = mUserStates.get(mCurrentUserId); - if (userState == null) { - userState = getCurrentUserStateLocked(); - userState.updateIfNeededLocked(); - } else { - userState.updateIfNeededLocked(); - } - } - // This is the first time we switch to this user after boot, so - // now is the time to remove obsolete print jobs since they - // are from the last boot and no application would query them. - userState.removeObsoletePrintJobs(); - } - - private void removeUser(int removedUserId) { - synchronized (mLock) { - UserState userState = mUserStates.get(removedUserId); - if (userState != null) { - userState.destroyLocked(); - mUserStates.remove(removedUserId); - } - } - } - - private int resolveCallingAppEnforcingPermissions(int appId) { - final int callingUid = Binder.getCallingUid(); - if (callingUid == 0 || callingUid == Process.SYSTEM_UID - || callingUid == Process.SHELL_UID) { - return appId; - } - final int callingAppId = UserHandle.getAppId(callingUid); - if (appId == callingAppId) { - return appId; - } - if (mContext.checkCallingPermission( - "com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS") - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Call from app " + callingAppId + " as app " - + appId + " without com.android.printspooler.permission" - + ".ACCESS_ALL_PRINT_JOBS"); - } - return appId; - } - - private int resolveCallingUserEnforcingPermissions(int userId) { - final int callingUid = Binder.getCallingUid(); - if (callingUid == 0 || callingUid == Process.SYSTEM_UID - || callingUid == Process.SHELL_UID) { - return userId; - } - final int callingUserId = UserHandle.getUserId(callingUid); - if (callingUserId == userId) { - return userId; - } - if (mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL) - != PackageManager.PERMISSION_GRANTED - || mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS) - != PackageManager.PERMISSION_GRANTED) { - if (userId == UserHandle.USER_CURRENT_OR_SELF) { - return callingUserId; - } - throw new SecurityException("Call from user " + callingUserId + " as user " - + userId + " without permission INTERACT_ACROSS_USERS or " - + "INTERACT_ACROSS_USERS_FULL not allowed."); - } - if (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) { - return mCurrentUserId; - } - throw new IllegalArgumentException("Calling user can be changed to only " - + "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF."); - } - - private String resolveCallingPackageNameEnforcingSecurity(String packageName) { - if (TextUtils.isEmpty(packageName)) { - return null; - } - String[] packages = mContext.getPackageManager().getPackagesForUid( - Binder.getCallingUid()); - final int packageCount = packages.length; - for (int i = 0; i < packageCount; i++) { - if (packageName.equals(packages[i])) { - return packageName; - } - } - return null; - } - - private void showEnableInstalledPrintServiceNotification(ComponentName component, - String label, int userId) { - UserHandle userHandle = new UserHandle(userId); - - Intent intent = new Intent(Settings.ACTION_PRINT_SETTINGS); - intent.putExtra(EXTRA_PRINT_SERVICE_COMPONENT_NAME, component.flattenToString()); - - PendingIntent pendingIntent = PendingIntent.getActivityAsUser(mContext, 0, intent, - PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT, null, userHandle); - - Notification.Builder builder = new Notification.Builder(mContext) - .setSmallIcon(R.drawable.ic_print) - .setContentTitle(mContext.getString(R.string.print_service_installed_title, label)) - .setContentText(mContext.getString(R.string.print_service_installed_message)) - .setContentIntent(pendingIntent) - .setWhen(System.currentTimeMillis()) - .setAutoCancel(true) - .setShowWhen(true); - - NotificationManager notificationManager = (NotificationManager) mContext - .getSystemService(Context.NOTIFICATION_SERVICE); - - String notificationTag = getClass().getName() + ":" + component.flattenToString(); - notificationManager.notifyAsUser(notificationTag, 0, builder.build(), - userHandle); - } -} diff --git a/services/java/com/android/server/wm/StackBox.java b/services/java/com/android/server/wm/StackBox.java deleted file mode 100644 index d351925015ee..000000000000 --- a/services/java/com/android/server/wm/StackBox.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -import android.graphics.Rect; -import android.util.Slog; - -import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; -import static com.android.server.wm.WindowManagerService.DEBUG_STACK; -import static com.android.server.wm.WindowManagerService.TAG; - -import java.io.PrintWriter; - -public class StackBox { - /** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */ - public static final int TASK_STACK_GOES_BEFORE = 0; - /** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */ - public static final int TASK_STACK_GOES_AFTER = 1; - /** Used with {@link WindowManagerService#createStack}. Horizontal to left of. */ - public static final int TASK_STACK_TO_LEFT_OF = 2; - /** Used with {@link WindowManagerService#createStack}. Horizontal to right of. */ - public static final int TASK_STACK_TO_RIGHT_OF = 3; - /** Used with {@link WindowManagerService#createStack}. Vertical: lower t/b Rect values. */ - public static final int TASK_STACK_GOES_ABOVE = 4; - /** Used with {@link WindowManagerService#createStack}. Vertical: higher t/b Rect values. */ - public static final int TASK_STACK_GOES_BELOW = 5; - /** Used with {@link WindowManagerService#createStack}. Put on a higher layer on display. */ - public static final int TASK_STACK_GOES_OVER = 6; - /** Used with {@link WindowManagerService#createStack}. Put on a lower layer on display. */ - public static final int TASK_STACK_GOES_UNDER = 7; - - static int sCurrentBoxId = 0; - - /** Unique id for this box */ - final int mStackBoxId; - - /** The service */ - final WindowManagerService mService; - - /** The display this box sits in. */ - final DisplayContent mDisplayContent; - - /** Non-null indicates this is mFirst or mSecond of a parent StackBox. Null indicates this - * is this entire size of mDisplayContent. */ - StackBox mParent; - - /** First child, this is null exactly when mStack is non-null. */ - StackBox mFirst; - - /** Second child, this is null exactly when mStack is non-null. */ - StackBox mSecond; - - /** Stack of Tasks, this is null exactly when mFirst and mSecond are non-null. */ - TaskStack mStack; - - /** Content limits relative to the DisplayContent this sits in. */ - Rect mBounds = new Rect(); - - /** Relative orientation of mFirst and mSecond. */ - boolean mVertical; - - /** Fraction of mBounds to devote to mFirst, remainder goes to mSecond */ - float mWeight; - - /** Dirty flag. Something inside this or some descendant of this has changed. */ - boolean layoutNeeded; - - /** True if this StackBox sits below the Status Bar. */ - boolean mUnderStatusBar; - - /** Used to keep from reallocating a temporary Rect for propagating bounds to child boxes */ - Rect mTmpRect = new Rect(); - - StackBox(WindowManagerService service, DisplayContent displayContent, StackBox parent) { - synchronized (StackBox.class) { - mStackBoxId = sCurrentBoxId++; - } - - mService = service; - mDisplayContent = displayContent; - mParent = parent; - } - - /** Propagate #layoutNeeded bottom up. */ - void makeDirty() { - layoutNeeded = true; - if (mParent != null) { - mParent.makeDirty(); - } - } - - /** - * Determine if a particular StackBox is this one or a descendant of this one. - * @param stackBoxId The StackBox being searched for. - * @return true if the specified StackBox matches this or one of its descendants. - */ - boolean contains(int stackBoxId) { - return mStackBoxId == stackBoxId || - (mStack == null && (mFirst.contains(stackBoxId) || mSecond.contains(stackBoxId))); - } - - /** - * Return the stackId of the stack that intersects the passed point. - * @param x coordinate of point. - * @param y coordinate of point. - * @return -1 if point is outside of mBounds, otherwise the stackId of the containing stack. - */ - int stackIdFromPoint(int x, int y) { - if (!mBounds.contains(x, y)) { - return -1; - } - if (mStack != null) { - return mStack.mStackId; - } - int stackId = mFirst.stackIdFromPoint(x, y); - if (stackId >= 0) { - return stackId; - } - return mSecond.stackIdFromPoint(x, y); - } - - /** Determine if this StackBox is the first child or second child. - * @return true if this is the first child. - */ - boolean isFirstChild() { - return mParent != null && mParent.mFirst == this; - } - - /** Returns the bounds of the specified TaskStack if it is contained in this StackBox. - * @param stackId the TaskStack to find the bounds of. - * @return a new Rect with the bounds of stackId if it is within this StackBox, null otherwise. - */ - Rect getStackBounds(int stackId) { - if (mStack != null) { - return mStack.mStackId == stackId ? new Rect(mBounds) : null; - } - Rect bounds = mFirst.getStackBounds(stackId); - if (bounds != null) { - return bounds; - } - return mSecond.getStackBounds(stackId); - } - - /** - * Create a new TaskStack relative to a specified one by splitting the StackBox containing - * the specified TaskStack into two children. The size and position each of the new StackBoxes - * is determined by the passed parameters. - * @param stackId The id of the new TaskStack to create. - * @param relativeStackBoxId The id of the StackBox to place the new TaskStack next to. - * @param position One of the static TASK_STACK_GOES_xxx positions defined in this class. - * @param weight The percentage size of the parent StackBox to devote to the new TaskStack. - * @return The new TaskStack. - */ - TaskStack split(int stackId, int relativeStackBoxId, int position, float weight) { - if (mStackBoxId != relativeStackBoxId) { - // This is not the targeted StackBox. - if (mStack != null) { - return null; - } - // Propagate the split to see if the targeted StackBox is in either sub box. - TaskStack stack = mFirst.split(stackId, relativeStackBoxId, position, weight); - if (stack != null) { - return stack; - } - return mSecond.split(stackId, relativeStackBoxId, position, weight); - } - - // Found it! - TaskStack stack = new TaskStack(mService, stackId, mDisplayContent); - TaskStack firstStack; - TaskStack secondStack; - if (position == TASK_STACK_GOES_BEFORE) { - // TODO: Test Configuration here for LTR/RTL. - position = TASK_STACK_TO_LEFT_OF; - } else if (position == TASK_STACK_GOES_AFTER) { - // TODO: Test Configuration here for LTR/RTL. - position = TASK_STACK_TO_RIGHT_OF; - } - switch (position) { - default: - case TASK_STACK_TO_LEFT_OF: - case TASK_STACK_TO_RIGHT_OF: - mVertical = false; - if (position == TASK_STACK_TO_LEFT_OF) { - mWeight = weight; - firstStack = stack; - secondStack = mStack; - } else { - mWeight = 1.0f - weight; - firstStack = mStack; - secondStack = stack; - } - break; - case TASK_STACK_GOES_ABOVE: - case TASK_STACK_GOES_BELOW: - mVertical = true; - if (position == TASK_STACK_GOES_ABOVE) { - mWeight = weight; - firstStack = stack; - secondStack = mStack; - } else { - mWeight = 1.0f - weight; - firstStack = mStack; - secondStack = stack; - } - break; - } - - mFirst = new StackBox(mService, mDisplayContent, this); - firstStack.mStackBox = mFirst; - mFirst.mStack = firstStack; - - mSecond = new StackBox(mService, mDisplayContent, this); - secondStack.mStackBox = mSecond; - mSecond.mStack = secondStack; - - mStack = null; - return stack; - } - - /** Return the stackId of the first mFirst StackBox with a non-null mStack */ - int getStackId() { - if (mStack != null) { - return mStack.mStackId; - } - return mFirst.getStackId(); - } - - /** Remove this box and propagate its sibling's content up to their parent. - * @return The first stackId of the resulting StackBox. */ - int remove() { - mDisplayContent.layoutNeeded = true; - - if (mParent == null) { - // This is the top-plane stack. - if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: removing top plane."); - mDisplayContent.removeStackBox(this); - return HOME_STACK_ID; - } - - StackBox sibling = isFirstChild() ? mParent.mSecond : mParent.mFirst; - StackBox grandparent = mParent.mParent; - sibling.mParent = grandparent; - if (grandparent == null) { - // mParent is a top-plane stack. Now sibling will be. - if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent null"); - mDisplayContent.removeStackBox(mParent); - mDisplayContent.addStackBox(sibling, true); - } else { - if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent getting sibling"); - if (mParent.isFirstChild()) { - grandparent.mFirst = sibling; - } else { - grandparent.mSecond = sibling; - } - } - return sibling.getStackId(); - } - - boolean resize(int stackBoxId, float weight) { - if (mStackBoxId != stackBoxId) { - return mStack == null && - (mFirst.resize(stackBoxId, weight) || mSecond.resize(stackBoxId, weight)); - } - // Don't change weight on topmost stack. - if (mParent != null) { - mParent.mWeight = isFirstChild() ? weight : 1.0f - weight; - } - return true; - } - - /** If this is a terminal StackBox (contains a TaskStack) set the bounds. - * @param bounds The rectangle to set the bounds to. - * @param underStatusBar True if the StackBox is directly below the Status Bar. - * @return True if the bounds changed, false otherwise. */ - boolean setStackBoxSizes(Rect bounds, boolean underStatusBar) { - boolean change = false; - if (mUnderStatusBar != underStatusBar) { - change = true; - mUnderStatusBar = underStatusBar; - } - if (mStack != null) { - change |= !mBounds.equals(bounds); - if (change) { - mBounds.set(bounds); - mStack.setBounds(bounds, underStatusBar); - } - } else { - mTmpRect.set(bounds); - if (mVertical) { - final int height = bounds.height(); - int firstHeight = (int)(height * mWeight); - mTmpRect.bottom = bounds.top + firstHeight; - change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar); - mTmpRect.top = mTmpRect.bottom; - mTmpRect.bottom = bounds.top + height; - change |= mSecond.setStackBoxSizes(mTmpRect, false); - } else { - final int width = bounds.width(); - int firstWidth = (int)(width * mWeight); - mTmpRect.right = bounds.left + firstWidth; - change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar); - mTmpRect.left = mTmpRect.right; - mTmpRect.right = bounds.left + width; - change |= mSecond.setStackBoxSizes(mTmpRect, underStatusBar); - } - } - return change; - } - - void resetAnimationBackgroundAnimator() { - if (mStack != null) { - mStack.resetAnimationBackgroundAnimator(); - return; - } - mFirst.resetAnimationBackgroundAnimator(); - mSecond.resetAnimationBackgroundAnimator(); - } - - boolean animateDimLayers() { - if (mStack != null) { - return mStack.animateDimLayers(); - } - boolean result = mFirst.animateDimLayers(); - result |= mSecond.animateDimLayers(); - return result; - } - - void resetDimming() { - if (mStack != null) { - mStack.resetDimmingTag(); - return; - } - mFirst.resetDimming(); - mSecond.resetDimming(); - } - - boolean isDimming() { - if (mStack != null) { - return mStack.isDimming(); - } - boolean result = mFirst.isDimming(); - result |= mSecond.isDimming(); - return result; - } - - void stopDimmingIfNeeded() { - if (mStack != null) { - mStack.stopDimmingIfNeeded(); - return; - } - mFirst.stopDimmingIfNeeded(); - mSecond.stopDimmingIfNeeded(); - } - - void switchUserStacks(int userId) { - if (mStack != null) { - mStack.switchUser(userId); - return; - } - mFirst.switchUserStacks(userId); - mSecond.switchUserStacks(userId); - } - - void close() { - if (mStack != null) { - mStack.mDimLayer.mDimSurface.destroy(); - mStack.mAnimationBackgroundSurface.mDimSurface.destroy(); - return; - } - mFirst.close(); - mSecond.close(); - } - - public void dump(String prefix, PrintWriter pw) { - pw.print(prefix); pw.print("mParent="); pw.println(mParent); - pw.print(prefix); pw.print("mBounds="); pw.print(mBounds.toShortString()); - pw.print(" mVertical="); pw.print(mVertical); - pw.print(" layoutNeeded="); pw.println(layoutNeeded); - if (mFirst != null) { - pw.print(prefix); pw.print("mFirst="); pw.println(System.identityHashCode(mFirst)); - mFirst.dump(prefix + " ", pw); - pw.print(prefix); pw.print("mSecond="); pw.println(System.identityHashCode(mSecond)); - mSecond.dump(prefix + " ", pw); - } else { - pw.print(prefix); pw.print("mStack="); pw.println(mStack); - mStack.dump(prefix + " ", pw); - } - } - - @Override - public String toString() { - if (mStack != null) { - return "Box{" + hashCode() + " stack=" + mStack.mStackId + "}"; - } - return "Box{" + hashCode() + " parent=" + System.identityHashCode(mParent) - + " first=" + System.identityHashCode(mFirst) - + " second=" + System.identityHashCode(mSecond) + "}"; - } -} diff --git a/services/jni/Android.mk b/services/jni/Android.mk deleted file mode 100644 index 98e9b3085736..000000000000 --- a/services/jni/Android.mk +++ /dev/null @@ -1,63 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - com_android_server_AlarmManagerService.cpp \ - com_android_server_AssetAtlasService.cpp \ - com_android_server_ConsumerIrService.cpp \ - com_android_server_input_InputApplicationHandle.cpp \ - com_android_server_input_InputManagerService.cpp \ - com_android_server_input_InputWindowHandle.cpp \ - com_android_server_LightsService.cpp \ - com_android_server_power_PowerManagerService.cpp \ - com_android_server_SerialService.cpp \ - com_android_server_SystemServer.cpp \ - com_android_server_UsbDeviceManager.cpp \ - com_android_server_UsbHostManager.cpp \ - com_android_server_VibratorService.cpp \ - com_android_server_location_GpsLocationProvider.cpp \ - com_android_server_location_FlpHardwareProvider.cpp \ - com_android_server_connectivity_Vpn.cpp \ - onload.cpp - -LOCAL_C_INCLUDES += \ - $(JNI_H_INCLUDE) \ - frameworks/base/services \ - frameworks/base/core/jni \ - frameworks/native/services \ - external/skia/include/core \ - libcore/include \ - libcore/include/libsuspend \ - $(call include-path-for, libhardware)/hardware \ - $(call include-path-for, libhardware_legacy)/hardware_legacy \ - -LOCAL_SHARED_LIBRARIES := \ - libandroid_runtime \ - libandroidfw \ - libbinder \ - libcutils \ - liblog \ - libhardware \ - libhardware_legacy \ - libnativehelper \ - libutils \ - libui \ - libinput \ - libinputservice \ - libsensorservice \ - libskia \ - libgui \ - libusbhost \ - libsuspend \ - libEGL \ - libGLESv2 - -LOCAL_CFLAGS += -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES - -ifeq ($(WITH_MALLOC_LEAK_CHECK),true) - LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK -endif - -LOCAL_MODULE:= libandroid_servers - -include $(BUILD_SHARED_LIBRARY) diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java new file mode 100644 index 000000000000..852736b682df --- /dev/null +++ b/services/print/java/com/android/server/print/PrintManagerService.java @@ -0,0 +1,690 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.print; + +import android.Manifest; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Binder; +import android.os.Bundle; +import android.os.Process; +import android.os.RemoteException; +import android.os.UserHandle; +import android.print.IPrintDocumentAdapter; +import android.print.IPrintJobStateChangeListener; +import android.print.IPrintManager; +import android.print.IPrinterDiscoveryObserver; +import android.print.PrintAttributes; +import android.print.PrintJobId; +import android.print.PrintJobInfo; +import android.print.PrinterId; +import android.printservice.PrintServiceInfo; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.SparseArray; + +import com.android.internal.R; +import com.android.internal.content.PackageMonitor; +import com.android.internal.os.BackgroundThread; +import com.android.server.SystemService; +import com.android.server.devicepolicy.DevicePolicyManagerService; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * SystemService wrapper for the PrintManager implementation. Publishes + * Context.PRINT_SERVICE. + * PrintManager implementation is contained within. + */ + +public final class PrintManagerService extends SystemService { + + private PrintManagerImpl mPrintManagerImpl; + + @Override + public void onCreate(Context context) { + mPrintManagerImpl = new PrintManagerImpl(context); + } + @Override + public void onStart() { + publishBinderService(Context.PRINT_SERVICE, mPrintManagerImpl); + } + + @Override + public void onBootPhase(int phase) { + if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { + mPrintManagerImpl.systemRunning(); + } + } + + class PrintManagerImpl extends IPrintManager.Stub { + private static final char COMPONENT_NAME_SEPARATOR = ':'; + + private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME = + "EXTRA_PRINT_SERVICE_COMPONENT_NAME"; + + private final Object mLock = new Object(); + + private final Context mContext; + + private final SparseArray<UserState> mUserStates = new SparseArray<UserState>(); + + private int mCurrentUserId = UserHandle.USER_OWNER; + + PrintManagerImpl(Context context) { + mContext = context; + registerContentObservers(); + registerBoradcastReceivers(); + } + + public void systemRunning() { + BackgroundThread.getHandler().post(new Runnable() { + @Override + public void run() { + final UserState userState; + synchronized (mLock) { + userState = getCurrentUserStateLocked(); + userState.updateIfNeededLocked(); + } + // This is the first time we switch to this user after boot, so + // now is the time to remove obsolete print jobs since they + // are from the last boot and no application would query them. + userState.removeObsoletePrintJobs(); + } + }); + } + + @Override + public Bundle print(String printJobName, IPrintDocumentAdapter adapter, + PrintAttributes attributes, String packageName, int appId, int userId) { + final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + String resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + return userState.print(printJobName, adapter, attributes, + resolvedPackageName, resolvedAppId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public List<PrintJobInfo> getPrintJobInfos(int appId, int userId) { + final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + return userState.getPrintJobInfos(resolvedAppId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) { + final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + return userState.getPrintJobInfo(printJobId, resolvedAppId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) { + final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.cancelPrintJob(printJobId, resolvedAppId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void restartPrintJob(PrintJobId printJobId, int appId, int userId) { + final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.restartPrintJob(printJobId, resolvedAppId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public List<PrintServiceInfo> getEnabledPrintServices(int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + return userState.getEnabledPrintServices(); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public List<PrintServiceInfo> getInstalledPrintServices(int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + return userState.getInstalledPrintServices(); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer, + int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.createPrinterDiscoverySession(observer); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer, + int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.destroyPrinterDiscoverySession(observer); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void startPrinterDiscovery(IPrinterDiscoveryObserver observer, + List<PrinterId> priorityList, int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.startPrinterDiscovery(observer, priorityList); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer, int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.stopPrinterDiscovery(observer); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void validatePrinters(List<PrinterId> printerIds, int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.validatePrinters(printerIds); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void startPrinterStateTracking(PrinterId printerId, int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.startPrinterStateTracking(printerId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void stopPrinterStateTracking(PrinterId printerId, int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.stopPrinterStateTracking(printerId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener, + int appId, int userId) throws RemoteException { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.addPrintJobStateChangeListener(listener, resolvedAppId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener, + int userId) { + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + final UserState userState; + synchronized (mLock) { + userState = getOrCreateUserStateLocked(resolvedUserId); + } + final long identity = Binder.clearCallingIdentity(); + try { + userState.removePrintJobStateChangeListener(listener); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) + != PackageManager.PERMISSION_GRANTED) { + pw.println("Permission Denial: can't dump PrintManager from from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid()); + return; + } + + synchronized (mLock) { + final long identity = Binder.clearCallingIdentity(); + try { + pw.println("PRINT MANAGER STATE (dumpsys print)"); + final int userStateCount = mUserStates.size(); + for (int i = 0; i < userStateCount; i++) { + UserState userState = mUserStates.valueAt(i); + userState.dump(fd, pw, ""); + pw.println(); + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + } + + private void registerContentObservers() { + final Uri enabledPrintServicesUri = Settings.Secure.getUriFor( + Settings.Secure.ENABLED_PRINT_SERVICES); + + ContentObserver observer = new ContentObserver(BackgroundThread.getHandler()) { + @Override + public void onChange(boolean selfChange, Uri uri) { + if (enabledPrintServicesUri.equals(uri)) { + synchronized (mLock) { + UserState userState = getCurrentUserStateLocked(); + userState.updateIfNeededLocked(); + } + } + } + }; + + mContext.getContentResolver().registerContentObserver(enabledPrintServicesUri, + false, observer, UserHandle.USER_ALL); + } + + private void registerBoradcastReceivers() { + PackageMonitor monitor = new PackageMonitor() { + @Override + public boolean onPackageChanged(String packageName, int uid, String[] components) { + synchronized (mLock) { + UserState userState = getOrCreateUserStateLocked(getChangingUserId()); + Iterator<ComponentName> iterator = userState.getEnabledServices() + .iterator(); + while (iterator.hasNext()) { + ComponentName componentName = iterator.next(); + if (packageName.equals(componentName.getPackageName())) { + userState.updateIfNeededLocked(); + return true; + } + } + } + return false; + } + + @Override + public void onPackageRemoved(String packageName, int uid) { + synchronized (mLock) { + UserState userState = getOrCreateUserStateLocked(getChangingUserId()); + Iterator<ComponentName> iterator = userState.getEnabledServices() + .iterator(); + while (iterator.hasNext()) { + ComponentName componentName = iterator.next(); + if (packageName.equals(componentName.getPackageName())) { + iterator.remove(); + persistComponentNamesToSettingLocked( + Settings.Secure.ENABLED_PRINT_SERVICES, + userState.getEnabledServices(), getChangingUserId()); + userState.updateIfNeededLocked(); + return; + } + } + } + } + + @Override + public boolean onHandleForceStop(Intent intent, String[] stoppedPackages, + int uid, boolean doit) { + synchronized (mLock) { + UserState userState = getOrCreateUserStateLocked(getChangingUserId()); + boolean stoppedSomePackages = false; + Iterator<ComponentName> iterator = userState.getEnabledServices() + .iterator(); + while (iterator.hasNext()) { + ComponentName componentName = iterator.next(); + String componentPackage = componentName.getPackageName(); + for (String stoppedPackage : stoppedPackages) { + if (componentPackage.equals(stoppedPackage)) { + if (!doit) { + return true; + } + stoppedSomePackages = true; + break; + } + } + } + if (stoppedSomePackages) { + userState.updateIfNeededLocked(); + } + return false; + } + } + + @Override + public void onPackageAdded(String packageName, int uid) { + Intent intent = new Intent(android.printservice.PrintService.SERVICE_INTERFACE); + intent.setPackage(packageName); + + List<ResolveInfo> installedServices = mContext.getPackageManager() + .queryIntentServicesAsUser(intent, PackageManager.GET_SERVICES, + getChangingUserId()); + + if (installedServices == null) { + return; + } + + final int installedServiceCount = installedServices.size(); + for (int i = 0; i < installedServiceCount; i++) { + ServiceInfo serviceInfo = installedServices.get(i).serviceInfo; + ComponentName component = new ComponentName(serviceInfo.packageName, + serviceInfo.name); + String label = serviceInfo.loadLabel(mContext.getPackageManager()) + .toString(); + showEnableInstalledPrintServiceNotification(component, label, + getChangingUserId()); + } + } + + private void persistComponentNamesToSettingLocked(String settingName, + Set<ComponentName> componentNames, int userId) { + StringBuilder builder = new StringBuilder(); + for (ComponentName componentName : componentNames) { + if (builder.length() > 0) { + builder.append(COMPONENT_NAME_SEPARATOR); + } + builder.append(componentName.flattenToShortString()); + } + Settings.Secure.putStringForUser(mContext.getContentResolver(), + settingName, builder.toString(), userId); + } + }; + + // package changes + monitor.register(mContext, BackgroundThread.getHandler().getLooper(), + UserHandle.ALL, true); + + // user changes + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Intent.ACTION_USER_SWITCHED); + intentFilter.addAction(Intent.ACTION_USER_REMOVED); + + mContext.registerReceiverAsUser(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_USER_SWITCHED.equals(action)) { + switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); + } else if (Intent.ACTION_USER_REMOVED.equals(action)) { + removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); + } + } + }, UserHandle.ALL, intentFilter, null, BackgroundThread.getHandler()); + } + + private UserState getCurrentUserStateLocked() { + return getOrCreateUserStateLocked(mCurrentUserId); + } + + private UserState getOrCreateUserStateLocked(int userId) { + UserState userState = mUserStates.get(userId); + if (userState == null) { + userState = new UserState(mContext, userId, mLock); + mUserStates.put(userId, userState); + } + return userState; + } + + private void switchUser(int newUserId) { + UserState userState; + synchronized (mLock) { + if (newUserId == mCurrentUserId) { + return; + } + mCurrentUserId = newUserId; + userState = mUserStates.get(mCurrentUserId); + if (userState == null) { + userState = getCurrentUserStateLocked(); + userState.updateIfNeededLocked(); + } else { + userState.updateIfNeededLocked(); + } + } + // This is the first time we switch to this user after boot, so + // now is the time to remove obsolete print jobs since they + // are from the last boot and no application would query them. + userState.removeObsoletePrintJobs(); + } + + private void removeUser(int removedUserId) { + synchronized (mLock) { + UserState userState = mUserStates.get(removedUserId); + if (userState != null) { + userState.destroyLocked(); + mUserStates.remove(removedUserId); + } + } + } + + private int resolveCallingAppEnforcingPermissions(int appId) { + final int callingUid = Binder.getCallingUid(); + if (callingUid == 0 || callingUid == Process.SYSTEM_UID + || callingUid == Process.SHELL_UID) { + return appId; + } + final int callingAppId = UserHandle.getAppId(callingUid); + if (appId == callingAppId) { + return appId; + } + if (mContext.checkCallingPermission( + "com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS") + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Call from app " + callingAppId + " as app " + + appId + " without com.android.printspooler.permission" + + ".ACCESS_ALL_PRINT_JOBS"); + } + return appId; + } + + private int resolveCallingUserEnforcingPermissions(int userId) { + final int callingUid = Binder.getCallingUid(); + if (callingUid == 0 || callingUid == Process.SYSTEM_UID + || callingUid == Process.SHELL_UID) { + return userId; + } + final int callingUserId = UserHandle.getUserId(callingUid); + if (callingUserId == userId) { + return userId; + } + if (mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL) + != PackageManager.PERMISSION_GRANTED + || mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS) + != PackageManager.PERMISSION_GRANTED) { + if (userId == UserHandle.USER_CURRENT_OR_SELF) { + return callingUserId; + } + throw new SecurityException("Call from user " + callingUserId + " as user " + + userId + " without permission INTERACT_ACROSS_USERS or " + + "INTERACT_ACROSS_USERS_FULL not allowed."); + } + if (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) { + return mCurrentUserId; + } + throw new IllegalArgumentException("Calling user can be changed to only " + + "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF."); + } + + private String resolveCallingPackageNameEnforcingSecurity(String packageName) { + if (TextUtils.isEmpty(packageName)) { + return null; + } + String[] packages = mContext.getPackageManager().getPackagesForUid( + Binder.getCallingUid()); + final int packageCount = packages.length; + for (int i = 0; i < packageCount; i++) { + if (packageName.equals(packages[i])) { + return packageName; + } + } + return null; + } + + private void showEnableInstalledPrintServiceNotification(ComponentName component, + String label, int userId) { + UserHandle userHandle = new UserHandle(userId); + + Intent intent = new Intent(Settings.ACTION_PRINT_SETTINGS); + intent.putExtra(EXTRA_PRINT_SERVICE_COMPONENT_NAME, component.flattenToString()); + + PendingIntent pendingIntent = PendingIntent.getActivityAsUser(mContext, 0, intent, + PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT, null, + userHandle); + + Notification.Builder builder = new Notification.Builder(mContext) + .setSmallIcon(R.drawable.ic_print) + .setContentTitle(mContext.getString(R.string.print_service_installed_title, + label)) + .setContentText(mContext.getString(R.string.print_service_installed_message)) + .setContentIntent(pendingIntent) + .setWhen(System.currentTimeMillis()) + .setAutoCancel(true) + .setShowWhen(true); + + NotificationManager notificationManager = (NotificationManager) mContext + .getSystemService(Context.NOTIFICATION_SERVICE); + + String notificationTag = getClass().getName() + ":" + component.flattenToString(); + notificationManager.notifyAsUser(notificationTag, 0, builder.build(), + userHandle); + } + } +} diff --git a/services/java/com/android/server/print/RemotePrintService.java b/services/print/java/com/android/server/print/RemotePrintService.java index 1bb61d246eb8..1bb61d246eb8 100644 --- a/services/java/com/android/server/print/RemotePrintService.java +++ b/services/print/java/com/android/server/print/RemotePrintService.java diff --git a/services/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java index ffe9806a2418..ffe9806a2418 100644 --- a/services/java/com/android/server/print/RemotePrintSpooler.java +++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java diff --git a/services/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java index f23a992cd58f..f23a992cd58f 100644 --- a/services/java/com/android/server/print/UserState.java +++ b/services/print/java/com/android/server/print/UserState.java diff --git a/services/print/java/service.mk b/services/print/java/service.mk new file mode 100644 index 000000000000..cba3612e901a --- /dev/null +++ b/services/print/java/service.mk @@ -0,0 +1,11 @@ +# Include only if the service is required +ifneq ($(findstring print,$(REQUIRED_SERVICES)),) + +SUB_DIR := print/java + +LOCAL_SRC_FILES += \ + $(call all-java-files-under,$(SUB_DIR)) + +#DEFINED_SERVICES += com.android.server.print.PrintManagerService + +endif diff --git a/services/tests/Android.mk b/services/tests/Android.mk new file mode 100644 index 000000000000..40369ee2ec5c --- /dev/null +++ b/services/tests/Android.mk @@ -0,0 +1,3 @@ +LOCAL_PATH:= $(call my-dir) + +include $(call all-makefiles-under, $(LOCAL_PATH)) |