diff options
| -rw-r--r-- | Android.mk | 2 | ||||
| -rw-r--r-- | CleanSpec.mk | 2 | ||||
| -rw-r--r-- | api/current.txt | 17 | ||||
| -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 | 258 | ||||
| -rw-r--r-- | core/java/android/app/IActivityContainer.aidl | 35 | ||||
| -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/app/Notification.java | 21 | ||||
| -rw-r--r-- | core/java/android/bluetooth/BluetoothAdapter.java | 210 | ||||
| -rw-r--r-- | core/java/android/bluetooth/BluetoothAdvScanData.java | 147 | ||||
| -rw-r--r-- | core/java/android/bluetooth/BluetoothGatt.java | 73 | ||||
| -rw-r--r-- | core/java/android/bluetooth/BluetoothGattServer.java | 2 | ||||
| -rw-r--r-- | core/java/android/bluetooth/BluetoothGattService.java | 23 | ||||
| -rw-r--r-- | core/java/android/bluetooth/BluetoothInputDevice.java | 12 | ||||
| -rw-r--r-- | core/java/android/bluetooth/BluetoothSocket.java | 27 | ||||
| -rw-r--r-- | core/java/android/bluetooth/BluetoothUuid.java | 16 | ||||
| -rw-r--r-- | core/java/android/bluetooth/IBluetoothGatt.aidl | 15 | ||||
| -rw-r--r-- | core/java/android/bluetooth/IBluetoothGattCallback.aidl | 1 | ||||
| -rw-r--r-- | core/java/android/content/Intent.java | 5 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManager.java | 14 | ||||
| -rw-r--r-- | core/java/android/database/sqlite/SQLiteDatabase.java | 10 | ||||
| -rw-r--r-- | core/java/android/hardware/display/DisplayManager.java | 21 | ||||
| -rw-r--r-- | core/java/android/hardware/display/DisplayManagerInternal.java | 109 | ||||
| -rw-r--r-- | core/java/android/hardware/display/DisplayViewport.java (renamed from services/java/com/android/server/display/DisplayViewport.java) | 4 | ||||
| -rw-r--r-- | core/java/android/hardware/input/InputManagerInternal.java | 36 | ||||
| -rw-r--r-- | core/java/android/net/ConnectivityManager.java | 12 | ||||
| -rw-r--r-- | core/java/android/net/ProxyDataTracker.java | 122 | ||||
| -rw-r--r-- | core/java/android/os/FactoryTest.java | 14 | ||||
| -rw-r--r-- | core/java/android/os/PowerManagerInternal.java | 60 | ||||
| -rw-r--r-- | core/java/android/os/Process.java | 13 | ||||
| -rw-r--r-- | core/java/android/service/dreams/DreamManagerInternal.java | 39 | ||||
| -rw-r--r-- | core/java/android/service/notification/NotificationListenerService.java | 11 | ||||
| -rw-r--r-- | core/java/android/util/TypedValue.java | 16 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceControl.java | 72 | ||||
| -rw-r--r-- | core/java/android/view/WindowManagerInternal.java | 33 | ||||
| -rw-r--r-- | core/java/android/view/accessibility/AccessibilityManager.java | 40 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/BatteryStatsImpl.java | 9 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/BinderInternal.java | 7 | ||||
| -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 | 195 | ||||
| -rw-r--r-- | core/java/com/android/server/SystemServiceManager.java | 169 | ||||
| -rw-r--r-- | core/jni/android_util_Process.cpp | 18 | ||||
| -rw-r--r-- | core/res/AndroidManifest.xml | 8 | ||||
| -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) | 190 | ||||
| -rw-r--r-- | libs/input/InputDispatcher.h (renamed from services/input/InputDispatcher.h) | 9 | ||||
| -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) | 39 | ||||
| -rw-r--r-- | libs/input/tests/InputReader_test.cpp (renamed from services/input/tests/InputReader_test.cpp) | 0 | ||||
| -rw-r--r-- | packages/Keyguard/Android.mk | 2 | ||||
| -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 | 45 | ||||
| -rw-r--r-- | services/accessibility/Android.mk | 10 | ||||
| -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/appwidget/Android.mk | 10 | ||||
| -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/backup/Android.mk | 12 | ||||
| -rw-r--r-- | services/backup/java/com/android/server/backup/BackupManagerService.java (renamed from services/java/com/android/server/BackupManagerService.java) | 31 | ||||
| -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/core/Android.mk | 14 | ||||
| -rw-r--r-- | services/core/java/com/android/server/AlarmManagerService.java (renamed from services/java/com/android/server/AlarmManagerService.java) | 579 | ||||
| -rw-r--r-- | services/core/java/com/android/server/AppOpsService.java (renamed from services/java/com/android/server/AppOpsService.java) | 4 | ||||
| -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) | 7 | ||||
| -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) | 4 | ||||
| -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/DisplayThread.java | 56 | ||||
| -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) | 11 | ||||
| -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) | 11 | ||||
| -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/ServiceThread.java | 48 | ||||
| -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/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) | 290 | ||||
| -rw-r--r-- | services/core/java/com/android/server/UiThread.java (renamed from services/java/com/android/server/UiThread.java) | 20 | ||||
| -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) | 33 | ||||
| -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) | 451 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityRecord.java (renamed from services/java/com/android/server/am/ActivityRecord.java) | 9 | ||||
| -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) | 179 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityStackSupervisor.java (renamed from services/java/com/android/server/am/ActivityStackSupervisor.java) | 1253 | ||||
| -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) | 5 | ||||
| -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) | 15 | ||||
| -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) | 18 | ||||
| -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) | 4 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/PendingIntentRecord.java (renamed from services/java/com/android/server/am/PendingIntentRecord.java) | 10 | ||||
| -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) | 135 | ||||
| -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) | 1 | ||||
| -rw-r--r-- | services/core/java/com/android/server/display/DisplayDeviceInfo.java (renamed from services/java/com/android/server/display/DisplayDeviceInfo.java) | 11 | ||||
| -rw-r--r-- | services/core/java/com/android/server/display/DisplayManagerService.java (renamed from services/java/com/android/server/display/DisplayManagerService.java) | 933 | ||||
| -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 | 494 | ||||
| -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) | 12 | ||||
| -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) | 41 | ||||
| -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) | 1244 | ||||
| -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) | 18 | ||||
| -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) | 64 | ||||
| -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) | 27 | ||||
| -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) | 29 | ||||
| -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) | 948 | ||||
| -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) | 250 | ||||
| -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 (renamed from services/java/com/android/server/display/DisplayTransactionListener.java) | 16 | ||||
| -rw-r--r-- | services/core/java/com/android/server/twilight/TwilightService.java (renamed from services/java/com/android/server/TwilightService.java) | 251 | ||||
| -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) | 2 | ||||
| -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) | 13 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/DisplayContent.java | 372 | ||||
| -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) | 6 | ||||
| -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) | 2 | ||||
| -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) | 214 | ||||
| -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) | 82 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java (renamed from services/java/com/android/server/wm/WindowManagerService.java) | 692 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowState.java (renamed from services/java/com/android/server/wm/WindowState.java) | 125 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowStateAnimator.java (renamed from services/java/com/android/server/wm/WindowStateAnimator.java) | 45 | ||||
| -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/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) | 8 | ||||
| -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/Android.mk | 12 | ||||
| -rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java (renamed from services/java/com/android/server/DevicePolicyManagerService.java) | 352 | ||||
| -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/SystemServer.java | 589 | ||||
| -rw-r--r-- | services/java/com/android/server/display/HeadlessDisplayAdapter.java | 73 | ||||
| -rw-r--r-- | services/java/com/android/server/dreams/DreamManagerService.java | 425 | ||||
| -rw-r--r-- | services/java/com/android/server/print/PrintManagerService.java | 656 | ||||
| -rw-r--r-- | services/java/com/android/server/wm/DisplayContent.java | 523 | ||||
| -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/Android.mk | 10 | ||||
| -rw-r--r-- | services/print/java/com/android/server/print/PrintManagerService.java | 689 | ||||
| -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/tests/Android.mk | 3 | ||||
| -rw-r--r-- | tools/aapt/AaptAssets.cpp | 45 | ||||
| -rw-r--r-- | tools/aapt/AaptAssets.h | 8 | ||||
| -rw-r--r-- | tools/aapt/Bundle.h | 6 | ||||
| -rw-r--r-- | tools/aapt/Command.cpp | 2 | ||||
| -rw-r--r-- | tools/aapt/Main.cpp | 2 | 
419 files changed, 10033 insertions, 7358 deletions
diff --git a/Android.mk b/Android.mk index efa1870c23e8..687989c9680a 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 50337c0cb8f6..d0bf458cdbf9 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3080,6 +3080,17 @@ 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 public boolean isAttachedToDisplay(); +    method protected void onLayout(boolean, int, int, int, int); +    method public void startActivity(android.content.Intent); +    method public void startActivity(android.content.IntentSender); +    method public void startActivity(android.app.PendingIntent); +  } +    public class AlarmManager {      method public void cancel(android.app.PendingIntent);      method public void set(int, long, android.app.PendingIntent); @@ -3941,6 +3952,7 @@ package android.app {      field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40      field public static final deprecated int FLAG_HIGH_PRIORITY = 128; // 0x80      field public static final int FLAG_INSISTENT = 4; // 0x4 +    field public static final int FLAG_LOCAL_ONLY = 256; // 0x100      field public static final int FLAG_NO_CLEAR = 32; // 0x20      field public static final int FLAG_ONGOING_EVENT = 2; // 0x2      field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8 @@ -4021,6 +4033,7 @@ package android.app {      method public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);      method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);      method public android.app.Notification.Builder setLights(int, int, int); +    method public android.app.Notification.Builder setLocalOnly(boolean);      method public android.app.Notification.Builder setNumber(int);      method public android.app.Notification.Builder setOngoing(boolean);      method public android.app.Notification.Builder setOnlyAlertOnce(boolean); @@ -7277,6 +7290,7 @@ package android.content.pm {      field public static final java.lang.String EXTRA_VERIFICATION_RESULT = "android.content.pm.extra.VERIFICATION_RESULT";      field public static final java.lang.String FEATURE_APP_WIDGETS = "android.software.app_widgets";      field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency"; +    field public static final java.lang.String FEATURE_BACKUP = "android.software.backup";      field public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth";      field public static final java.lang.String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";      field public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera"; @@ -7298,6 +7312,7 @@ package android.content.pm {      field public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone";      field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";      field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce"; +    field public static final java.lang.String FEATURE_PRINTING = "android.software.print";      field public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape";      field public static final java.lang.String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait";      field public static final java.lang.String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer"; @@ -10870,6 +10885,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 @@ -26175,7 +26191,6 @@ package android.util {      method public final java.lang.CharSequence coerceToString();      method public static final java.lang.String coerceToString(int, int);      method public static float complexToDimension(int, android.util.DisplayMetrics); -    method public static float complexToDimensionNoisy(int, android.util.DisplayMetrics);      method public static int complexToDimensionPixelOffset(int, android.util.DisplayMetrics);      method public static int complexToDimensionPixelSize(int, android.util.DisplayMetrics);      method public static float complexToFloat(int); 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..48ec420bb435 --- /dev/null +++ b/core/java/android/app/ActivityView.java @@ -0,0 +1,258 @@ +/* + * 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.IIntentSender; +import android.content.Intent; +import android.content.IntentSender; +import android.graphics.SurfaceTexture; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.InputDevice; +import android.view.InputEvent; +import android.view.MotionEvent; +import android.view.Surface; +import android.view.TextureView; +import android.view.TextureView.SurfaceTextureListener; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +public class ActivityView extends ViewGroup { +    private final String TAG = "ActivityView"; + +    private final TextureView mTextureView; +    private IActivityContainer mActivityContainer; +    private Activity mActivity; +    private int mWidth; +    private int mHeight; +    private Surface mSurface; + +    // Only one IIntentSender or Intent may be queued at a time. Most recent one wins. +    IIntentSender mQueuedPendingIntent; +    Intent mQueuedIntent; + +    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(0, 0, r - l, b - t); +    } + +    @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); +        } + +        attachToSurfaceWhenReady(); +    } + +    @Override +    protected void onDetachedFromWindow() { +        if (mActivityContainer != null) { +            detach(); +            mActivityContainer = null; +        } +    } + +    @Override +    protected void onWindowVisibilityChanged(int visibility) { +        super.onWindowVisibilityChanged(visibility); +        if (visibility == View.VISIBLE) { +            attachToSurfaceWhenReady(); +        } else { +            detach(); +        } +    } + +    private boolean injectInputEvent(InputEvent event) { +        try { +            return mActivityContainer != null && mActivityContainer.injectEvent(event); +        } catch (RemoteException e) { +            return false; +        } +    } + +    @Override +    public boolean onTouchEvent(MotionEvent event) { +        return injectInputEvent(event) || super.onTouchEvent(event); +    } + +    @Override +    public boolean onGenericMotionEvent(MotionEvent event) { +        if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { +            if (injectInputEvent(event)) { +                return true; +            } +        } +        return super.onGenericMotionEvent(event); +    } + +    public boolean isAttachedToDisplay() { +        return mSurface != null; +    } + +    public void startActivity(Intent intent) { +        if (mSurface != null) { +            try { +                mActivityContainer.startActivity(intent); +            } catch (RemoteException e) { +                throw new IllegalStateException("ActivityView: Unable to startActivity. " + e); +            } +        } else { +            mQueuedIntent = intent; +            mQueuedPendingIntent = null; +        } +    } + +    private void startActivityIntentSender(IIntentSender iIntentSender) { +        try { +            mActivityContainer.startActivityIntentSender(iIntentSender); +        } catch (RemoteException e) { +            throw new IllegalStateException( +                    "ActivityView: Unable to startActivity from IntentSender. " + e); +        } +    } + +    public void startActivity(IntentSender intentSender) { +        final IIntentSender iIntentSender = intentSender.getTarget(); +        if (mSurface != null) { +            startActivityIntentSender(iIntentSender); +        } else { +            mQueuedPendingIntent = iIntentSender; +            mQueuedIntent = null; +        } +    } + +    public void startActivity(PendingIntent pendingIntent) { +        final IIntentSender iIntentSender = pendingIntent.getTarget(); +        if (mSurface != null) { +            startActivityIntentSender(iIntentSender); +        } else { +            mQueuedPendingIntent = iIntentSender; +            mQueuedIntent = null; +        } +    } + +    private void attachToSurfaceWhenReady() { +        final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture(); +        if (mActivityContainer == null || surfaceTexture == null || mSurface != null) { +            // Either not ready to attach, or already attached. +            return; +        } + +        WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE); +        DisplayMetrics metrics = new DisplayMetrics(); +        wm.getDefaultDisplay().getMetrics(metrics); + +        mSurface = new Surface(surfaceTexture); +        try { +            mActivityContainer.attachToSurface(mSurface, mWidth, mHeight, metrics.densityDpi); +        } catch (RemoteException e) { +            mSurface.release(); +            mSurface = null; +            throw new IllegalStateException( +                    "ActivityView: Unable to create ActivityContainer. " + e); +        } + +        if (mQueuedIntent != null) { +            startActivity(mQueuedIntent); +            mQueuedIntent = null; +        } else if (mQueuedPendingIntent != null) { +            startActivityIntentSender(mQueuedPendingIntent); +            mQueuedPendingIntent = null; +        } +    } + +    private void detach() { +        if (mSurface != null) { +            try { +                mActivityContainer.detachFromDisplay(); +            } catch (RemoteException e) { +            } +            mSurface.release(); +            mSurface = null; +        } +    } + +    private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener { +        @Override +        public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, +                int height) { +            mWidth = width; +            mHeight = height; +            if (mActivityContainer != null) { +                attachToSurfaceWhenReady(); +            } +        } + +        @Override +        public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, +                int height) { +            Log.d(TAG, "onSurfaceTextureSizeChanged: w=" + width + " h=" + height); +        } + +        @Override +        public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { +            Log.d(TAG, "onSurfaceTextureDestroyed"); +            detach(); +            return true; +        } + +        @Override +        public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { +//            Log.d(TAG, "onSurfaceTextureUpdated"); +        } + +    } +} diff --git a/core/java/android/app/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl new file mode 100644 index 000000000000..5b80e06e1611 --- /dev/null +++ b/core/java/android/app/IActivityContainer.aidl @@ -0,0 +1,35 @@ +/** + * 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.content.IIntentSender; +import android.os.IBinder; +import android.view.InputEvent; +import android.view.Surface; + +/** @hide */ +interface IActivityContainer { +    void attachToDisplay(int displayId); +    void attachToSurface(in Surface surface, int width, int height, int density); +    void detachFromDisplay(); +    int startActivity(in Intent intent); +    int startActivityIntentSender(in IIntentSender intentSender); +    int getDisplayId(); +    boolean injectEvent(in InputEvent event); +} 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/app/Notification.java b/core/java/android/app/Notification.java index c63e586a7127..1e96ebf3d1c5 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -348,6 +348,13 @@ public class Notification implements Parcelable       */      public static final int FLAG_HIGH_PRIORITY      = 0x00000080; +    /** +     * Bit to be bitswise-ored into the {@link #flags} field that should be +     * set if this notification is relevant to the current device only +     * and it is not recommended that it bridge to other devices. +     */ +    public static final int FLAG_LOCAL_ONLY         = 0x00000100; +      public int flags;      /** @@ -1532,6 +1539,17 @@ public class Notification implements Parcelable          }          /** +         * Set whether or not this notification should not bridge to other devices. +         * +         * <p>Some notifications can be bridged to other devices for remote display. +         * This hint can be set to recommend this notification not be bridged. +         */ +        public Builder setLocalOnly(boolean localOnly) { +            setFlag(FLAG_LOCAL_ONLY, localOnly); +            return this; +        } + +        /**           * Set which notification properties will be inherited from system defaults.           * <p>           * The value should be one or more of the following fields combined with @@ -1900,8 +1918,7 @@ public class Notification implements Parcelable       * An object that can apply a rich notification style to a {@link Notification.Builder}       * object.       */ -    public static abstract class Style -    { +    public static abstract class Style {          private CharSequence mBigContentTitle;          private CharSequence mSummaryText = null;          private boolean mSummaryTextSet = false; diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index e2bc80aad66d..d1f1f2af44c9 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -27,14 +27,14 @@ import android.os.RemoteException;  import android.os.ServiceManager;  import android.util.Log;  import android.util.Pair; +  import java.io.IOException;  import java.lang.ref.WeakReference;  import java.util.ArrayList;  import java.util.Arrays;  import java.util.Collections; -import java.util.HashSet;  import java.util.HashMap; -import java.util.LinkedList; +import java.util.HashSet;  import java.util.Locale;  import java.util.Map;  import java.util.Random; @@ -183,6 +183,43 @@ public final class BluetoothAdapter {              "android.bluetooth.adapter.extra.DISCOVERABLE_DURATION";      /** +     * Activity Action: Show a system activity to request BLE advertising.<br> +     * If the device is not doing BLE advertising, this activity will start BLE advertising for the +     * device, otherwise it will continue BLE advertising using the current +     * {@link BluetoothAdvScanData}. <br> +     * Note this activity will also request the user to turn on Bluetooth if it's not currently +     * enabled. +     * @hide +     */ +    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) +    public static final String ACTION_START_ADVERTISING = +        "android.bluetooth.adapter.action.START_ADVERTISING"; + +    /** +     * Activity Action: Stop the current BLE advertising. +     * @hide +     */ +    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) +    public static final String ACTION_STOP_ADVERTISING = +        "android.bluetooth.adapter.action.STOP_ADVERTISING"; + +    /** +     * Broadcast Action: Indicate BLE Advertising is started. +     * @hide +     */ +    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) +    public static final String ACTION_BLUETOOTH_ADVERTISING_STARTED = +        "android.bluetooth.adapter.action.ADVERTISING_STARTED"; + +    /** +     * Broadcast Action: Indicated BLE Advertising is stopped. +     * @hide +     */ +    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) +    public static final String ACTION_BLUETOOTH_ADVERTISING_STOPPED = +        "android.bluetooth.adapter.action.ADVERTISING_STOPPED"; + +    /**       * Activity Action: Show a system activity that allows the user to turn on       * Bluetooth.       * <p>This system activity will return once Bluetooth has completed turning @@ -251,7 +288,6 @@ public final class BluetoothAdapter {       */      public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23; -      /**       * Broadcast Action: The local Bluetooth adapter has started the remote       * device discovery process. @@ -365,6 +401,8 @@ public final class BluetoothAdapter {      private IBluetooth mService;      private final Map<LeScanCallback, GattCallbackWrapper> mLeScanClients; +    private BluetoothAdvScanData mBluetoothAdvScanData = null; +    private GattCallbackWrapper mAdvertisingCallback;      /**       * Get a handle to the default local Bluetooth adapter. @@ -438,6 +476,97 @@ public final class BluetoothAdapter {      }      /** +     * Returns a {@link BluetoothAdvScanData} object representing advertising data. +     * @hide +     */ +    public BluetoothAdvScanData getAdvScanData() { +      try { +          IBluetoothGatt iGatt = mManagerService.getBluetoothGatt(); +          if (iGatt == null) { +              // BLE is not supported +              Log.e(TAG, "failed to start, iGatt null"); +              return null; +          } +          if (mBluetoothAdvScanData == null) { +              mBluetoothAdvScanData = new BluetoothAdvScanData(iGatt, BluetoothAdvScanData.AD); +          } +          return mBluetoothAdvScanData; +      } catch (RemoteException e) { +          Log.e(TAG, "failed to get advScanData, error: " + e); +          return null; +      } +    } + + +    /** +     * Start BLE advertising using current {@link BluetoothAdvScanData}. +     * An app should start advertising by requesting +     * {@link BluetoothAdapter#ACTION_START_ADVERTISING} instead of calling this method directly. +     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} +     * +     * @return true if BLE avertising succeeds, false otherwise. +     * @hide +     */ +    public boolean startAdvertising() { +        if (getState() != STATE_ON) return false; + +        try { +            IBluetoothGatt iGatt = mManagerService.getBluetoothGatt(); +            if (iGatt == null) { +                // BLE is not supported. +                return false; +            } +            // Restart/reset advertising packets if advertising is in progress. +            if (isAdvertising()) { +                // Invalid advertising callback. +                if (mAdvertisingCallback == null || mAdvertisingCallback.mLeHandle == -1) { +                    Log.e(TAG, "failed to restart advertising, invalid callback"); +                    return false; +                } +                iGatt.startAdvertising(mAdvertisingCallback.mLeHandle); +                return true; +            } +            UUID uuid = UUID.randomUUID(); +            GattCallbackWrapper wrapper = +                new GattCallbackWrapper(this, null, null, GattCallbackWrapper.CALLBACK_TYPE_ADV); +            iGatt.registerClient(new ParcelUuid(uuid), wrapper); +            mAdvertisingCallback = wrapper; +            return true; +        } catch (RemoteException e) { +            Log.e(TAG, "", e); +            return false; +        } +    } + +    /** +     * Stop BLE advertising. +     * An app should stop advertising by requesting +     * {@link BluetoothAdapter#ACTION_STOP_ADVERTISING} instead of calling this method directly. +     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} +     * @return true if BLE advertising stops, false otherwise. +     * @hide +     */ +    public boolean stopAdvertisting() { +        try { +            IBluetoothGatt iGatt = mManagerService.getBluetoothGatt(); +            if (iGatt == null) { +                // BLE is not supported +                return false; +            } +            if (mAdvertisingCallback == null) { +                // no callback. +                return false; +            } +            mAdvertisingCallback.stopAdvertising(); +            mAdvertisingCallback = null; +            return true; +        } catch (RemoteException e) { +            Log.e(TAG, "", e); +            return false; +        } +    } + +    /**       * Return true if Bluetooth is currently enabled and ready for use.       * <p>Equivalent to:       * <code>getBluetoothState() == STATE_ON</code> @@ -849,6 +978,23 @@ public final class BluetoothAdapter {      }      /** +     * Returns whether BLE is currently advertising. +     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}. +     * +     * @hide +     */ +    public boolean isAdvertising() { +        if (getState() != STATE_ON) return false; +        try { +            IBluetoothGatt iGatt = mManagerService.getBluetoothGatt(); +            return iGatt.isAdvertising(); +        } catch (RemoteException e) { +            Log.e(TAG, "", e); +        } +        return false; +    } + +    /**       * Return the set of {@link BluetoothDevice} objects that are bonded       * (paired) to the local adapter.       * <p>If Bluetooth state is not {@link #STATE_ON}, this API @@ -1546,8 +1692,12 @@ public final class BluetoothAdapter {      private static class GattCallbackWrapper extends IBluetoothGattCallback.Stub {          private static final int LE_CALLBACK_REG_TIMEOUT = 2000;          private static final int LE_CALLBACK_REG_WAIT_COUNT = 5; +        private static final int CALLBACK_TYPE_SCAN = 0; +        private static final int CALLBACK_TYPE_ADV = 1;          private final LeScanCallback mLeScanCb; +        private int mCallbackType; +          // mLeHandle 0: not registered          //           -1: scan stopped          //           >0: registered and scan started @@ -1561,6 +1711,16 @@ public final class BluetoothAdapter {              mLeScanCb = leScanCb;              mScanFilter = uuid;              mLeHandle = 0; +            mCallbackType = CALLBACK_TYPE_SCAN; +        } + +        public GattCallbackWrapper(BluetoothAdapter bluetoothAdapter, LeScanCallback leScanCb, +            UUID[] uuid, int type) { +          mBluetoothAdapter = new WeakReference<BluetoothAdapter>(bluetoothAdapter); +          mLeScanCb = leScanCb; +          mScanFilter = uuid; +          mLeHandle = 0; +          mCallbackType = type;          }          public boolean scanStarted() { @@ -1583,6 +1743,30 @@ public final class BluetoothAdapter {              return started;          } +        public void stopAdvertising() { +            synchronized (this) { +                if (mLeHandle <= 0) { +                    Log.e(TAG, "Error state, mLeHandle: " + mLeHandle); +                    return; +                } +                BluetoothAdapter adapter = mBluetoothAdapter.get(); +                if (adapter != null) { +                    try { +                        IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt(); +                        iGatt.stopAdvertising(); +                        Log.d(TAG, "unregeistering client " + mLeHandle); +                        iGatt.unregisterClient(mLeHandle); +                    } catch (RemoteException e) { +                        Log.e(TAG, "Failed to stop advertising and unregister" + e); +                    } +                } else { +                    Log.e(TAG, "stopAdvertising, BluetoothAdapter is null"); +                } +                mLeHandle = -1; +                notifyAll(); +            } +        } +          public void stopLeScan() {              synchronized(this) {                  if (mLeHandle <= 0) { @@ -1624,14 +1808,18 @@ public final class BluetoothAdapter {                          BluetoothAdapter adapter = mBluetoothAdapter.get();                          if (adapter != null) {                              iGatt = adapter.getBluetoothManager().getBluetoothGatt(); -                            if (mScanFilter == null) { -                                iGatt.startScan(mLeHandle, false); +                            if (mCallbackType == CALLBACK_TYPE_ADV) { +                                iGatt.startAdvertising(mLeHandle);                              } else { -                                ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length]; -                                for(int i = 0; i != uuids.length; ++i) { -                                    uuids[i] = new ParcelUuid(mScanFilter[i]); -                                } -                                iGatt.startScanWithUuids(mLeHandle, false, uuids); +                              if (mScanFilter == null) { +                                  iGatt.startScan(mLeHandle, false); +                              } else { +                                  ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length]; +                                  for(int i = 0; i != uuids.length; ++i) { +                                      uuids[i] = new ParcelUuid(mScanFilter[i]); +                                  } +                                  iGatt.startScanWithUuids(mLeHandle, false, uuids); +                              }                              }                          } else {                              Log.e(TAG, "onClientRegistered, BluetoothAdapter null"); @@ -1642,7 +1830,7 @@ public final class BluetoothAdapter {                          mLeHandle = -1;                      }                      if (mLeHandle == -1) { -                        // registration succeeded but start scan failed +                        // registration succeeded but start scan or advertise failed                          if (iGatt != null) {                              try {                                  iGatt.unregisterClient(mLeHandle); diff --git a/core/java/android/bluetooth/BluetoothAdvScanData.java b/core/java/android/bluetooth/BluetoothAdvScanData.java new file mode 100644 index 000000000000..a97b0a806e38 --- /dev/null +++ b/core/java/android/bluetooth/BluetoothAdvScanData.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.bluetooth; +import android.os.ParcelUuid; +import android.os.RemoteException; +import android.util.Log; + +import java.util.Collections; +import java.util.List; + + +/** + * This class provides the public APIs to set advertising and scan response data when BLE device + * operates in peripheral mode. <br> + * The exact format is defined in Bluetooth 4.0 specification, Volume 3, Part C, Section 11 + * @hide + */ +public final class BluetoothAdvScanData { + +  /** +   * Available data types of {@link BluetoothAdvScanData}. +   */ +  public static final int AD = 0;  // Advertising Data +  public static final int SCAN_RESPONSE = 1;  // Scan Response +  public static final int EIR = 2;  // Extended Inquiry Response + +  private static final String TAG = "BluetoothAdvScanData"; + +  /** +   * Data type of BluetoothAdvScanData. +   */ +  private final int mDataType; +  /** +   * Bluetooth Gatt Service. +   */ +  private IBluetoothGatt mBluetoothGatt; + +  /** +   * @param mBluetoothGatt +   * @param dataType +   */ +  public BluetoothAdvScanData(IBluetoothGatt mBluetoothGatt, int dataType) { +    this.mBluetoothGatt = mBluetoothGatt; +    this.mDataType = dataType; +  } + +  /** +   * @return advertising data type. +   */ +  public int getDataType() { +    return mDataType; +  } + +  /** +   * Set manufactureCode and manufactureData. +   * Returns true if manufacturer data is set, false if there is no enough room to set +   * manufacturer data or the data is already set. +   * @param manufacturerCode - unique identifier for the manufacturer +   * @param manufacturerData - data associated with the specific manufacturer. +   */ +  public boolean setManufacturerData(int manufacturerCode, byte[] manufacturerData) { +    if (mDataType != AD) return false; +    try { +      return mBluetoothGatt.setAdvManufacturerCodeAndData(manufacturerCode, manufacturerData); +    } catch (RemoteException e) { +      return false; +    } +  } + +  /** +   * Set service data.  Note the service data can only be set when the data type is {@code AD}; +   * @param serviceData +   */ +  public boolean setServiceData(byte[] serviceData) { + +    if (mDataType != AD) return false; +    if (serviceData == null) return false; +    try { +      return mBluetoothGatt.setAdvServiceData(serviceData); +    } catch (RemoteException e) { +      return false; +    } +  } + +  /** +   * Returns an immutable list of service uuids that will be advertised. +   */ +  public List<ParcelUuid> getServiceUuids() { +    try { +      return Collections.unmodifiableList(mBluetoothGatt.getAdvServiceUuids()); +    } catch (RemoteException e) { +      return null; +    } +  } + +  /** +   * Returns manufacturer data. +   */ +  public byte[] getManufacturerData() { +    if (mBluetoothGatt == null) return null; +    try { +      return mBluetoothGatt.getAdvManufacturerData(); +    } catch (RemoteException e) { +      return null; +    } +  } + +  /** +   * Returns service data. +   */ +  public byte[] getServiceData() { +    if (mBluetoothGatt == null) return null; +    try { +      return mBluetoothGatt.getAdvServiceData(); +    } catch (RemoteException e) { +      return null; +    } +  } + +  /** +   * Remove manufacturer data based on given manufacturer code. +   * @param manufacturerCode +   */ +  public void removeManufacturerCodeAndData(int manufacturerCode) { +    if (mBluetoothGatt != null) { +      try { +        mBluetoothGatt.removeAdvManufacturerCodeAndData(manufacturerCode); +      } catch (RemoteException e) { +        Log.e(TAG, e.toString()); +      } +    } +  } +} diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java index a2bb78c4c158..cd093c5a4419 100644 --- a/core/java/android/bluetooth/BluetoothGatt.java +++ b/core/java/android/bluetooth/BluetoothGatt.java @@ -553,14 +553,6 @@ public final class BluetoothGatt implements BluetoothProfile {                      Log.w(TAG, "Unhandled exception in callback", ex);                  }              } - -            /** -             * Listen command status callback -             * @hide -             */ -            public void onListen(int status) { -                if (DBG) Log.d(TAG, "onListen() - status=" + status); -            }          };      /*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device) { @@ -693,71 +685,6 @@ public final class BluetoothGatt implements BluetoothProfile {          return true;      } -   /** -     * Starts or stops sending of advertisement packages to listen for connection -     * requests from a central devices. -     * -     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. -     * -     * @param start Start or stop advertising -     */ -    /*package*/ void listen(boolean start) { -        if (mContext == null || !mContext.getResources(). -            getBoolean(com.android.internal.R.bool.config_bluetooth_le_peripheral_mode_supported)) { -            throw new UnsupportedOperationException("BluetoothGatt#listen is blocked"); -        } -        if (DBG) Log.d(TAG, "listen() - start: " + start); -        if (mService == null || mClientIf == 0) return; - -        try { -            mService.clientListen(mClientIf, start); -        } catch (RemoteException e) { -            Log.e(TAG,"",e); -        } -    } - -    /** -     * Sets the advertising data contained in the adv. response packet. -     * -     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. -     * -     * @param advData true to set adv. data, false to set scan response -     * @param includeName Inlucde the name in the adv. response -     * @param includeTxPower Include TX power value -     * @param minInterval Minimum desired scan interval (optional) -     * @param maxInterval Maximum desired scan interval (optional) -     * @param appearance The appearance flags for the device (optional) -     * @param manufacturerData Manufacturer specific data including company ID (optional) -     */ -    /*package*/ void setAdvData(boolean advData, boolean includeName, boolean includeTxPower, -                           Integer minInterval, Integer maxInterval, -                           Integer appearance, Byte[] manufacturerData) { -        if (mContext == null || !mContext.getResources(). -            getBoolean(com.android.internal.R.bool.config_bluetooth_le_peripheral_mode_supported)) { -            throw new UnsupportedOperationException("BluetoothGatt#setAdvData is blocked"); -        } -        if (DBG) Log.d(TAG, "setAdvData()"); -        if (mService == null || mClientIf == 0) return; - -        byte[] data = new byte[0]; -        if (manufacturerData != null) { -            data = new byte[manufacturerData.length]; -            for(int i = 0; i != manufacturerData.length; ++i) { -                data[i] = manufacturerData[i]; -            } -        } - -        try { -            mService.setAdvData(mClientIf, !advData, -                includeName, includeTxPower, -                minInterval != null ? minInterval : 0, -                maxInterval != null ? maxInterval : 0, -                appearance != null ? appearance : 0, data); -        } catch (RemoteException e) { -            Log.e(TAG,"",e); -        } -    } -      /**       * Disconnects an established connection, or cancels a connection attempt       * currently in progress. diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java index 58ee54fdb100..153215cb5256 100644 --- a/core/java/android/bluetooth/BluetoothGattServer.java +++ b/core/java/android/bluetooth/BluetoothGattServer.java @@ -537,7 +537,7 @@ public final class BluetoothGattServer implements BluetoothProfile {          try {              mService.beginServiceDeclaration(mServerIf, service.getType(),                  service.getInstanceId(), service.getHandles(), -                new ParcelUuid(service.getUuid())); +                new ParcelUuid(service.getUuid()), service.isAdvertisePreferred());              List<BluetoothGattService> includedServices = service.getIncludedServices();              for (BluetoothGattService includedService : includedServices) { diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java index 1e6636960105..52bc0f796cb5 100644 --- a/core/java/android/bluetooth/BluetoothGattService.java +++ b/core/java/android/bluetooth/BluetoothGattService.java @@ -15,8 +15,6 @@   */  package android.bluetooth; -import android.bluetooth.BluetoothDevice; -  import java.util.ArrayList;  import java.util.List;  import java.util.UUID; @@ -82,6 +80,11 @@ public class BluetoothGattService {      protected List<BluetoothGattService> mIncludedServices;      /** +     * Whether the service uuid should be advertised. +     */ +    private boolean mAdvertisePreferred; + +    /**       * Create a new BluetoothGattService.       * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.       * @@ -263,4 +266,20 @@ public class BluetoothGattService {          }          return null;      } + +    /** +     * Returns whether the uuid of the service should be advertised. +     * @hide +     */ +    public boolean isAdvertisePreferred() { +      return mAdvertisePreferred; +    } + +    /** +     * Set whether the service uuid should be advertised. +     * @hide +     */ +    public void setAdvertisePreferred(boolean advertisePreferred) { +      this.mAdvertisePreferred = advertisePreferred; +    }  } diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java index 844f432ca32f..33232edf58cc 100644 --- a/core/java/android/bluetooth/BluetoothInputDevice.java +++ b/core/java/android/bluetooth/BluetoothInputDevice.java @@ -76,6 +76,12 @@ public final class BluetoothInputDevice implements BluetoothProfile {      public static final String ACTION_PROTOCOL_MODE_CHANGED =          "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED"; +    /** +     * @hide +     */ +    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) +    public static final String ACTION_REPORT = +        "android.bluetooth.input.profile.action.REPORT";      /**       * @hide @@ -130,17 +136,17 @@ public final class BluetoothInputDevice implements BluetoothProfile {      /**       * @hide       */ -    public static final byte REPORT_TYPE_INPUT = 0; +    public static final byte REPORT_TYPE_INPUT = 1;      /**       * @hide       */ -    public static final byte REPORT_TYPE_OUTPUT = 1; +    public static final byte REPORT_TYPE_OUTPUT = 2;      /**       * @hide       */ -    public static final byte REPORT_TYPE_FEATURE = 2; +    public static final byte REPORT_TYPE_FEATURE = 3;      /**       * @hide diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index d10eaea2fba1..1e75fc2a1c01 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -417,27 +417,28 @@ public final class BluetoothSocket implements Closeable {       *             if an i/o error occurs.       */      /*package*/ void flush() throws IOException { +        if (mSocketOS == null) throw new IOException("flush is called on null OutputStream");          if (VDBG) Log.d(TAG, "flush: " + mSocketOS);          mSocketOS.flush();      }      /*package*/ int read(byte[] b, int offset, int length) throws IOException { - -            if (VDBG) Log.d(TAG, "read in:  " + mSocketIS + " len: " + length); -            int ret = mSocketIS.read(b, offset, length); -            if(ret < 0) -                throw new IOException("bt socket closed, read return: " + ret); -            if (VDBG) Log.d(TAG, "read out:  " + mSocketIS + " ret: " + ret); -            return ret; +        if (mSocketIS == null) throw new IOException("read is called on null InputStream"); +        if (VDBG) Log.d(TAG, "read in:  " + mSocketIS + " len: " + length); +        int ret = mSocketIS.read(b, offset, length); +        if(ret < 0) +            throw new IOException("bt socket closed, read return: " + ret); +        if (VDBG) Log.d(TAG, "read out:  " + mSocketIS + " ret: " + ret); +        return ret;      }      /*package*/ int write(byte[] b, int offset, int length) throws IOException { - -            if (VDBG) Log.d(TAG, "write: " + mSocketOS + " length: " + length); -            mSocketOS.write(b, offset, length); -            // There is no good way to confirm since the entire process is asynchronous anyway -            if (VDBG) Log.d(TAG, "write out: " + mSocketOS + " length: " + length); -            return length; +        if (mSocketOS == null) throw new IOException("write is called on null OutputStream"); +        if (VDBG) Log.d(TAG, "write: " + mSocketOS + " length: " + length); +        mSocketOS.write(b, offset, length); +        // There is no good way to confirm since the entire process is asynchronous anyway +        if (VDBG) Log.d(TAG, "write out: " + mSocketOS + " length: " + length); +        return length;      }      @Override diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java index abdf949ebcfd..4b28516e15a2 100644 --- a/core/java/android/bluetooth/BluetoothUuid.java +++ b/core/java/android/bluetooth/BluetoothUuid.java @@ -73,6 +73,9 @@ public final class BluetoothUuid {      public static final ParcelUuid MAS =              ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB"); +    public static final ParcelUuid BASE_UUID = +            ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB"); +      public static final ParcelUuid[] RESERVED_UUIDS = {          AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget, @@ -211,4 +214,17 @@ public final class BluetoothUuid {          long value = (uuid.getMostSignificantBits() & 0x0000FFFF00000000L) >>> 32;          return (int)value;      } + +    /** +     * Check whether the given parcelUuid can be converted to 16 bit bluetooth uuid. +     * @param parcelUuid +     * @return true if the parcelUuid can be converted to 16 bit uuid, false otherwise. +     */ +    public static boolean isShortUuid(ParcelUuid parcelUuid) { +      UUID uuid = parcelUuid.getUuid(); +      if (uuid.getLeastSignificantBits() != BASE_UUID.getUuid().getLeastSignificantBits()) { +        return false; +      } +      return ((uuid.getMostSignificantBits() & 0xFFFF0000FFFFFFFFL) == 0x1000L); +    }  } diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl index df393dbb2899..784cdcc5318c 100644 --- a/core/java/android/bluetooth/IBluetoothGatt.aidl +++ b/core/java/android/bluetooth/IBluetoothGatt.aidl @@ -37,10 +37,15 @@ interface IBluetoothGatt {      void unregisterClient(in int clientIf);      void clientConnect(in int clientIf, in String address, in boolean isDirect);      void clientDisconnect(in int clientIf, in String address); -    void clientListen(in int clientIf, in boolean start); -    void setAdvData(in int clientIf, in boolean setScanRsp, in boolean inclName, -                            in boolean inclTxPower, in int minInterval, in int maxInterval, -                            in int appearance, in byte[] manufacturerData); +    void startAdvertising(in int appIf); +    void stopAdvertising(); +    boolean setAdvServiceData(in byte[] serviceData); +    byte[] getAdvServiceData(); +    boolean setAdvManufacturerCodeAndData(int manufactureCode, in byte[] manufacturerData); +    byte[] getAdvManufacturerData(); +    List<ParcelUuid> getAdvServiceUuids(); +    void removeAdvManufacturerCodeAndData(int manufacturerCode); +    boolean isAdvertising();      void refreshDevice(in int clientIf, in String address);      void discoverServices(in int clientIf, in String address);      void readCharacteristic(in int clientIf, in String address, in int srvcType, @@ -75,7 +80,7 @@ interface IBluetoothGatt {      void serverDisconnect(in int serverIf, in String address);      void beginServiceDeclaration(in int serverIf, in int srvcType,                              in int srvcInstanceId, in int minHandles, -                            in ParcelUuid srvcId); +                            in ParcelUuid srvcId, boolean advertisePreferred);      void addIncludedService(in int serverIf, in int srvcType,                              in int srvcInstanceId, in ParcelUuid srvcId);      void addCharacteristic(in int serverIf, in ParcelUuid charId, diff --git a/core/java/android/bluetooth/IBluetoothGattCallback.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl index 60c297b59798..e3563fcc3a77 100644 --- a/core/java/android/bluetooth/IBluetoothGattCallback.aidl +++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl @@ -63,5 +63,4 @@ interface IBluetoothGattCallback {                               in int charInstId, in ParcelUuid charUuid,                               in byte[] value);      void onReadRemoteRssi(in String address, in int rssi, in int status); -    void onListen(in int status);  } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 3c66b6871f74..11ac15fbe0a4 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -3538,6 +3538,11 @@ public class Intent implements Parcelable, Cloneable {       * it will be finished so that the user does not return to them, but       * instead returns to whatever activity preceeded it.       * +     * <p>When this flag is assigned to the root activity all activities up +     * to, but not including the root activity, will be cleared. This prevents +     * this flag from being used to finish all activities in a task and thereby +     * ending the task. +     *       * <p>This is useful for cases where you have a logical break in your       * application.  For example, an e-mail application may have a command       * to view an attachment, which launches an image view activity to diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index c97c2b89304d..485ee68746ee 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1249,6 +1249,20 @@ public abstract class PackageManager {      public static final String FEATURE_TELEVISION = "android.hardware.type.television";      /** +     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: +     * The device supports printing. +     */ +    @SdkConstant(SdkConstantType.FEATURE) +    public static final String FEATURE_PRINTING = "android.software.print"; + +    /** +     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: +     * The device can perform backup and restore operations on installed applications. +     */ +    @SdkConstant(SdkConstantType.FEATURE) +    public static final String FEATURE_BACKUP = "android.software.backup"; + +    /**       * Action to external storage service to clean out removed apps.       * @hide       */ diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index 60ccc6180eb6..433d5d1c713e 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -738,14 +738,16 @@ public final class SQLiteDatabase extends SQLiteClosable {          File dir = file.getParentFile();          if (dir != null) {              final String prefix = file.getName() + "-mj"; -            final FileFilter filter = new FileFilter() { +            File[] files = dir.listFiles(new FileFilter() {                  @Override                  public boolean accept(File candidate) {                      return candidate.getName().startsWith(prefix);                  } -            }; -            for (File masterJournal : dir.listFiles(filter)) { -                deleted |= masterJournal.delete(); +            }); +            if (files != null) { +                for (File masterJournal : files) { +                    deleted |= masterJournal.delete(); +                }              }          }          return deleted; 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/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java new file mode 100644 index 000000000000..8430973c79d3 --- /dev/null +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.display; + +import android.view.DisplayInfo; + +/** + * Display manager local system service interface. + * + * @hide Only for use within the system server. + */ +public abstract class DisplayManagerInternal { +    /** +     * Called by the power manager to blank all displays. +     */ +    public abstract void blankAllDisplaysFromPowerManager(); + +    /** +     * Called by the power manager to unblank all displays. +     */ +    public abstract void unblankAllDisplaysFromPowerManager(); + +    /** +     * Returns information about the specified logical display. +     * +     * @param displayId The logical display id. +     * @return The logical display info, or null if the display does not exist.  The +     * returned object must be treated as immutable. +     */ +    public abstract DisplayInfo getDisplayInfo(int displayId); + +    /** +     * Registers a display transaction listener to provide the client a chance to +     * update its surfaces within the same transaction as any display layout updates. +     * +     * @param listener The listener to register. +     */ +    public abstract void registerDisplayTransactionListener(DisplayTransactionListener listener); + +    /** +     * Unregisters a display transaction listener to provide the client a chance to +     * update its surfaces within the same transaction as any display layout updates. +     * +     * @param listener The listener to unregister. +     */ +    public abstract void unregisterDisplayTransactionListener(DisplayTransactionListener listener); + +    /** +     * Overrides the display information of a particular logical display. +     * This is used by the window manager to control the size and characteristics +     * of the default display.  It is expected to apply the requested change +     * to the display information synchronously so that applications will immediately +     * observe the new state. +     * +     * NOTE: This method must be the only entry point by which the window manager +     * influences the logical configuration of displays. +     * +     * @param displayId The logical display id. +     * @param info The new data to be stored. +     */ +    public abstract void setDisplayInfoOverrideFromWindowManager( +            int displayId, DisplayInfo info); + +    /** +     * Called by the window manager to perform traversals while holding a +     * surface flinger transaction. +     */ +    public abstract void performTraversalInTransactionFromWindowManager(); + +    /** +     * Tells the display manager whether there is interesting unique content on the +     * specified logical display.  This is used to control automatic mirroring. +     * <p> +     * If the display has unique content, then the display manager arranges for it +     * to be presented on a physical display if appropriate.  Otherwise, the display manager +     * may choose to make the physical display mirror some other logical display. +     * </p> +     * +     * @param displayId The logical display id to update. +     * @param hasContent True if the logical display has content. +     * @param inTraversal True if called from WindowManagerService during a window traversal +     * prior to call to performTraversalInTransactionFromWindowManager. +     */ +    public abstract void setDisplayHasContent(int displayId, boolean hasContent, +            boolean inTraversal); + +    /** +     * Called within a Surface transaction whenever the size or orientation of a +     * display may have changed.  Provides an opportunity for the client to +     * update the position of its surfaces as part of the same transaction. +     */ +    public interface DisplayTransactionListener { +        void onDisplayTransaction(); +    } +} diff --git a/services/java/com/android/server/display/DisplayViewport.java b/core/java/android/hardware/display/DisplayViewport.java index 5080556a54a3..c2d498b7fe68 100644 --- a/services/java/com/android/server/display/DisplayViewport.java +++ b/core/java/android/hardware/display/DisplayViewport.java @@ -14,7 +14,7 @@   * limitations under the License.   */ -package com.android.server.display; +package android.hardware.display;  import android.graphics.Rect; @@ -25,6 +25,8 @@ import android.graphics.Rect;   * This information is used by the input system to translate touch input from   * physical display coordinates into logical display coordinates.   * </p> + * + * @hide Only for use within the system server.   */  public final class DisplayViewport {      // True if this viewport is valid. diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java new file mode 100644 index 000000000000..8be94d0f7e85 --- /dev/null +++ b/core/java/android/hardware/input/InputManagerInternal.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.input; + +import android.hardware.display.DisplayViewport; +import android.view.InputEvent; + +/** + * Input manager local system service interface. + * + * @hide Only for use within the system server. + */ +public abstract class InputManagerInternal { +    /** +     * Sets information about the displays as needed by the input system. +     * The input system should copy this information if required. +     */ +    public abstract void setDisplayViewports(DisplayViewport defaultViewport, +            DisplayViewport externalTouchViewport); + +    public abstract boolean injectInputEvent(InputEvent event, int displayId, int mode); +} diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index c78a973ceeb0..9ae4fa2f9da5 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -361,11 +361,17 @@ public class ConnectivityManager {       */      public static final int TYPE_MOBILE_IA = 14; +    /** +     * The network that uses proxy to achieve connectivity. +     * {@hide} +     */ +    public static final int TYPE_PROXY = 16; +      /** {@hide} */ -    public static final int MAX_RADIO_TYPE   = TYPE_MOBILE_IA; +    public static final int MAX_RADIO_TYPE   = TYPE_PROXY;      /** {@hide} */ -    public static final int MAX_NETWORK_TYPE = TYPE_MOBILE_IA; +    public static final int MAX_NETWORK_TYPE = TYPE_PROXY;      /**       * If you want to set the default network preference,you can directly @@ -444,6 +450,8 @@ public class ConnectivityManager {                  return "WIFI_P2P";              case TYPE_MOBILE_IA:                  return "MOBILE_IA"; +            case TYPE_PROXY: +                return "PROXY";              default:                  return Integer.toString(type);          } diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java new file mode 100644 index 000000000000..a7d287bde27d --- /dev/null +++ b/core/java/android/net/ProxyDataTracker.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * A data tracker responsible for bringing up and tearing down the system proxy server. + * + * {@hide} + */ +public class ProxyDataTracker extends BaseNetworkStateTracker { +    private static final String NETWORK_TYPE = "PROXY"; +    private static final String TAG = "ProxyDataTracker"; + +    // TODO: investigate how to get these DNS addresses from the system. +    private static final String DNS1 = "8.8.8.8"; +    private static final String DNS2 = "8.8.4.4"; +    private static final String REASON_ENABLED = "enabled"; + +    private final AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0); +    private final AtomicInteger mReconnectGeneration = new AtomicInteger(0); + +    /** +     * Create a new ProxyDataTracker +     */ +    public ProxyDataTracker() { +        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_PROXY, 0, NETWORK_TYPE, ""); +        // TODO: update available state according to proxy state. +        mNetworkInfo.setIsAvailable(true); +        mLinkProperties = new LinkProperties(); +        mLinkCapabilities = new LinkCapabilities(); + +        try { +          mLinkProperties.addDns(InetAddress.getByName(DNS1)); +          mLinkProperties.addDns(InetAddress.getByName(DNS2)); +        } catch (UnknownHostException e) { +          Log.e(TAG, "Could not add DNS address", e); +        } +    } + +    public Object Clone() throws CloneNotSupportedException { +        throw new CloneNotSupportedException(); +    } + +    /** +     * Disable connectivity to the network. +     */ +    public boolean teardown() { +        // TODO: tell relevant service to tear down proxy. +        return true; +    } + +    /** +     * Re-enable proxy data connectivity after a {@link #teardown()}. +     */ +    public boolean reconnect() { +        if (!isAvailable()) { +            Log.w(TAG, "Reconnect requested even though network is disabled. Bailing."); +            return false; +        } +        setTeardownRequested(false); +        mReconnectGeneration.incrementAndGet(); +        // TODO: tell relevant service to setup proxy. Set state to connected only if setup +        // succeeds. +        setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null); + +        return true; +    } + +    /** +     * Fetch default gateway address for the network +     */ +    public int getDefaultGatewayAddr() { +        return mDefaultGatewayAddr.get(); +    } + +    /** +     * Return the system properties name associated with the tcp buffer sizes +     * for this network. +     */ +    public String getTcpBufferSizesPropName() { +        return "net.tcp.buffersize.wifi"; +    } + +    /** +     * Record the detailed state of a network, and if it is a +     * change from the previous state, send a notification to +     * any listeners. +     * @param state the new @{code DetailedState} +     * @param reason a {@code String} indicating a reason for the state change, +     * if one was supplied. May be {@code null}. +     * @param extraInfo optional {@code String} providing extra information about the state change +     */ +    private void setDetailedState(NetworkInfo.DetailedState state, String reason, +            String extraInfo) { +        mNetworkInfo.setDetailedState(state, reason, extraInfo); +        Message msg = getTargetHandler().obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo); +        msg.sendToTarget(); +    } +} diff --git a/core/java/android/os/FactoryTest.java b/core/java/android/os/FactoryTest.java index ec996973fdb0..7a252f933446 100644 --- a/core/java/android/os/FactoryTest.java +++ b/core/java/android/os/FactoryTest.java @@ -25,6 +25,20 @@ package android.os;   * {@hide}   */  public final class FactoryTest { +    public static final int FACTORY_TEST_OFF = 0; +    public static final int FACTORY_TEST_LOW_LEVEL = 1; +    public static final int FACTORY_TEST_HIGH_LEVEL = 2; + +    /** +     * Gets the current factory test mode. +     * +     * @return One of: {@link #FACTORY_TEST_OFF}, {@link #FACTORY_TEST_LOW_LEVEL}, +     * or {@link #FACTORY_TEST_HIGH_LEVEL}. +     */ +    public static int getMode() { +        return SystemProperties.getInt("ro.factorytest", FACTORY_TEST_OFF); +    } +      /**       * When true, long-press on power should immediately cause the device to       * shut down, without prompting the user. diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java new file mode 100644 index 000000000000..cb3d52819825 --- /dev/null +++ b/core/java/android/os/PowerManagerInternal.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import android.view.WindowManagerPolicy; + +/** + * Power manager local system service interface. + * + * @hide Only for use within the system server. + */ +public abstract class PowerManagerInternal { +    /** +     * Used by the window manager to override the screen brightness based on the +     * current foreground activity. +     * +     * This method must only be called by the window manager. +     * +     * @param brightness The overridden brightness, or -1 to disable the override. +     */ +    public abstract void setScreenBrightnessOverrideFromWindowManager(int brightness); + +    /** +     * Used by the window manager to override the button brightness based on the +     * current foreground activity. +     * +     * This method must only be called by the window manager. +     * +     * @param brightness The overridden brightness, or -1 to disable the override. +     */ +    public abstract void setButtonBrightnessOverrideFromWindowManager(int brightness); + +    /** +     * Used by the window manager to override the user activity timeout based on the +     * current foreground activity.  It can only be used to make the timeout shorter +     * than usual, not longer. +     * +     * This method must only be called by the window manager. +     * +     * @param timeoutMillis The overridden timeout, or -1 to disable the override. +     */ +    public abstract void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis); + +    // TODO: Remove this and retrieve as a local service instead. +    public abstract void setPolicy(WindowManagerPolicy policy); +} diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 631edd67957b..057f516af17b 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -892,19 +892,6 @@ public class Process {      }      /** -     * Set the out-of-memory badness adjustment for a process. -     *  -     * @param pid The process identifier to set. -     * @param amt Adjustment value -- linux allows -16 to +15. -     *  -     * @return Returns true if the underlying system supports this -     *         feature, else false. -     *          -     * {@hide} -     */ -    public static final native boolean setOomAdj(int pid, int amt); - -    /**       * Adjust the swappiness level for a process.       *       * @param pid The process identifier to set. diff --git a/core/java/android/service/dreams/DreamManagerInternal.java b/core/java/android/service/dreams/DreamManagerInternal.java new file mode 100644 index 000000000000..17ea996b38c9 --- /dev/null +++ b/core/java/android/service/dreams/DreamManagerInternal.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.dreams; + +/** + * Dream manager local system service interface. + * + * @hide Only for use within the system server. + */ +public abstract class DreamManagerInternal { +    /** +     * Called by the power manager to start a dream. +     */ +    public abstract void startDream(); + +    /** +     * Called by the power manager to stop a dream. +     */ +    public abstract void stopDream(); + +    /** +     * Called by the power manager to determine whether a dream is running. +     */ +    public abstract boolean isDreaming(); +} diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 2e0e59bc91c9..cf862b872aa3 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -112,6 +112,7 @@ public abstract class NotificationListenerService extends Service {       *     {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.       */      public final void cancelNotification(String pkg, String tag, int id) { +        if (!isBound()) return;          try {              getNotificationInterface().cancelNotificationFromListener(mWrapper, pkg, tag, id);          } catch (android.os.RemoteException ex) { @@ -131,6 +132,7 @@ public abstract class NotificationListenerService extends Service {       * {@see #cancelNotification(String, String, int)}       */      public final void cancelAllNotifications() { +        if (!isBound()) return;          try {              getNotificationInterface().cancelAllNotificationsFromListener(mWrapper);          } catch (android.os.RemoteException ex) { @@ -145,6 +147,7 @@ public abstract class NotificationListenerService extends Service {       * @return An array of active notifications.       */      public StatusBarNotification[] getActiveNotifications() { +        if (!isBound()) return null;          try {              return getNotificationInterface().getActiveNotificationsFromListener(mWrapper);          } catch (android.os.RemoteException ex) { @@ -161,6 +164,14 @@ public abstract class NotificationListenerService extends Service {          return mWrapper;      } +    private boolean isBound() { +        if (mWrapper == null) { +            Log.w(TAG, "Notification listener service not yet bound."); +            return false; +        } +        return true; +    } +      private class INotificationListenerWrapper extends INotificationListener.Stub {          @Override          public void onNotificationPosted(StatusBarNotification sbn) { diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java index ed4529851d8f..931fb8114716 100644 --- a/core/java/android/util/TypedValue.java +++ b/core/java/android/util/TypedValue.java @@ -290,18 +290,14 @@ public class TypedValue {          return -1;      } +    /** +     * @hide Was accidentally exposed in API level 1 for debugging purposes. +     * Kept for compatibility just in case although the debugging code has been removed. +     */ +    @Deprecated      public static float complexToDimensionNoisy(int data, DisplayMetrics metrics)      { -        float res = complexToDimension(data, metrics); -        System.out.println( -            "Dimension (0x" + ((data>>TypedValue.COMPLEX_MANTISSA_SHIFT) -                               & TypedValue.COMPLEX_MANTISSA_MASK) -            + "*" + (RADIX_MULTS[(data>>TypedValue.COMPLEX_RADIX_SHIFT) -                                & TypedValue.COMPLEX_RADIX_MASK] / MANTISSA_MULT) -            + ")" + DIMENSION_UNIT_STRS[(data>>COMPLEX_UNIT_SHIFT) -                                & COMPLEX_UNIT_MASK] -            + " = " + res); -        return res; +        return complexToDimension(data, metrics);      }      /** diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 62afa60d594b..eea58843a7f6 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;      long 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) */      /** @@ -106,18 +103,18 @@ public class SurfaceControl {       * surfaces are pre-multiplied, which means that each color component is       * already multiplied by its alpha value. In this case the blending       * equation used is: -     * -     *    DEST = SRC + DEST * (1-SRC_ALPHA) -     * +     * <p> +     *    <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code> +     * <p>       * By contrast, non pre-multiplied surfaces use the following equation: -     * -     *    DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA) -     * +     * <p> +     *    <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code> +     * <p>       * pre-multiplied surfaces must always be used if transparent pixels are       * composited on top of each-other into the surface. A pre-multiplied       * surface can never lower the value of the alpha component of a given       * pixel. -     * +     * <p>       * In some rare situations, a non pre-multiplied surface is preferable.       *       */ @@ -128,7 +125,17 @@ public class SurfaceControl {       * even if its pixel format is set to translucent. This can be useful if an       * application needs full RGBA 8888 support for instance but will       * still draw every pixel opaque. -     * +     * <p> +     * This flag is ignored if setAlpha() is used to make the surface non-opaque. +     * Combined effects are (assuming a buffer format with an alpha channel): +     * <ul> +     * <li>OPAQUE + alpha(1.0) == opaque composition +     * <li>OPAQUE + alpha(0.x) == blended composition +     * <li>!OPAQUE + alpha(1.0) == blended composition +     * <li>!OPAQUE + alpha(0.x) == blended composition +     * </ul> +     * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively +     * set automatically.       */      public static final int OPAQUE = 0x00000400; @@ -169,9 +176,16 @@ public class SurfaceControl {      /**       * Surface flag: Hide the surface.       * Equivalent to calling hide(). +     * Updates the value set during Surface creation (see {@link #HIDDEN}).       */      public static final int SURFACE_HIDDEN = 0x01; +    /** +     * Surface flag: composite without blending when possible. +     * Updates the value set during Surface creation (see {@link #OPAQUE}). +     */ +    public static final int SURFACE_OPAQUE = 0x02; +      /* built-in physical display ids (keep in sync with ISurfaceComposer.h)       * these are different from the logical display ids used elsewhere in the framework */ @@ -192,14 +206,14 @@ public class SurfaceControl {      /**       * Create a surface with a name. -     * +     * <p>       * The surface creation flags specify what kind of surface to create and       * certain options such as whether the surface can be assumed to be opaque       * and whether it should be initially hidden.  Surfaces should always be       * created with the {@link #HIDDEN} flag set to ensure that they are not       * made visible prematurely before all of the surface's properties have been       * configured. -     * +     * <p>       * Good practice is to first create the surface with the {@link #HIDDEN} flag       * specified, open a transaction, set the surface layer, layer stack, alpha,       * and position, call {@link #show} if appropriate, and close the transaction. @@ -232,8 +246,6 @@ public class SurfaceControl {                      new Throwable());          } -        checkHeadless(); -          mName = name;          mNativeObject = nativeCreate(session, name, w, h, format, flags);          if (mNativeObject == 0) { @@ -344,6 +356,10 @@ public class SurfaceControl {          nativeSetTransparentRegionHint(mNativeObject, region);      } +    /** +     * Sets an alpha value for the entire Surface.  This value is combined with the +     * per-pixel alpha.  It may be used with opaque Surfaces. +     */      public void setAlpha(float alpha) {          checkNotReleased();          nativeSetAlpha(mNativeObject, alpha); @@ -354,6 +370,13 @@ public class SurfaceControl {          nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy);      } +    /** +     * Sets and clears flags, such as {@link #SURFACE_HIDDEN}.  The new value will be: +     * <p> +     *   <code>newFlags = (oldFlags & ~mask) | (flags & mask)</code> +     * <p> +     * Note this does not take the same set of flags as the constructor. +     */      public void setFlags(int flags, int mask) {          checkNotReleased();          nativeSetFlags(mNativeObject, flags, mask); @@ -374,6 +397,19 @@ public class SurfaceControl {          nativeSetLayerStack(mNativeObject, layerStack);      } +    /** +     * Sets the opacity of the surface.  Setting the flag is equivalent to creating the +     * Surface with the {@link #OPAQUE} flag. +     */ +    public void setOpaque(boolean isOpaque) { +        checkNotReleased(); +        if (isOpaque) { +            nativeSetFlags(mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE); +        } else { +            nativeSetFlags(mNativeObject, 0, SURFACE_OPAQUE); +        } +    } +      /*       * set display parameters.       * needs to be inside open/closeTransaction block @@ -619,10 +655,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/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java new file mode 100644 index 000000000000..a1bd4bd1f7ca --- /dev/null +++ b/core/java/android/view/WindowManagerInternal.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import android.hardware.display.DisplayManagerInternal; + +/** + * Window manager local system service interface. + * + * @hide Only for use within the system server. + */ +public abstract class WindowManagerInternal { +    /** +     * Request that the window manager call +     * {@link DisplayManagerInternal#performTraversalInTransactionFromWindowManager} +     * within a surface transaction at a later time. +     */ +    public abstract void requestTraversalFromDisplayManager(); +}
\ No newline at end of file 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/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 2e5fcecbf26c..872861024cdd 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -26,6 +26,7 @@ import android.os.BatteryManager;  import android.os.BatteryStats;  import android.os.FileUtils;  import android.os.Handler; +import android.os.Looper;  import android.os.Message;  import android.os.Parcel;  import android.os.ParcelFormatException; @@ -113,6 +114,10 @@ public final class BatteryStatsImpl extends BatteryStats {      }      final class MyHandler extends Handler { +        public MyHandler(Looper looper) { +            super(looper, null, true); +        } +          @Override          public void handleMessage(Message msg) {              BatteryCallback cb = mCallback; @@ -4487,9 +4492,9 @@ public final class BatteryStatsImpl extends BatteryStats {          }      } -    public BatteryStatsImpl(String filename) { +    public BatteryStatsImpl(String filename, Handler handler) {          mFile = new JournaledFile(new File(filename), new File(filename + ".tmp")); -        mHandler = new MyHandler(); +        mHandler = new MyHandler(handler.getLooper());          mStartCount++;          mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);          for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java index f54a3e9ce9c3..3b0f0f4777dd 100644 --- a/core/java/com/android/internal/os/BinderInternal.java +++ b/core/java/com/android/internal/os/BinderInternal.java @@ -16,18 +16,11 @@  package com.android.internal.os; -import android.os.Binder;  import android.os.IBinder;  import android.os.SystemClock;  import android.util.EventLog; -import android.util.Log; -import java.io.FileDescriptor; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintWriter;  import java.lang.ref.WeakReference; -import java.lang.reflect.Modifier;  /**   * Private and debugging Binder APIs. 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..194a084148d1 --- /dev/null +++ b/core/java/com/android/server/SystemService.java @@ -0,0 +1,195 @@ +/* + * 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. + * <p> + * The lifecycle of a SystemService: + * </p><ul> + * <li>The constructor is called and provided with the system {@link Context} + * to initialize the system service. + * <li>{@link #onStart()} is called to get the service running.  The service should + * publish its binder interface at this point using + * {@link #publishBinderService(String, IBinder)}.  It may also publish additional + * local interfaces that other services within the system server may use to access + * privileged internal functions. + * <li>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. + * </ul><p> + * NOTE: All lifecycle methods are called from the system server's main looper thread. + * </p> + * + * {@hide} + */ +public abstract class SystemService { +    /* +     * Boot Phases +     */ +    public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency? +    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 final Context mContext; + +    /** +     * Initializes the system service. +     * <p> +     * Subclasses must define a single argument constructor that accepts the context +     * and passes it to super. +     * </p> +     * +     * @param context The system server context. +     */ +    public SystemService(Context context) { +        mContext = context; +    } + +    /** +     * Gets the system context. +     */ +    public final Context getContext() { +        return mContext; +    } + +    /** +     * Returns true if the system is running in safe mode. +     * TODO: we should define in which phase this becomes valid +     */ +    public final boolean isSafeMode() { +        return getManager().isSafeMode(); +    } + +    /** +     * 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) { +        publishBinderService(name, service, false); +    } + +    /** +     * Publish the service so it is accessible to other services and apps. +     */ +    protected final void publishBinderService(String name, IBinder service, +            boolean allowIsolated) { +        ServiceManager.addService(name, service, allowIsolated); +    } + +    /** +     * 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); +    } + +    private SystemServiceManager getManager() { +        return LocalServices.getService(SystemServiceManager.class); +    } + +//    /** +//     * 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..6c853be81cdd --- /dev/null +++ b/core/java/com/android/server/SystemServiceManager.java @@ -0,0 +1,169 @@ +/* + * 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.Slog; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +/** + * Manages creating, starting, and other lifecycle events of + * {@link com.android.server.SystemService system services}. + * + * {@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; +    } + +    /** +     * Starts a service by name if the class exists, otherwise ignores it. +     * +     * @return The service instance, or null if not found. +     */ +    @SuppressWarnings("unchecked") +    public SystemService startServiceIfExists(String className) { +        try { +            return startService((Class<SystemService>)Class.forName(className)); +        } catch (ClassNotFoundException cnfe) { +            Slog.i(TAG, className + " not available, ignoring."); +            return null; +        } +    } + +    /** +     * 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. +     * @return The service instance, never null. +     * @throws RuntimeException if the service fails to start. +     */ +    @SuppressWarnings("unchecked") +    public <T extends SystemService> T startService(Class<T> serviceClass) { +        final String name = serviceClass.getName(); +        Slog.i(TAG, "Starting " + name); + +        // Create the service. +        if (!SystemService.class.isAssignableFrom(serviceClass)) { +            throw new RuntimeException("Failed to create " + name +                    + ": service must extend " + SystemService.class.getName()); +        } +        final T service; +        try { +            Constructor<T> constructor = serviceClass.getConstructor(Context.class); +            service = constructor.newInstance(mContext); +        } catch (InstantiationException ex) { +            throw new RuntimeException("Failed to create service " + name +                    + ": service could not be instantiated", ex); +        } catch (IllegalAccessException ex) { +            throw new RuntimeException("Failed to create service " + name +                    + ": service must have a public constructor with a Context argument", ex); +        } catch (NoSuchMethodException ex) { +            throw new RuntimeException("Failed to create service " + name +                    + ": service must have a public constructor with a Context argument", ex); +        } catch (InvocationTargetException ex) { +            throw new RuntimeException("Failed to create service " + name +                    + ": service constructor threw an exception", ex); +        } + +        // Register it. +        mServices.add(service); + +        // Start it. +        try { +            service.onStart(); +        } catch (RuntimeException ex) { +            throw new RuntimeException("Failed to start service " + name +                    + ": onStart threw an exception", ex); +        } +        return service; +    } + +    /** +     * 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 (Exception ex) { +                throw new RuntimeException("Failed to boot service " +                        + service.getClass().getName() +                        + ": onBootPhase threw an exception during phase " +                        + mCurrentPhase, ex); +            } +        } +    } + +    /** 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()); +    } +} diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 601975af01b9..cbed99f9acad 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -344,23 +344,6 @@ jint android_os_Process_getThreadPriority(JNIEnv* env, jobject clazz,      return pri;  } -jboolean android_os_Process_setOomAdj(JNIEnv* env, jobject clazz, -                                      jint pid, jint adj) -{ -#ifdef HAVE_OOM_ADJ -    char text[64]; -    sprintf(text, "/proc/%d/oom_adj", pid); -    int fd = open(text, O_WRONLY); -    if (fd >= 0) { -        sprintf(text, "%d", adj); -        write(fd, text, strlen(text)); -        close(fd); -    } -    return true; -#endif -    return false; -} -  jboolean android_os_Process_setSwappiness(JNIEnv *env, jobject clazz,                                            jint pid, jboolean is_increased)  { @@ -1023,7 +1006,6 @@ static const JNINativeMethod methods[] = {      {"setThreadGroup",      "(II)V", (void*)android_os_Process_setThreadGroup},      {"setProcessGroup",     "(II)V", (void*)android_os_Process_setProcessGroup},      {"getProcessGroup",     "(I)I", (void*)android_os_Process_getProcessGroup}, -    {"setOomAdj",   "(II)Z", (void*)android_os_Process_setOomAdj},      {"setSwappiness",   "(IZ)Z", (void*)android_os_Process_setSwappiness},      {"setArgV0",    "(Ljava/lang/String;)V", (void*)android_os_Process_setArgV0},      {"setUid", "(I)I", (void*)android_os_Process_setUid}, diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index b198937df18d..e7db535650a9 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1288,7 +1288,7 @@      <!-- @hide Allows an application to create/manage/remove stacks -->      <permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"          android:permissionGroup="android.permission-group.APP_INFO" -        android:protectionLevel="signature" +        android:protectionLevel="signature|system"          android:label="@string/permlab_manageActivityStacks"          android:description="@string/permdesc_manageActivityStacks" /> @@ -2356,13 +2356,13 @@           @hide -->      <permission android:name="android.permission.READ_DREAM_STATE"          android:permissionGroup="android.permission-group.SYSTEM_TOOLS" -        android:protectionLevel="signature" /> +        android:protectionLevel="signature|system" />      <!-- Allows applications to write dream settings, and start or stop dreaming.           @hide -->      <permission android:name="android.permission.WRITE_DREAM_STATE"          android:permissionGroup="android.permission-group.SYSTEM_TOOLS" -        android:protectionLevel="signature" /> +        android:protectionLevel="signature|system" />      <!-- Allow an application to read and write the cache partition.           @hide --> @@ -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..4d447878da4b 100644 --- a/services/input/InputDispatcher.cpp +++ b/libs/input/InputDispatcher.cpp @@ -1020,7 +1020,14 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout                  sp<InputWindowHandle> windowHandle = connection->inputWindowHandle;                  if (windowHandle != NULL) { -                    mTouchState.removeWindow(windowHandle); +                    const InputWindowInfo* info = windowHandle->getInfo(); +                    if (info) { +                        ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(info->displayId); +                        if (stateIndex >= 0) { +                            mTouchStatesByDisplay.editValueAt(stateIndex).removeWindow( +                                    windowHandle); +                        } +                    }                  }                  if (connection->status == Connection::STATUS_NORMAL) { @@ -1161,11 +1168,21 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,      InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;      sp<InputWindowHandle> newHoverWindowHandle; -    bool isSplit = mTouchState.split; -    bool switchedDevice = mTouchState.deviceId >= 0 && mTouchState.displayId >= 0 -            && (mTouchState.deviceId != entry->deviceId -                    || mTouchState.source != entry->source -                    || mTouchState.displayId != displayId); +    // Copy current touch state into mTempTouchState. +    // This state is always reset at the end of this function, so if we don't find state +    // for the specified display then our initial state will be empty. +    const TouchState* oldState = NULL; +    ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId); +    if (oldStateIndex >= 0) { +        oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex); +        mTempTouchState.copyFrom(*oldState); +    } + +    bool isSplit = mTempTouchState.split; +    bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 +            && (mTempTouchState.deviceId != entry->deviceId +                    || mTempTouchState.source != entry->source +                    || mTempTouchState.displayId != displayId);      bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE              || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER              || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT); @@ -1175,11 +1192,10 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,      bool wrongDevice = false;      if (newGesture) {          bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN; -        if (switchedDevice && mTouchState.down && !down) { +        if (switchedDevice && mTempTouchState.down && !down) {  #if DEBUG_FOCUS              ALOGD("Dropping event because a pointer for a different device is already down.");  #endif -            mTempTouchState.copyFrom(mTouchState);              injectionResult = INPUT_EVENT_INJECTION_FAILED;              switchedDevice = false;              wrongDevice = true; @@ -1191,8 +1207,6 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,          mTempTouchState.source = entry->source;          mTempTouchState.displayId = displayId;          isSplit = false; -    } else { -        mTempTouchState.copyFrom(mTouchState);      }      if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) { @@ -1515,32 +1529,31 @@ Failed:              if (isHoverAction) {                  // Started hovering, therefore no longer down. -                if (mTouchState.down) { +                if (oldState && oldState->down) {  #if DEBUG_FOCUS                      ALOGD("Conflicting pointer actions: Hover received while pointer was down.");  #endif                      *outConflictingPointerActions = true;                  } -                mTouchState.reset(); +                mTempTouchState.reset();                  if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER                          || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) { -                    mTouchState.deviceId = entry->deviceId; -                    mTouchState.source = entry->source; -                    mTouchState.displayId = displayId; +                    mTempTouchState.deviceId = entry->deviceId; +                    mTempTouchState.source = entry->source; +                    mTempTouchState.displayId = displayId;                  }              } else if (maskedAction == AMOTION_EVENT_ACTION_UP                      || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {                  // All pointers up or canceled. -                mTouchState.reset(); +                mTempTouchState.reset();              } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {                  // First pointer went down. -                if (mTouchState.down) { +                if (oldState && oldState->down) {  #if DEBUG_FOCUS                      ALOGD("Conflicting pointer actions: Down received while already down.");  #endif                      *outConflictingPointerActions = true;                  } -                mTouchState.copyFrom(mTempTouchState);              } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {                  // One pointer went up.                  if (isSplit) { @@ -1559,12 +1572,20 @@ Failed:                          i += 1;                      }                  } -                mTouchState.copyFrom(mTempTouchState); -            } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) { -                // Discard temporary touch state since it was only valid for this action. -            } else { -                // Save changes to touch state as-is for all other actions. -                mTouchState.copyFrom(mTempTouchState); +            } + +            // Save changes unless the action was scroll in which case the temporary touch +            // state was only valid for this one action. +            if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) { +                if (mTempTouchState.displayId >= 0) { +                    if (oldStateIndex >= 0) { +                        mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState); +                    } else { +                        mTouchStatesByDisplay.add(displayId, mTempTouchState); +                    } +                } else if (oldStateIndex >= 0) { +                    mTouchStatesByDisplay.removeItemsAt(oldStateIndex); +                }              }              // Update hover state. @@ -2316,7 +2337,7 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet              originalMotionEntry->yPrecision,              originalMotionEntry->downTime,              originalMotionEntry->displayId, -            splitPointerCount, splitPointerProperties, splitPointerCoords); +            splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);      if (originalMotionEntry->injectionState) {          splitMotionEntry->injectionState = originalMotionEntry->injectionState; @@ -2488,7 +2509,7 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {                  args->action, args->flags, args->metaState, args->buttonState,                  args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,                  args->displayId, -                args->pointerCount, args->pointerProperties, args->pointerCoords); +                args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0);          needWake = enqueueInboundEventLocked(newEntry);          mLock.unlock(); @@ -2536,7 +2557,7 @@ void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {      }  } -int32_t InputDispatcher::injectInputEvent(const InputEvent* event, +int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t displayId,          int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,          uint32_t policyFlags) {  #if DEBUG_INBOUND_EVENT_DETAILS @@ -2587,7 +2608,6 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,      case AINPUT_EVENT_TYPE_MOTION: {          const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event); -        int32_t displayId = ADISPLAY_ID_DEFAULT;          int32_t action = motionEvent->getAction();          size_t pointerCount = motionEvent->getPointerCount();          const PointerProperties* pointerProperties = motionEvent->getPointerProperties(); @@ -2610,7 +2630,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,                  motionEvent->getEdgeFlags(),                  motionEvent->getXPrecision(), motionEvent->getYPrecision(),                  motionEvent->getDownTime(), displayId, -                uint32_t(pointerCount), pointerProperties, samplePointerCoords); +                uint32_t(pointerCount), pointerProperties, samplePointerCoords, +                motionEvent->getXOffset(), motionEvent->getYOffset());          lastInjectedEntry = firstInjectedEntry;          for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {              sampleEventTimes += 1; @@ -2622,7 +2643,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,                      motionEvent->getEdgeFlags(),                      motionEvent->getXPrecision(), motionEvent->getYPrecision(),                      motionEvent->getDownTime(), displayId, -                    uint32_t(pointerCount), pointerProperties, samplePointerCoords); +                    uint32_t(pointerCount), pointerProperties, samplePointerCoords, +                    motionEvent->getXOffset(), motionEvent->getYOffset());              lastInjectedEntry->next = nextInjectedEntry;              lastInjectedEntry = nextInjectedEntry;          } @@ -2847,22 +2869,25 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu              mFocusedWindowHandle = newFocusedWindowHandle;          } -        for (size_t i = 0; i < mTouchState.windows.size(); i++) { -            TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i); -            if (!hasWindowHandleLocked(touchedWindow.windowHandle)) { +        for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) { +            TouchState& state = mTouchStatesByDisplay.editValueAt(d); +            for (size_t i = 0; i < state.windows.size(); i++) { +                TouchedWindow& touchedWindow = state.windows.editItemAt(i); +                if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {  #if DEBUG_FOCUS -                ALOGD("Touched window was removed: %s", -                        touchedWindow.windowHandle->getName().string()); +                    ALOGD("Touched window was removed: %s", +                            touchedWindow.windowHandle->getName().string());  #endif -                sp<InputChannel> touchedInputChannel = -                        touchedWindow.windowHandle->getInputChannel(); -                if (touchedInputChannel != NULL) { -                    CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, -                            "touched window was removed"); -                    synthesizeCancelationEventsForInputChannelLocked( -                            touchedInputChannel, options); +                    sp<InputChannel> touchedInputChannel = +                            touchedWindow.windowHandle->getInputChannel(); +                    if (touchedInputChannel != NULL) { +                        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, +                                "touched window was removed"); +                        synthesizeCancelationEventsForInputChannelLocked( +                                touchedInputChannel, options); +                    } +                    state.windows.removeAt(i--);                  } -                mTouchState.windows.removeAt(i--);              }          } @@ -3003,23 +3028,27 @@ bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,          }          bool found = false; -        for (size_t i = 0; i < mTouchState.windows.size(); i++) { -            const TouchedWindow& touchedWindow = mTouchState.windows[i]; -            if (touchedWindow.windowHandle == fromWindowHandle) { -                int32_t oldTargetFlags = touchedWindow.targetFlags; -                BitSet32 pointerIds = touchedWindow.pointerIds; - -                mTouchState.windows.removeAt(i); - -                int32_t newTargetFlags = oldTargetFlags -                        & (InputTarget::FLAG_FOREGROUND -                                | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS); -                mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds); - -                found = true; -                break; +        for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) { +            TouchState& state = mTouchStatesByDisplay.editValueAt(d); +            for (size_t i = 0; i < state.windows.size(); i++) { +                const TouchedWindow& touchedWindow = state.windows[i]; +                if (touchedWindow.windowHandle == fromWindowHandle) { +                    int32_t oldTargetFlags = touchedWindow.targetFlags; +                    BitSet32 pointerIds = touchedWindow.pointerIds; + +                    state.windows.removeAt(i); + +                    int32_t newTargetFlags = oldTargetFlags +                            & (InputTarget::FLAG_FOREGROUND +                                    | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS); +                    state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds); + +                    found = true; +                    goto Found; +                }              }          } +Found:          if (! found) {  #if DEBUG_FOCUS @@ -3063,7 +3092,7 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {      drainInboundQueueLocked();      resetANRTimeoutsLocked(); -    mTouchState.reset(); +    mTouchStatesByDisplay.clear();      mLastHoverWindowHandle.clear();  } @@ -3098,22 +3127,28 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {      dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",              mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>"); -    dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down)); -    dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split)); -    dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId); -    dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source); -    dump.appendFormat(INDENT "TouchDisplayId: %d\n", mTouchState.displayId); -    if (!mTouchState.windows.isEmpty()) { -        dump.append(INDENT "TouchedWindows:\n"); -        for (size_t i = 0; i < mTouchState.windows.size(); i++) { -            const TouchedWindow& touchedWindow = mTouchState.windows[i]; -            dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", -                    i, touchedWindow.windowHandle->getName().string(), -                    touchedWindow.pointerIds.value, -                    touchedWindow.targetFlags); +    if (!mTouchStatesByDisplay.isEmpty()) { +        dump.appendFormat(INDENT "TouchStatesByDisplay:\n"); +        for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) { +            const TouchState& state = mTouchStatesByDisplay.valueAt(i); +            dump.appendFormat(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n", +                    state.displayId, toString(state.down), toString(state.split), +                    state.deviceId, state.source); +            if (!state.windows.isEmpty()) { +                dump.append(INDENT3 "Windows:\n"); +                for (size_t i = 0; i < state.windows.size(); i++) { +                    const TouchedWindow& touchedWindow = state.windows[i]; +                    dump.appendFormat(INDENT4 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", +                            i, touchedWindow.windowHandle->getName().string(), +                            touchedWindow.pointerIds.value, +                            touchedWindow.targetFlags); +                } +            } else { +                dump.append(INDENT3 "Windows: <none>\n"); +            }          }      } else { -        dump.append(INDENT "TouchedWindows: <none>\n"); +        dump.append(INDENT "TouchStates: <no displays touched>\n");      }      if (!mWindowHandles.isEmpty()) { @@ -3898,7 +3933,8 @@ InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,          int32_t metaState, int32_t buttonState,          int32_t edgeFlags, float xPrecision, float yPrecision,          nsecs_t downTime, int32_t displayId, uint32_t pointerCount, -        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) : +        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords, +        float xOffset, float yOffset) :          EventEntry(TYPE_MOTION, eventTime, policyFlags),          eventTime(eventTime),          deviceId(deviceId), source(source), action(action), flags(flags), @@ -3908,6 +3944,9 @@ InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,      for (uint32_t i = 0; i < pointerCount; i++) {          this->pointerProperties[i].copyFrom(pointerProperties[i]);          this->pointerCoords[i].copyFrom(pointerCoords[i]); +        if (xOffset || yOffset) { +            this->pointerCoords[i].applyOffset(xOffset, yOffset); +        }      }  } @@ -4201,7 +4240,8 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim                      memento.flags, 0, 0, 0,                      memento.xPrecision, memento.yPrecision, memento.downTime,                      memento.displayId, -                    memento.pointerCount, memento.pointerProperties, memento.pointerCoords)); +                    memento.pointerCount, memento.pointerProperties, memento.pointerCoords, +                    0, 0));          }      }  } diff --git a/services/input/InputDispatcher.h b/libs/input/InputDispatcher.h index 190e7b221058..29854b2d56e4 100644 --- a/services/input/InputDispatcher.h +++ b/libs/input/InputDispatcher.h @@ -297,7 +297,7 @@ public:       *       * This method may be called on any thread (usually by the input manager).       */ -    virtual int32_t injectInputEvent(const InputEvent* event, +    virtual int32_t injectInputEvent(const InputEvent* event, int32_t displayId,              int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,              uint32_t policyFlags) = 0; @@ -381,7 +381,7 @@ public:      virtual void notifySwitch(const NotifySwitchArgs* args);      virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args); -    virtual int32_t injectInputEvent(const InputEvent* event, +    virtual int32_t injectInputEvent(const InputEvent* event, int32_t displayId,              int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,              uint32_t policyFlags); @@ -525,7 +525,8 @@ private:                  int32_t metaState, int32_t buttonState, int32_t edgeFlags,                  float xPrecision, float yPrecision,                  nsecs_t downTime, int32_t displayId, uint32_t pointerCount, -                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords); +                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords, +                float xOffset, float yOffset);          virtual void appendDescription(String8& msg) const;      protected: @@ -959,7 +960,7 @@ private:          bool isSlippery() const;      }; -    TouchState mTouchState; +    KeyedVector<int32_t, TouchState> mTouchStatesByDisplay;      TouchState mTempTouchState;      // Focused application. 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..fc89a9b18905 100644 --- a/services/input/tests/InputDispatcher_test.cpp +++ b/libs/input/tests/InputDispatcher_test.cpp @@ -27,6 +27,9 @@ static const nsecs_t ARBITRARY_TIME = 1234;  // An arbitrary device id.  static const int32_t DEVICE_ID = 1; +// An arbitrary display id. +static const int32_t DISPLAY_ID = 0; +  // An arbitrary injector pid / uid pair that has permission to inject events.  static const int32_t INJECTOR_PID = 999;  static const int32_t INJECTOR_UID = 1001; @@ -126,7 +129,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {      event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,              /*action*/ -1, 0,              AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject key events with undefined action."; @@ -134,7 +138,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {      event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,              AKEY_EVENT_ACTION_MULTIPLE, 0,              AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject key events with ACTION_MULTIPLE.";  } @@ -154,7 +159,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {              /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,              ARBITRARY_TIME, ARBITRARY_TIME,              /*pointerCount*/ 1, pointerProperties, pointerCoords); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject motion events with undefined action."; @@ -164,7 +170,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {              0, 0, AMETA_NONE, 0, 0, 0, 0, 0,              ARBITRARY_TIME, ARBITRARY_TIME,              /*pointerCount*/ 1, pointerProperties, pointerCoords); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject motion events with pointer down index too large."; @@ -173,7 +180,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {              0, 0, AMETA_NONE, 0, 0, 0, 0, 0,              ARBITRARY_TIME, ARBITRARY_TIME,              /*pointerCount*/ 1, pointerProperties, pointerCoords); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject motion events with pointer down index too small."; @@ -183,7 +191,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {              0, 0, AMETA_NONE, 0, 0, 0, 0, 0,              ARBITRARY_TIME, ARBITRARY_TIME,              /*pointerCount*/ 1, pointerProperties, pointerCoords); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject motion events with pointer up index too large."; @@ -192,7 +201,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {              0, 0, AMETA_NONE, 0, 0, 0, 0, 0,              ARBITRARY_TIME, ARBITRARY_TIME,              /*pointerCount*/ 1, pointerProperties, pointerCoords); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject motion events with pointer up index too small."; @@ -201,7 +211,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {              AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,              ARBITRARY_TIME, ARBITRARY_TIME,              /*pointerCount*/ 0, pointerProperties, pointerCoords); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject motion events with 0 pointers."; @@ -209,7 +220,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {              AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,              ARBITRARY_TIME, ARBITRARY_TIME,              /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject motion events with more than MAX_POINTERS pointers."; @@ -219,7 +231,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {              AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,              ARBITRARY_TIME, ARBITRARY_TIME,              /*pointerCount*/ 1, pointerProperties, pointerCoords); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject motion events with pointer ids less than 0."; @@ -228,7 +241,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {              AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,              ARBITRARY_TIME, ARBITRARY_TIME,              /*pointerCount*/ 1, pointerProperties, pointerCoords); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject motion events with pointer ids greater than MAX_POINTER_ID."; @@ -239,7 +253,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {              AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,              ARBITRARY_TIME, ARBITRARY_TIME,              /*pointerCount*/ 2, pointerProperties, pointerCoords); -    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, +    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( +            &event, DISPLAY_ID,              INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))              << "Should reject motion events with duplicate pointer ids.";  } 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/packages/Keyguard/Android.mk b/packages/Keyguard/Android.mk index f6f441d002fb..1f2b5fb51372 100644 --- a/packages/Keyguard/Android.mk +++ b/packages/Keyguard/Android.mk @@ -18,8 +18,6 @@ include $(CLEAR_VARS)  LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files) -LOCAL_JAVA_LIBRARIES := services -  LOCAL_PACKAGE_NAME := Keyguard  LOCAL_CERTIFICATE := platform 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..a8881b6e6e2c --- /dev/null +++ b/services/Android.mk @@ -0,0 +1,45 @@ +LOCAL_PATH:= $(call my-dir) + +# merge all required services into one jar +# ============================================================ +include $(CLEAR_VARS) + +LOCAL_MODULE := services + +LOCAL_SRC_FILES := $(call all-java-files-under,java) + +LOCAL_STATIC_JAVA_LIBRARIES := \ +    services.core \ +    services.accessibility \ +    services.appwidget \ +    services.backup \ +    services.devicepolicy \ +    services.print + +include $(BUILD_JAVA_LIBRARY) + +# 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/accessibility/Android.mk b/services/accessibility/Android.mk new file mode 100644 index 000000000000..d98fc281dfb7 --- /dev/null +++ b/services/accessibility/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := services.accessibility + +LOCAL_SRC_FILES += \ +      $(call all-java-files-under,java) + +include $(BUILD_STATIC_JAVA_LIBRARY) 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/appwidget/Android.mk b/services/appwidget/Android.mk new file mode 100644 index 000000000000..ca38f2f6449d --- /dev/null +++ b/services/appwidget/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := services.appwidget + +LOCAL_SRC_FILES += \ +      $(call all-java-files-under,java) + +include $(BUILD_STATIC_JAVA_LIBRARY) 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..e20867762daa --- /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"; + +    final Context mContext; +    final Handler mSaveStateHandler; + +    final SparseArray<AppWidgetServiceImpl> mAppWidgetServices; + +    public AppWidgetService(Context context) { +        super(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/backup/Android.mk b/services/backup/Android.mk new file mode 100644 index 000000000000..3e686d122668 --- /dev/null +++ b/services/backup/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := services.backup + +LOCAL_SRC_FILES += \ +      $(call all-java-files-under,java) + +LOCAL_JAVA_LIBRARIES := services.core + +include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/services/java/com/android/server/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 00bfee78bfbb..ca2f7b1c46e6 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; @@ -271,6 +274,20 @@ class BackupManagerService extends IBackupManager.Stub {      // Watch the device provisioning operation during setup      ContentObserver mProvisionedObserver; +    public static final class Lifecycle extends SystemService { +        private final BackupManagerService mService; + +        public Lifecycle(Context context) { +            super(context); +            mService = new BackupManagerService(context); +        } + +        @Override +        public void onStart() { +            publishBinderService(Context.BACKUP_SERVICE, mService); +        } +    } +      class ProvisionedObserver extends ContentObserver {          public ProvisionedObserver(Handler handler) {              super(handler); @@ -1178,7 +1195,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 +5455,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 +6105,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/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/core/Android.mk b/services/core/Android.mk new file mode 100644 index 000000000000..5c4520170fd8 --- /dev/null +++ b/services/core/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := services.core + +LOCAL_SRC_FILES += \ +    $(call all-java-files-under,java) \ +    java/com/android/server/EventLogTags.logtags \ +    java/com/android/server/am/EventLogTags.logtags + +LOCAL_JAVA_LIBRARIES := android.policy telephony-common + +include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 2e1b0af7b099..96063d577526 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,13 @@ 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>(); + +    public AlarmManagerService(Context context) { +        super(context); +    }      static long convertToElapsed(long when, int type) {          final boolean isRtc = (type == RTC || type == RTC_WAKEUP); @@ -403,7 +405,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 +429,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 +445,7 @@ class AlarmManagerService extends IAlarmManager.Stub {          }      } -    private static final class BroadcastStats { +    static final class BroadcastStats {          final String mPackageName;          long aggregateTime; @@ -459,47 +461,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 +511,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;          } -        set(type, triggerAtTime, windowLength, interval, operation, false, workSource); +        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()); +            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 +641,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 +848,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 +1041,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 +1187,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 +1227,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 +1269,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 +1331,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 +1344,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 +1375,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 +1389,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 +1400,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..e5615c0441a2 100644 --- a/services/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -186,9 +186,9 @@ public class AppOpsService extends IAppOpsService.Stub {          }      } -    public AppOpsService(File storagePath) { +    public AppOpsService(File storagePath, Handler handler) {          mFile = new AtomicFile(storagePath); -        mHandler = new Handler(); +        mHandler = handler;          readState();      } diff --git a/services/java/com/android/server/AssetAtlasService.java b/services/core/java/com/android/server/AssetAtlasService.java index 3fb006b8486d..3fb006b8486d 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 da1b2548238f..bce85cee338b 100644 --- a/services/java/com/android/server/BootReceiver.java +++ b/services/core/java/com/android/server/BootReceiver.java @@ -120,6 +120,8 @@ public class BootReceiver extends BroadcastReceiver {              // Negative sizes mean to take the *tail* of the file (see FileUtils.readTextFile())              addFileToDropBox(db, prefs, headers, "/proc/last_kmsg",                      -LOG_SIZE, "SYSTEM_LAST_KMSG"); +            addFileToDropBox(db, prefs, headers, "/sys/fs/pstore/console-ramoops", +                    -LOG_SIZE, "SYSTEM_LAST_KMSG");              addFileToDropBox(db, prefs, headers, "/cache/recovery/log",                      -LOG_SIZE, "SYSTEM_RECOVERY_LOG");              addFileToDropBox(db, prefs, headers, "/data/dontpanic/apanic_console", @@ -184,6 +186,11 @@ public class BootReceiver extends BroadcastReceiver {          File file = new File("/proc/last_kmsg");          long fileTime = file.lastModified(); +        if (fileTime <= 0) { +            file = new File("/sys/fs/pstore/console-ramoops"); +            fileTime = file.lastModified(); +        } +          if (fileTime <= 0) return;  // File does not exist          if (prefs != null) { 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..8d158cfd8f6b 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -26,6 +26,7 @@ import static android.net.ConnectivityManager.TYPE_ETHERNET;  import static android.net.ConnectivityManager.TYPE_MOBILE;  import static android.net.ConnectivityManager.TYPE_WIFI;  import static android.net.ConnectivityManager.TYPE_WIMAX; +import static android.net.ConnectivityManager.TYPE_PROXY;  import static android.net.ConnectivityManager.getNetworkTypeName;  import static android.net.ConnectivityManager.isNetworkTypeValid;  import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; @@ -69,6 +70,7 @@ import android.net.NetworkState;  import android.net.NetworkStateTracker;  import android.net.NetworkUtils;  import android.net.Proxy; +import android.net.ProxyDataTracker;  import android.net.ProxyProperties;  import android.net.RouteInfo;  import android.net.SamplingDataTracker; @@ -729,6 +731,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {                      return makeWimaxStateTracker(mContext, mTrackerHandler);                  case TYPE_ETHERNET:                      return EthernetDataTracker.getInstance(); +                case TYPE_PROXY: +                    return new ProxyDataTracker();                  default:                      throw new IllegalArgumentException(                              "Trying to create a NetworkStateTracker for an unknown radio type: " 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/core/java/com/android/server/DisplayThread.java b/services/core/java/com/android/server/DisplayThread.java new file mode 100644 index 000000000000..528ba0a90a0b --- /dev/null +++ b/services/core/java/com/android/server/DisplayThread.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.os.Handler; + +/** + * Shared singleton foreground thread for the system.  This is a thread for + * operations that affect what's on the display, which needs to have a minimum + * of latency.  This thread should pretty much only be used by the WindowManager, + * DisplayManager, and InputManager to perform quick operations in real time. + */ +public final class DisplayThread extends ServiceThread { +    private static DisplayThread sInstance; +    private static Handler sHandler; + +    private DisplayThread() { +        super("android.display", android.os.Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/); +    } + +    private static void ensureThreadLocked() { +        if (sInstance == null) { +            sInstance = new DisplayThread(); +            sInstance.start(); +            sHandler = new Handler(sInstance.getLooper()); +        } +    } + +    public static DisplayThread get() { +        synchronized (UiThread.class) { +            ensureThreadLocked(); +            return sInstance; +        } +    } + +    public static Handler getHandler() { +        synchronized (UiThread.class) { +            ensureThreadLocked(); +            return sHandler; +        } +    } +} 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..03765db35bae 100644 --- a/services/java/com/android/server/FgThread.java +++ b/services/core/java/com/android/server/FgThread.java @@ -17,7 +17,6 @@  package com.android.server;  import android.os.Handler; -import android.os.HandlerThread;  /**   * Shared singleton foreground thread for the system.  This is a thread for regular @@ -27,12 +26,12 @@ import android.os.HandlerThread;   * simply being a background priority), which can cause operations scheduled on it   * to be delayed for a user-noticeable amount of time.   */ -public final class FgThread extends HandlerThread { +public final class FgThread extends ServiceThread {      private static FgThread sInstance;      private static Handler sHandler;      private FgThread() { -        super("android.fg", android.os.Process.THREAD_PRIORITY_DEFAULT); +        super("android.fg", android.os.Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);      }      private static void ensureThreadLocked() { @@ -40,12 +39,6 @@ public final class FgThread extends HandlerThread {              sInstance = new FgThread();              sInstance.start();              sHandler = new Handler(sInstance.getLooper()); -            sHandler.post(new Runnable() { -                @Override -                public void run() { -                    android.os.Process.setCanSelfBackground(false); -                } -            });          }      } 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..0f29857db345 100644 --- a/services/java/com/android/server/IoThread.java +++ b/services/core/java/com/android/server/IoThread.java @@ -17,19 +17,18 @@  package com.android.server;  import android.os.Handler; -import android.os.HandlerThread;  /**   * Shared singleton I/O thread for the system.  This is a thread for non-background   * service operations that can potential block briefly on network IO operations   * (not waiting for data itself, but communicating with network daemons).   */ -public final class IoThread extends HandlerThread { +public final class IoThread extends ServiceThread {      private static IoThread sInstance;      private static Handler sHandler;      private IoThread() { -        super("android.io", android.os.Process.THREAD_PRIORITY_DEFAULT); +        super("android.io", android.os.Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);      }      private static void ensureThreadLocked() { @@ -37,12 +36,6 @@ public final class IoThread extends HandlerThread {              sInstance = new IoThread();              sInstance.start();              sHandler = new Handler(sInstance.getLooper()); -            sHandler.post(new Runnable() { -                @Override -                public void run() { -                    android.os.Process.setCanSelfBackground(false); -                } -            });          }      } 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 816ae6967cfd..816ae6967cfd 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/core/java/com/android/server/ServiceThread.java b/services/core/java/com/android/server/ServiceThread.java new file mode 100644 index 000000000000..bce64afd0c5e --- /dev/null +++ b/services/core/java/com/android/server/ServiceThread.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.os.HandlerThread; +import android.os.Process; +import android.os.StrictMode; +import android.util.Slog; + +/** + * Special handler thread that we create for system services that require their own loopers. + */ +public class ServiceThread extends HandlerThread { +    private static final String TAG = "ServiceThread"; + +    private final boolean mAllowIo; + +    public ServiceThread(String name, int priority, boolean allowIo) { +        super(name, priority); +        mAllowIo = allowIo; +    } + +    @Override +    public void run() { +        Process.setCanSelfBackground(false); + +        // For debug builds, log event loop stalls to dropbox for analysis. +        if (!mAllowIo && StrictMode.conditionallyEnableDebugLogging()) { +            Slog.i(TAG, "Enabled StrictMode logging for " + getName() + " looper."); +        } + +        super.run(); +    } +}
\ No newline at end of file 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/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..ad693d00248d 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,40 @@ 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; + +    public UiModeManagerService(Context context) { +        super(context); +    } -    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 +144,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 +175,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 +382,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 +397,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 +405,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 +431,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 +529,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 +551,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 +575,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 +588,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 +602,7 @@ final class UiModeManagerService extends IUiModeManager.Stub {          }      } -    private void updateTwilight() { +    void updateTwilight() {          synchronized (mLock) {              if (isDoingNightModeLocked() && mNightMode == UiModeManager.MODE_NIGHT_AUTO) {                  updateComputedNightModeLocked(); @@ -573,36 +612,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..0beb77fb4b92 100644 --- a/services/java/com/android/server/UiThread.java +++ b/services/core/java/com/android/server/UiThread.java @@ -17,21 +17,18 @@  package com.android.server;  import android.os.Handler; -import android.os.HandlerThread; -import android.os.StrictMode; -import android.util.Slog;  /**   * Shared singleton thread for showing UI.  This is a foreground thread, and in   * additional should not have operations that can take more than a few ms scheduled   * on it to avoid UI jank.   */ -public final class UiThread extends HandlerThread { +public final class UiThread extends ServiceThread {      private static UiThread sInstance;      private static Handler sHandler;      private UiThread() { -        super("android.ui", android.os.Process.THREAD_PRIORITY_FOREGROUND); +        super("android.ui", android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);      }      private static void ensureThreadLocked() { @@ -39,19 +36,6 @@ public final class UiThread extends HandlerThread {              sInstance = new UiThread();              sInstance.start();              sHandler = new Handler(sInstance.getLooper()); -            sHandler.post(new Runnable() { -                @Override -                public void run() { -                    //Looper.myLooper().setMessageLogging(new LogPrinter( -                    //        Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM)); -                    android.os.Process.setCanSelfBackground(false); - -                    // For debug builds, log event loop stalls to dropbox for analysis. -                    if (StrictMode.conditionallyEnableDebugLogging()) { -                        Slog.i("UiThread", "Enabled StrictMode logging for UI thread"); -                    } -                } -            });          }      } 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..1ce073a7a836 100644 --- a/services/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -20,18 +20,15 @@ import android.app.IActivityController;  import android.os.Binder;  import android.os.RemoteException;  import com.android.server.am.ActivityManagerService; -import com.android.server.power.PowerManagerService; -import android.app.AlarmManager; -import android.app.PendingIntent;  import android.content.BroadcastReceiver;  import android.content.ContentResolver;  import android.content.Context;  import android.content.Intent;  import android.content.IntentFilter; -import android.os.BatteryManager;  import android.os.Debug;  import android.os.Handler; +import android.os.IPowerManager;  import android.os.Looper;  import android.os.Process;  import android.os.ServiceManager; @@ -45,7 +42,6 @@ import java.io.File;  import java.io.FileWriter;  import java.io.IOException;  import java.util.ArrayList; -import java.util.Calendar;  /** This class calls its monitor every minute. Killing this process if they don't return **/  public class Watchdog extends Thread { @@ -80,9 +76,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; @@ -232,15 +225,13 @@ public class Watchdog extends Thread {          // And also check IO thread.          mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(),                  "i/o thread", DEFAULT_TIMEOUT)); +        // And the display thread. +        mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(), +                "display 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(), @@ -277,15 +268,16 @@ public class Watchdog extends Thread {          }      } -    public void addThread(Handler thread, String name) { -        addThread(thread, name, DEFAULT_TIMEOUT); +    public void addThread(Handler thread) { +        addThread(thread, DEFAULT_TIMEOUT);      } -    public void addThread(Handler thread, String name, long timeoutMillis) { +    public void addThread(Handler thread, long timeoutMillis) {          synchronized (this) {              if (isAlive()) {                  throw new RuntimeException("Threads can't be added once the Watchdog is running");              } +            final String name = thread.getLooper().getThread().getName();              mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis));          }      } @@ -295,8 +287,11 @@ public class Watchdog extends Thread {       */      void rebootSystem(String reason) {          Slog.i(TAG, "Rebooting system because: " + reason); -        PowerManagerService pms = (PowerManagerService) ServiceManager.getService("power"); -        pms.reboot(false, reason, false); +        IPowerManager pms = (IPowerManager)ServiceManager.getService(Context.POWER_SERVICE); +        try { +            pms.reboot(false, reason, false); +        } catch (RemoteException ex) { +        }      }      private int evaluateCheckerCompletionLocked() { 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 fc66e45c0cee..46891f5920a4 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,13 @@ 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.ServiceThread; +import com.android.server.SystemService;  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 +71,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; @@ -134,6 +136,7 @@ import android.os.Bundle;  import android.os.Debug;  import android.os.DropBoxManager;  import android.os.Environment; +import android.os.FactoryTest;  import android.os.FileObserver;  import android.os.FileUtils;  import android.os.Handler; @@ -331,8 +334,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. @@ -747,7 +748,7 @@ public final class ActivityManagerService extends ActivityManagerNative          }      } -    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); +    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();      /**       * All information we have collected about the runtime performance of @@ -996,8 +997,7 @@ public final class ActivityManagerService extends ActivityManagerNative      WindowManagerService mWindowManager; -    static ActivityManagerService mSelf; -    static ActivityThread mSystemThread; +    final ActivityThread mSystemThread;      int mCurrentUserId = 0;      private UserManagerService mUserManager; @@ -1074,10 +1074,13 @@ public final class ActivityManagerService extends ActivityManagerNative       */      private boolean mUserIsMonkey; -    final Handler mHandler = new Handler() { -        //public Handler() { -        //    if (localLOGV) Slog.v(TAG, "Handler started!"); -        //} +    final ServiceThread mHandlerThread; +    final MainHandler mHandler; + +    final class MainHandler extends Handler { +        public MainHandler(Looper looper) { +            super(looper, null, true); +        }          @Override          public void handleMessage(Message msg) { @@ -1730,38 +1733,34 @@ public final class ActivityManagerService extends ActivityManagerNative          }      }; -    public static void setSystemProcess() { +    public void setSystemProcess() {          try { -            ActivityManagerService m = mSelf; - -            ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true); -            ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats); -            ServiceManager.addService("meminfo", new MemBinder(m)); -            ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); -            ServiceManager.addService("dbinfo", new DbBinder(m)); +            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); +            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); +            ServiceManager.addService("meminfo", new MemBinder(this)); +            ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); +            ServiceManager.addService("dbinfo", new DbBinder(this));              if (MONITOR_CPU_USAGE) { -                ServiceManager.addService("cpuinfo", new CpuBinder(m)); +                ServiceManager.addService("cpuinfo", new CpuBinder(this));              } -            ServiceManager.addService("permission", new PermissionController(m)); +            ServiceManager.addService("permission", new PermissionController(this)); -            ApplicationInfo info = -                mSelf.mContext.getPackageManager().getApplicationInfo( -                            "android", STOCK_PM_FLAGS); +            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( +                    "android", STOCK_PM_FLAGS);              mSystemThread.installSystemApplicationInfo(info); -            synchronized (mSelf) { -                ProcessRecord app = mSelf.newProcessRecordLocked(info, -                        info.processName, false); +            synchronized (this) { +                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);                  app.persistent = true;                  app.pid = MY_PID;                  app.maxAdj = ProcessList.SYSTEM_ADJ; -                app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats); -                mSelf.mProcessNames.put(app.processName, app.uid, app); -                synchronized (mSelf.mPidsSelfLocked) { -                    mSelf.mPidsSelfLocked.put(app.pid, app); +                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); +                mProcessNames.put(app.processName, app.uid, app); +                synchronized (mPidsSelfLocked) { +                    mPidsSelfLocked.put(app.pid, app);                  } -                mSelf.updateLruProcessLocked(app, false, null); -                mSelf.updateOomAdjLocked(); +                updateLruProcessLocked(app, false, null); +                updateOomAdjLocked();              }          } catch (PackageManager.NameNotFoundException e) {              throw new RuntimeException( @@ -1772,105 +1771,17 @@ 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() { -        final NativeCrashListener ncl = new NativeCrashListener(); +        final NativeCrashListener ncl = new NativeCrashListener(this);          ncl.start();      } -    public static final Context main(int factoryTest) { -        AThread thr = new AThread(); -        thr.start(); - -        synchronized (thr) { -            while (thr.mService == null) { -                try { -                    thr.wait(); -                } catch (InterruptedException e) { -                } -            } -        } - -        ActivityManagerService m = thr.mService; -        mSelf = m; -        ActivityThread at = ActivityThread.systemMain(); -        mSystemThread = at; -        Context context = at.getSystemContext(); -        context.setTheme(android.R.style.Theme_Holo); -        m.mContext = context; -        m.mFactoryTest = factoryTest; -        m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface()); - -        m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper); - -        m.mBatteryStatsService.publish(context); -        m.mUsageStatsService.publish(context); -        m.mAppOpsService.publish(context); - -        synchronized (thr) { -            thr.mReady = true; -            thr.notifyAll(); -        } - -        m.startRunning(null, null, null, null); - -        return context; -    } - -    public static ActivityManagerService self() { -        return mSelf; -    } -      public IAppOpsService getAppOpsService() {          return mAppOpsService;      } -    static class AThread extends Thread { -        ActivityManagerService mService; -        Looper mLooper; -        boolean mReady = false; - -        public AThread() { -            super("ActivityManager"); -        } - -        @Override -        public void run() { -            Looper.prepare(); - -            android.os.Process.setThreadPriority( -                    android.os.Process.THREAD_PRIORITY_FOREGROUND); -            android.os.Process.setCanSelfBackground(false); - -            ActivityManagerService m = new ActivityManagerService(); - -            synchronized (this) { -                mService = m; -                mLooper = Looper.myLooper(); -                Watchdog.getInstance().addThread(new Handler(mLooper), getName()); -                notifyAll(); -            } - -            synchronized (this) { -                while (!mReady) { -                    try { -                        wait(); -                    } catch (InterruptedException e) { -                    } -                } -            } - -            // For debug builds, log event loop stalls to dropbox for analysis. -            if (StrictMode.conditionallyEnableDebugLogging()) { -                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); -            } - -            Looper.loop(); -        } -    } -      static class MemBinder extends Binder {          ActivityManagerService mActivityManagerService;          MemBinder(ActivityManagerService activityManagerService) { @@ -1955,22 +1866,54 @@ public final class ActivityManagerService extends ActivityManagerNative          }      } -    private ActivityManagerService() { +    public static final class Lifecycle extends SystemService { +        private final ActivityManagerService mService; + +        public Lifecycle(Context context) { +            super(context); +            mService = new ActivityManagerService(context); +        } + +        @Override +        public void onStart() { +            mService.start(); +        } + +        public ActivityManagerService getService() { +            return mService; +        } +    } + +    // Note: This method is invoked on the main thread but may need to attach various +    // handlers to other threads.  So take care to be explicit about the looper. +    public ActivityManagerService(Context systemContext) { +        mContext = systemContext; +        mFactoryTest = FactoryTest.getMode(); +        mSystemThread = ActivityThread.currentActivityThread(); +          Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); -        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false); -        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true); +        mHandlerThread = new ServiceThread(TAG, +                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); +        mHandlerThread.start(); +        mHandler = new MainHandler(mHandlerThread.getLooper()); + +        mFgBroadcastQueue = new BroadcastQueue(this, mHandler, +                "foreground", BROADCAST_FG_TIMEOUT, false); +        mBgBroadcastQueue = new BroadcastQueue(this, mHandler, +                "background", BROADCAST_BG_TIMEOUT, true);          mBroadcastQueues[0] = mFgBroadcastQueue;          mBroadcastQueues[1] = mBgBroadcastQueue;          mServices = new ActiveServices(this);          mProviderMap = new ProviderMap(this); +        // TODO: Move creation of battery stats service outside of activity manager service.          File dataDir = Environment.getDataDirectory();          File systemDir = new File(dataDir, "system");          systemDir.mkdirs();          mBatteryStatsService = new BatteryStatsService(new File( -                systemDir, "batterystats.bin").toString()); +                systemDir, "batterystats.bin").toString(), mHandler);          mBatteryStatsService.getActiveStatistics().readLocked();          mBatteryStatsService.getActiveStatistics().writeAsyncLocked();          mOnBattery = DEBUG_POWER ? true @@ -1980,12 +1923,10 @@ public final class ActivityManagerService extends ActivityManagerNative          mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));          mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); -        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml")); +        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);          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)); @@ -2000,10 +1941,9 @@ public final class ActivityManagerService extends ActivityManagerNative          mConfigurationSeq = mConfiguration.seq = 1;          mProcessCpuTracker.init(); -        mCompatModePackages = new CompatModePackages(this, systemDir); - -        // Add ourself to the Watchdog monitors. -        Watchdog.getInstance().addMonitor(this); +        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); +        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); +        mStackSupervisor = new ActivityStackSupervisor(this);          mProcessCpuThread = new Thread("CpuTracker") {              @Override @@ -2034,7 +1974,18 @@ public final class ActivityManagerService extends ActivityManagerNative                  }              }          }; + +        Watchdog.getInstance().addMonitor(this); +        Watchdog.getInstance().addThread(mHandler); +    } + +    private void start() {          mProcessCpuThread.start(); + +        mBatteryStatsService.publish(mContext); +        mUsageStatsService.publish(mContext); +        mAppOpsService.publish(mContext); +        startRunning(null, null, null, null);      }      @Override @@ -2730,13 +2681,13 @@ public final class ActivityManagerService extends ActivityManagerNative                  }                  gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));              } -            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { -                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL +            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { +                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL                          && mTopComponent != null                          && app.processName.equals(mTopComponent.getPackageName())) {                      uid = 0;                  } -                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL +                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL                          && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {                      uid = 0;                  } @@ -2846,21 +2797,14 @@ public final class ActivityManagerService extends ActivityManagerNative      Intent getHomeIntent() {          Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);          intent.setComponent(mTopComponent); -        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { +        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {              intent.addCategory(Intent.CATEGORY_HOME);          }          return intent;      }      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 +        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL                  && mTopAction == null) {              // We are running in factory test mode, but unable to find              // the factory test app, so just sit around displaying the @@ -2924,14 +2868,14 @@ public final class ActivityManagerService extends ActivityManagerNative          // version than the last one shown, and we are not running in          // low-level factory test mode.          final ContentResolver resolver = mContext.getContentResolver(); -        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && +        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&                  Settings.Global.getInt(resolver,                          Settings.Global.DEVICE_PROVISIONED, 0) != 0) {              mCheckedForSetup = true;              // See if we should be showing the platform update setup UI.              Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); -            List<ResolveInfo> ris = mSelf.mContext.getPackageManager() +            List<ResolveInfo> ris = mContext.getPackageManager()                      .queryIntentActivities(intent, PackageManager.GET_META_DATA);              // We don't allow third party apps to replace this. @@ -2959,7 +2903,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 +3061,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 +3076,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 +3091,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;      } @@ -3179,7 +3123,7 @@ public final class ActivityManagerService extends ActivityManagerNative              }          }          int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, -                resultTo, resultWho, requestCode, flagsMask, flagsValues, options); +                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);          return ret;      } @@ -3278,7 +3222,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; @@ -3291,7 +3235,8 @@ public final class ActivityManagerService extends ActivityManagerNative      final int startActivityInPackage(int uid, String callingPackage,              Intent intent, String resolvedType, IBinder resultTo, -            String resultWho, int requestCode, int startFlags, Bundle options, int userId) { +            String resultWho, int requestCode, int startFlags, Bundle options, int userId, +                    IActivityContainer container) {          userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,                  false, true, "startActivityInPackage", null); @@ -3299,7 +3244,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, container);          return ret;      } @@ -3603,9 +3548,13 @@ public final class ActivityManagerService extends ActivityManagerNative       */      private final void handleAppDiedLocked(ProcessRecord app,              boolean restarting, boolean allowRestart) { +        int pid = app.pid;          cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);          if (!restarting) {              removeLruProcessLocked(app); +            if (pid > 0) { +                ProcessList.remove(pid); +            }          }          if (mProfileProc == app) { @@ -5000,7 +4949,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) { @@ -5157,7 +5106,7 @@ public final class ActivityManagerService extends ActivityManagerNative                  }              } -            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { +            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {                  // Start looking for apps that are abusing wake locks.                  Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);                  mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); @@ -7107,23 +7056,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;          }      } @@ -7148,99 +7114,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);          } @@ -8061,11 +7968,11 @@ public final class ActivityManagerService extends ActivityManagerNative          }      } -    public static final void installSystemProviders() { +    public final void installSystemProviders() {          List<ProviderInfo> providers; -        synchronized (mSelf) { -            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); -            providers = mSelf.generateApplicationProvidersLocked(app); +        synchronized (this) { +            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); +            providers = generateApplicationProvidersLocked(app);              if (providers != null) {                  for (int i=providers.size()-1; i>=0; i--) {                      ProviderInfo pi = (ProviderInfo)providers.get(i); @@ -8081,9 +7988,9 @@ public final class ActivityManagerService extends ActivityManagerNative              mSystemThread.installSystemProviders(providers);          } -        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); +        mCoreSettingsObserver = new CoreSettingsObserver(this); -        mSelf.mUsageStatsService.monitorPackages(); +        mUsageStatsService.monitorPackages();      }      /** @@ -9321,7 +9228,7 @@ public final class ActivityManagerService extends ActivityManagerNative          synchronized(this) {              // Make sure we have no pre-ready processes sitting around. -            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { +            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {                  ResolveInfo ri = mContext.getPackageManager()                          .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),                                  STOCK_PM_FLAGS); @@ -9363,7 +9270,7 @@ public final class ActivityManagerService extends ActivityManagerNative          if (goingCallback != null) goingCallback.run();          synchronized (this) { -            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { +            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {                  try {                      List apps = AppGlobals.getPackageManager().                          getPersistentApplications(STOCK_PM_FLAGS); @@ -9496,10 +9403,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; @@ -12388,6 +12291,7 @@ public final class ActivityManagerService extends ActivityManagerNative              boolean restarting, boolean allowRestart, int index) {          if (index >= 0) {              removeLruProcessLocked(app); +            ProcessList.remove(app.pid);          }          mProcessesToGc.remove(app); @@ -14042,9 +13946,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) { @@ -14127,18 +14028,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); -        } +        // 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 (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) { @@ -15250,16 +15154,13 @@ public final class ActivityManagerService extends ActivityManagerNative          }          if (app.curAdj != app.setAdj) { -            if (Process.setOomAdj(app.pid, app.curAdj)) { -                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( -                    TAG, "Set " + app.pid + " " + app.processName + -                    " adj " + app.curAdj + ": " + app.adjType); -                app.setAdj = app.curAdj; -            } else { -                success = false; -                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); -            } +            ProcessList.setOomAdj(app.pid, app.curAdj); +            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( +                TAG, "Set " + app.pid + " " + app.processName + +                " adj " + app.curAdj + ": " + app.adjType); +            app.setAdj = app.curAdj;          } +          if (app.setSchedGroup != app.curSchedGroup) {              app.setSchedGroup = app.curSchedGroup;              if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 49f29fe6c372..a27288ab08c7 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 @@ -481,7 +486,7 @@ final class ActivityRecord {      void setTask(TaskRecord newTask, ThumbnailHolder newThumbHolder, boolean isRoot) {          if (task != null && task.removeActivity(this)) {              if (task != newTask) { -                mStackSupervisor.removeTask(task); +                task.stack.removeTask(task);              } else {                  Slog.d(TAG, "!!! REMOVE THIS LOG !!! setTask: nearly removed stack=" +                          (newTask == null ? null : newTask.stack)); 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 d651a6217c49..9c631c492f53 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; @@ -319,7 +322,7 @@ final class ActivityStack {          }      } -    private int numActivities() { +    int numActivities() {          int count = 0;          for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {              count += mTaskHistory.get(taskNdx).mActivities.size(); @@ -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. @@ -733,6 +736,12 @@ final class ActivityStack {              mStackSupervisor.resumeTopActivitiesLocked();              return;          } + +        if (mActivityContainer.mParentActivity == null) { +            // Top level stack, not a child. Look for child stacks. +            mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping); +        } +          if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);          else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);          mResumedActivity = null; @@ -1251,6 +1260,13 @@ final class ActivityStack {      final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {          if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); +        ActivityRecord parent = mActivityContainer.mParentActivity; +        if (parent != null && parent.state != ActivityState.RESUMED) { +            // Do not resume this stack if its parent is not resumed. +            // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st. +            return false; +        } +          // Find the first activity that is not finishing.          ActivityRecord next = topRunningActivityLocked(null); @@ -1265,7 +1281,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; @@ -1288,25 +1305,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);              }          } @@ -1668,10 +1677,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); @@ -1750,9 +1763,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 @@ -2413,15 +2426,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);              }          } @@ -2600,7 +2610,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; @@ -2678,7 +2688,8 @@ final class ActivityStack {          r.finishLaunchTickingLocked();      } -    final void removeActivityFromHistoryLocked(ActivityRecord r) { +    private void removeActivityFromHistoryLocked(ActivityRecord r) { +        mStackSupervisor.removeChildActivityContainers(r);          finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);          r.makeFinishing();          if (DEBUG_ADD_REMOVE) { @@ -2686,15 +2697,6 @@ final class ActivityStack {              here.fillInStackTrace();              Slog.i(TAG, "Removing activity " + r + " from stack");          } -        final TaskRecord task = r.task; -        if (task != null && task.removeActivity(r)) { -            if (DEBUG_STACK) Slog.i(TAG, -                    "removeActivityFromHistoryLocked: last activity removed from " + this); -            if (mStackSupervisor.isFrontStack(this) && task == topTask() && task.mOnTopOfHome) { -                mStackSupervisor.moveHomeToTop(); -            } -            mStackSupervisor.removeTask(task); -        }          r.takeFromHistory();          removeTimeoutsForActivityLocked(r);          if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (removed from history)"); @@ -2705,6 +2707,15 @@ final class ActivityStack {          if (VALIDATE_TOKENS) {              validateAppTokensLocked();          } +        final TaskRecord task = r.task; +        if (task != null && task.removeActivity(r)) { +            if (DEBUG_STACK) Slog.i(TAG, +                    "removeActivityFromHistoryLocked: last activity removed from " + this); +            if (mStackSupervisor.isFrontStack(this) && task == topTask() && task.mOnTopOfHome) { +                mStackSupervisor.moveHomeToTop(); +            } +            removeTask(task); +        }          cleanUpActivityServicesLocked(r);          r.removeUriPermissionsLocked();      } @@ -3052,7 +3063,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. @@ -3161,7 +3172,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);          } @@ -3322,6 +3333,8 @@ final class ActivityStack {          r.startFreezingScreenLocked(r.app, 0); +        mStackSupervisor.removeChildActivityContainers(r); +          try {              if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG,                      (andResume ? "Relaunching to RESUMED " : "Relaunching to PAUSED ") @@ -3354,14 +3367,20 @@ final class ActivityStack {              for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {                  final ActivityRecord r = activities.get(activityNdx);                  if (r.appToken == token) { -                        return true; +                    return true;                  }                  if (r.fullscreen && !r.finishing) {                      return false;                  }              }          } -        return true; +        final ActivityRecord r = ActivityRecord.forToken(token); +        if (r == null) { +            return false; +        } +        if (r.finishing) Slog.e(TAG, "willActivityBeVisibleLocked: Returning false," +                + " would have returned true for r=" + r); +        return !r.finishing;      }      void closeSystemDialogsLocked() { @@ -3600,14 +3619,30 @@ final class ActivityStack {          return starting;      } -    boolean removeTask(TaskRecord task) { +    void removeTask(TaskRecord task) { +        mWindowManager.removeTask(task.taskId); +        final ActivityRecord r = mResumedActivity; +        if (r != null && r.task == task) { +            mResumedActivity = null; +        } +          final int taskNdx = mTaskHistory.indexOf(task);          final int topTaskNdx = mTaskHistory.size() - 1;          if (task.mOnTopOfHome && taskNdx < topTaskNdx) {              mTaskHistory.get(taskNdx + 1).mOnTopOfHome = true;          }          mTaskHistory.remove(task); -        return mTaskHistory.isEmpty(); + +        if (mTaskHistory.isEmpty()) { +            if (DEBUG_STACK) Slog.i(TAG, "removeTask: moving to back stack=" + this); +            if (isOnHomeDisplay()) { +                mStackSupervisor.moveHomeStack(!isHomeStack()); +            } +            if (mStacks != null) { +                mStacks.remove(this); +                mStacks.add(0, this); +            } +        }      }      TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, boolean toTop) { diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 483b4a04390e..b99823f51290 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,13 @@ 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.hardware.input.InputManager; +import android.hardware.input.InputManagerInternal;  import android.os.Binder;  import android.os.Bundle;  import android.os.Debug; @@ -68,22 +78,28 @@ 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.InputEvent; +import android.view.Surface;  import com.android.internal.app.HeavyWeightSwitcherActivity;  import com.android.internal.os.TransferPipe; +import com.android.server.LocalServices;  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 +123,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 +154,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 +221,21 @@ 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>(); + +    InputManagerInternal mInputManagerInternal; + +    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 +245,25 @@ 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); + +            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); +        }      }      void dismissKeyguard() { @@ -237,43 +275,42 @@ 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()); +        final ActivityRecord parent = stack.mActivityContainer.mParentActivity; +        if (parent != null) { +            stack = parent.task.stack; +        } +        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 +338,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; @@ -331,26 +376,6 @@ public final class ActivityStackSupervisor {          return mCurTaskId;      } -    void removeTask(TaskRecord task) { -        mWindowManager.removeTask(task.taskId); -        final ActivityStack stack = task.stack; -        final ActivityRecord r = stack.mResumedActivity; -        if (r != null && r.task == task) { -            stack.mResumedActivity = null; -        } -        if (stack.removeTask(task) && !stack.isHomeStack()) { -            if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack); -            mStacks.remove(stack); -            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); -            } -        } -    } -      ActivityRecord resumedAppLocked() {          ActivityStack stack = getFocusedStack();          if (stack == null) { @@ -366,29 +391,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 +425,54 @@ 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) || stack.numActivities() == 0) { +                    continue; +                } +                final ActivityRecord resumedActivity = stack.mResumedActivity; +                if (resumedActivity == null || !resumedActivity.idle) { +                    if (DEBUG_STATES) Slog.d(TAG, "allResumedActivitiesIdle: stack=" +                             + stack.mStackId + " " + resumedActivity + " not 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 +485,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,23 +502,40 @@ 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; +                    }                  }              }          }          return pausing;      } +    void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) { +		// TODO: Put all stacks in supervisor and iterate through them instead. +        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 (stack.mResumedActivity != null && +                        stack.mActivityContainer.mParentActivity == parent) { +                    stack.startPausingLocked(userLeaving, uiSleeping); +                } +            } +        } +    } +      void reportActivityVisibleLocked(ActivityRecord r) {          for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {              WaitResult w = mWaitingActivityVisible.get(i); @@ -525,8 +571,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 +590,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 +611,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 +683,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 +704,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 +716,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 +797,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 +914,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 +1138,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; @@ -1099,7 +1158,11 @@ public final class ActivityStackSupervisor {          if (err == ActivityManager.START_SUCCESS) {              final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;              Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) -                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)); +                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid) +                    + " on display " + (container == null ? (mFocusedStack == null ? +                            Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) : +                            (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY : +                                    container.mActivityDisplay.mDisplayId)));          }          ActivityRecord sourceRecord = null; @@ -1214,8 +1277,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 +1326,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 +1363,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 +1374,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 +1504,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 @@ -1502,9 +1554,6 @@ public final class ActivityStackSupervisor {                          } else {                              ActivityOptions.abort(options);                          } -                        if (r.task == null)  Slog.v(TAG, -                                "startActivityUncheckedLocked: task left null", -                                new RuntimeException("here").fillInStackTrace());                          return ActivityManager.START_RETURN_INTENT_TO_CALLER;                      }                      if ((launchFlags & @@ -1597,9 +1646,6 @@ public final class ActivityStackSupervisor {                          } else {                              ActivityOptions.abort(options);                          } -                        if (r.task == null)  Slog.v(TAG, -                            "startActivityUncheckedLocked: task left null", -                            new RuntimeException("here").fillInStackTrace());                          return ActivityManager.START_TASK_TO_FRONT;                      }                  } @@ -1637,15 +1683,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 +1698,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 +1708,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 +1726,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 @@ -1713,9 +1750,6 @@ public final class ActivityStackSupervisor {                          targetStack.resumeTopActivityLocked(null);                      }                      ActivityOptions.abort(options); -                    if (r.task == null)  Slog.w(TAG, -                        "startActivityUncheckedLocked: task left null", -                        new RuntimeException("here").fillInStackTrace());                      return ActivityManager.START_DELIVERED_TO_TOP;                  }              } else if (!addingToTask && @@ -1749,7 +1783,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 +1975,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 +2002,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 +2024,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 +2059,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 +2076,118 @@ 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; +    } + +    ActivityContainer createActivityContainer(ActivityRecord parentActivity, +            IActivityContainerCallback callback) { +        return createActivityContainer(parentActivity, getNextStackId(), callback); +    } + +    void removeChildActivityContainers(ActivityRecord parentActivity) { +        for (int ndx = mActivityContainers.size() - 1; ndx >= 0; --ndx) { +            final ActivityContainer container = mActivityContainers.valueAt(ndx).get(); +            if (container == null) { +                mActivityContainers.removeAt(ndx); +                continue; +            } +            if (container.mParentActivity != parentActivity) { +                continue; +            } + +            ActivityStack stack = container.mStack; +            ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null); +            if (top != null) { +                // TODO: Make sure the next activity doesn't start up when top is destroyed. +                stack.destroyActivityLocked(top, true, true, "stack removal"); +            } +            mActivityContainers.removeAt(ndx); +            container.detachLocked(); +        } +    } + +    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 createStack() { +    int getNextStackId() {          while (true) {              if (++mLastStackId <= HOME_STACK_ID) {                  mLastStackId = HOME_STACK_ID + 1; @@ -2069,7 +2196,6 @@ public final class ActivityStackSupervisor {                  break;              }          } -        mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));          return mLastStackId;      } @@ -2083,7 +2209,7 @@ public final class ActivityStackSupervisor {              Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);              return;          } -        removeTask(task); +        task.stack.removeTask(task);          stack.addTask(task, toTop);          mWindowManager.addTask(taskId, stackId, toTop);          resumeTopActivitiesLocked(); @@ -2091,15 +2217,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 +2236,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 +2270,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 +2305,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 +2331,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 +2358,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 +2389,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 +2437,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 +2451,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 +2502,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 +2534,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 +2570,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 = true; +                    needSep = false;                  } -                printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage, -                        needSep, "    mLastNoHistoryActivity: "); +                pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep, +                        "    mResumedActivity: "); +                if (pr) { +                    printed = true; +                    needSep = false; +                } +                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, @@ -2568,7 +2728,9 @@ public final class ActivityStackSupervisor {      }      final void scheduleResumeTopActivities() { -        mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); +        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) { +            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); +        }      }      void removeSleepTimeouts() { @@ -2581,6 +2743,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) { +                    stacks.get(stackNdx).mActivityContainer.detachLocked(); +                } +                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 +2901,251 @@ 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; +        final String mIdString; + +        /** 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; +                mIdString = "ActivtyContainer{" + mStackId + ", parent=" + mParentActivity + "}"; +                if (DEBUG_STACK) Slog.d(TAG, "Creating " + this); +            } +        } + +        void attachToDisplayLocked(ActivityDisplay activityDisplay) { +            if (DEBUG_STACK) Slog.d(TAG, "attachToDisplayLocked: " + this +                    + " to display=" + activityDisplay); +            mActivityDisplay = activityDisplay; +            mStack.mDisplayId = activityDisplay.mDisplayId; +            mStack.mStacks = activityDisplay.mStacks; + +            activityDisplay.attachActivities(mStack); +            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); +        } + +        @Override +        public void attachToDisplay(int displayId) { +            synchronized (mService) { +                ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); +                if (activityDisplay == null) { +                    return; +                } +                attachToDisplayLocked(activityDisplay); +            } +        } + +        @Override +        public int getDisplayId() { +            if (mActivityDisplay != null) { +                return mActivityDisplay.mDisplayId;              } +            return -1; +        } + +        @Override +        public boolean injectEvent(InputEvent event) { +            final long origId = Binder.clearCallingIdentity(); +            try { +                if (mActivityDisplay != null) { +                    return mInputManagerInternal.injectInputEvent(event, +                            mActivityDisplay.mDisplayId, +                            InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); +                } +                return false; +            } finally { +                Binder.restoreCallingIdentity(origId); +            } +        } + +        private void detachLocked() { +            if (DEBUG_STACK) Slog.d(TAG, "detachLocked: " + this + " from display=" +                    + mActivityDisplay + " Callers=" + Debug.getCallers(2)); +            if (mActivityDisplay != null) { +                mActivityDisplay.detachActivitiesLocked(mStack); +                mActivityDisplay = null; +                mStack.mDisplayId = -1; +                mStack.mStacks = null; +                mWindowManager.detachStack(mStackId); +            } +        } + +        @Override +        public void detachFromDisplay() { +            synchronized (mService) { +                detachLocked(); +            } +        } + +        @Override +        public final int startActivity(Intent intent) { +            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); +            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 final int startActivityIntentSender(IIntentSender intentSender) { +            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); + +            if (!(intentSender instanceof PendingIntentRecord)) { +                throw new IllegalArgumentException("Bad PendingIntent object"); +            } + +            return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, +                    null, 0, 0, 0, null, this); +        } + +        @Override +        public IBinder asBinder() { +            return this; +        } + +        @Override +        public void attachToSurface(Surface surface, int width, int height, int density) { +            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); + +            final long origId = Binder.clearCallingIdentity(); +            try { +                synchronized (mService) { +                    ActivityDisplay activityDisplay = +                            new ActivityDisplay(surface, width, height, density); +                    mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay); +                    attachToDisplayLocked(activityDisplay); +                    mStack.resumeTopActivityLocked(null); +                } +                if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display=" +                        + mActivityDisplay); +            } finally { +                Binder.restoreCallingIdentity(origId); +            } +        } + +        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); +            } +        } + +        @Override +        public String toString() { +            return mIdString + (mActivityDisplay == null ? "N" : "A"); +        } +    } + +    /** 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. */ +        int mDisplayId; +        Display mDisplay; +        DisplayInfo mDisplayInfo = new DisplayInfo(); +        Surface mSurface; + +        /** 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) { +            init(mDisplayManager.getDisplay(displayId)); +        } + +        ActivityDisplay(Surface surface, int width, int height, int density) { +            DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); +            long ident = Binder.clearCallingIdentity(); +            try { +                mVirtualDisplay = 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); +            } + +            init(mVirtualDisplay.getDisplay()); +            mSurface = surface; + +            mWindowManager.handleDisplayAdded(mDisplayId); +        } + +        private void init(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, "detachActivitiesLocked: detaching " + stack +                    + " from displayId=" + mDisplayId); +            mStacks.remove(stack); +            if (mStacks.isEmpty() && mVirtualDisplay != null) { +                mVirtualDisplay.release(); +                mVirtualDisplay = null; +            } +            mSurface.release(); +        } + +        void getBounds(Point bounds) { +            mDisplay.getDisplayInfo(mDisplayInfo); +            bounds.x = mDisplayInfo.appWidth; +            bounds.y = mDisplayInfo.appHeight; +        } + +        @Override +        public String toString() { +            return "ActivityDisplay={" + mDisplayId + (mVirtualDisplay == null ? "" : "V") +                    + " numStacks=" + mStacks.size() + "}";          }      }  } 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..ff06513fb858 100644 --- a/services/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -24,6 +24,7 @@ import android.content.pm.ApplicationInfo;  import android.content.pm.PackageManager;  import android.os.BatteryStats;  import android.os.Binder; +import android.os.Handler;  import android.os.IBinder;  import android.os.Parcel;  import android.os.Process; @@ -54,8 +55,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub {      private boolean mBluetoothPendingStats;      private BluetoothHeadset mBluetoothHeadset; -    BatteryStatsService(String filename) { -        mStats = new BatteryStatsImpl(filename); +    BatteryStatsService(String filename, Handler handler) { +        mStats = new BatteryStatsImpl(filename, handler);      }      public void publish(Context context) { 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..aef9e5c38e6f 100644 --- a/services/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -33,6 +33,7 @@ import android.content.pm.ResolveInfo;  import android.os.Bundle;  import android.os.Handler;  import android.os.IBinder; +import android.os.Looper;  import android.os.Message;  import android.os.Process;  import android.os.RemoteException; @@ -132,7 +133,14 @@ public final class BroadcastQueue {      static final int BROADCAST_INTENT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG;      static final int BROADCAST_TIMEOUT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 1; -    final Handler mHandler = new Handler() { +    final BroadcastHandler mHandler; + +    private final class BroadcastHandler extends Handler { +        public BroadcastHandler(Looper looper) { +            super(looper, null, true); +        } + +        @Override          public void handleMessage(Message msg) {              switch (msg.what) {                  case BROADCAST_INTENT_MSG: { @@ -164,9 +172,10 @@ public final class BroadcastQueue {          }      } -    BroadcastQueue(ActivityManagerService service, String name, long timeoutPeriod, -            boolean allowDelayBehindServices) { +    BroadcastQueue(ActivityManagerService service, Handler handler, +            String name, long timeoutPeriod, boolean allowDelayBehindServices) {          mService = service; +        mHandler = new BroadcastHandler(handler.getLooper());          mQueueName = name;          mTimeoutPeriod = timeoutPeriod;          mDelayBehindServices = allowDelayBehindServices; 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..207d6306334b 100644 --- a/services/java/com/android/server/am/CompatModePackages.java +++ b/services/core/java/com/android/server/am/CompatModePackages.java @@ -19,6 +19,7 @@ import android.content.pm.ApplicationInfo;  import android.content.pm.IPackageManager;  import android.content.res.CompatibilityInfo;  import android.os.Handler; +import android.os.Looper;  import android.os.Message;  import android.os.RemoteException;  import android.util.AtomicFile; @@ -41,22 +42,27 @@ public final class CompatModePackages {      private static final int MSG_WRITE = ActivityManagerService.FIRST_COMPAT_MODE_MSG; -    private final Handler mHandler = new Handler() { -        @Override public void handleMessage(Message msg) { +    private final CompatHandler mHandler; + +    private final class CompatHandler extends Handler { +        public CompatHandler(Looper looper) { +            super(looper, null, true); +        } + +        @Override +        public void handleMessage(Message msg) {              switch (msg.what) {                  case MSG_WRITE:                      saveCompatModes();                      break; -                default: -                    super.handleMessage(msg); -                    break;              }          }      }; -    public CompatModePackages(ActivityManagerService service, File systemDir) { +    public CompatModePackages(ActivityManagerService service, File systemDir, Handler handler) {          mService = service;          mFile = new AtomicFile(new File(systemDir, "packages-compat.xml")); +        mHandler = new CompatHandler(handler.getLooper());          FileInputStream fis = null;          try { 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..b12843bcf678 100644 --- a/services/java/com/android/server/am/NativeCrashListener.java +++ b/services/core/java/com/android/server/am/NativeCrashListener.java @@ -95,8 +95,8 @@ final class NativeCrashListener extends Thread {       * Daemon thread that accept()s incoming domain socket connections from debuggerd       * and processes the crash dump that is passed through.       */ -    NativeCrashListener() { -        mAm = ActivityManagerService.self(); +    NativeCrashListener(ActivityManagerService am) { +        mAm = am;      }      @Override diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 17f24a928b90..00fa21658e51 100644 --- a/services/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -17,6 +17,7 @@  package com.android.server.am;  import android.app.ActivityManager; +import android.app.IActivityContainer;  import android.content.IIntentSender;  import android.content.IIntentReceiver;  import android.app.PendingIntent; @@ -190,13 +191,13 @@ final class PendingIntentRecord extends IIntentSender.Stub {      public int send(int code, Intent intent, String resolvedType,              IIntentReceiver finishedReceiver, String requiredPermission) {          return sendInner(code, intent, resolvedType, finishedReceiver, -                requiredPermission, null, null, 0, 0, 0, null); +                requiredPermission, null, null, 0, 0, 0, null, null);      }      int sendInner(int code, Intent intent, String resolvedType,              IIntentReceiver finishedReceiver, String requiredPermission,              IBinder resultTo, String resultWho, int requestCode, -            int flagsMask, int flagsValues, Bundle options) { +            int flagsMask, int flagsValues, Bundle options, IActivityContainer container) {          synchronized(owner) {              if (!canceled) {                  sent = true; @@ -251,7 +252,7 @@ final class PendingIntentRecord extends IIntentSender.Stub {                              } else {                                  owner.startActivityInPackage(uid, key.packageName, finalIntent,                                          resolvedType, resultTo, resultWho, requestCode, 0, -                                        options, userId); +                                        options, userId, container);                              }                          } catch (RuntimeException e) {                              Slog.w(ActivityManagerService.TAG, @@ -302,7 +303,8 @@ final class PendingIntentRecord extends IIntentSender.Stub {          }          return ActivityManager.START_CANCELED;      } -     + +    @Override      protected void finalize() throws Throwable {          try {              if (!canceled) { 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 d3777c7ae134..f5920c8db355 100644 --- a/services/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -18,6 +18,8 @@ package com.android.server.am;  import java.io.FileOutputStream;  import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer;  import android.app.ActivityManager;  import com.android.internal.util.MemInfoReader; @@ -26,6 +28,8 @@ import com.android.server.wm.WindowManagerService;  import android.content.res.Resources;  import android.graphics.Point;  import android.os.SystemProperties; +import android.net.LocalSocketAddress; +import android.net.LocalSocket;  import android.util.Slog;  import android.view.Display; @@ -141,6 +145,16 @@ final class ProcessList {      // Threshold of number of cached+empty where we consider memory critical.      static final int TRIM_LOW_THRESHOLD = 5; +    // Low Memory Killer Daemon command codes. +    // These must be kept in sync with the definitions in lmkd.c +    // +    // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs) +    // LMK_PROCPRIO <pid> <prio> +    // LMK_PROCREMOVE <pid> +    static final byte LMK_TARGET = 0; +    static final byte LMK_PROCPRIO = 1; +    static final byte LMK_PROCREMOVE = 2; +      // These are the various interesting memory levels that we will give to      // the OOM killer.  Note that the OOM killer only supports 6 slots, so we      // can't give it a different value for every possible kind of process. @@ -150,18 +164,18 @@ final class ProcessList {      };      // These are the low-end OOM level limits.  This is appropriate for an      // HVGA or smaller phone with less than 512MB.  Values are in KB. -    private final long[] mOomMinFreeLow = new long[] { +    private final int[] mOomMinFreeLow = new int[] {              8192, 12288, 16384,              24576, 28672, 32768      };      // These are the high-end OOM level limits.  This is appropriate for a      // 1280x800 or larger screen with around 1GB RAM.  Values are in KB. -    private final long[] mOomMinFreeHigh = new long[] { +    private final int[] mOomMinFreeHigh = new int[] {              49152, 61440, 73728,              86016, 98304, 122880      };      // The actual OOM killer memory levels we are using. -    private final long[] mOomMinFree = new long[mOomAdj.length]; +    private final int[] mOomMinFree = new int[mOomAdj.length];      private final long mTotalMemMb; @@ -169,6 +183,9 @@ final class ProcessList {      private boolean mHaveDisplaySize; +    private static LocalSocket sLmkdSocket; +    private static OutputStream sLmkdOutputStream; +      ProcessList() {          MemInfoReader minfo = new MemInfoReader();          minfo.readMemInfo(); @@ -202,9 +219,6 @@ final class ProcessList {                      + " dh=" + displayHeight);          } -        StringBuilder adjString = new StringBuilder(); -        StringBuilder memString = new StringBuilder(); -          float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;          if (scale < 0) scale = 0;          else if (scale > 1) scale = 1; @@ -217,20 +231,20 @@ final class ProcessList {          }          for (int i=0; i<mOomAdj.length; i++) { -            long low = mOomMinFreeLow[i]; -            long high = mOomMinFreeHigh[i]; -            mOomMinFree[i] = (long)(low + ((high-low)*scale)); +            int low = mOomMinFreeLow[i]; +            int high = mOomMinFreeHigh[i]; +            mOomMinFree[i] = (int)(low + ((high-low)*scale));          }          if (minfree_abs >= 0) {              for (int i=0; i<mOomAdj.length; i++) { -                mOomMinFree[i] = (long)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); +                mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]);              }          }          if (minfree_adj != 0) {              for (int i=0; i<mOomAdj.length; i++) { -                mOomMinFree[i] += (long)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); +                mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]);                  if (mOomMinFree[i] < 0) {                      mOomMinFree[i] = 0;                  } @@ -242,15 +256,6 @@ final class ProcessList {          // before killing background processes.          mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024) / 3; -        for (int i=0; i<mOomAdj.length; i++) { -            if (i > 0) { -                adjString.append(','); -                memString.append(','); -            } -            adjString.append(mOomAdj[i]); -            memString.append((mOomMinFree[i]*1024)/PAGE_SIZE); -        } -          // Ask the kernel to try to keep enough memory free to allocate 3 full          // screen 32bpp buffers without entering direct reclaim.          int reserve = displayWidth * displayHeight * 4 * 3 / 1024; @@ -268,10 +273,15 @@ final class ProcessList {              }          } -        //Slog.i("XXXXXXX", "******************************* MINFREE: " + memString);          if (write) { -            writeFile("/sys/module/lowmemorykiller/parameters/adj", adjString.toString()); -            writeFile("/sys/module/lowmemorykiller/parameters/minfree", memString.toString()); +            ByteBuffer buf = ByteBuffer.allocate(4 * (2*mOomAdj.length + 1)); +            buf.putInt(LMK_TARGET); +            for (int i=0; i<mOomAdj.length; i++) { +                buf.putInt((mOomMinFree[i]*1024)/PAGE_SIZE); +                buf.putInt(mOomAdj[i]); +            } + +            writeLmkd(buf);              SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));          }          // GB: 2048,3072,4096,6144,7168,8192 @@ -506,19 +516,78 @@ final class ProcessList {          return mCachedRestoreLevel;      } -    private void writeFile(String path, String data) { -        FileOutputStream fos = null; +    /** +     * Set the out-of-memory badness adjustment for a process. +     * +     * @param pid The process identifier to set. +     * @param amt Adjustment value -- lmkd allows -16 to +15. +     * +     * {@hide} +     */ +    public static final void setOomAdj(int pid, int amt) { +        if (amt == UNKNOWN_ADJ) +            return; + +        ByteBuffer buf = ByteBuffer.allocate(4 * 3); +        buf.putInt(LMK_PROCPRIO); +        buf.putInt(pid); +        buf.putInt(amt); +        writeLmkd(buf); +    } + +    /* +     * {@hide} +     */ +    public static final void remove(int pid) { +        ByteBuffer buf = ByteBuffer.allocate(4 * 2); +        buf.putInt(LMK_PROCREMOVE); +        buf.putInt(pid); +        writeLmkd(buf); +    } + +    private static boolean openLmkdSocket() {          try { -            fos = new FileOutputStream(path); -            fos.write(data.getBytes()); -        } catch (IOException e) { -            Slog.w(ActivityManagerService.TAG, "Unable to write " + path); -        } finally { -            if (fos != null) { +            sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET); +            sLmkdSocket.connect( +                new LocalSocketAddress("lmkd", +                        LocalSocketAddress.Namespace.RESERVED)); +            sLmkdOutputStream = sLmkdSocket.getOutputStream(); +        } catch (IOException ex) { +            Slog.w(ActivityManagerService.TAG, +                   "lowmemorykiller daemon socket open failed"); +            sLmkdSocket = null; +            return false; +        } + +        return true; +    } + +    private static void writeLmkd(ByteBuffer buf) { + +        for (int i = 0; i < 3; i++) { +            if (sLmkdSocket == null) { +                    if (openLmkdSocket() == false) { +                        try { +                            Thread.sleep(1000); +                        } catch (InterruptedException ie) { +                        } +                        continue; +                    } +            } + +            try { +                sLmkdOutputStream.write(buf.array(), 0, buf.position()); +                return; +            } catch (IOException ex) { +                Slog.w(ActivityManagerService.TAG, +                       "Error writing to lowmemorykiller socket"); +                  try { -                    fos.close(); -                } catch (IOException e) { +                    sLmkdSocket.close(); +                } catch (IOException ex2) {                  } + +                sLmkdSocket = null;              }          }      } 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..9ec1122b7859 100644 --- a/services/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java @@ -17,6 +17,7 @@  package com.android.server.display;  import android.graphics.Rect; +import android.hardware.display.DisplayViewport;  import android.os.IBinder;  import android.view.Surface;  import android.view.SurfaceControl; diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java index 11c5d879b498..75f1f53f79db 100644 --- a/services/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java @@ -16,6 +16,7 @@  package com.android.server.display; +import android.hardware.display.DisplayViewport;  import android.util.DisplayMetrics;  import android.view.Display;  import android.view.Surface; @@ -63,6 +64,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 +80,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 +305,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..6be6405daa4d 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -23,14 +23,20 @@ import android.content.Context;  import android.content.pm.PackageManager;  import android.hardware.display.DisplayManager;  import android.hardware.display.DisplayManagerGlobal; +import android.hardware.display.DisplayManagerInternal; +import android.hardware.display.DisplayViewport; +import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;  import android.hardware.display.IDisplayManager;  import android.hardware.display.IDisplayManagerCallback;  import android.hardware.display.WifiDisplayStatus; +import android.hardware.input.InputManagerInternal;  import android.os.Binder;  import android.os.Handler;  import android.os.IBinder; +import android.os.IBinder.DeathRecipient;  import android.os.Looper;  import android.os.Message; +import android.os.Process;  import android.os.RemoteException;  import android.os.SystemClock;  import android.os.SystemProperties; @@ -41,7 +47,11 @@ import android.util.SparseArray;  import android.view.Display;  import android.view.DisplayInfo;  import android.view.Surface; +import android.view.WindowManagerInternal; +import com.android.server.DisplayThread; +import com.android.server.LocalServices; +import com.android.server.SystemService;  import com.android.server.UiThread;  import java.io.FileDescriptor; @@ -93,7 +103,7 @@ import java.util.concurrent.CopyOnWriteArrayList;   * avoid this by making all potentially reentrant out-calls asynchronous.   * </p>   */ -public final class DisplayManagerService extends IDisplayManager.Stub { +public final class DisplayManagerService extends SystemService {      private static final String TAG = "DisplayManagerService";      private static final boolean DEBUG = false; @@ -102,7 +112,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,12 +125,11 @@ 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; -    private WindowManagerFuncs mWindowManagerFuncs; -    private InputManagerFuncs mInputManagerFuncs; +    private WindowManagerInternal mWindowManagerInternal; +    private InputManagerInternal mInputManagerInternal;      // The synchronization root for the display manager.      // This lock guards most of the display manager's state. @@ -200,59 +208,52 @@ public final class DisplayManagerService extends IDisplayManager.Stub {      private final DisplayViewport mTempDefaultViewport = new DisplayViewport();      private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport(); -    public DisplayManagerService(Context context, Handler mainHandler) { +    public DisplayManagerService(Context context) { +        super(context);          mContext = context; -        mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1"); - -        mHandler = new DisplayManagerHandler(mainHandler.getLooper()); +        mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());          mUiHandler = UiThread.getHandler();          mDisplayAdapterListener = new DisplayAdapterListener();          mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false); +    } +    @Override +    public void onStart() {          mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER); + +        publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), +                true /*allowIsolated*/); +        publishLocalService(DisplayManagerInternal.class, new LocalService());      } -    /** -     * Pauses the boot process to wait for the first display to be initialized. -     */ -    public boolean waitForDefaultDisplay() { -        synchronized (mSyncRoot) { -            long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; -            while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) { -                long delay = timeout - SystemClock.uptimeMillis(); -                if (delay <= 0) { -                    return false; -                } -                if (DEBUG) { -                    Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay); -                } -                try { -                    mSyncRoot.wait(delay); -                } catch (InterruptedException ex) { +    @Override +    public void onBootPhase(int phase) { +        if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) { +            synchronized (mSyncRoot) { +                long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; +                while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) { +                    long delay = timeout - SystemClock.uptimeMillis(); +                    if (delay <= 0) { +                        throw new RuntimeException("Timeout waiting for default display " +                                + "to be initialized."); +                    } +                    if (DEBUG) { +                        Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay); +                    } +                    try { +                        mSyncRoot.wait(delay); +                    } catch (InterruptedException ex) { +                    }                  }              }          } -        return true;      } -    /** -     * Called during initialization to associate the display manager with the -     * window manager. -     */ -    public void setWindowManager(WindowManagerFuncs windowManagerFuncs) { +    // TODO: Use dependencies or a boot phase +    public void windowManagerAndInputReady() {          synchronized (mSyncRoot) { -            mWindowManagerFuncs = windowManagerFuncs; -            scheduleTraversalLocked(false); -        } -    } - -    /** -     * Called during initialization to associate the display manager with the -     * input manager. -     */ -    public void setInputManager(InputManagerFuncs inputManagerFuncs) { -        synchronized (mSyncRoot) { -            mInputManagerFuncs = inputManagerFuncs; +            mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); +            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);              scheduleTraversalLocked(false);          }      } @@ -269,59 +270,19 @@ public final class DisplayManagerService extends IDisplayManager.Stub {          mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);      } -    /** -     * 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. -     * -     * @param listener The listener to register. -     */ -    public void registerDisplayTransactionListener(DisplayTransactionListener listener) { -        if (listener == null) { -            throw new IllegalArgumentException("listener must not be null"); -        } - +    private void registerDisplayTransactionListenerInternal( +            DisplayTransactionListener listener) {          // List is self-synchronized copy-on-write.          mDisplayTransactionListeners.add(listener);      } -    /** -     * Unregisters a display transaction listener to provide the client a chance to -     * update its surfaces within the same transaction as any display layout updates. -     * -     * @param listener The listener to unregister. -     */ -    public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) { -        if (listener == null) { -            throw new IllegalArgumentException("listener must not be null"); -        } - +    private void unregisterDisplayTransactionListenerInternal( +            DisplayTransactionListener listener) {          // List is self-synchronized copy-on-write.          mDisplayTransactionListeners.remove(listener);      } -    /** -     * Overrides the display information of a particular logical display. -     * This is used by the window manager to control the size and characteristics -     * of the default display.  It is expected to apply the requested change -     * to the display information synchronously so that applications will immediately -     * observe the new state. -     * -     * NOTE: This method must be the only entry point by which the window manager -     * influences the logical configuration of displays. -     * -     * @param displayId The logical display id. -     * @param info The new data to be stored. -     */ -    public void setDisplayInfoOverrideFromWindowManager( +    private void setDisplayInfoOverrideFromWindowManagerInternal(              int displayId, DisplayInfo info) {          synchronized (mSyncRoot) {              LogicalDisplay display = mLogicalDisplays.get(displayId); @@ -334,11 +295,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub {          }      } -    /** -     * Called by the window manager to perform traversals while holding a -     * surface flinger transaction. -     */ -    public void performTraversalInTransactionFromWindowManager() { +    private void performTraversalInTransactionFromWindowManagerInternal() {          synchronized (mSyncRoot) {              if (!mPendingTraversal) {                  return; @@ -354,10 +311,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub {          }      } -    /** -     * Called by the power manager to blank all displays. -     */ -    public void blankAllDisplaysFromPowerManager() { +    private void blankAllDisplaysFromPowerManagerInternal() {          synchronized (mSyncRoot) {              if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_BLANKED) {                  mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_BLANKED; @@ -367,10 +321,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub {          }      } -    /** -     * Called by the power manager to unblank all displays. -     */ -    public void unblankAllDisplaysFromPowerManager() { +    private void unblankAllDisplaysFromPowerManagerInternal() {          synchronized (mSyncRoot) {              if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_UNBLANKED) {                  mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNBLANKED; @@ -380,70 +331,40 @@ public final class DisplayManagerService extends IDisplayManager.Stub {          }      } -    /** -     * Returns information about the specified logical display. -     * -     * @param displayId The logical display id. -     * @return The logical display info, or null if the display does not exist.  The -     * returned object must be treated as immutable. -     */ -    @Override // Binder call -    public DisplayInfo getDisplayInfo(int displayId) { -        final int callingUid = Binder.getCallingUid(); -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                LogicalDisplay display = mLogicalDisplays.get(displayId); -                if (display != null) { -                    DisplayInfo info = display.getDisplayInfoLocked(); -                    if (info.hasAccess(callingUid)) { -                        return info; -                    } +    private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) { +        synchronized (mSyncRoot) { +            LogicalDisplay display = mLogicalDisplays.get(displayId); +            if (display != null) { +                DisplayInfo info = display.getDisplayInfoLocked(); +                if (info.hasAccess(callingUid)) { +                    return info;                  } -                return null;              } -        } finally { -            Binder.restoreCallingIdentity(token); +            return null;          }      } -    /** -     * Returns the list of all display ids. -     */ -    @Override // Binder call -    public int[] getDisplayIds() { -        final int callingUid = Binder.getCallingUid(); -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                final int count = mLogicalDisplays.size(); -                int[] displayIds = new int[count]; -                int n = 0; -                for (int i = 0; i < count; i++) { -                    LogicalDisplay display = mLogicalDisplays.valueAt(i); -                    DisplayInfo info = display.getDisplayInfoLocked(); -                    if (info.hasAccess(callingUid)) { -                        displayIds[n++] = mLogicalDisplays.keyAt(i); -                    } -                } -                if (n != count) { -                    displayIds = Arrays.copyOfRange(displayIds, 0, n); +    private int[] getDisplayIdsInternal(int callingUid) { +        synchronized (mSyncRoot) { +            final int count = mLogicalDisplays.size(); +            int[] displayIds = new int[count]; +            int n = 0; +            for (int i = 0; i < count; i++) { +                LogicalDisplay display = mLogicalDisplays.valueAt(i); +                DisplayInfo info = display.getDisplayInfoLocked(); +                if (info.hasAccess(callingUid)) { +                    displayIds[n++] = mLogicalDisplays.keyAt(i);                  } -                return displayIds;              } -        } finally { -            Binder.restoreCallingIdentity(token); +            if (n != count) { +                displayIds = Arrays.copyOfRange(displayIds, 0, n); +            } +            return displayIds;          }      } -    @Override // Binder call -    public void registerCallback(IDisplayManagerCallback callback) { -        if (callback == null) { -            throw new IllegalArgumentException("listener must not be null"); -        } - +    private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) {          synchronized (mSyncRoot) { -            int callingPid = Binder.getCallingPid();              if (mCallbacks.get(callingPid) != null) {                  throw new SecurityException("The calling process has already "                          + "registered an IDisplayManagerCallback."); @@ -469,24 +390,14 @@ public final class DisplayManagerService extends IDisplayManager.Stub {          }      } -    @Override // Binder call -    public void startWifiDisplayScan() { -        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, -                "Permission required to start wifi display scans"); - -        final int callingPid = Binder.getCallingPid(); -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                CallbackRecord record = mCallbacks.get(callingPid); -                if (record == null) { -                    throw new IllegalStateException("The calling process has not " -                            + "registered an IDisplayManagerCallback."); -                } -                startWifiDisplayScanLocked(record); +    private void startWifiDisplayScanInternal(int callingPid) { +        synchronized (mSyncRoot) { +            CallbackRecord record = mCallbacks.get(callingPid); +            if (record == null) { +                throw new IllegalStateException("The calling process has not " +                        + "registered an IDisplayManagerCallback.");              } -        } finally { -            Binder.restoreCallingIdentity(token); +            startWifiDisplayScanLocked(record);          }      } @@ -501,24 +412,14 @@ public final class DisplayManagerService extends IDisplayManager.Stub {          }      } -    @Override // Binder call -    public void stopWifiDisplayScan() { -        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, -                "Permission required to stop wifi display scans"); - -        final int callingPid = Binder.getCallingPid(); -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                CallbackRecord record = mCallbacks.get(callingPid); -                if (record == null) { -                    throw new IllegalStateException("The calling process has not " -                            + "registered an IDisplayManagerCallback."); -                } -                stopWifiDisplayScanLocked(record); +    private void stopWifiDisplayScanInternal(int callingPid) { +        synchronized (mSyncRoot) { +            CallbackRecord record = mCallbacks.get(callingPid); +            if (record == null) { +                throw new IllegalStateException("The calling process has not " +                        + "registered an IDisplayManagerCallback.");              } -        } finally { -            Binder.restoreCallingIdentity(token); +            stopWifiDisplayScanLocked(record);          }      } @@ -537,255 +438,113 @@ public final class DisplayManagerService extends IDisplayManager.Stub {          }      } -    @Override // Binder call -    public void connectWifiDisplay(String address) { -        if (address == null) { -            throw new IllegalArgumentException("address must not be null"); -        } -        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, -                "Permission required to connect to a wifi display"); - -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                if (mWifiDisplayAdapter != null) { -                    mWifiDisplayAdapter.requestConnectLocked(address); -                } +    private void connectWifiDisplayInternal(String address) { +        synchronized (mSyncRoot) { +            if (mWifiDisplayAdapter != null) { +                mWifiDisplayAdapter.requestConnectLocked(address);              } -        } finally { -            Binder.restoreCallingIdentity(token);          }      } -    @Override -    public void pauseWifiDisplay() { -        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, -                "Permission required to pause a wifi display session"); - -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                if (mWifiDisplayAdapter != null) { -                    mWifiDisplayAdapter.requestPauseLocked(); -                } +    private void pauseWifiDisplayInternal() { +        synchronized (mSyncRoot) { +            if (mWifiDisplayAdapter != null) { +                mWifiDisplayAdapter.requestPauseLocked();              } -        } finally { -            Binder.restoreCallingIdentity(token);          }      } -    @Override -    public void resumeWifiDisplay() { -        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, -                "Permission required to resume a wifi display session"); - -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                if (mWifiDisplayAdapter != null) { -                    mWifiDisplayAdapter.requestResumeLocked(); -                } +    private void resumeWifiDisplayInternal() { +        synchronized (mSyncRoot) { +            if (mWifiDisplayAdapter != null) { +                mWifiDisplayAdapter.requestResumeLocked();              } -        } finally { -            Binder.restoreCallingIdentity(token);          }      } -    @Override // Binder call -    public void disconnectWifiDisplay() { -        // This request does not require special permissions. -        // Any app can request disconnection from the currently active wifi display. -        // This exception should no longer be needed once wifi display control moves -        // to the media router service. - -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                if (mWifiDisplayAdapter != null) { -                    mWifiDisplayAdapter.requestDisconnectLocked(); -                } +    private void disconnectWifiDisplayInternal() { +        synchronized (mSyncRoot) { +            if (mWifiDisplayAdapter != null) { +                mWifiDisplayAdapter.requestDisconnectLocked();              } -        } finally { -            Binder.restoreCallingIdentity(token);          }      } -    @Override // Binder call -    public void renameWifiDisplay(String address, String alias) { -        if (address == null) { -            throw new IllegalArgumentException("address must not be null"); -        } -        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, -                "Permission required to rename to a wifi display"); - -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                if (mWifiDisplayAdapter != null) { -                    mWifiDisplayAdapter.requestRenameLocked(address, alias); -                } +    private void renameWifiDisplayInternal(String address, String alias) { +        synchronized (mSyncRoot) { +            if (mWifiDisplayAdapter != null) { +                mWifiDisplayAdapter.requestRenameLocked(address, alias);              } -        } finally { -            Binder.restoreCallingIdentity(token);          }      } -    @Override // Binder call -    public void forgetWifiDisplay(String address) { -        if (address == null) { -            throw new IllegalArgumentException("address must not be null"); -        } -        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, -                "Permission required to forget to a wifi display"); - -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                if (mWifiDisplayAdapter != null) { -                    mWifiDisplayAdapter.requestForgetLocked(address); -                } +    private void forgetWifiDisplayInternal(String address) { +        synchronized (mSyncRoot) { +            if (mWifiDisplayAdapter != null) { +                mWifiDisplayAdapter.requestForgetLocked(address);              } -        } finally { -            Binder.restoreCallingIdentity(token);          }      } -    @Override // Binder call -    public WifiDisplayStatus getWifiDisplayStatus() { -        // This request does not require special permissions. -        // Any app can get information about available wifi displays. - -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                if (mWifiDisplayAdapter != null) { -                    return mWifiDisplayAdapter.getWifiDisplayStatusLocked(); -                } -                return new WifiDisplayStatus(); +    private WifiDisplayStatus getWifiDisplayStatusInternal() { +        synchronized (mSyncRoot) { +            if (mWifiDisplayAdapter != null) { +                return mWifiDisplayAdapter.getWifiDisplayStatusLocked();              } -        } finally { -            Binder.restoreCallingIdentity(token); +            return new WifiDisplayStatus();          }      } -    @Override // Binder call -    public int createVirtualDisplay(IBinder appToken, String packageName, +    private int createVirtualDisplayInternal(IBinder appToken, int callingUid, String packageName,              String name, int width, int height, int densityDpi, Surface surface, int flags) { -        final int callingUid = Binder.getCallingUid(); -        if (!validatePackageName(callingUid, packageName)) { -            throw new SecurityException("packageName must match the calling uid"); -        } -        if (appToken == null) { -            throw new IllegalArgumentException("appToken must not be null"); -        } -        if (TextUtils.isEmpty(name)) { -            throw new IllegalArgumentException("name must be non-null and non-empty"); -        } -        if (width <= 0 || height <= 0 || densityDpi <= 0) { -            throw new IllegalArgumentException("width, height, and densityDpi must be " -                    + "greater than 0"); -        } -        if (surface == null) { -            throw new IllegalArgumentException("surface must not be null"); -        } -        if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { -            if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT) -                    != PackageManager.PERMISSION_GRANTED -                    && mContext.checkCallingPermission( -                            android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT) -                            != PackageManager.PERMISSION_GRANTED) { -                throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or " -                        + "CAPTURE_SECURE_VIDEO_OUTPUT permission to create a " -                        + "public virtual display."); -            } -        } -        if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { -            if (mContext.checkCallingPermission( -                    android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT) -                    != PackageManager.PERMISSION_GRANTED) { -                throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT " -                        + "to create a secure virtual display."); +        synchronized (mSyncRoot) { +            if (mVirtualDisplayAdapter == null) { +                Slog.w(TAG, "Rejecting request to create private virtual display " +                        + "because the virtual display adapter is not available."); +                return -1;              } -        } -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                if (mVirtualDisplayAdapter == null) { -                    Slog.w(TAG, "Rejecting request to create private virtual display " -                            + "because the virtual display adapter is not available."); -                    return -1; -                } - -                DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked( -                        appToken, callingUid, packageName, name, width, height, densityDpi, -                        surface, flags); -                if (device == null) { -                    return -1; -                } - -                handleDisplayDeviceAddedLocked(device); -                LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); -                if (display != null) { -                    return display.getDisplayIdLocked(); -                } +            DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked( +                    appToken, callingUid, packageName, name, width, height, densityDpi, +                    surface, flags); +            if (device == null) { +                return -1; +            } -                // Something weird happened and the logical display was not created. -                Slog.w(TAG, "Rejecting request to create virtual display " -                        + "because the logical display was not created."); -                mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); -                handleDisplayDeviceRemovedLocked(device); +            handleDisplayDeviceAddedLocked(device); +            LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); +            if (display != null) { +                return display.getDisplayIdLocked();              } -        } finally { -            Binder.restoreCallingIdentity(token); + +            // Something weird happened and the logical display was not created. +            Slog.w(TAG, "Rejecting request to create virtual display " +                    + "because the logical display was not created."); +            mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); +            handleDisplayDeviceRemovedLocked(device);          }          return -1;      } -    @Override // Binder call -    public void releaseVirtualDisplay(IBinder appToken) { -        final long token = Binder.clearCallingIdentity(); -        try { -            synchronized (mSyncRoot) { -                if (mVirtualDisplayAdapter == null) { -                    return; -                } - -                DisplayDevice device = -                        mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); -                if (device != null) { -                    handleDisplayDeviceRemovedLocked(device); -                } +    private void releaseVirtualDisplayInternal(IBinder appToken) { +        synchronized (mSyncRoot) { +            if (mVirtualDisplayAdapter == null) { +                return;              } -        } finally { -            Binder.restoreCallingIdentity(token); -        } -    } -    private boolean validatePackageName(int uid, String packageName) { -        if (packageName != null) { -            String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); -            if (packageNames != null) { -                for (String n : packageNames) { -                    if (n.equals(packageName)) { -                        return true; -                    } -                } +            DisplayDevice device = +                    mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); +            if (device != null) { +                handleDisplayDeviceRemovedLocked(device);              }          } -        return false;      }      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));          }      } @@ -1002,26 +761,13 @@ public final class DisplayManagerService extends IDisplayManager.Stub {          }          // Tell the input system about these new viewports. -        if (mInputManagerFuncs != null) { +        if (mInputManagerInternal != null) {              mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);          }      } -    /** -     * Tells the display manager whether there is interesting unique content on the -     * specified logical display.  This is used to control automatic mirroring. -     * <p> -     * If the display has unique content, then the display manager arranges for it -     * to be presented on a physical display if appropriate.  Otherwise, the display manager -     * may choose to make the physical display mirror some other logical display. -     * </p> -     * -     * @param displayId The logical display id to update. -     * @param hasContent True if the logical display has content. -     * @param inTraversal True if called from WindowManagerService during a window traversal prior -     * to call to performTraversalInTransactionFromWindowManager. -     */ -    public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) { +    private void setDisplayHasContentInternal(int displayId, boolean hasContent, +            boolean inTraversal) {          synchronized (mSyncRoot) {              LogicalDisplay display = mLogicalDisplays.get(displayId);              if (display != null && display.hasContentLocked() != hasContent) { @@ -1042,13 +788,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. @@ -1107,7 +853,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub {      // Requests that performTraversalsInTransactionFromWindowManager be called at a      // later time to apply changes to surfaces and displays.      private void scheduleTraversalLocked(boolean inTraversal) { -        if (!mPendingTraversal && mWindowManagerFuncs != null) { +        if (!mPendingTraversal && mWindowManagerInternal != null) {              mPendingTraversal = true;              if (!inTraversal) {                  mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL); @@ -1140,20 +886,10 @@ public final class DisplayManagerService extends IDisplayManager.Stub {          mTempCallbacks.clear();      } -    @Override // Binder call -    public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { -        if (mContext == null -                || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) -                        != PackageManager.PERMISSION_GRANTED) { -            pw.println("Permission Denial: can't dump DisplayManager from from pid=" -                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); -            return; -        } - +    private void dumpInternal(PrintWriter pw) {          pw.println("DISPLAY MANAGER (dumpsys display)");          synchronized (mSyncRoot) { -            pw.println("  mHeadless=" + mHeadless);              pw.println("  mOnlyCode=" + mOnlyCore);              pw.println("  mSafeMode=" + mSafeMode);              pw.println("  mPendingTraversal=" + mPendingTraversal); @@ -1212,30 +948,6 @@ public final class DisplayManagerService extends IDisplayManager.Stub {      public static final class SyncRoot {      } -    /** -     * Private interface to the window manager. -     */ -    public interface WindowManagerFuncs { -        /** -         * Request that the window manager call -         * {@link #performTraversalInTransactionFromWindowManager} within a surface -         * transaction at a later time. -         */ -        void requestTraversal(); -    } - -    /** -     * Private interface to the input manager. -     */ -    public interface InputManagerFuncs { -        /** -         * Sets information about the displays as needed by the input system. -         * The input system should copy this information if required. -         */ -        void setDisplayViewports(DisplayViewport defaultViewport, -                DisplayViewport externalTouchViewport); -    } -      private final class DisplayManagerHandler extends Handler {          public DisplayManagerHandler(Looper looper) {              super(looper, null, true /*async*/); @@ -1257,7 +969,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub {                      break;                  case MSG_REQUEST_TRAVERSAL: -                    mWindowManagerFuncs.requestTraversal(); +                    mWindowManagerInternal.requestTraversalFromDisplayManager();                      break;                  case MSG_UPDATE_VIEWPORT: { @@ -1265,7 +977,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub {                          mTempDefaultViewport.copyFrom(mDefaultViewport);                          mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);                      } -                    mInputManagerFuncs.setDisplayViewports( +                    mInputManagerInternal.setDisplayViewports(                              mTempDefaultViewport, mTempExternalTouchViewport);                      break;                  } @@ -1328,4 +1040,325 @@ public final class DisplayManagerService extends IDisplayManager.Stub {              }          }      } + +    private final class BinderService extends IDisplayManager.Stub { +        /** +         * Returns information about the specified logical display. +         * +         * @param displayId The logical display id. +         * @return The logical display info, or null if the display does not exist.  The +         * returned object must be treated as immutable. +         */ +        @Override // Binder call +        public DisplayInfo getDisplayInfo(int displayId) { +            final int callingUid = Binder.getCallingUid(); +            final long token = Binder.clearCallingIdentity(); +            try { +                return getDisplayInfoInternal(displayId, callingUid); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        /** +         * Returns the list of all display ids. +         */ +        @Override // Binder call +        public int[] getDisplayIds() { +            final int callingUid = Binder.getCallingUid(); +            final long token = Binder.clearCallingIdentity(); +            try { +                return getDisplayIdsInternal(callingUid); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void registerCallback(IDisplayManagerCallback callback) { +            if (callback == null) { +                throw new IllegalArgumentException("listener must not be null"); +            } + +            final int callingPid = Binder.getCallingPid(); +            final long token = Binder.clearCallingIdentity(); +            try { +                registerCallbackInternal(callback, callingPid); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void startWifiDisplayScan() { +            mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, +                    "Permission required to start wifi display scans"); + +            final int callingPid = Binder.getCallingPid(); +            final long token = Binder.clearCallingIdentity(); +            try { +                startWifiDisplayScanInternal(callingPid); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void stopWifiDisplayScan() { +            mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, +                    "Permission required to stop wifi display scans"); + +            final int callingPid = Binder.getCallingPid(); +            final long token = Binder.clearCallingIdentity(); +            try { +                stopWifiDisplayScanInternal(callingPid); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void connectWifiDisplay(String address) { +            if (address == null) { +                throw new IllegalArgumentException("address must not be null"); +            } +            mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, +                    "Permission required to connect to a wifi display"); + +            final long token = Binder.clearCallingIdentity(); +            try { +                connectWifiDisplayInternal(address); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void disconnectWifiDisplay() { +            // This request does not require special permissions. +            // Any app can request disconnection from the currently active wifi display. +            // This exception should no longer be needed once wifi display control moves +            // to the media router service. + +            final long token = Binder.clearCallingIdentity(); +            try { +                disconnectWifiDisplayInternal(); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void renameWifiDisplay(String address, String alias) { +            if (address == null) { +                throw new IllegalArgumentException("address must not be null"); +            } +            mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, +                    "Permission required to rename to a wifi display"); + +            final long token = Binder.clearCallingIdentity(); +            try { +                renameWifiDisplayInternal(address, alias); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void forgetWifiDisplay(String address) { +            if (address == null) { +                throw new IllegalArgumentException("address must not be null"); +            } +            mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, +                    "Permission required to forget to a wifi display"); + +            final long token = Binder.clearCallingIdentity(); +            try { +                forgetWifiDisplayInternal(address); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void pauseWifiDisplay() { +            mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, +                    "Permission required to pause a wifi display session"); + +            final long token = Binder.clearCallingIdentity(); +            try { +                pauseWifiDisplayInternal(); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void resumeWifiDisplay() { +            mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, +                    "Permission required to resume a wifi display session"); + +            final long token = Binder.clearCallingIdentity(); +            try { +                resumeWifiDisplayInternal(); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public WifiDisplayStatus getWifiDisplayStatus() { +            // This request does not require special permissions. +            // Any app can get information about available wifi displays. + +            final long token = Binder.clearCallingIdentity(); +            try { +                return getWifiDisplayStatusInternal(); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public int createVirtualDisplay(IBinder appToken, String packageName, +                String name, int width, int height, int densityDpi, Surface surface, int flags) { +            final int callingUid = Binder.getCallingUid(); +            if (!validatePackageName(callingUid, packageName)) { +                throw new SecurityException("packageName must match the calling uid"); +            } +            if (appToken == null) { +                throw new IllegalArgumentException("appToken must not be null"); +            } +            if (TextUtils.isEmpty(name)) { +                throw new IllegalArgumentException("name must be non-null and non-empty"); +            } +            if (width <= 0 || height <= 0 || densityDpi <= 0) { +                throw new IllegalArgumentException("width, height, and densityDpi must be " +                        + "greater than 0"); +            } +            if (surface == null) { +                throw new IllegalArgumentException("surface must not be null"); +            } +            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( +                                android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT) +                                != PackageManager.PERMISSION_GRANTED) { +                    throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or " +                            + "CAPTURE_SECURE_VIDEO_OUTPUT permission to create a " +                            + "public virtual display."); +                } +            } +            if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { +                if (mContext.checkCallingPermission( +                        android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT) +                        != PackageManager.PERMISSION_GRANTED) { +                    throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT " +                            + "to create a secure virtual display."); +                } +            } + +            final long token = Binder.clearCallingIdentity(); +            try { +                return createVirtualDisplayInternal(appToken, callingUid, packageName, +                        name, width, height, densityDpi, surface, flags); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void releaseVirtualDisplay(IBinder appToken) { +            final long token = Binder.clearCallingIdentity(); +            try { +                releaseVirtualDisplayInternal(appToken); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        @Override // Binder call +        public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { +            if (mContext == null +                    || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) +                            != PackageManager.PERMISSION_GRANTED) { +                pw.println("Permission Denial: can't dump DisplayManager from from pid=" +                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); +                return; +            } + +            final long token = Binder.clearCallingIdentity(); +            try { +                dumpInternal(pw); +            } finally { +                Binder.restoreCallingIdentity(token); +            } +        } + +        private boolean validatePackageName(int uid, String packageName) { +            if (packageName != null) { +                String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); +                if (packageNames != null) { +                    for (String n : packageNames) { +                        if (n.equals(packageName)) { +                            return true; +                        } +                    } +                } +            } +            return false; +        } +    } + +    private final class LocalService extends DisplayManagerInternal { +        @Override +        public void blankAllDisplaysFromPowerManager() { +            blankAllDisplaysFromPowerManagerInternal(); +        } + +        @Override +        public void unblankAllDisplaysFromPowerManager() { +            unblankAllDisplaysFromPowerManagerInternal(); +        } + +        @Override +        public DisplayInfo getDisplayInfo(int displayId) { +            return getDisplayInfoInternal(displayId, Process.myUid()); +        } + +        @Override +        public void registerDisplayTransactionListener(DisplayTransactionListener listener) { +            if (listener == null) { +                throw new IllegalArgumentException("listener must not be null"); +            } + +            registerDisplayTransactionListenerInternal(listener); +        } + +        @Override +        public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) { +            if (listener == null) { +                throw new IllegalArgumentException("listener must not be null"); +            } + +            unregisterDisplayTransactionListenerInternal(listener); +        } + +        @Override +        public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) { +            setDisplayInfoOverrideFromWindowManagerInternal(displayId, info); +        } + +        @Override +        public void performTraversalInTransactionFromWindowManager() { +            performTraversalInTransactionFromWindowManagerInternal(); +        } + +        @Override +        public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) { +            setDisplayHasContentInternal(displayId, hasContent, inTraversal); +        } +    }  } 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/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java new file mode 100644 index 000000000000..ffb113cb6ab7 --- /dev/null +++ b/services/core/java/com/android/server/dreams/DreamManagerService.java @@ -0,0 +1,494 @@ +/* + * 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.dreams; + +import com.android.internal.util.DumpUtils; +import com.android.server.FgThread; +import com.android.server.SystemService; + +import android.Manifest; +import android.app.ActivityManager; +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.PackageManager.NameNotFoundException; +import android.os.Binder; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.PowerManager; +import android.os.SystemClock; +import android.os.UserHandle; +import android.provider.Settings; +import android.service.dreams.DreamManagerInternal; +import android.service.dreams.DreamService; +import android.service.dreams.IDreamManager; +import android.util.Slog; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +import libcore.util.Objects; + +/** + * Service api for managing dreams. + * + * @hide + */ +public final class DreamManagerService extends SystemService { +    private static final boolean DEBUG = false; +    private static final String TAG = "DreamManagerService"; + +    private final Object mLock = new Object(); + +    private final Context mContext; +    private final DreamHandler mHandler; +    private final DreamController mController; +    private final PowerManager mPowerManager; + +    private Binder mCurrentDreamToken; +    private ComponentName mCurrentDreamName; +    private int mCurrentDreamUserId; +    private boolean mCurrentDreamIsTest; + +    public DreamManagerService(Context context) { +        super(context); +        mContext = context; +        mHandler = new DreamHandler(FgThread.get().getLooper()); +        mController = new DreamController(context, mHandler, mControllerListener); + +        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); +    } + +    @Override +    public void onStart() { +        publishBinderService(DreamService.DREAM_SERVICE, new BinderService()); +        publishLocalService(DreamManagerInternal.class, new LocalService()); +    } + +    @Override +    public void onBootPhase(int phase) { +        if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { +            mContext.registerReceiver(new BroadcastReceiver() { +                @Override +                public void onReceive(Context context, Intent intent) { +                    synchronized (mLock) { +                        stopDreamLocked(); +                    } +                } +            }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); +        } +    } + +    private void dumpInternal(PrintWriter pw) { +        pw.println("DREAM MANAGER (dumpsys dreams)"); +        pw.println(); + +        pw.println("mCurrentDreamToken=" + mCurrentDreamToken); +        pw.println("mCurrentDreamName=" + mCurrentDreamName); +        pw.println("mCurrentDreamUserId=" + mCurrentDreamUserId); +        pw.println("mCurrentDreamIsTest=" + mCurrentDreamIsTest); +        pw.println(); + +        DumpUtils.dumpAsync(mHandler, new DumpUtils.Dump() { +            @Override +            public void dump(PrintWriter pw) { +                mController.dump(pw); +            } +        }, pw, 200); +    } + +    private boolean isDreamingInternal() { +        synchronized (mLock) { +            return mCurrentDreamToken != null && !mCurrentDreamIsTest; +        } +    } + +    private void requestDreamInternal() { +        // Ask the power manager to nap.  It will eventually call back into +        // startDream() if/when it is appropriate to start dreaming. +        // Because napping could cause the screen to turn off immediately if the dream +        // cannot be started, we keep one eye open and gently poke user activity. +        long time = SystemClock.uptimeMillis(); +        mPowerManager.userActivity(time, true /*noChangeLights*/); +        mPowerManager.nap(time); +    } + +    private void requestAwakenInternal() { +        // Treat an explicit request to awaken as user activity so that the +        // device doesn't immediately go to sleep if the timeout expired, +        // for example when being undocked. +        long time = SystemClock.uptimeMillis(); +        mPowerManager.userActivity(time, false /*noChangeLights*/); +        stopDreamInternal(); +    } + +    private void finishSelfInternal(IBinder token) { +        if (DEBUG) { +            Slog.d(TAG, "Dream finished: " + token); +        } + +        // Note that a dream finishing and self-terminating is not +        // itself considered user activity.  If the dream is ending because +        // the user interacted with the device then user activity will already +        // have been poked so the device will stay awake a bit longer. +        // If the dream is ending on its own for other reasons and no wake +        // locks are held and the user activity timeout has expired then the +        // device may simply go to sleep. +        synchronized (mLock) { +            if (mCurrentDreamToken == token) { +                stopDreamLocked(); +            } +        } +    } + +    private void testDreamInternal(ComponentName dream, int userId) { +        synchronized (mLock) { +            startDreamLocked(dream, true /*isTest*/, userId); +        } +    } + +    private void startDreamInternal() { +        int userId = ActivityManager.getCurrentUser(); +        ComponentName dream = chooseDreamForUser(userId); +        if (dream != null) { +            synchronized (mLock) { +                startDreamLocked(dream, false /*isTest*/, userId); +            } +        } +    } + +    private void stopDreamInternal() { +        synchronized (mLock) { +            stopDreamLocked(); +        } +    } + +    private ComponentName chooseDreamForUser(int userId) { +        ComponentName[] dreams = getDreamComponentsForUser(userId); +        return dreams != null && dreams.length != 0 ? dreams[0] : null; +    } + +    private ComponentName[] getDreamComponentsForUser(int userId) { +        String names = Settings.Secure.getStringForUser(mContext.getContentResolver(), +                Settings.Secure.SCREENSAVER_COMPONENTS, +                userId); +        ComponentName[] components = componentsFromString(names); + +        // first, ensure components point to valid services +        List<ComponentName> validComponents = new ArrayList<ComponentName>(); +        if (components != null) { +            for (ComponentName component : components) { +                if (serviceExists(component)) { +                    validComponents.add(component); +                } else { +                    Slog.w(TAG, "Dream " + component + " does not exist"); +                } +            } +        } + +        // fallback to the default dream component if necessary +        if (validComponents.isEmpty()) { +            ComponentName defaultDream = getDefaultDreamComponentForUser(userId); +            if (defaultDream != null) { +                Slog.w(TAG, "Falling back to default dream " + defaultDream); +                validComponents.add(defaultDream); +            } +        } +        return validComponents.toArray(new ComponentName[validComponents.size()]); +    } + +    private void setDreamComponentsForUser(int userId, ComponentName[] componentNames) { +        Settings.Secure.putStringForUser(mContext.getContentResolver(), +                Settings.Secure.SCREENSAVER_COMPONENTS, +                componentsToString(componentNames), +                userId); +    } + +    private ComponentName getDefaultDreamComponentForUser(int userId) { +        String name = Settings.Secure.getStringForUser(mContext.getContentResolver(), +                Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT, +                userId); +        return name == null ? null : ComponentName.unflattenFromString(name); +    } + +    private boolean serviceExists(ComponentName name) { +        try { +            return name != null && mContext.getPackageManager().getServiceInfo(name, 0) != null; +        } catch (NameNotFoundException e) { +            return false; +        } +    } + +    private void startDreamLocked(final ComponentName name, +            final boolean isTest, final int userId) { +        if (Objects.equal(mCurrentDreamName, name) +                && mCurrentDreamIsTest == isTest +                && mCurrentDreamUserId == userId) { +            return; +        } + +        stopDreamLocked(); + +        if (DEBUG) Slog.i(TAG, "Entering dreamland."); + +        final Binder newToken = new Binder(); +        mCurrentDreamToken = newToken; +        mCurrentDreamName = name; +        mCurrentDreamIsTest = isTest; +        mCurrentDreamUserId = userId; + +        mHandler.post(new Runnable() { +            @Override +            public void run() { +                mController.startDream(newToken, name, isTest, userId); +            } +        }); +    } + +    private void stopDreamLocked() { +        if (mCurrentDreamToken != null) { +            if (DEBUG) Slog.i(TAG, "Leaving dreamland."); + +            cleanupDreamLocked(); + +            mHandler.post(new Runnable() { +                @Override +                public void run() { +                    mController.stopDream(); +                } +            }); +        } +    } + +    private void cleanupDreamLocked() { +        mCurrentDreamToken = null; +        mCurrentDreamName = null; +        mCurrentDreamIsTest = false; +        mCurrentDreamUserId = 0; +    } + +    private void checkPermission(String permission) { +        if (mContext.checkCallingOrSelfPermission(permission) +                != PackageManager.PERMISSION_GRANTED) { +            throw new SecurityException("Access denied to process: " + Binder.getCallingPid() +                    + ", must have permission " + permission); +        } +    } + +    private static String componentsToString(ComponentName[] componentNames) { +        StringBuilder names = new StringBuilder(); +        if (componentNames != null) { +            for (ComponentName componentName : componentNames) { +                if (names.length() > 0) { +                    names.append(','); +                } +                names.append(componentName.flattenToString()); +            } +        } +        return names.toString(); +    } + +    private static ComponentName[] componentsFromString(String names) { +        if (names == null) { +            return null; +        } +        String[] namesArray = names.split(","); +        ComponentName[] componentNames = new ComponentName[namesArray.length]; +        for (int i = 0; i < namesArray.length; i++) { +            componentNames[i] = ComponentName.unflattenFromString(namesArray[i]); +        } +        return componentNames; +    } + +    private final DreamController.Listener mControllerListener = new DreamController.Listener() { +        @Override +        public void onDreamStopped(Binder token) { +            synchronized (mLock) { +                if (mCurrentDreamToken == token) { +                    cleanupDreamLocked(); +                } +            } +        } +    }; + +    /** +     * Handler for asynchronous operations performed by the dream manager. +     * Ensures operations to {@link DreamController} are single-threaded. +     */ +    private final class DreamHandler extends Handler { +        public DreamHandler(Looper looper) { +            super(looper, null, true /*async*/); +        } +    } + +    private final class BinderService extends IDreamManager.Stub { +        @Override // Binder call +        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { +            if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) +                    != PackageManager.PERMISSION_GRANTED) { +                pw.println("Permission Denial: can't dump DreamManager from from pid=" +                        + Binder.getCallingPid() +                        + ", uid=" + Binder.getCallingUid()); +                return; +            } + +            final long ident = Binder.clearCallingIdentity(); +            try { +                dumpInternal(pw); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public ComponentName[] getDreamComponents() { +            checkPermission(android.Manifest.permission.READ_DREAM_STATE); + +            final int userId = UserHandle.getCallingUserId(); +            final long ident = Binder.clearCallingIdentity(); +            try { +                return getDreamComponentsForUser(userId); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void setDreamComponents(ComponentName[] componentNames) { +            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); + +            final int userId = UserHandle.getCallingUserId(); +            final long ident = Binder.clearCallingIdentity(); +            try { +                setDreamComponentsForUser(userId, componentNames); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public ComponentName getDefaultDreamComponent() { +            checkPermission(android.Manifest.permission.READ_DREAM_STATE); + +            final int userId = UserHandle.getCallingUserId(); +            final long ident = Binder.clearCallingIdentity(); +            try { +                return getDefaultDreamComponentForUser(userId); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public boolean isDreaming() { +            checkPermission(android.Manifest.permission.READ_DREAM_STATE); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                return isDreamingInternal(); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void dream() { +            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                requestDreamInternal(); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void testDream(ComponentName dream) { +            if (dream == null) { +                throw new IllegalArgumentException("dream must not be null"); +            } +            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); + +            final int callingUserId = UserHandle.getCallingUserId(); +            final int currentUserId = ActivityManager.getCurrentUser(); +            if (callingUserId != currentUserId) { +                // This check is inherently prone to races but at least it's something. +                Slog.w(TAG, "Aborted attempt to start a test dream while a different " +                        + " user is active: callingUserId=" + callingUserId +                        + ", currentUserId=" + currentUserId); +                return; +            } +            final long ident = Binder.clearCallingIdentity(); +            try { +                testDreamInternal(dream, callingUserId); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void awaken() { +            checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                requestAwakenInternal(); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void finishSelf(IBinder token) { +            // Requires no permission, called by Dream from an arbitrary process. +            if (token == null) { +                throw new IllegalArgumentException("token must not be null"); +            } + +            final long ident = Binder.clearCallingIdentity(); +            try { +                finishSelfInternal(token); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } +    } + +    private final class LocalService extends DreamManagerInternal { +        @Override +        public void startDream() { +            startDreamInternal(); +        } + +        @Override +        public void stopDream() { +            stopDreamInternal(); +        } + +        @Override +        public boolean isDreaming() { +            return isDreamingInternal(); +        } +    } +} 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..88a2207d53b6 100644 --- a/services/java/com/android/server/firewall/IntentFirewall.java +++ b/services/core/java/com/android/server/firewall/IntentFirewall.java @@ -26,6 +26,7 @@ import android.content.pm.PackageManager;  import android.os.Environment;  import android.os.FileObserver;  import android.os.Handler; +import android.os.Looper;  import android.os.Message;  import android.os.RemoteException;  import android.util.ArrayMap; @@ -106,8 +107,9 @@ public class IntentFirewall {          }      } -    public IntentFirewall(AMSInterface ams) { +    public IntentFirewall(AMSInterface ams, Handler handler) {          mAms = ams; +        mHandler = new FirewallHandler(handler.getLooper());          File rulesDir = getRulesDir();          rulesDir.mkdirs(); @@ -531,7 +533,13 @@ public class IntentFirewall {                  new ArrayMap<ComponentName, Rule[]>(0);      } -    final Handler mHandler = new Handler() { +    final FirewallHandler mHandler; + +    private final class FirewallHandler extends Handler { +        public FirewallHandler(Looper looper) { +            super(looper, null, true); +        } +          @Override          public void handleMessage(Message msg) {              readRulesDir(getRulesDir()); 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..69281bc3a3f9 100644 --- a/services/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -16,11 +16,12 @@  package com.android.server.input; +import android.view.Display;  import com.android.internal.R;  import com.android.internal.util.XmlUtils; +import com.android.server.DisplayThread; +import com.android.server.LocalServices;  import com.android.server.Watchdog; -import com.android.server.display.DisplayManagerService; -import com.android.server.display.DisplayViewport;  import org.xmlpull.v1.XmlPullParser; @@ -44,9 +45,11 @@ import android.content.res.Resources.NotFoundException;  import android.content.res.TypedArray;  import android.content.res.XmlResourceParser;  import android.database.ContentObserver; +import android.hardware.display.DisplayViewport;  import android.hardware.input.IInputDevicesChangedListener;  import android.hardware.input.IInputManager;  import android.hardware.input.InputManager; +import android.hardware.input.InputManagerInternal;  import android.hardware.input.KeyboardLayout;  import android.os.Binder;  import android.os.Bundle; @@ -94,7 +97,7 @@ import libcore.util.Objects;   * Wraps the C++ InputManager and provides its callbacks.   */  public class InputManagerService extends IInputManager.Stub -        implements Watchdog.Monitor, DisplayManagerService.InputManagerFuncs { +        implements Watchdog.Monitor {      static final String TAG = "InputManager";      static final boolean DEBUG = false; @@ -167,7 +170,7 @@ public class InputManagerService extends IInputManager.Stub              InputWindowHandle inputWindowHandle, boolean monitor);      private static native void nativeUnregisterInputChannel(long ptr, InputChannel inputChannel);      private static native void nativeSetInputFilterEnabled(long ptr, boolean enable); -    private static native int nativeInjectInputEvent(long ptr, InputEvent event, +    private static native int nativeInjectInputEvent(long ptr, InputEvent event, int displayId,              int injectorPid, int injectorUid, int syncMode, int timeoutMillis,              int policyFlags);      private static native void nativeSetInputWindows(long ptr, InputWindowHandle[] windowHandles); @@ -241,15 +244,17 @@ public class InputManagerService extends IInputManager.Stub      /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */      final boolean mUseDevInputEventForAudioJack; -    public InputManagerService(Context context, Handler handler) { +    public InputManagerService(Context context) {          this.mContext = context; -        this.mHandler = new InputManagerHandler(handler.getLooper()); +        this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());          mUseDevInputEventForAudioJack =                  context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);          Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="                  + mUseDevInputEventForAudioJack);          mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue()); + +        LocalServices.addService(InputManagerInternal.class, new LocalService());      }      public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) { @@ -329,8 +334,7 @@ public class InputManagerService extends IInputManager.Stub          nativeReloadDeviceAliases(mPtr);      } -    @Override -    public void setDisplayViewports(DisplayViewport defaultViewport, +    private void setDisplayViewportsInternal(DisplayViewport defaultViewport,              DisplayViewport externalTouchViewport) {          if (defaultViewport.valid) {              setDisplayViewport(false, defaultViewport); @@ -505,6 +509,10 @@ public class InputManagerService extends IInputManager.Stub      @Override // Binder call      public boolean injectInputEvent(InputEvent event, int mode) { +        return injectInputEventInternal(event, Display.DEFAULT_DISPLAY, mode); +    } + +    private boolean injectInputEventInternal(InputEvent event, int displayId, int mode) {          if (event == null) {              throw new IllegalArgumentException("event must not be null");          } @@ -519,7 +527,7 @@ public class InputManagerService extends IInputManager.Stub          final long ident = Binder.clearCallingIdentity();          final int result;          try { -            result = nativeInjectInputEvent(mPtr, event, pid, uid, mode, +            result = nativeInjectInputEvent(mPtr, event, displayId, pid, uid, mode,                      INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);          } finally {              Binder.restoreCallingIdentity(ident); @@ -1549,7 +1557,7 @@ public class InputManagerService extends IInputManager.Stub              synchronized (mInputFilterLock) {                  if (!mDisconnected) { -                    nativeInjectInputEvent(mPtr, event, 0, 0, +                    nativeInjectInputEvent(mPtr, event, Display.DEFAULT_DISPLAY, 0, 0,                              InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0,                              policyFlags | WindowManagerPolicy.FLAG_FILTERED);                  } @@ -1639,4 +1647,17 @@ public class InputManagerService extends IInputManager.Stub              onVibratorTokenDied(this);          }      } + +    private final class LocalService extends InputManagerInternal { +        @Override +        public void setDisplayViewports( +                DisplayViewport defaultViewport, DisplayViewport externalTouchViewport) { +            setDisplayViewportsInternal(defaultViewport, externalTouchViewport); +        } + +        @Override +        public boolean injectInputEvent(InputEvent event, int displayId, int mode) { +            return injectInputEventInternal(event, displayId, mode); +        } +    }  } 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..62c0ec9a2ce0 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,43 @@ public class LightsService {          }      }; -    LightsService(Context context) { +    public LightsService(Context context) { +        super(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; +            } +        } +    }; + +    @Override      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 +200,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..2ba6c711bce3 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(); @@ -840,7 +725,14 @@ public class NotificationManagerService extends INotificationManager.Stub      // -- APIs to support listeners clicking/clearing notifications -- +    private void checkNullListener(INotificationListener listener) { +        if (listener == null) { +            throw new IllegalArgumentException("Listener must not be null"); +        } +    } +      private NotificationListenerInfo checkListenerToken(INotificationListener listener) { +        checkNullListener(listener);          final IBinder token = listener.asBinder();          final int N = mListeners.size();          for (int i=0; i<N; i++) { @@ -850,66 +742,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 +825,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 +864,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 +874,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 +893,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 +909,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 +918,7 @@ public class NotificationManagerService extends INotificationManager.Stub                  true, ActivityManager.getCurrentUser());          } +        @Override          public void onPanelRevealed() {              synchronized (mNotificationList) {                  // sound @@ -1089,7 +926,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 +951,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 +1006,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 +1082,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 +1095,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 +1125,28 @@ 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); +    public NotificationManagerService(Context context) { +        super(context); +    } + +    @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 +1168,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 +1181,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 +1189,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 +1201,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 +1213,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 +1224,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 +1240,423 @@ 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); -        if (pkg == null || callback == null) { -            Slog.e(TAG, "Not doing toast. pkg=" + pkg + " callback=" + callback); -            return ; +        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));          } +    } -        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); +                } +            } +        } -                    record = new ToastRecord(callingPid, pkg, callback, duration); -                    mToastQueue.add(record); -                    index = mToastQueue.size() - 1; -                    keepProcessAliveLocked(callingPid); +        @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 ; +            } + +            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(); +            checkNullListener(listener); +            registerListenerImpl(listener, component, userid);          } -        synchronized (mToastQueue) { -            long callingId = Binder.clearCallingIdentity(); +        /** +         * Remove a listener binder directly +         */ +        @Override +        public void unregisterListener(INotificationListener listener, int userid) { +            checkNullListener(listener); +            // 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 +1807,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 +1834,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 +1878,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 +1887,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 +1898,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 +1923,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 +1931,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 +1985,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 +2170,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 +2185,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 +2221,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 +2314,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 +2374,7 @@ public class NotificationManagerService extends INotificationManager.Stub      }      // lock on mNotificationList -    private void updateLightsLocked() +    void updateLightsLocked()      {          // handle notification lights          if (mLedNotification == null) { @@ -2251,14 +2400,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 +2437,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..6185e5010466 100644 --- a/services/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -16,6 +16,9 @@  package com.android.server.pm; +import com.android.server.SystemService; + +import android.content.Context;  import android.content.pm.PackageStats;  import android.net.LocalSocket;  import android.net.LocalSocketAddress; @@ -25,21 +28,28 @@ import java.io.IOException;  import java.io.InputStream;  import java.io.OutputStream; -public final class Installer { +public final class Installer extends SystemService {      private static final String TAG = "Installer";      private static final boolean LOCAL_DEBUG = false;      InputStream mIn; -      OutputStream mOut; -      LocalSocket mSocket;      byte buf[] = new byte[1024]; -      int buflen = 0; +    public Installer(Context context) { +        super(context); +    } + +    @Override +    public void onStart() { +        Slog.i(TAG, "Waiting for installd to be ready."); +        ping(); +    } +      private boolean connect() {          if (mSocket != null) {              return true; 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 7e244b96b020..df83fd70c5ce 100755 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -38,10 +38,11 @@ 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.ServiceThread; +import com.android.server.LocalServices;  import com.android.server.Watchdog;  import org.xmlpull.v1.XmlPullParser;  import org.xmlpull.v1.XmlPullParserException; @@ -92,6 +93,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 +129,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 +163,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. @@ -259,8 +261,7 @@ public class PackageManagerService extends IPackageManager.Stub {      static final String mTempContainerPrefix = "smdl2tmp"; -    final HandlerThread mHandlerThread = new HandlerThread("PackageManager", -            Process.THREAD_PRIORITY_BACKGROUND); +    final ServiceThread mHandlerThread;      final PackageHandler mHandler;      final int mSdkVersion = Build.VERSION.SDK_INT; @@ -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,17 +1121,16 @@ 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          synchronized (mPackages) { +            mHandlerThread = new ServiceThread(TAG, +                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);              mHandlerThread.start();              mHandler = new PackageHandler(mHandlerThread.getLooper()); -            Watchdog.getInstance().addThread(mHandler, mHandlerThread.getName(), -                    WATCHDOG_TIMEOUT); +            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);              File dataDir = Environment.getDataDirectory();              mAppDataDir = new File(dataDir, "data"); @@ -7345,6 +7351,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 @@ -7362,15 +7377,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 { @@ -7928,8 +7937,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; @@ -9744,10 +9753,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) { @@ -11572,12 +11581,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..f1be504e5549 100644 --- a/services/java/com/android/server/power/DisplayPowerController.java +++ b/services/core/java/com/android/server/power/DisplayPowerController.java @@ -16,10 +16,10 @@  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.display.DisplayManagerService; +import com.android.server.lights.LightsManager; +import com.android.server.twilight.TwilightListener; +import com.android.server.twilight.TwilightManager; +import com.android.server.twilight.TwilightState;  import android.animation.Animator;  import android.animation.ObjectAnimator; @@ -179,13 +179,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; - -    // The display manager. -    private final DisplayManagerService mDisplayManager; +    private final TwilightManager mTwilight;      // The sensor manager.      private final SensorManager mSensorManager; @@ -351,8 +348,7 @@ final class DisplayPowerController {       * Creates the display power controller.       */      public DisplayPowerController(Looper looper, Context context, Notifier notifier, -            LightsService lights, TwilightService twilight, SensorManager sensorManager, -            DisplayManagerService displayManager, +            LightsManager lights, TwilightManager twilight, SensorManager sensorManager,              SuspendBlocker displaySuspendBlocker, DisplayBlanker displayBlanker,              Callbacks callbacks, Handler callbackHandler) {          mHandler = new DisplayControllerHandler(looper); @@ -365,7 +361,6 @@ final class DisplayPowerController {          mLights = lights;          mTwilight = twilight;          mSensorManager = sensorManager; -        mDisplayManager = displayManager;          final Resources resources = context.getResources(); @@ -526,9 +521,8 @@ final class DisplayPowerController {      }      private void initialize() { -        mPowerState = new DisplayPowerState( -                new ElectronBeam(mDisplayManager), mDisplayBlanker, -                mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT)); +        mPowerState = new DisplayPowerState(new ElectronBeam(), mDisplayBlanker, +                mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT));          mElectronBeamOnAnimator = ObjectAnimator.ofFloat(                  mPowerState, DisplayPowerState.ELECTRON_BEAM_LEVEL, 0.0f, 1.0f); @@ -1368,8 +1362,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..64921d73a784 100644 --- a/services/java/com/android/server/power/ElectronBeam.java +++ b/services/core/java/com/android/server/power/ElectronBeam.java @@ -23,6 +23,8 @@ import java.nio.FloatBuffer;  import android.graphics.PixelFormat;  import android.graphics.SurfaceTexture; +import android.hardware.display.DisplayManagerInternal; +import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;  import android.opengl.EGL14;  import android.opengl.EGLConfig;  import android.opengl.EGLContext; @@ -40,8 +42,7 @@ import android.view.Surface;  import android.view.SurfaceControl;  import android.view.SurfaceSession; -import com.android.server.display.DisplayManagerService; -import com.android.server.display.DisplayTransactionListener; +import com.android.server.LocalServices;  /**   * Bzzzoooop!  *crackle* @@ -77,7 +78,7 @@ final class ElectronBeam {      private boolean mPrepared;      private int mMode; -    private final DisplayManagerService mDisplayManager; +    private final DisplayManagerInternal mDisplayManagerInternal;      private int mDisplayLayerStack; // layer stack associated with primary display      private int mDisplayWidth;      // real width, not rotated      private int mDisplayHeight;     // real height, not rotated @@ -118,8 +119,8 @@ final class ElectronBeam {      public static final int MODE_FADE = 2; -    public ElectronBeam(DisplayManagerService displayManager) { -        mDisplayManager = displayManager; +    public ElectronBeam() { +        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);      }      /** @@ -138,7 +139,7 @@ final class ElectronBeam {          // Get the display size and layer stack.          // This is not expected to change while the electron beam surface is showing. -        DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY); +        DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(Display.DEFAULT_DISPLAY);          mDisplayLayerStack = displayInfo.layerStack;          mDisplayWidth = displayInfo.getNaturalWidth();          mDisplayHeight = displayInfo.getNaturalHeight(); @@ -527,7 +528,7 @@ final class ElectronBeam {              mSurface = new Surface();              mSurface.copyFrom(mSurfaceControl); -            mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManager, mSurfaceControl); +            mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal, mSurfaceControl);              mSurfaceLayout.onDisplayTransaction();          } finally {              SurfaceControl.closeTransaction(); @@ -685,20 +686,21 @@ final class ElectronBeam {       * owns the electron beam.       */      private static final class NaturalSurfaceLayout implements DisplayTransactionListener { -        private final DisplayManagerService mDisplayManager; +        private final DisplayManagerInternal mDisplayManagerInternal;          private SurfaceControl mSurfaceControl; -        public NaturalSurfaceLayout(DisplayManagerService displayManager, SurfaceControl surfaceControl) { -            mDisplayManager = displayManager; +        public NaturalSurfaceLayout(DisplayManagerInternal displayManagerInternal, +                SurfaceControl surfaceControl) { +            mDisplayManagerInternal = displayManagerInternal;              mSurfaceControl = surfaceControl; -            mDisplayManager.registerDisplayTransactionListener(this); +            mDisplayManagerInternal.registerDisplayTransactionListener(this);          }          public void dispose() {              synchronized (this) {                  mSurfaceControl = null;              } -            mDisplayManager.unregisterDisplayTransactionListener(this); +            mDisplayManagerInternal.unregisterDisplayTransactionListener(this);          }          @Override @@ -708,7 +710,8 @@ final class ElectronBeam {                      return;                  } -                DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY); +                DisplayInfo displayInfo = +                        mDisplayManagerInternal.getDisplayInfo(Display.DEFAULT_DISPLAY);                  switch (displayInfo.rotation) {                      case Surface.ROTATION_0:                          mSurfaceControl.setPosition(0, 0); 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..3dec23471ce4 100644 --- a/services/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -20,12 +20,12 @@ 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.LocalServices; +import com.android.server.ServiceThread; +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;  import android.Manifest;  import android.content.BroadcastReceiver; @@ -38,16 +38,17 @@ import android.content.res.Resources;  import android.database.ContentObserver;  import android.hardware.SensorManager;  import android.hardware.SystemSensorManager; +import android.hardware.display.DisplayManagerInternal;  import android.net.Uri;  import android.os.BatteryManager;  import android.os.Binder;  import android.os.Handler; -import android.os.HandlerThread;  import android.os.IBinder;  import android.os.IPowerManager;  import android.os.Looper;  import android.os.Message;  import android.os.PowerManager; +import android.os.PowerManagerInternal;  import android.os.Process;  import android.os.RemoteException;  import android.os.SystemClock; @@ -56,6 +57,7 @@ import android.os.SystemService;  import android.os.UserHandle;  import android.os.WorkSource;  import android.provider.Settings; +import android.service.dreams.DreamManagerInternal;  import android.util.EventLog;  import android.util.Log;  import android.util.Slog; @@ -72,7 +74,7 @@ import libcore.util.Objects;   * The power manager service is responsible for coordinating power management   * functions on the device.   */ -public final class PowerManagerService extends IPowerManager.Stub +public final class PowerManagerService extends com.android.server.SystemService          implements Watchdog.Monitor {      private static final String TAG = "PowerManagerService"; @@ -167,21 +169,21 @@ public final class PowerManagerService extends IPowerManager.Stub      // effectively and terminate the dream.      private static final int DREAM_BATTERY_LEVEL_DRAIN_CUTOFF = 5; -    private Context mContext; -    private LightsService mLightsService; +    private final Context mContext; +    private LightsManager mLightsManager;      private BatteryService mBatteryService; -    private DisplayManagerService mDisplayManagerService; +    private DisplayManagerInternal mDisplayManagerInternal;      private IBatteryStats mBatteryStats;      private IAppOpsService mAppOps; -    private HandlerThread mHandlerThread; +    private ServiceThread mHandlerThread;      private PowerManagerHandler mHandler;      private WindowManagerPolicy mPolicy;      private Notifier mNotifier;      private DisplayPowerController mDisplayPowerController;      private WirelessChargerDetector mWirelessChargerDetector;      private SettingsObserver mSettingsObserver; -    private DreamManagerService mDreamManager; -    private LightsService.Light mAttentionLight; +    private DreamManagerInternal mDreamManager; +    private Light mAttentionLight;      private final Object mLock = new Object(); @@ -231,9 +233,6 @@ public final class PowerManagerService extends IPowerManager.Stub      // requested because it is updated asynchronously by the display power controller.      private final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest(); -    // The time the screen was last turned off, in elapsedRealtime() timebase. -    private long mLastScreenOffEventElapsedRealTime; -      // True if the display power state has been fully applied, which means the display      // is actually on or actually off or whatever was requested.      private boolean mDisplayReady; @@ -376,7 +375,9 @@ public final class PowerManagerService extends IPowerManager.Stub      private static native void nativeSetInteractive(boolean enable);      private static native void nativeSetAutoSuspend(boolean enable); -    public PowerManagerService() { +    public PowerManagerService(Context context) { +        super(context); +        mContext = context;          synchronized (mLock) {              mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");              mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display"); @@ -392,25 +393,31 @@ public final class PowerManagerService extends IPowerManager.Stub          nativeSetPowerState(true, true);      } +    @Override +    public void onStart() { +        publishBinderService(Context.POWER_SERVICE, new BinderService()); +        publishLocalService(PowerManagerInternal.class, new LocalService()); +    } +      /**       * 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, -            IAppOpsService appOps, DisplayManagerService dm) { -        mContext = context; -        mLightsService = ls; +    public void init(LightsManager ls, +            BatteryService bs, IBatteryStats bss, +            IAppOpsService appOps) { +        mLightsManager = ls;          mBatteryService = bs;          mBatteryStats = bss;          mAppOps = appOps; -        mDisplayManagerService = dm; -        mHandlerThread = new HandlerThread(TAG); +        mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class); +        mHandlerThread = new ServiceThread(TAG, +                Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);          mHandlerThread.start();          mHandler = new PowerManagerHandler(mHandlerThread.getLooper());          Watchdog.getInstance().addMonitor(this); -        Watchdog.getInstance().addThread(mHandler, mHandlerThread.getName()); +        Watchdog.getInstance().addThread(mHandler);          // Forcibly turn the screen on at boot so that it is in a known power state.          // We do this in init() rather than in the constructor because setting the @@ -421,18 +428,18 @@ public final class PowerManagerService extends IPowerManager.Stub          mDisplayBlanker.unblankAllDisplays();      } -    public void setPolicy(WindowManagerPolicy policy) { +    void setPolicy(WindowManagerPolicy policy) {          synchronized (mLock) {              mPolicy = policy;          }      } -    public void systemReady(TwilightService twilight, DreamManagerService dreamManager) { +    public void systemReady() {          synchronized (mLock) {              mSystemReady = true; -            mDreamManager = dreamManager; +            mDreamManager = LocalServices.getService(DreamManagerInternal.class); -            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,15 +455,16 @@ 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, -                    mDisplayManagerService, mDisplaySuspendBlocker, mDisplayBlanker, +                    mContext, mNotifier, mLightsManager, +                    LocalServices.getService(TwilightManager.class), sensorManager, +                    mDisplaySuspendBlocker, mDisplayBlanker,                      mDisplayPowerControllerCallbacks, mHandler);              mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,                      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(); @@ -579,41 +587,6 @@ public final class PowerManagerService extends IPowerManager.Stub          updatePowerStateLocked();      } -    @Override // Binder call -    public void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName, -            int uid) { -        acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid)); -    } - -    @Override // Binder call -    public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, -            WorkSource ws) { -        if (lock == null) { -            throw new IllegalArgumentException("lock must not be null"); -        } -        if (packageName == null) { -            throw new IllegalArgumentException("packageName must not be null"); -        } -        PowerManager.validateWakeLockParameters(flags, tag); - -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); -        if (ws != null && ws.size() != 0) { -            mContext.enforceCallingOrSelfPermission( -                    android.Manifest.permission.UPDATE_DEVICE_STATS, null); -        } else { -            ws = null; -        } - -        final int uid = Binder.getCallingUid(); -        final int pid = Binder.getCallingPid(); -        final long ident = Binder.clearCallingIdentity(); -        try { -            acquireWakeLockInternal(lock, flags, tag, packageName, ws, uid, pid); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,              WorkSource ws, int uid, int pid) {          synchronized (mLock) { @@ -668,22 +641,6 @@ public final class PowerManagerService extends IPowerManager.Stub          }      } -    @Override // Binder call -    public void releaseWakeLock(IBinder lock, int flags) { -        if (lock == null) { -            throw new IllegalArgumentException("lock must not be null"); -        } - -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            releaseWakeLockInternal(lock, flags); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void releaseWakeLockInternal(IBinder lock, int flags) {          synchronized (mLock) {              int index = findWakeLockIndexLocked(lock); @@ -746,43 +703,6 @@ public final class PowerManagerService extends IPowerManager.Stub          }      } -    @Override // Binder call -    public void updateWakeLockUids(IBinder lock, int[] uids) { -        WorkSource ws = null; - -        if (uids != null) { -            ws = new WorkSource(); -            // XXX should WorkSource have a way to set uids as an int[] instead of adding them -            // one at a time? -            for (int i = 0; i < uids.length; i++) { -                ws.add(uids[i]); -            } -        } -        updateWakeLockWorkSource(lock, ws); -    } - -    @Override // Binder call -    public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) { -        if (lock == null) { -            throw new IllegalArgumentException("lock must not be null"); -        } - -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); -        if (ws != null && ws.size() != 0) { -            mContext.enforceCallingOrSelfPermission( -                    android.Manifest.permission.UPDATE_DEVICE_STATS, null); -        } else { -            ws = null; -        } - -        final long ident = Binder.clearCallingIdentity(); -        try { -            updateWakeLockWorkSourceInternal(lock, ws); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws) {          synchronized (mLock) {              int index = findWakeLockIndexLocked(lock); @@ -834,16 +754,6 @@ public final class PowerManagerService extends IPowerManager.Stub          }      } -    @Override // Binder call -    public boolean isWakeLockLevelSupported(int level) { -        final long ident = Binder.clearCallingIdentity(); -        try { -            return isWakeLockLevelSupportedInternal(level); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      @SuppressWarnings("deprecation")      private boolean isWakeLockLevelSupportedInternal(int level) {          synchronized (mLock) { @@ -863,40 +773,6 @@ public final class PowerManagerService extends IPowerManager.Stub          }      } -    @Override // Binder call -    public void userActivity(long eventTime, int event, int flags) { -        final long now = SystemClock.uptimeMillis(); -        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER) -                != PackageManager.PERMISSION_GRANTED) { -            // Once upon a time applications could call userActivity(). -            // Now we require the DEVICE_POWER permission.  Log a warning and ignore the -            // request instead of throwing a SecurityException so we don't break old apps. -            synchronized (mLock) { -                if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) { -                    mLastWarningAboutUserActivityPermission = now; -                    Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the " -                            + "caller does not have DEVICE_POWER permission.  " -                            + "Please fix your app!  " -                            + " pid=" + Binder.getCallingPid() -                            + " uid=" + Binder.getCallingUid()); -                } -            } -            return; -        } - -        if (eventTime > SystemClock.uptimeMillis()) { -            throw new IllegalArgumentException("event time must not be in the future"); -        } - -        final int uid = Binder.getCallingUid(); -        final long ident = Binder.clearCallingIdentity(); -        try { -            userActivityInternal(eventTime, event, flags, uid); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      // Called from native code.      private void userActivityFromNative(long eventTime, int event, int flags) {          userActivityInternal(eventTime, event, flags, Process.SYSTEM_UID); @@ -941,22 +817,6 @@ public final class PowerManagerService extends IPowerManager.Stub          return false;      } -    @Override // Binder call -    public void wakeUp(long eventTime) { -        if (eventTime > SystemClock.uptimeMillis()) { -            throw new IllegalArgumentException("event time must not be in the future"); -        } - -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            wakeUpInternal(eventTime); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      // Called from native code.      private void wakeUpFromNative(long eventTime) {          wakeUpInternal(eventTime); @@ -1004,22 +864,6 @@ public final class PowerManagerService extends IPowerManager.Stub          return true;      } -    @Override // Binder call -    public void goToSleep(long eventTime, int reason) { -        if (eventTime > SystemClock.uptimeMillis()) { -            throw new IllegalArgumentException("event time must not be in the future"); -        } - -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            goToSleepInternal(eventTime, reason); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      // Called from native code.      private void goToSleepFromNative(long eventTime, int reason) {          goToSleepInternal(eventTime, reason); @@ -1082,22 +926,6 @@ public final class PowerManagerService extends IPowerManager.Stub          return true;      } -    @Override // Binder call -    public void nap(long eventTime) { -        if (eventTime > SystemClock.uptimeMillis()) { -            throw new IllegalArgumentException("event time must not be in the future"); -        } - -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            napInternal(eventTime); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void napInternal(long eventTime) {          synchronized (mLock) {              if (napNoUpdateLocked(eventTime)) { @@ -1656,12 +1484,6 @@ public final class PowerManagerService extends IPowerManager.Stub                  | DIRTY_SETTINGS | DIRTY_SCREEN_ON_BLOCKER_RELEASED)) != 0) {              int newScreenState = getDesiredScreenPowerStateLocked();              if (newScreenState != mDisplayPowerRequest.screenState) { -                if (newScreenState == DisplayPowerRequest.SCREEN_STATE_OFF -                        && mDisplayPowerRequest.screenState -                                != DisplayPowerRequest.SCREEN_STATE_OFF) { -                    mLastScreenOffEventElapsedRealTime = SystemClock.elapsedRealtime(); -                } -                  mDisplayPowerRequest.screenState = newScreenState;                  nativeSetPowerState(                          newScreenState != DisplayPowerRequest.SCREEN_STATE_OFF, @@ -1828,16 +1650,6 @@ public final class PowerManagerService extends IPowerManager.Stub          return false;      } -    @Override // Binder call -    public boolean isScreenOn() { -        final long ident = Binder.clearCallingIdentity(); -        try { -            return isScreenOnInternal(); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private boolean isScreenOnInternal() {          synchronized (mLock) {              return !mSystemReady @@ -1882,43 +1694,6 @@ public final class PowerManagerService extends IPowerManager.Stub          updatePowerStateLocked();      } -    /** -     * Reboots the device. -     * -     * @param confirm If true, shows a reboot confirmation dialog. -     * @param reason The reason for the reboot, or null if none. -     * @param wait If true, this call waits for the reboot to complete and does not return. -     */ -    @Override // Binder call -    public void reboot(boolean confirm, String reason, boolean wait) { -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            shutdownOrRebootInternal(false, confirm, reason, wait); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } - -    /** -     * Shuts down the device. -     * -     * @param confirm If true, shows a shutdown confirmation dialog. -     * @param wait If true, this call waits for the shutdown to complete and does not return. -     */ -    @Override // Binder call -    public void shutdown(boolean confirm, boolean wait) { -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            shutdownOrRebootInternal(true, confirm, null, wait); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,              final String reason, boolean wait) {          if (mHandler == null || !mSystemReady) { @@ -1956,22 +1731,6 @@ public final class PowerManagerService extends IPowerManager.Stub          }      } -    /** -     * Crash the runtime (causing a complete restart of the Android framework). -     * Requires REBOOT permission.  Mostly for testing.  Should not return. -     */ -    @Override // Binder call -    public void crash(String message) { -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            crashInternal(message); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void crashInternal(final String message) {          Thread t = new Thread("PowerManagerService.crash()") {              @Override @@ -1987,51 +1746,11 @@ public final class PowerManagerService extends IPowerManager.Stub          }      } -    /** -     * Set the setting that determines whether the device stays on when plugged in. -     * The argument is a bit string, with each bit specifying a power source that, -     * when the device is connected to that source, causes the device to stay on. -     * See {@link android.os.BatteryManager} for the list of power sources that -     * can be specified. Current values include {@link android.os.BatteryManager#BATTERY_PLUGGED_AC} -     * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB} -     * -     * Used by "adb shell svc power stayon ..." -     * -     * @param val an {@code int} containing the bits that specify which power sources -     * should cause the device to stay on. -     */ -    @Override // Binder call -    public void setStayOnSetting(int val) { -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            setStayOnSettingInternal(val); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void setStayOnSettingInternal(int val) {          Settings.Global.putInt(mContext.getContentResolver(),                  Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);      } -    /** -     * Used by device administration to set the maximum screen off timeout. -     * -     * This method must only be called by the device administration policy manager. -     */ -    @Override // Binder call -    public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) { -        final long ident = Binder.clearCallingIdentity(); -        try { -            setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void setMaximumScreenOffTimeoutFromDeviceAdminInternal(int timeMs) {          synchronized (mLock) {              mMaximumScreenOffTimeoutFromDeviceAdmin = timeMs; @@ -2045,23 +1764,8 @@ public final class PowerManagerService extends IPowerManager.Stub                  && mMaximumScreenOffTimeoutFromDeviceAdmin < Integer.MAX_VALUE;      } -    /** -     * Used by the phone application to make the attention LED flash when ringing. -     */ -    @Override // Binder call -    public void setAttentionLight(boolean on, int color) { -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            setAttentionLightInternal(on, color); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void setAttentionLightInternal(boolean on, int color) { -        LightsService.Light light; +        Light light;          synchronized (mLock) {              if (!mSystemReady) {                  return; @@ -2070,38 +1774,7 @@ public final class PowerManagerService extends IPowerManager.Stub          }          // Control light outside of lock. -        light.setFlashing(color, LightsService.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0); -    } - -    /** -     * Used by the Watchdog. -     */ -    public long timeSinceScreenWasLastOn() { -        synchronized (mLock) { -            if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) { -                return 0; -            } -            return SystemClock.elapsedRealtime() - mLastScreenOffEventElapsedRealTime; -        } -    } - -    /** -     * Used by the window manager to override the screen brightness based on the -     * current foreground activity. -     * -     * This method must only be called by the window manager. -     * -     * @param brightness The overridden brightness, or -1 to disable the override. -     */ -    public void setScreenBrightnessOverrideFromWindowManager(int brightness) { -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            setScreenBrightnessOverrideFromWindowManagerInternal(brightness); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } +        light.setFlashing(color, Light.LIGHT_FLASH_HARDWARE, (on ? 3 : 0), 0);      }      private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) { @@ -2114,40 +1787,6 @@ public final class PowerManagerService extends IPowerManager.Stub          }      } -    /** -     * Used by the window manager to override the button brightness based on the -     * current foreground activity. -     * -     * This method must only be called by the window manager. -     * -     * @param brightness The overridden brightness, or -1 to disable the override. -     */ -    public void setButtonBrightnessOverrideFromWindowManager(int brightness) { -        // Do nothing. -        // Button lights are not currently supported in the new implementation. -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); -    } - -    /** -     * Used by the window manager to override the user activity timeout based on the -     * current foreground activity.  It can only be used to make the timeout shorter -     * than usual, not longer. -     * -     * This method must only be called by the window manager. -     * -     * @param timeoutMillis The overridden timeout, or -1 to disable the override. -     */ -    public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) { -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {          synchronized (mLock) {              if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) { @@ -2158,30 +1797,6 @@ public final class PowerManagerService extends IPowerManager.Stub          }      } -    /** -     * Used by the settings application and brightness control widgets to -     * temporarily override the current screen brightness setting so that the -     * user can observe the effect of an intended settings change without applying -     * it immediately. -     * -     * The override will be canceled when the setting value is next updated. -     * -     * @param brightness The overridden brightness. -     * -     * @see android.provider.Settings.System#SCREEN_BRIGHTNESS -     */ -    @Override // Binder call -    public void setTemporaryScreenBrightnessSettingOverride(int brightness) { -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            setTemporaryScreenBrightnessSettingOverrideInternal(brightness); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {          synchronized (mLock) {              if (mTemporaryScreenBrightnessSettingOverride != brightness) { @@ -2192,30 +1807,6 @@ public final class PowerManagerService extends IPowerManager.Stub          }      } -    /** -     * Used by the settings application and brightness control widgets to -     * temporarily override the current screen auto-brightness adjustment setting so that the -     * user can observe the effect of an intended settings change without applying -     * it immediately. -     * -     * The override will be canceled when the setting value is next updated. -     * -     * @param adj The overridden brightness, or Float.NaN to disable the override. -     * -     * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ -     */ -    @Override // Binder call -    public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) { -        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(adj); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } -      private void setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(float adj) {          synchronized (mLock) {              // Note: This condition handles NaN because NaN is not equal to any other @@ -2262,16 +1853,7 @@ public final class PowerManagerService extends IPowerManager.Stub          }      } -    @Override // Binder call -    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { -        if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) -                != PackageManager.PERMISSION_GRANTED) { -            pw.println("Permission Denial: can't dump PowerManager from from pid=" -                    + Binder.getCallingPid() -                    + ", uid=" + Binder.getCallingUid()); -            return; -        } - +    private void dumpInternal(PrintWriter pw) {          pw.println("POWER MANAGER (dumpsys power)\n");          final DisplayPowerController dpc; @@ -2712,7 +2294,7 @@ public final class PowerManagerService extends IPowerManager.Stub          public void blankAllDisplays() {              synchronized (this) {                  mBlanked = true; -                mDisplayManagerService.blankAllDisplaysFromPowerManager(); +                mDisplayManagerInternal.blankAllDisplaysFromPowerManager();                  nativeSetInteractive(false);                  nativeSetAutoSuspend(true);              } @@ -2723,7 +2305,7 @@ public final class PowerManagerService extends IPowerManager.Stub              synchronized (this) {                  nativeSetAutoSuspend(false);                  nativeSetInteractive(true); -                mDisplayManagerService.unblankAllDisplaysFromPowerManager(); +                mDisplayManagerInternal.unblankAllDisplaysFromPowerManager();                  mBlanked = false;              }          } @@ -2735,4 +2317,444 @@ public final class PowerManagerService extends IPowerManager.Stub              }          }      } + +    private final class BinderService extends IPowerManager.Stub { +        @Override // Binder call +        public void acquireWakeLockWithUid(IBinder lock, int flags, String tag, +                String packageName, int uid) { +            acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid)); +        } + +        @Override // Binder call +        public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, +                WorkSource ws) { +            if (lock == null) { +                throw new IllegalArgumentException("lock must not be null"); +            } +            if (packageName == null) { +                throw new IllegalArgumentException("packageName must not be null"); +            } +            PowerManager.validateWakeLockParameters(flags, tag); + +            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); +            if (ws != null && ws.size() != 0) { +                mContext.enforceCallingOrSelfPermission( +                        android.Manifest.permission.UPDATE_DEVICE_STATS, null); +            } else { +                ws = null; +            } + +            final int uid = Binder.getCallingUid(); +            final int pid = Binder.getCallingPid(); +            final long ident = Binder.clearCallingIdentity(); +            try { +                acquireWakeLockInternal(lock, flags, tag, packageName, ws, uid, pid); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void releaseWakeLock(IBinder lock, int flags) { +            if (lock == null) { +                throw new IllegalArgumentException("lock must not be null"); +            } + +            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                releaseWakeLockInternal(lock, flags); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void updateWakeLockUids(IBinder lock, int[] uids) { +            WorkSource ws = null; + +            if (uids != null) { +                ws = new WorkSource(); +                // XXX should WorkSource have a way to set uids as an int[] instead of adding them +                // one at a time? +                for (int i = 0; i < uids.length; i++) { +                    ws.add(uids[i]); +                } +            } +            updateWakeLockWorkSource(lock, ws); +        } + +        @Override // Binder call +        public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) { +            if (lock == null) { +                throw new IllegalArgumentException("lock must not be null"); +            } + +            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); +            if (ws != null && ws.size() != 0) { +                mContext.enforceCallingOrSelfPermission( +                        android.Manifest.permission.UPDATE_DEVICE_STATS, null); +            } else { +                ws = null; +            } + +            final long ident = Binder.clearCallingIdentity(); +            try { +                updateWakeLockWorkSourceInternal(lock, ws); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public boolean isWakeLockLevelSupported(int level) { +            final long ident = Binder.clearCallingIdentity(); +            try { +                return isWakeLockLevelSupportedInternal(level); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void userActivity(long eventTime, int event, int flags) { +            final long now = SystemClock.uptimeMillis(); +            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER) +                    != PackageManager.PERMISSION_GRANTED) { +                // Once upon a time applications could call userActivity(). +                // Now we require the DEVICE_POWER permission.  Log a warning and ignore the +                // request instead of throwing a SecurityException so we don't break old apps. +                synchronized (mLock) { +                    if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) { +                        mLastWarningAboutUserActivityPermission = now; +                        Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the " +                                + "caller does not have DEVICE_POWER permission.  " +                                + "Please fix your app!  " +                                + " pid=" + Binder.getCallingPid() +                                + " uid=" + Binder.getCallingUid()); +                    } +                } +                return; +            } + +            if (eventTime > SystemClock.uptimeMillis()) { +                throw new IllegalArgumentException("event time must not be in the future"); +            } + +            final int uid = Binder.getCallingUid(); +            final long ident = Binder.clearCallingIdentity(); +            try { +                userActivityInternal(eventTime, event, flags, uid); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void wakeUp(long eventTime) { +            if (eventTime > SystemClock.uptimeMillis()) { +                throw new IllegalArgumentException("event time must not be in the future"); +            } + +            mContext.enforceCallingOrSelfPermission( +                    android.Manifest.permission.DEVICE_POWER, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                wakeUpInternal(eventTime); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void goToSleep(long eventTime, int reason) { +            if (eventTime > SystemClock.uptimeMillis()) { +                throw new IllegalArgumentException("event time must not be in the future"); +            } + +            mContext.enforceCallingOrSelfPermission( +                    android.Manifest.permission.DEVICE_POWER, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                goToSleepInternal(eventTime, reason); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public void nap(long eventTime) { +            if (eventTime > SystemClock.uptimeMillis()) { +                throw new IllegalArgumentException("event time must not be in the future"); +            } + +            mContext.enforceCallingOrSelfPermission( +                    android.Manifest.permission.DEVICE_POWER, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                napInternal(eventTime); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        public boolean isScreenOn() { +            final long ident = Binder.clearCallingIdentity(); +            try { +                return isScreenOnInternal(); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        /** +         * Reboots the device. +         * +         * @param confirm If true, shows a reboot confirmation dialog. +         * @param reason The reason for the reboot, or null if none. +         * @param wait If true, this call waits for the reboot to complete and does not return. +         */ +        @Override // Binder call +        public void reboot(boolean confirm, String reason, boolean wait) { +            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                shutdownOrRebootInternal(false, confirm, reason, wait); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        /** +         * Shuts down the device. +         * +         * @param confirm If true, shows a shutdown confirmation dialog. +         * @param wait If true, this call waits for the shutdown to complete and does not return. +         */ +        @Override // Binder call +        public void shutdown(boolean confirm, boolean wait) { +            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                shutdownOrRebootInternal(true, confirm, null, wait); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        /** +         * Crash the runtime (causing a complete restart of the Android framework). +         * Requires REBOOT permission.  Mostly for testing.  Should not return. +         */ +        @Override // Binder call +        public void crash(String message) { +            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                crashInternal(message); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        /** +         * Set the setting that determines whether the device stays on when plugged in. +         * The argument is a bit string, with each bit specifying a power source that, +         * when the device is connected to that source, causes the device to stay on. +         * See {@link android.os.BatteryManager} for the list of power sources that +         * can be specified. Current values include +         * {@link android.os.BatteryManager#BATTERY_PLUGGED_AC} +         * and {@link android.os.BatteryManager#BATTERY_PLUGGED_USB} +         * +         * Used by "adb shell svc power stayon ..." +         * +         * @param val an {@code int} containing the bits that specify which power sources +         * should cause the device to stay on. +         */ +        @Override // Binder call +        public void setStayOnSetting(int val) { +            mContext.enforceCallingOrSelfPermission( +                    android.Manifest.permission.WRITE_SETTINGS, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                setStayOnSettingInternal(val); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        /** +         * Used by device administration to set the maximum screen off timeout. +         * +         * This method must only be called by the device administration policy manager. +         */ +        @Override // Binder call +        public void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs) { +            final long ident = Binder.clearCallingIdentity(); +            try { +                setMaximumScreenOffTimeoutFromDeviceAdminInternal(timeMs); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        /** +         * Used by the settings application and brightness control widgets to +         * temporarily override the current screen brightness setting so that the +         * user can observe the effect of an intended settings change without applying +         * it immediately. +         * +         * The override will be canceled when the setting value is next updated. +         * +         * @param brightness The overridden brightness. +         * +         * @see android.provider.Settings.System#SCREEN_BRIGHTNESS +         */ +        @Override // Binder call +        public void setTemporaryScreenBrightnessSettingOverride(int brightness) { +            mContext.enforceCallingOrSelfPermission( +                    android.Manifest.permission.DEVICE_POWER, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                setTemporaryScreenBrightnessSettingOverrideInternal(brightness); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        /** +         * Used by the settings application and brightness control widgets to +         * temporarily override the current screen auto-brightness adjustment setting so that the +         * user can observe the effect of an intended settings change without applying +         * it immediately. +         * +         * The override will be canceled when the setting value is next updated. +         * +         * @param adj The overridden brightness, or Float.NaN to disable the override. +         * +         * @see Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ +         */ +        @Override // Binder call +        public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float adj) { +            mContext.enforceCallingOrSelfPermission( +                    android.Manifest.permission.DEVICE_POWER, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternal(adj); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        /** +         * Used by the phone application to make the attention LED flash when ringing. +         */ +        @Override // Binder call +        public void setAttentionLight(boolean on, int color) { +            mContext.enforceCallingOrSelfPermission( +                    android.Manifest.permission.DEVICE_POWER, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                setAttentionLightInternal(on, color); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override // Binder call +        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { +            if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) +                    != PackageManager.PERMISSION_GRANTED) { +                pw.println("Permission Denial: can't dump PowerManager from from pid=" +                        + Binder.getCallingPid() +                        + ", uid=" + Binder.getCallingUid()); +                return; +            } + +            final long ident = Binder.clearCallingIdentity(); +            try { +                dumpInternal(pw); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } +    } + +    private final class LocalService extends PowerManagerInternal { +        /** +         * Used by the window manager to override the screen brightness based on the +         * current foreground activity. +         * +         * This method must only be called by the window manager. +         * +         * @param brightness The overridden brightness, or -1 to disable the override. +         */ +        @Override +        public void setScreenBrightnessOverrideFromWindowManager(int brightness) { +            mContext.enforceCallingOrSelfPermission( +                    android.Manifest.permission.DEVICE_POWER, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                setScreenBrightnessOverrideFromWindowManagerInternal(brightness); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        /** +         * Used by the window manager to override the button brightness based on the +         * current foreground activity. +         * +         * This method must only be called by the window manager. +         * +         * @param brightness The overridden brightness, or -1 to disable the override. +         */ +        @Override +        public void setButtonBrightnessOverrideFromWindowManager(int brightness) { +            // Do nothing. +            // Button lights are not currently supported in the new implementation. +            mContext.enforceCallingOrSelfPermission( +                    android.Manifest.permission.DEVICE_POWER, null); +        } + +        /** +         * Used by the window manager to override the user activity timeout based on the +         * current foreground activity.  It can only be used to make the timeout shorter +         * than usual, not longer. +         * +         * This method must only be called by the window manager. +         * +         * @param timeoutMillis The overridden timeout, or -1 to disable the override. +         */ +        @Override +        public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) { +            mContext.enforceCallingOrSelfPermission( +                    android.Manifest.permission.DEVICE_POWER, null); + +            final long ident = Binder.clearCallingIdentity(); +            try { +                setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } + +        @Override +        public void setPolicy(WindowManagerPolicy policy) { +            PowerManagerService.this.setPolicy(policy); +        } +    }  } 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..43a99e082295 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,33 +87,32 @@ 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; -    private StatFs mSystemFileStats; -    private StatFs mCacheFileStats; +    private final ContentResolver mResolver; +    private final long mTotalMemory;  // on /data +    private final StatFs mDataFileStats; +    private final StatFs mSystemFileStats; +    private final StatFs mCacheFileStats;      private static final File DATA_PATH = Environment.getDataDirectory();      private static final File SYSTEM_PATH = Environment.getRootDirectory();      private static final File CACHE_PATH = Environment.getDownloadCacheDirectory();      private long mThreadStartTime = -1; -    private boolean mClearSucceeded = false; -    private boolean mClearingCache; -    private Intent mStorageLowIntent; -    private Intent mStorageOkIntent; -    private Intent mStorageFullIntent; -    private Intent mStorageNotFullIntent; +    boolean mClearSucceeded = false; +    boolean mClearingCache; +    private final Intent mStorageLowIntent; +    private final Intent mStorageOkIntent; +    private final Intent mStorageFullIntent; +    private final 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 final 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, @@ -308,14 +310,10 @@ public class DeviceStorageMonitorService extends Binder {                  delay);      } -    /** -    * Constructor to run service. initializes the disk space threshold value -    * and posts an empty message to kickstart the process. -    */      public DeviceStorageMonitorService(Context context) { +        super(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 +329,16 @@ 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); +    } +    /** +    * Initializes the disk space threshold value and posts an empty message to +    * kickstart the process. +    */ +    @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); -    } - -    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; +        getContext().removeStickyBroadcastAsUser(mStorageFullIntent, UserHandle.ALL); +        getContext().sendBroadcastAsUser(mStorageNotFullIntent, UserHandle.ALL);      } -    /** -     * 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/java/com/android/server/display/DisplayTransactionListener.java b/services/core/java/com/android/server/twilight/TwilightManager.java index 34eb8f930e9d..b3de58b279af 100644 --- a/services/java/com/android/server/display/DisplayTransactionListener.java +++ b/services/core/java/com/android/server/twilight/TwilightManager.java @@ -1,5 +1,5 @@  /* - * Copyright (C) 2012 The Android Open Source Project + * 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. @@ -14,13 +14,11 @@   * limitations under the License.   */ -package com.android.server.display; +package com.android.server.twilight; -/** - * Called within a Surface transaction whenever the size or orientation of a - * display may have changed.  Provides an opportunity for the client to - * update the position of its surfaces as part of the same transaction. - */ -public interface DisplayTransactionListener { -    void onDisplayTransaction(); +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..a71961c8fe9b 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,92 @@ 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; - -    private TwilightState mTwilightState; +    TwilightState mTwilightState;      public TwilightService(Context context) { -        mContext = context; +        super(context); +    } -        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); -        mLocationManager = (LocationManager)mContext.getSystemService(Context.LOCATION_SERVICE); +    @Override +    public void onStart() { +        mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); +        mLocationManager = (LocationManager) getContext().getSystemService( +                Context.LOCATION_SERVICE);          mLocationHandler = new LocationHandler(); + +        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); + +        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; +            } +        } + +        /** +         * 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 (mSystemReady && mListeners.size() == 1) { -                mLocationHandler.enableLocationUpdates(); +                if (mListeners.size() == 1) { +                    mLocationHandler.enableLocationUpdates(); +                }              }          } -    } +    };      private void setTwilightState(TwilightState state) {          synchronized (mLock) { @@ -128,9 +143,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 +178,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 +416,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..ca4ad8a32e0d 100644 --- a/services/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -105,6 +105,8 @@ class AppWindowToken extends WindowToken {      // Input application handle used by the input dispatcher.      final InputApplicationHandle mInputApplicationHandle; +    boolean mDeferRemoval; +      AppWindowToken(WindowManagerService _service, IApplicationToken _token) {          super(_service, _token.asBinder(),                  WindowManager.LayoutParams.TYPE_APPLICATION, true); 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..aa7d4851fa9c 100644 --- a/services/java/com/android/server/wm/DimLayer.java +++ b/services/core/java/com/android/server/wm/DimLayer.java @@ -51,9 +51,9 @@ public class DimLayer {      /** Owning stack */      final TaskStack mStack; -    DimLayer(WindowManagerService service, TaskStack stack) { +    DimLayer(WindowManagerService service, TaskStack stack, DisplayContent displayContent) {          mStack = stack; -        mDisplayContent = stack.getDisplayContent(); +        mDisplayContent = displayContent;          final int displayId = mDisplayContent.getDisplayId();          if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId);          SurfaceControl.openTransaction(); @@ -127,6 +127,11 @@ public class DimLayer {      void setBounds(Rect bounds) {          mBounds.set(bounds); +        if (isDimming() && !mLastBounds.equals(bounds)) { +            // Clearing mAlpha forces show to redisplay with new size.  +            mAlpha = 0; +            show(); +        }      }      /** @@ -166,11 +171,11 @@ 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; -            yPos = mBounds.right; +            yPos = mBounds.top;          } else {              // Set surface size to screen size.              final DisplayInfo info = mDisplayContent.getDisplayInfo(); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java new file mode 100644 index 000000000000..68834d8f691b --- /dev/null +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -0,0 +1,372 @@ +/* + * 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.wm; + +import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; +import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY; +import static com.android.server.wm.WindowManagerService.TAG; + +import android.graphics.Rect; +import android.graphics.Region; +import android.util.Slog; +import android.view.Display; +import android.view.DisplayInfo; +import android.view.Surface; + +import java.io.PrintWriter; +import java.util.ArrayList; + +class DisplayContentList extends ArrayList<DisplayContent> { +} + +/** + * Utility class for keeping track of the WindowStates and other pertinent contents of a + * particular Display. + * + * IMPORTANT: No method from this class should ever be used without holding + * WindowManagerService.mWindowMap. + */ +class DisplayContent { + +    /** Unique identifier of this stack. */ +    private final int mDisplayId; + +    /** Z-ordered (bottom-most first) list of all Window objects. Assigned to an element +     * from mDisplayWindows; */ +    private final WindowList mWindows = new WindowList(); + +    // This protects the following display size properties, so that +    // getDisplaySize() doesn't need to acquire the global lock.  This is +    // needed because the window manager sometimes needs to use ActivityThread +    // while it has its global state locked (for example to load animation +    // resources), but the ActivityThread also needs get the current display +    // size sometimes when it has its package lock held. +    // +    // These will only be modified with both mWindowMap and mDisplaySizeLock +    // held (in that order) so the window manager doesn't need to acquire this +    // lock when needing these values in its normal operation. +    final Object mDisplaySizeLock = new Object(); +    int mInitialDisplayWidth = 0; +    int mInitialDisplayHeight = 0; +    int mInitialDisplayDensity = 0; +    int mBaseDisplayWidth = 0; +    int mBaseDisplayHeight = 0; +    int mBaseDisplayDensity = 0; +    private final DisplayInfo mDisplayInfo = new DisplayInfo(); +    private final Display mDisplay; + +    Rect mBaseDisplayRect = new Rect(); +    Rect mContentRect = new Rect(); + +    // Accessed directly by all users. +    boolean layoutNeeded; +    int pendingLayoutChanges; +    final boolean isDefaultDisplay; + +    /** Window tokens that are in the process of exiting, but still on screen for animations. */ +    final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>(); + +    /** Array containing all TaskStacks on this display.  Array +     * is stored in display order with the current bottom stack at 0. */ +    private final ArrayList<TaskStack> mStacks = new ArrayList<TaskStack>(); + +    /** 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 .*/ +    StackTapPointerEventListener mTapDetector; + +    /** Detect user tapping outside of current focused stack bounds .*/ +    Region mTouchExcludeRegion = new Region(); + +    /** Save allocating when calculating rects */ +    Rect mTmpRect = new Rect(); + +    /** For gathering Task objects in order. */ +    final ArrayList<Task> mTmpTaskHistory = new ArrayList<Task>(); + +    final WindowManagerService mService; + +    static final int DEFER_DETACH = 1; +    static final int DEFER_REMOVAL = 2; +    int mDeferredActions; + +    /** +     * @param display May not be null. +     * @param service You know. +     */ +    DisplayContent(Display display, WindowManagerService service) { +        mDisplay = display; +        mDisplayId = display.getDisplayId(); +        display.getDisplayInfo(mDisplayInfo); +        isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY; +        mService = service; +    } + +    int getDisplayId() { +        return mDisplayId; +    } + +    WindowList getWindowList() { +        return mWindows; +    } + +    Display getDisplay() { +        return mDisplay; +    } + +    DisplayInfo getDisplayInfo() { +        return mDisplayInfo; +    } + +    /** +     * Returns true if the specified UID has access to this display. +     */ +    public boolean hasAccess(int uid) { +        return mDisplay.hasAccess(uid); +    } + +    public boolean isPrivate() { +        return (mDisplay.getFlags() & Display.FLAG_PRIVATE) != 0; +    } + +    ArrayList<TaskStack> getStacks() { +        return mStacks; +    } + +    /** +     * Retrieve the tasks on this display in stack order from the bottommost TaskStack up. +     * @return All the Tasks, in order, on this display. +     */ +    ArrayList<Task> getTasks() { +        mTmpTaskHistory.clear(); +        final int numStacks = mStacks.size(); +        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { +            mTmpTaskHistory.addAll(mStacks.get(stackNdx).getTasks()); +        } +        return mTmpTaskHistory; +    } + +    TaskStack getHomeStack() { +        if (mHomeStack == null) { +            Slog.e(TAG, "getHomeStack: Returning null from this=" + this); +        } +        return mHomeStack; +    } + +    void updateDisplayInfo() { +        mDisplay.getDisplayInfo(mDisplayInfo); +        for (int i = mStacks.size() - 1; i >= 0; --i) { +            mStacks.get(i).updateDisplayInfo(); +        } +    } + +    void getLogicalDisplayRect(Rect out) { +        // 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 = (physWidth - width) / 2; +        int height = mDisplayInfo.logicalHeight; +        int top = (physHeight - height) / 2; +        out.set(left, top, left + width, top + height); +    } + +    /** Refer to {@link WindowManagerService#attachStack(int, int)} */ +    void attachStack(TaskStack stack) { +        if (stack.mStackId == HOME_STACK_ID) { +            if (mHomeStack != null) { +                throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first."); +            } +            mHomeStack = stack; +        } +        mStacks.add(stack); +        layoutNeeded = true; +    } + +    void moveStack(TaskStack stack, boolean toTop) { +        mStacks.remove(stack); +        mStacks.add(toTop ? mStacks.size() : 0, stack); +    } + +    void detachStack(TaskStack stack) { +        mStacks.remove(stack); +    } + +    /** +     * Propagate the new bounds to all child stacks. +     * @param contentRect The bounds to apply at the top level. +     */ +    void resize(Rect contentRect) { +        mContentRect.set(contentRect); +    } + +    int stackIdFromPoint(int x, int 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) { +        mTouchExcludeRegion.set(mBaseDisplayRect); +        WindowList windows = getWindowList(); +        for (int i = windows.size() - 1; i >= 0; --i) { +            final WindowState win = windows.get(i); +            final TaskStack stack = win.getStack(); +            if (win.isVisibleLw() && stack != null && stack != focusedStack) { +                mTmpRect.set(win.mVisibleFrame); +                mTmpRect.intersect(win.mVisibleInsets); +                mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE); +            } +        } +    } + +    void switchUserStacks(int newUserId) { +        final WindowList windows = getWindowList(); +        for (int i = 0; i < windows.size(); i++) { +            final WindowState win = windows.get(i); +            if (win.isHiddenFromUserLocked()) { +                if (DEBUG_VISIBILITY) Slog.w(TAG, "user changing " + newUserId + " hiding " +                        + win + ", attrs=" + win.mAttrs.type + ", belonging to " +                        + win.mOwnerUid); +                win.hideLw(false); +            } +        } + +        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { +            mStacks.get(stackNdx).switchUser(newUserId); +        } +    } + +    void resetAnimationBackgroundAnimator() { +        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { +            mStacks.get(stackNdx).resetAnimationBackgroundAnimator(); +        } +    } + +    boolean animateDimLayers() { +        boolean result = false; +        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { +            result |= mStacks.get(stackNdx).animateDimLayers(); +        } +        return result; +    } + +    void resetDimming() { +        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { +            mStacks.get(stackNdx).resetDimmingTag(); +        } +    } + +    boolean isDimming() { +        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { +            if (mStacks.get(stackNdx).isDimming()) { +                return true; +            } +        } +        return false; +    } + +    void stopDimmingIfNeeded() { +        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { +            mStacks.get(stackNdx).stopDimmingIfNeeded(); +        } +    } + +    void close() { +        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { +            mStacks.get(stackNdx).close(); +        } +    } + +    public void dump(String prefix, PrintWriter pw) { +        pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId); +        final String subPrefix = "  " + prefix; +        pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x"); +            pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity); +            pw.print("dpi"); +            if (mInitialDisplayWidth != mBaseDisplayWidth +                    || mInitialDisplayHeight != mBaseDisplayHeight +                    || mInitialDisplayDensity != mBaseDisplayDensity) { +                pw.print(" base="); +                pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight); +                pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi"); +            } +            pw.print(" cur="); +            pw.print(mDisplayInfo.logicalWidth); +            pw.print("x"); pw.print(mDisplayInfo.logicalHeight); +            pw.print(" app="); +            pw.print(mDisplayInfo.appWidth); +            pw.print("x"); pw.print(mDisplayInfo.appHeight); +            pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth); +            pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight); +            pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth); +            pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight); +            pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded); +        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); +        } +        pw.println(); +        pw.println("  Application tokens in bottom up Z order:"); +        int ndx = 0; +        final int numStacks = mStacks.size(); +        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { +            ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks(); +            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { +                AppTokenList tokens = tasks.get(taskNdx).mAppTokens; +                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { +                    final AppWindowToken wtoken = tokens.get(tokenNdx); +                    pw.print("  App #"); pw.print(ndx++); +                            pw.print(' '); pw.print(wtoken); pw.println(":"); +                    wtoken.dump(pw, "    "); +                } +            } +        } +        if (ndx == 0) { +            pw.println("    None"); +        } +        pw.println(); +        if (!mExitingTokens.isEmpty()) { +            pw.println(); +            pw.println("  Exiting tokens:"); +            for (int i=mExitingTokens.size()-1; i>=0; i--) { +                WindowToken token = mExitingTokens.get(i); +                pw.print("  Exiting #"); pw.print(i); +                pw.print(' '); pw.print(token); +                pw.println(':'); +                token.dump(pw, "    "); +            } +        } +        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..ca9076f51496 100644 --- a/services/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -293,7 +293,11 @@ final class Session extends IWindowSession.Stub              // !!! FIXME: put all this heavy stuff onto the mH looper, as well as              // the actual drag event dispatch stuff in the dragstate -            Display display = callingWin.mDisplayContent.getDisplay(); +            final DisplayContent displayContent = callingWin.getDisplayContent(); +            if (displayContent == null) { +               return false; +            } +            Display display = displayContent.getDisplay();              mService.mDragState.register(display);              mService.mInputMonitor.updateInputWindowsLw(true /*force*/);              if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel, 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..036804c55b7d 100644 --- a/services/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -25,6 +25,7 @@ class Task {      final AppTokenList mAppTokens = new AppTokenList();      final int taskId;      final int mUserId; +    boolean mDeferRemoval = false;      Task(AppWindowToken wtoken, TaskStack stack, int userId) {          taskId = wtoken.groupId; @@ -46,7 +47,6 @@ class Task {          if (mAppTokens.size() == 0) {              EventLog.writeEvent(com.android.server.EventLogTags.WM_TASK_REMOVED, taskId,                      "removeAppToken: last token"); -            mStack.removeTask(this);              return true;          }          return false; 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..c70bc621658b 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; @@ -43,23 +41,29 @@ public class TaskStack {      private final WindowManagerService mService;      /** The display this stack sits under. */ -    private final DisplayContent mDisplayContent; +    private DisplayContent mDisplayContent;      /** The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match       * mTaskHistory in the ActivityStack with the same mStackId */      private final ArrayList<Task> mTasks = new ArrayList<Task>(); -    /** The StackBox this sits in. */ -    StackBox mStackBox; +    /** For comparison with DisplayContent bounds. */ +    private Rect mTmpRect = new Rect(); + +    /** Content limits relative to the DisplayContent this sits in. */ +    private Rect mBounds = new Rect(); + +    /** Whether mBounds is fullscreen */ +    private boolean mFullscreen = true;      /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */ -    final DimLayer mDimLayer; +    private DimLayer mDimLayer;      /** The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer. */      WindowStateAnimator mDimWinAnimator;      /** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */ -    final DimLayer mAnimationBackgroundSurface; +    DimLayer mAnimationBackgroundSurface;      /** The particular window with an Animation with non-zero background color. */      WindowStateAnimator mAnimationBackgroundAnimator; @@ -68,12 +72,15 @@ public class TaskStack {       * then stop any dimming. */      boolean mDimmingTag; -    TaskStack(WindowManagerService service, int stackId, DisplayContent displayContent) { +    /** Application tokens that are exiting, but still on screen for animations. */ +    final AppTokenList mExitingAppTokens = new AppTokenList(); + +    TaskStack(WindowManagerService service, int stackId) {          mService = service;          mStackId = stackId; -        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 +91,73 @@ public class TaskStack {          return mTasks;      } -    boolean isHomeStack() { -        return mStackId == HOME_STACK_ID; +    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 hasSibling() { -        return mStackBox.mParent != null; +    boolean setBounds(Rect bounds) { +        boolean oldFullscreen = mFullscreen; +        if (mDisplayContent != null) { +            mDisplayContent.getLogicalDisplayRect(mTmpRect); +            mFullscreen = mTmpRect.equals(bounds); +        } + +        if (mBounds.equals(bounds) && oldFullscreen == mFullscreen) { +            return false; +        } + +        mDimLayer.setBounds(bounds); +        mAnimationBackgroundSurface.setBounds(bounds); +        mBounds.set(bounds); + +        return true; +    } + +    void getBounds(Rect out) { +        out.set(mBounds); +    } + +    void updateDisplayInfo() { +        if (mFullscreen && mDisplayContent != null) { +            mDisplayContent.getLogicalDisplayRect(mTmpRect); +            setBounds(mTmpRect); +        } +    } + +    boolean isFullscreen() { +        return mFullscreen; +    } + +    boolean isAnimating() { +        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) { +                    if (windows.get(winNdx).mWinAnimator.isAnimating()) { +                        return true; +                    } +                } +            } +        } +        return false;      }      /** @@ -97,9 +165,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; @@ -121,40 +187,60 @@ public class TaskStack {          mTasks.add(stackNdx, task);          task.mStack = this; -        mDisplayContent.addTask(task, toTop); -        return mDisplayContent.moveHomeStackBox(mStackId == HOME_STACK_ID); +        mDisplayContent.moveStack(this, true); +        EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.taskId, toTop ? 1 : 0, stackNdx);      } -    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);      }      /** -     * Delete a Task from this stack. If it is the last Task in the stack, remove this stack from -     * its parent StackBox and merge the parent. +     * Delete a Task from this stack. If it is the last Task in the stack, move this stack to the +     * back.       * @param task The Task to delete.       */      void removeTask(Task task) {          if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task); -        mStackBox.makeDirty();          mTasks.remove(task); -        mDisplayContent.removeTask(task); +        if (mDisplayContent != null) { +            if (mTasks.isEmpty()) { +                mDisplayContent.moveStack(this, false); +            } +            mDisplayContent.layoutNeeded = true; +        } +    } + +    void attachDisplayContent(DisplayContent displayContent) { +        if (mDisplayContent != null) { +            throw new IllegalStateException("attachDisplayContent: Already attached"); +        } + +        mDisplayContent = displayContent; +        mDimLayer = new DimLayer(mService, this, displayContent); +        mAnimationBackgroundSurface = new DimLayer(mService, this, displayContent); +        updateDisplayInfo();      } -    int remove() { +    void detachDisplay() { +        EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId); +        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { +            mService.tmpRemoveTaskWindowsLocked(mTasks.get(taskNdx)); +        }          mAnimationBackgroundSurface.destroySurface(); +        mAnimationBackgroundSurface = null;          mDimLayer.destroySurface(); -        EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId); -        return mStackBox.remove(); +        mDimLayer = null; +        mDisplayContent = null;      }      void resetAnimationBackgroundAnimator() { @@ -259,28 +345,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 +357,39 @@ public class TaskStack {          }      } +    void close() { +        mDimLayer.mDimSurface.destroy(); +        mAnimationBackgroundSurface.mDimSurface.destroy(); +    } + +    void checkForDeferredActions() { +        if (mDisplayContent != null && +                (mDisplayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0 && +                !isAnimating()) { +            mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_DETACH; +            if ((mDisplayContent.mDeferredActions & DisplayContent.DEFER_REMOVAL) != 0) { +                mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_REMOVAL; +                mService.onDisplayRemoved(mDisplayContent.getDisplayId()); +            } +            mService.detachStack(mStackId); +        } +        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { +            final Task task = mTasks.get(taskNdx); +            AppTokenList tokens = task.mAppTokens; +            for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { +                AppWindowToken wtoken = tokens.get(tokenNdx); +                if (wtoken.mDeferRemoval) { +                    wtoken.mDeferRemoval = false; +                    mService.removeAppFromTaskLocked(wtoken); +                } +            } +            if (task.mDeferRemoval) { +                task.mDeferRemoval = false; +                mService.removeTaskLocked(task); +            } +        } +    } +      public void dump(String prefix, PrintWriter pw) {          pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);          for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) { @@ -307,6 +404,17 @@ public class TaskStack {              mDimLayer.printTo(prefix, pw);              pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);          } +        if (!mExitingAppTokens.isEmpty()) { +            pw.println(); +            pw.println("  Exiting application tokens:"); +            for (int i=mExitingAppTokens.size()-1; i>=0; i--) { +                WindowToken token = mExitingAppTokens.get(i); +                pw.print("  Exiting App #"); pw.print(i); +                pw.print(' '); pw.print(token); +                pw.println(':'); +                token.dump(pw, "    "); +            } +        }      }      @Override 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..a9947c05d2b9 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -64,7 +64,7 @@ public class WindowAnimator {      Object mLastWindowFreezeSource;      SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators = -            new SparseArray<WindowAnimator.DisplayContentsAnimator>(2); +            new SparseArray<DisplayContentsAnimator>(2);      boolean mInitialized = false; @@ -151,14 +151,33 @@ public class WindowAnimator {      }      private void updateAppWindowsLocked(int displayId) { -        final DisplayContent displayContent = mService.getDisplayContentLocked(displayId); -        final ArrayList<Task> tasks = displayContent.getTasks(); -        final int numTasks = tasks.size(); -        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { -            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; -            final int numTokens = tokens.size(); -            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { -                final AppWindowAnimator appAnimator = tokens.get(tokenNdx).mAppAnimator; +        ArrayList<TaskStack> stacks = mService.getDisplayContentLocked(displayId).getStacks(); +        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { +            final TaskStack stack = stacks.get(stackNdx); +            final ArrayList<Task> tasks = stack.getTasks(); +            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { +                final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; +                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { +                    final AppWindowAnimator appAnimator = tokens.get(tokenNdx).mAppAnimator; +                    final boolean wasAnimating = appAnimator.animation != null +                            && appAnimator.animation != AppWindowAnimator.sDummyAnimation; +                    if (appAnimator.stepAnimationLocked(mCurrentTime)) { +                        mAnimating = true; +                    } else if (wasAnimating) { +                        // stopped animating, do one more pass through the layout +                        setAppLayoutChanges(appAnimator, +                                WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, +                                "appToken " + appAnimator.mAppToken + " done"); +                        if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, +                                "updateWindowsApps...: done animating " + appAnimator.mAppToken); +                    } +                } +            } + +            final AppTokenList exitingAppTokens = stack.mExitingAppTokens; +            final int NEAT = exitingAppTokens.size(); +            for (int i = 0; i < NEAT; i++) { +                final AppWindowAnimator appAnimator = exitingAppTokens.get(i).mAppAnimator;                  final boolean wasAnimating = appAnimator.animation != null                          && appAnimator.animation != AppWindowAnimator.sDummyAnimation;                  if (appAnimator.stepAnimationLocked(mCurrentTime)) { @@ -166,29 +185,12 @@ public class WindowAnimator {                  } else if (wasAnimating) {                      // stopped animating, do one more pass through the layout                      setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, -                            "appToken " + appAnimator.mAppToken + " done"); +                        "exiting appToken " + appAnimator.mAppToken + " done");                      if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, -                            "updateWindowsApps...: done animating " + appAnimator.mAppToken); +                            "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken);                  }              }          } - -        final AppTokenList exitingAppTokens = displayContent.mExitingAppTokens; -        final int NEAT = exitingAppTokens.size(); -        for (int i = 0; i < NEAT; i++) { -            final AppWindowAnimator appAnimator = exitingAppTokens.get(i).mAppAnimator; -            final boolean wasAnimating = appAnimator.animation != null -                    && appAnimator.animation != AppWindowAnimator.sDummyAnimation; -            if (appAnimator.stepAnimationLocked(mCurrentTime)) { -                mAnimating = true; -            } else if (wasAnimating) { -                // stopped animating, do one more pass through the layout -                setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, -                    "exiting appToken " + appAnimator.mAppToken + " done"); -                if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, -                        "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken); -            } -        }      }      private void updateWindowsLocked(final int displayId) { @@ -449,11 +451,6 @@ public class WindowAnimator {          }      } -    private void performAnimationsLocked(final int displayId) { -        updateWindowsLocked(displayId); -        updateWallpaperLocked(displayId); -    } -      /** Locked on mService.mWindowMap. */      private void animateLocked() { @@ -494,7 +491,8 @@ public class WindowAnimator {                  // Update animations of all applications, including those                  // associated with exiting/removed apps -                performAnimationsLocked(displayId); +                updateWindowsLocked(displayId); +                updateWallpaperLocked(displayId);                  final WindowList windows = mService.getWindowListLocked(displayId);                  final int N = windows.size(); @@ -642,11 +640,16 @@ public class WindowAnimator {      }      int getPendingLayoutChanges(final int displayId) { +        if (displayId < 0) { +            return 0; +        }          return mService.getDisplayContentLocked(displayId).pendingLayoutChanges;      }      void setPendingLayoutChanges(final int displayId, final int changes) { -        mService.getDisplayContentLocked(displayId).pendingLayoutChanges |= changes; +        if (displayId >= 0) { +            mService.getDisplayContentLocked(displayId).pendingLayoutChanges |= changes; +        }      }      void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) { @@ -655,7 +658,7 @@ public class WindowAnimator {          WindowList windows = appAnimator.mAppToken.allAppWindows;          for (int i = windows.size() - 1; i >= 0; i--) {              final int displayId = windows.get(i).getDisplayId(); -            if (displays.indexOfKey(displayId) < 0) { +            if (displayId >= 0 && displays.indexOfKey(displayId) < 0) {                  setPendingLayoutChanges(displayId, changes);                  if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {                      mService.debugLayoutRepeats(s, getPendingLayoutChanges(displayId)); @@ -676,10 +679,15 @@ public class WindowAnimator {      }      void setScreenRotationAnimationLocked(int displayId, ScreenRotationAnimation animation) { -        getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation; +        if (displayId >= 0) { +            getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation; +        }      }      ScreenRotationAnimation getScreenRotationAnimationLocked(int displayId) { +        if (displayId < 0) { +            return null; +        }          return getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation;      } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f9773a6f25cf..296e50bd133b 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -18,11 +18,10 @@ package com.android.server.wm;  import static android.view.WindowManager.LayoutParams.*; -import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; -  import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;  import android.app.AppOpsManager; +import android.util.ArraySet;  import android.util.TimeUtils;  import android.view.IWindowId; @@ -35,17 +34,16 @@ import com.android.internal.view.IInputMethodClient;  import com.android.internal.view.IInputMethodManager;  import com.android.internal.view.WindowManagerPolicyThread;  import com.android.server.AttributeCache; +import com.android.server.DisplayThread;  import com.android.server.EventLogTags; +import com.android.server.LocalServices;  import com.android.server.UiThread;  import com.android.server.Watchdog;  import com.android.server.am.BatteryStatsService; -import com.android.server.display.DisplayManagerService;  import com.android.server.input.InputManagerService; -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; @@ -69,6 +67,7 @@ import android.graphics.Rect;  import android.graphics.RectF;  import android.graphics.Region;  import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManagerInternal;  import android.os.Binder;  import android.os.Bundle;  import android.os.Debug; @@ -80,6 +79,7 @@ import android.os.Message;  import android.os.Parcel;  import android.os.ParcelFileDescriptor;  import android.os.PowerManager; +import android.os.PowerManagerInternal;  import android.os.Process;  import android.os.RemoteException;  import android.os.ServiceManager; @@ -117,6 +117,7 @@ import android.view.InputEventReceiver;  import android.view.KeyEvent;  import android.view.MagnificationSpec;  import android.view.MotionEvent; +import android.view.WindowManagerInternal;  import android.view.Surface.OutOfResourcesException;  import android.view.Surface;  import android.view.SurfaceControl; @@ -155,8 +156,7 @@ import java.util.List;  /** {@hide} */  public class WindowManagerService extends IWindowManager.Stub -        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs, -                DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener { +        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {      static final String TAG = "WindowManager";      static final boolean DEBUG = false;      static final boolean DEBUG_ADD_REMOVE = false; @@ -272,10 +272,10 @@ public class WindowManagerService extends IWindowManager.Stub      // Default input dispatching timeout in nanoseconds.      static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L; -    /** Minimum value for createStack and resizeStack weight value */ +    /** Minimum value for attachStack and resizeStack weight value */      public static final float STACK_WEIGHT_MIN = 0.2f; -    /** Maximum value for createStack and resizeStack weight value */ +    /** Maximum value for attachStack and resizeStack weight value */      public static final float STACK_WEIGHT_MAX = 0.8f;      static final int UPDATE_FOCUS_NORMAL = 0; @@ -293,8 +293,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) { @@ -369,6 +367,11 @@ public class WindowManagerService extends IWindowManager.Stub      final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();      /** +     * Stacks whose animations have ended and whose tasks, apps, selves may now be removed. +     */ +    final ArraySet<TaskStack> mPendingStacksRemove = new ArraySet<TaskStack>(); + +    /**       * Used when processing mPendingRemove to avoid working on the original array.       */      WindowState[] mPendingRemoveTmp = new WindowState[20]; @@ -534,14 +537,15 @@ public class WindowManagerService extends IWindowManager.Stub      AppWindowToken mFocusedApp = null; -    PowerManagerService mPowerManager; +    PowerManager mPowerManager; +    PowerManagerInternal mPowerManagerInternal;      float mWindowAnimationScale = 1.0f;      float mTransitionAnimationScale = 1.0f;      float mAnimatorDurationScale = 1.0f;      final InputManagerService mInputManager; -    final DisplayManagerService mDisplayManagerService; +    final DisplayManagerInternal mDisplayManagerInternal;      final DisplayManager mDisplayManager;      // Who is holding the screen on. @@ -600,6 +604,9 @@ public class WindowManagerService extends IWindowManager.Stub      final WindowAnimator mAnimator;      SparseArray<Task> mTaskIdToTask = new SparseArray<Task>(); + +    /** All of the TaskStacks in the window manager, unordered. For an ordered list call +     * DisplayContent.getStacks(). */      SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>();      private final PointerEventDispatcher mPointerEventDispatcher; @@ -694,23 +701,22 @@ public class WindowManagerService extends IWindowManager.Stub      final boolean mOnlyCore;      public static WindowManagerService main(final Context context, -            final PowerManagerService pm, final DisplayManagerService dm, -            final InputManagerService im, final Handler wmHandler, +            final InputManagerService im,              final boolean haveInputMethods, final boolean showBootMsgs,              final boolean onlyCore) {          final WindowManagerService[] holder = new WindowManagerService[1]; -        wmHandler.runWithScissors(new Runnable() { +        DisplayThread.getHandler().runWithScissors(new Runnable() {              @Override              public void run() { -                holder[0] = new WindowManagerService(context, pm, dm, im, +                holder[0] = new WindowManagerService(context, im,                          haveInputMethods, showBootMsgs, onlyCore);              }          }, 0);          return holder[0];      } -    private void initPolicy(Handler uiHandler) { -        uiHandler.runWithScissors(new Runnable() { +    private void initPolicy() { +        UiThread.getHandler().runWithScissors(new Runnable() {              @Override              public void run() {                  WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper()); @@ -723,8 +729,7 @@ public class WindowManagerService extends IWindowManager.Stub          }, 0);      } -    private WindowManagerService(Context context, PowerManagerService pm, -            DisplayManagerService displayManager, InputManagerService inputManager, +    private WindowManagerService(Context context, InputManagerService inputManager,              boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {          mContext = context;          mHaveInputMethods = haveInputMethods; @@ -733,8 +738,7 @@ public class WindowManagerService extends IWindowManager.Stub          mLimitedAlphaCompositing = context.getResources().getBoolean(                  com.android.internal.R.bool.config_sf_limitedAlpha);          mInputManager = inputManager; // Must be before createDisplayContentLocked. -        mDisplayManagerService = displayManager; -        mHeadless = displayManager.isHeadless(); +        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);          mDisplaySettings = new DisplaySettings(context);          mDisplaySettings.readSettingsLocked(); @@ -742,7 +746,6 @@ public class WindowManagerService extends IWindowManager.Stub          mFxSession = new SurfaceSession();          mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); -        mDisplayManager.registerDisplayListener(this, null);          Display[] displays = mDisplayManager.getDisplays();          for (Display display : displays) {              createDisplayContentLocked(display); @@ -750,10 +753,11 @@ public class WindowManagerService extends IWindowManager.Stub          mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy); -        mPowerManager = pm; -        mPowerManager.setPolicy(mPolicy); -        PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE); -        mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN"); +        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); +        mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); +        mPowerManagerInternal.setPolicy(mPolicy); // TODO: register as local service instead +        mScreenFrozenLock = mPowerManager.newWakeLock( +                PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");          mScreenFrozenLock.setReferenceCounted(false);          mAppTransition = new AppTransition(context, mH); @@ -783,13 +787,13 @@ public class WindowManagerService extends IWindowManager.Stub          filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);          mContext.registerReceiver(mBroadcastReceiver, filter); -        mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK -                | PowerManager.ON_AFTER_RELEASE, TAG); +        mHoldingScreenWakeLock = mPowerManager.newWakeLock( +                PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);          mHoldingScreenWakeLock.setReferenceCounted(false);          mAnimator = new WindowAnimator(this); -        initPolicy(UiThread.getHandler()); +        initPolicy();          // Add ourself to the Watchdog monitors.          Watchdog.getInstance().addMonitor(this); @@ -802,6 +806,8 @@ public class WindowManagerService extends IWindowManager.Stub          } finally {              SurfaceControl.closeTransaction();          } + +        LocalServices.addService(WindowManagerInternal.class, new LocalService());      }      public InputMonitor getInputMonitor() { @@ -871,7 +877,7 @@ public class WindowManagerService extends IWindowManager.Stub          final int count = token.windows.size();          for (int i = 0; i < count; i++) {              final WindowState win = token.windows.get(i); -            if (win.mDisplayContent == displayContent) { +            if (win.getDisplayContent() == displayContent) {                  windowList.add(win);              }          } @@ -902,7 +908,7 @@ public class WindowManagerService extends IWindowManager.Stub      private int addAppWindowToListLocked(final WindowState win) {          final IWindow client = win.mClient;          final WindowToken token = win.mToken; -        final DisplayContent displayContent = win.mDisplayContent; +        final DisplayContent displayContent = win.getDisplayContent();          final WindowList windows = win.getWindowList();          final int N = windows.size(); @@ -1079,7 +1085,7 @@ public class WindowManagerService extends IWindowManager.Stub      private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) {          final WindowToken token = win.mToken; -        final DisplayContent displayContent = win.mDisplayContent; +        final DisplayContent displayContent = win.getDisplayContent();          final WindowState attached = win.mAttachedWindow;          WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent); @@ -2013,7 +2019,10 @@ public class WindowManagerService extends IWindowManager.Stub      }      void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) { -        final DisplayContent displayContent = changingTarget.mDisplayContent; +        final DisplayContent displayContent = changingTarget.getDisplayContent(); +        if (displayContent == null) { +            return; +        }          final DisplayInfo displayInfo = displayContent.getDisplayInfo();          final int dw = displayInfo.logicalWidth;          final int dh = displayInfo.logicalHeight; @@ -2073,7 +2082,10 @@ public class WindowManagerService extends IWindowManager.Stub      void updateWallpaperVisibilityLocked() {          final boolean visible = isWallpaperVisible(mWallpaperTarget); -        final DisplayContent displayContent = mWallpaperTarget.mDisplayContent; +        final DisplayContent displayContent = mWallpaperTarget.getDisplayContent(); +        if (displayContent == null) { +            return; +        }          final DisplayInfo displayInfo = displayContent.getDisplayInfo();          final int dw = displayInfo.logicalWidth;          final int dh = displayInfo.logicalHeight; @@ -2428,7 +2440,10 @@ public class WindowManagerService extends IWindowManager.Stub                  //Slog.i(TAG, "*** Running exit animation...");                  win.mExiting = true;                  win.mRemoveOnExit = true; -                win.mDisplayContent.layoutNeeded = true; +                final DisplayContent displayContent = win.getDisplayContent(); +                if (displayContent != null) { +                    displayContent.layoutNeeded = true; +                }                  updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,                          false /*updateInputWindows*/);                  performLayoutAndPlaceSurfacesLocked(); @@ -2485,8 +2500,6 @@ public class WindowManagerService extends IWindowManager.Stub              mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());          } -        final WindowList windows = win.getWindowList(); -        windows.remove(win);          mPendingRemove.remove(win);          mResizingWindows.remove(win);          mWindowsChanged = true; @@ -2542,12 +2555,19 @@ public class WindowManagerService extends IWindowManager.Stub                      WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;          } -        if (!mInLayout) { -            assignLayersLocked(windows); -            win.mDisplayContent.layoutNeeded = true; -            performLayoutAndPlaceSurfacesLocked(); -            if (win.mAppToken != null) { -                win.mAppToken.updateReportedVisibilityLocked(); +        final WindowList windows = win.getWindowList(); +        if (windows != null) { +            windows.remove(win); +            if (!mInLayout) { +                assignLayersLocked(windows); +                final DisplayContent displayContent = win.getDisplayContent(); +                if (displayContent != null) { +                    displayContent.layoutNeeded = true; +                } +                performLayoutAndPlaceSurfacesLocked(); +                if (win.mAppToken != null) { +                    win.mAppToken.updateReportedVisibilityLocked(); +                }              }          } @@ -2622,7 +2642,10 @@ public class WindowManagerService extends IWindowManager.Stub                          w.mGivenVisibleInsets.scale(w.mGlobalScale);                          w.mGivenTouchableRegion.scale(w.mGlobalScale);                      } -                    w.mDisplayContent.layoutNeeded = true; +                    final DisplayContent displayContent = w.getDisplayContent(); +                    if (displayContent != null) { +                        displayContent.layoutNeeded = true; +                    }                      performLayoutAndPlaceSurfacesLocked();                  }              } @@ -2708,7 +2731,12 @@ public class WindowManagerService extends IWindowManager.Stub          mTmpFloats[Matrix.MSKEW_X] = dsdy;          mTmpFloats[Matrix.MSCALE_Y] = dtdy;          matrix.setValues(mTmpFloats); -        final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo(); +        final DisplayContent displayContent = window.getDisplayContent(); +        if (displayContent == null) { +            return; +        } + +        final DisplayInfo displayInfo = window.getDisplayContent().getDisplayInfo();          final RectF dispRect = new RectF(0, 0,                  displayInfo.logicalWidth, displayInfo.logicalHeight);          matrix.mapRect(dispRect); @@ -2717,7 +2745,7 @@ public class WindowManagerService extends IWindowManager.Stub          window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,                  (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);          window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; -        window.mDisplayContent.layoutNeeded = true; +        displayContent.layoutNeeded = true;          performLayoutAndPlaceSurfacesLocked();      } @@ -2998,7 +3026,10 @@ public class WindowManagerService extends IWindowManager.Stub                          WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;              } -            win.mDisplayContent.layoutNeeded = true; +            final DisplayContent displayContent = win.getDisplayContent(); +            if (displayContent != null) { +                displayContent.layoutNeeded = true; +            }              win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;              configChanged = updateOrientationFromAppTokensLocked(false);              performLayoutAndPlaceSurfacesLocked(); @@ -3092,7 +3123,10 @@ public class WindowManagerService extends IWindowManager.Stub                          getDefaultDisplayContentLocked().pendingLayoutChanges |=                                  WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;                      } -                    win.mDisplayContent.layoutNeeded = true; +                    final DisplayContent displayContent = win.getDisplayContent(); +                    if (displayContent != null) { +                        displayContent.layoutNeeded = true; +                    }                      requestTraversalLocked();                  }              } @@ -3350,7 +3384,7 @@ public class WindowManagerService extends IWindowManager.Stub                      for (int i=0; i<N; i++) {                          WindowState win = wtoken.windows.get(i); -                        displayContent = win.mDisplayContent; +                        displayContent = win.getDisplayContent();                          if (win.mWinAnimator.isAnimating()) {                              delayed = true; @@ -3365,7 +3399,9 @@ public class WindowManagerService extends IWindowManager.Stub                                          WindowManagerPolicy.TRANSIT_EXIT);                              }                              changed = true; -                            displayContent.layoutNeeded = true; +                            if (displayContent != null) { +                                displayContent.layoutNeeded = true; +                            }                          }                      } @@ -3378,7 +3414,9 @@ public class WindowManagerService extends IWindowManager.Stub                      }                      if (delayed) { -                        displayContent.mExitingTokens.add(wtoken); +                        if (displayContent != null) { +                            displayContent.mExitingTokens.add(wtoken); +                        }                      } else if (wtoken.windowType == TYPE_WALLPAPER) {                          mWallpaperTokens.remove(wtoken);                      } @@ -3393,6 +3431,8 @@ public class WindowManagerService extends IWindowManager.Stub      }      private Task createTask(int taskId, int stackId, int userId, AppWindowToken atoken) { +        if (DEBUG_STACK) Slog.i(TAG, "createTask: taskId=" + taskId + " stackId=" + stackId +                + " atoken=" + atoken);          final TaskStack stack = mStackIdToStack.get(stackId);          if (stack == null) {              throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId); @@ -3474,8 +3514,8 @@ public class WindowManagerService extends IWindowManager.Stub                  Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);                  return;              } -            Task oldTask = mTaskIdToTask.get(atoken.groupId); -            oldTask.removeAppToken(atoken); +            final Task oldTask = mTaskIdToTask.get(atoken.groupId); +            removeAppFromTaskLocked(atoken);              atoken.groupId = groupId;              Task newTask = mTaskIdToTask.get(groupId); @@ -3626,7 +3666,7 @@ public class WindowManagerService extends IWindowManager.Stub              if (freezeThisOneIfNeeded != null) {                  AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded);                  if (atoken != null) { -                    startAppFreezingScreenLocked(atoken, ActivityInfo.CONFIG_ORIENTATION); +                    startAppFreezingScreenLocked(atoken);                  }              }              config = computeNewConfigurationLocked(); @@ -3768,7 +3808,10 @@ public class WindowManagerService extends IWindowManager.Stub          if (mFocusedApp != null) {              Task task = mTaskIdToTask.get(mFocusedApp.groupId);              stack = task.mStack; -            task.getDisplayContent().setTouchExcludeRegion(stack); +            final DisplayContent displayContent = task.getDisplayContent(); +            if (displayContent != null) { +                displayContent.setTouchExcludeRegion(stack); +            }          } else {              stack = null;          } @@ -3778,10 +3821,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 { @@ -4219,7 +4260,10 @@ public class WindowManagerService extends IWindowManager.Stub                              }                          }                          changed = true; -                        win.mDisplayContent.layoutNeeded = true; +                        final DisplayContent displayContent = win.getDisplayContent(); +                        if (displayContent != null) { +                            displayContent.layoutNeeded = true; +                        }                      }                  } else if (win.isVisibleNow()) {                      if (!runningAppAnimation) { @@ -4233,7 +4277,10 @@ public class WindowManagerService extends IWindowManager.Stub                          }                      }                      changed = true; -                    win.mDisplayContent.layoutNeeded = true; +                    final DisplayContent displayContent = win.getDisplayContent(); +                    if (displayContent != null) { +                        displayContent.layoutNeeded = true; +                    }                  }              } @@ -4381,7 +4428,10 @@ public class WindowManagerService extends IWindowManager.Stub                      }                      w.mLastFreezeDuration = 0;                      unfrozeWindows = true; -                    w.mDisplayContent.layoutNeeded = true; +                    final DisplayContent displayContent = w.getDisplayContent(); +                    if (displayContent != null) { +                        displayContent.layoutNeeded = true; +                    }                  }              }              if (force || unfrozeWindows) { @@ -4401,8 +4451,7 @@ public class WindowManagerService extends IWindowManager.Stub          }      } -    public void startAppFreezingScreenLocked(AppWindowToken wtoken, -            int configChanges) { +    private void startAppFreezingScreenLocked(AppWindowToken wtoken) {          if (DEBUG_ORIENTATION) {              RuntimeException e = null;              if (!HIDE_STACK_CRAWLS) { @@ -4451,7 +4500,7 @@ public class WindowManagerService extends IWindowManager.Stub                  return;              }              final long origId = Binder.clearCallingIdentity(); -            startAppFreezingScreenLocked(wtoken, configChanges); +            startAppFreezingScreenLocked(wtoken);              Binder.restoreCallingIdentity(origId);          }      } @@ -4476,6 +4525,17 @@ public class WindowManagerService extends IWindowManager.Stub          }      } +    void removeAppFromTaskLocked(AppWindowToken wtoken) { +        final Task task = mTaskIdToTask.get(wtoken.groupId); +        if (task != null) { +            task.removeAppToken(wtoken); +            // Remove after bug resolved. +            Slog.d(TAG, "removeAppFromTaskLocked: wtoken=" + wtoken +                    + " numTokens left=" + task.mAppTokens.size() +                    + " Callers=" + Debug.getCallers(5)); +        } +    } +      @Override      public void removeAppToken(IBinder token) {          if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, @@ -4508,26 +4568,25 @@ public class WindowManagerService extends IWindowManager.Stub                          TAG, "Removing app " + wtoken + " delayed=" + delayed                          + " animation=" + wtoken.mAppAnimator.animation                          + " animating=" + wtoken.mAppAnimator.animating); -                final Task task = mTaskIdToTask.get(wtoken.groupId); -                DisplayContent displayContent = task.getDisplayContent(); +                final TaskStack stack = mTaskIdToTask.get(wtoken.groupId).mStack;                  if (delayed) {                      // set the token aside because it has an active animation to be finished                      if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,                              "removeAppToken make exiting: " + wtoken); -                    displayContent.mExitingAppTokens.add(wtoken); +                    stack.mExitingAppTokens.add(wtoken); +                    wtoken.mDeferRemoval = true;                  } else {                      // Make sure there is no animation running on this token,                      // so any windows associated with it will be removed as                      // soon as their animations are complete                      wtoken.mAppAnimator.clearAnimation();                      wtoken.mAppAnimator.animating = false; +                    removeAppFromTaskLocked(wtoken);                  }                  if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,                          "removeAppToken: " + wtoken); -                if (task.removeAppToken(wtoken)) { -                    mTaskIdToTask.delete(wtoken.groupId); -                } +                  wtoken.removed = true;                  if (wtoken.startingData != null) {                      startingToken = wtoken; @@ -4572,13 +4631,15 @@ public class WindowManagerService extends IWindowManager.Stub              mH.sendMessage(m);          }      } +      private boolean tmpRemoveAppWindowsLocked(WindowToken token) { -        final int NW = token.windows.size(); +        WindowList windows = token.windows; +        final int NW = windows.size();          if (NW > 0) {              mWindowsChanged = true;          } -        for (int i=0; i<NW; i++) { -            WindowState win = token.windows.get(i); +        for (int i = 0; i < NW; i++) { +            WindowState win = windows.get(i);              if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);              win.getWindowList().remove(win);              int j = win.mChildWindows.size(); @@ -4594,29 +4655,32 @@ public class WindowManagerService extends IWindowManager.Stub      }      void dumpAppTokensLocked() { -        final int numDisplays = mDisplayContents.size(); -        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { -            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); -            Slog.v(TAG, "  Display " + displayContent.getDisplayId()); -            final ArrayList<Task> tasks = displayContent.getTasks(); -            int i = displayContent.numTokens(); -            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { -                AppTokenList tokens = tasks.get(taskNdx).mAppTokens; -                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { -                    final AppWindowToken wtoken = tokens.get(tokenNdx); -                    Slog.v(TAG, "  #" + --i + ": " + wtoken.token); +        final int numStacks = mStackIdToStack.size(); +        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { +            final TaskStack stack = mStackIdToStack.valueAt(stackNdx); +            Slog.v(TAG, "  Stack #" + stack.mStackId + " tasks from bottom to top:"); +            final ArrayList<Task> tasks = stack.getTasks(); +            final int numTasks = tasks.size(); +            for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { +                final Task task = tasks.get(taskNdx); +                Slog.v(TAG, "    Task #" + task.taskId + " activities from bottom to top:"); +                AppTokenList tokens = task.mAppTokens; +                final int numTokens = tokens.size(); +                for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { +                    Slog.v(TAG, "      activity #" + tokenNdx + ": " + tokens.get(tokenNdx).token);                  }              }          }      }      void dumpWindowsLocked() { -        int i = 0;          final int numDisplays = mDisplayContents.size();          for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { -            final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList(); +            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); +            Slog.v(TAG, " Display #" + displayContent.getDisplayId()); +            final WindowList windows = displayContent.getWindowList();              for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { -                Slog.v(TAG, "  #" + i++ + ": " + windows.get(winNdx)); +                Slog.v(TAG, "  #" + winNdx + ": " + windows.get(winNdx));              }          }      } @@ -4728,23 +4792,28 @@ public class WindowManagerService extends IWindowManager.Stub          final int NW = token.windows.size();          for (int i=0; i<NW; i++) {              final WindowState win = token.windows.get(i); -            if (win.mDisplayContent == displayContent) { +            final DisplayContent winDisplayContent = win.getDisplayContent(); +            if (winDisplayContent == displayContent || winDisplayContent == null) { +                win.mDisplayContent = displayContent;                  index = reAddWindowLocked(index, win);              }          }          return index;      } +    void tmpRemoveTaskWindowsLocked(Task task) { +        AppTokenList tokens = task.mAppTokens; +        for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { +            tmpRemoveAppWindowsLocked(tokens.get(tokenNdx)); +        } +    } +      void moveStackWindowsLocked(DisplayContent displayContent) {          // First remove all of the windows from the list.          final ArrayList<Task> tasks = displayContent.getTasks();          final int numTasks = tasks.size();          for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { -            AppTokenList tokens = tasks.get(taskNdx).mAppTokens; -            final int numTokens = tokens.size(); -            for (int tokenNdx = numTokens - 1; tokenNdx >= 0; --tokenNdx) { -                tmpRemoveAppWindowsLocked(tokens.get(tokenNdx)); -            } +            tmpRemoveTaskWindowsLocked(tasks.get(taskNdx));          }          // And now add them back at the correct place. @@ -4788,10 +4857,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,54 +4893,66 @@ 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) { -                    mStackIdToStack.put(stackId, stack); -                    performLayoutAndPlaceSurfacesLocked(); -                    return; +    public void attachStack(int stackId, int displayId) { +        final long origId = Binder.clearCallingIdentity(); +        try { +            synchronized (mWindowMap) { +                final DisplayContent displayContent = mDisplayContents.get(displayId); +                if (displayContent != null) { +                    TaskStack stack = mStackIdToStack.get(stackId); +                    if (stack == null) { +                        if (DEBUG_STACK) Slog.d(TAG, "attachStack: stackId=" + stackId); +                        stack = new TaskStack(this, stackId); +                        mStackIdToStack.put(stackId, stack); +                    } +                    stack.attachDisplayContent(displayContent); +                    displayContent.attachStack(stack); +                    moveStackWindowsLocked(displayContent); +                    final WindowList windows = displayContent.getWindowList(); +                    for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { +                        windows.get(winNdx).reportResized(); +                    }                  }              } -            Slog.e(TAG, "createStack: Unable to find relativeStackBoxId=" + relativeStackBoxId); +        } finally { +            Binder.restoreCallingIdentity(origId);          }      } -    public int removeStack(int stackId) { +    public void detachStack(int stackId) {          synchronized (mWindowMap) { -            final TaskStack stack = mStackIdToStack.get(stackId); +            TaskStack stack = mStackIdToStack.get(stackId);              if (stack != null) { -                mStackIdToStack.delete(stackId); -                int nextStackId = stack.remove(); -                stack.getDisplayContent().layoutNeeded = true; -                requestTraversalLocked(); -                return nextStackId; +                final DisplayContent displayContent = stack.getDisplayContent(); +                if (displayContent != null) { +                    if (stack.isAnimating()) { +                        displayContent.mDeferredActions |= DisplayContent.DEFER_DETACH; +                        return; +                    } +                    displayContent.detachStack(stack); +                    stack.detachDisplay(); +                }              } -            if (DEBUG_STACK) Slog.i(TAG, "removeStack: could not find stackId=" + stackId);          } -        return HOME_STACK_ID; +    } + +    void removeTaskLocked(Task task) { +        final int taskId = task.taskId; +        final TaskStack stack = task.mStack; +        if (stack.isAnimating()) { +            if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + taskId); +            task.mDeferRemoval = true; +            return; +        } +        if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + taskId); +        EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask"); +        task.mDeferRemoval = false; +        task.mStack.removeTask(task); +        mTaskIdToTask.delete(task.taskId);      }      public void removeTask(int taskId) { @@ -4877,15 +4962,14 @@ public class WindowManagerService extends IWindowManager.Stub                  if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId);                  return;              } -            final TaskStack stack = task.mStack; -            EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask"); -            stack.removeTask(task); -            stack.getDisplayContent().layoutNeeded = true; +            removeTaskLocked(task);          }      }      public void addTask(int taskId, int stackId, boolean toTop) {          synchronized (mWindowMap) { +            if (DEBUG_STACK) Slog.i(TAG, "addTask: adding taskId=" + taskId +                    + " to " + (toTop ? "top" : "bottom"));              Task task = mTaskIdToTask.get(taskId);              if (task == null) {                  return; @@ -4898,40 +4982,28 @@ 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.resizeWindows(); +                stack.getDisplayContent().layoutNeeded = true; +                performLayoutAndPlaceSurfacesLocked();              } -        } -        throw new IllegalArgumentException("resizeStack: stackBoxId " + stackBoxId -                + " not found."); -    } - -    public ArrayList<StackBoxInfo> getStackBoxInfos() { -        synchronized(mWindowMap) { -            return getDefaultDisplayContentLocked().getStackBoxInfos();          }      } -    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; -            } +    public void getStackBounds(int stackId, Rect bounds) { +        final TaskStack stack = mStackIdToStack.get(stackId); +        if (stack != null) { +            stack.getBounds(bounds); +            return;          } -        return null; +        bounds.setEmpty();      }      // ------------------------------------------------------------- @@ -5207,7 +5279,7 @@ public class WindowManagerService extends IWindowManager.Stub              final int numDisplays = mDisplayContents.size();              for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {                  final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); -                displayContent.switchUserStacks(oldUserId, newUserId); +                displayContent.switchUserStacks(newUserId);                  rebuildAppWindowListLocked(displayContent);              }              performLayoutAndPlaceSurfacesLocked(); @@ -5259,7 +5331,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 +5515,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 +5660,7 @@ public class WindowManagerService extends IWindowManager.Stub                                  continue;                              }                              appWin = ws; -                            stackBounds.set(ws.getStackBounds()); +                            ws.getStackBounds(stackBounds);                          }                      } @@ -5964,7 +6035,7 @@ public class WindowManagerService extends IWindowManager.Stub                  }              } -            mDisplayManagerService.performTraversalInTransactionFromWindowManager(); +            mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();          } finally {              if (!inTransaction) {                  SurfaceControl.closeTransaction(); @@ -6658,7 +6729,7 @@ public class WindowManagerService extends IWindowManager.Stub              displayInfo.getLogicalMetrics(mRealDisplayMetrics,                      CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);              displayInfo.getAppMetrics(mDisplayMetrics); -            mDisplayManagerService.setDisplayInfoOverrideFromWindowManager( +            mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(                      displayContent.getDisplayId(), displayInfo);          }          if (false) { @@ -6991,7 +7062,7 @@ public class WindowManagerService extends IWindowManager.Stub                  synchronized(displayContent.mDisplaySizeLock) {                      // Bootstrap the default logical display from the display manager.                      final DisplayInfo displayInfo = displayContent.getDisplayInfo(); -                    DisplayInfo newDisplayInfo = mDisplayManagerService.getDisplayInfo(displayId); +                    DisplayInfo newDisplayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);                      if (newDisplayInfo != null) {                          displayInfo.copyFrom(newDisplayInfo);                      } @@ -7361,15 +7432,18 @@ public class WindowManagerService extends IWindowManager.Stub                  case APP_FREEZE_TIMEOUT: {                      synchronized (mWindowMap) {                          Slog.w(TAG, "App freeze timeout expired."); -                        DisplayContent displayContent = getDefaultDisplayContentLocked(); -                        final ArrayList<Task> tasks = displayContent.getTasks(); -                        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { -                            AppTokenList tokens = tasks.get(taskNdx).mAppTokens; -                            for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { -                                AppWindowToken tok = tokens.get(tokenNdx); -                                if (tok.mAppAnimator.freezingScreen) { -                                    Slog.w(TAG, "Force clearing freeze: " + tok); -                                    unsetAppFreezingScreenLocked(tok, true, true); +                        final int numStacks = mStackIdToStack.size(); +                        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { +                            final TaskStack stack = mStackIdToStack.valueAt(stackNdx); +                            final ArrayList<Task> tasks = stack.getTasks(); +                            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { +                                AppTokenList tokens = tasks.get(taskNdx).mAppTokens; +                                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { +                                    AppWindowToken tok = tokens.get(tokenNdx); +                                    if (tok.mAppAnimator.freezingScreen) { +                                        Slog.w(TAG, "Force clearing freeze: " + tok); +                                        unsetAppFreezingScreenLocked(tok, true, true); +                                    }                                  }                              }                          } @@ -7476,9 +7550,7 @@ public class WindowManagerService extends IWindowManager.Stub                  }                  case DO_DISPLAY_ADDED: -                    synchronized (mWindowMap) { -                        handleDisplayAddedLocked(msg.arg1); -                    } +                    handleDisplayAdded(msg.arg1);                      break;                  case DO_DISPLAY_REMOVED: @@ -7937,7 +8009,6 @@ public class WindowManagerService extends IWindowManager.Stub      }      final void rebuildAppWindowListLocked() { -        // TODO: Multidisplay, when ActivityStacks and tasks exist on more than one display.          rebuildAppWindowListLocked(getDefaultDisplayContentLocked());      } @@ -7982,27 +8053,37 @@ public class WindowManagerService extends IWindowManager.Stub          // in the main app list, but still have windows shown.  We put them          // in the back because now that the animation is over we no longer          // will care about them. -        AppTokenList exitingAppTokens = displayContent.mExitingAppTokens; -        int NT = exitingAppTokens.size(); -        for (int j=0; j<NT; j++) { -            i = reAddAppWindowsLocked(displayContent, i, exitingAppTokens.get(j)); +        final ArrayList<TaskStack> stacks = displayContent.getStacks(); +        final int numStacks = stacks.size(); +        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { +            AppTokenList exitingAppTokens = stacks.get(stackNdx).mExitingAppTokens; +            int NT = exitingAppTokens.size(); +            for (int j = 0; j < NT; j++) { +                i = reAddAppWindowsLocked(displayContent, i, exitingAppTokens.get(j)); +            }          }          // And add in the still active app tokens in Z order. -        final ArrayList<Task> tasks = displayContent.getTasks(); -        final int numTasks = tasks.size(); -        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { -            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; -            final int numTokens = tokens.size(); -            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { -                final AppWindowToken wtoken = tokens.get(tokenNdx); -                i = reAddAppWindowsLocked(displayContent, i, wtoken); +        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { +            final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks(); +            final int numTasks = tasks.size(); +            for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { +                final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; +                final int numTokens = tokens.size(); +                for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { +                    final AppWindowToken wtoken = tokens.get(tokenNdx); +                    if (wtoken.mDeferRemoval) { +                        continue; +                    } +                    i = reAddAppWindowsLocked(displayContent, i, wtoken); +                }              }          }          i -= lastBelow;          if (i != numRemoved) { -            Slog.w(TAG, "Rebuild removed " + numRemoved + " windows but added " + i, +            Slog.w(TAG, "On display=" + displayContent.getDisplayId() + " Rebuild removed " + +                    numRemoved + " windows but added " + i,                      new RuntimeException("here").fillInStackTrace());              for (i=0; i<numRemoved; i++) {                  WindowState ws = mRebuildTmp[i]; @@ -8218,7 +8299,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; @@ -8362,8 +8443,7 @@ public class WindowManagerService extends IWindowManager.Stub          // it frozen/off until this window draws at its new          // orientation.          if (!okToDisplay()) { -            if (DEBUG_ORIENTATION) Slog.v(TAG, -                    "Changing surface while display frozen: " + w); +            if (DEBUG_ORIENTATION) Slog.v(TAG, "Changing surface while display frozen: " + w);              w.mOrientationChanging = true;              w.mLastFreezeDuration = 0;              mInnerFields.mOrientationChangeComplete = false; @@ -8671,15 +8751,14 @@ public class WindowManagerService extends IWindowManager.Stub          mAppTransition.setIdle();          // Restore window app tokens to the ActivityManager views -        final DisplayContent displayContent = getDefaultDisplayContentLocked(); -        final ArrayList<Task> tasks = displayContent.getTasks(); -        final int numTasks = tasks.size(); -        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { -            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; -            final int numTokens = tokens.size(); -            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { -                final AppWindowToken wtoken = tokens.get(tokenNdx); -                wtoken.sendingToBottom = false; +        ArrayList<TaskStack> stacks = getDefaultDisplayContentLocked().getStacks(); +        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { +            final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks(); +            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { +                final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; +                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { +                    tokens.get(tokenNdx).sendingToBottom = false; +                }              }          }          rebuildAppWindowListLocked(); @@ -8813,7 +8892,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.getDisplayContent(); +                if (displayContent != null && 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 @@ -8822,8 +8902,9 @@ public class WindowManagerService extends IWindowManager.Stub                          mInnerFields.mObscureApplicationContentOnSecondaryDisplays = true;                      }                      mInnerFields.mDisplayHasContent = true; -                } else if (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays -                        || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG)) { +                } else if (displayContent != null && +                        (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays +                        || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG))) {                      // Allow full screen keyguard presentation dialogs to be seen.                      mInnerFields.mDisplayHasContent = true;                  } @@ -8831,7 +8912,7 @@ public class WindowManagerService extends IWindowManager.Stub          }      } -    private void handleFlagDimBehind(WindowState w, int innerDw, int innerDh) { +    private void handleFlagDimBehind(WindowState w) {          final WindowManager.LayoutParams attrs = w.mAttrs;          if ((attrs.flags & FLAG_DIM_BEHIND) != 0                  && w.isDisplayedLw() @@ -8849,22 +8930,23 @@ public class WindowManagerService extends IWindowManager.Stub      private void updateAllDrawnLocked(DisplayContent displayContent) {          // See if any windows have been drawn, so they (and others          // associated with them) can now be shown. -        final ArrayList<Task> tasks = displayContent.getTasks(); -        final int numTasks = tasks.size(); -        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { -            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; -            final int numTokens = tokens.size(); -            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { -                final AppWindowToken wtoken = tokens.get(tokenNdx); -                if (!wtoken.allDrawn) { -                    int numInteresting = wtoken.numInterestingWindows; -                    if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) { -                        if (DEBUG_VISIBILITY) Slog.v(TAG, -                                "allDrawn: " + wtoken -                                + " interesting=" + numInteresting -                                + " drawn=" + wtoken.numDrawnWindows); -                        wtoken.allDrawn = true; -                        mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget(); +        ArrayList<TaskStack> stacks = displayContent.getStacks(); +        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { +            final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks(); +            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { +                final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; +                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { +                    final AppWindowToken wtoken = tokens.get(tokenNdx); +                    if (!wtoken.allDrawn) { +                        int numInteresting = wtoken.numInterestingWindows; +                        if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) { +                            if (DEBUG_VISIBILITY) Slog.v(TAG, +                                    "allDrawn: " + wtoken +                                    + " interesting=" + numInteresting +                                    + " drawn=" + wtoken.numDrawnWindows); +                            wtoken.allDrawn = true; +                            mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget(); +                        }                      }                  }              } @@ -8895,10 +8977,14 @@ public class WindowManagerService extends IWindowManager.Stub              for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {                  displayContent.mExitingTokens.get(i).hasVisible = false;              } +        } +        for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {              // Initialize state of exiting applications. -            for (i=displayContent.mExitingAppTokens.size()-1; i>=0; i--) { -                displayContent.mExitingAppTokens.get(i).hasVisible = false; +            final AppTokenList exitingAppTokens = +                    mStackIdToStack.valueAt(stackNdx).mExitingAppTokens; +            for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) { +                exitingAppTokens.get(tokenNdx).hasVisible = false;              }          } @@ -9017,6 +9103,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,8 +9116,8 @@ public class WindowManagerService extends IWindowManager.Stub                          handleNotObscuredLocked(w, currentTime, innerDw, innerDh);                      } -                    if (!w.getStack().testDimmingTag()) { -                        handleFlagDimBehind(w, innerDw, innerDh); +                    if (!stack.testDimmingTag()) { +                        handleFlagDimBehind(w);                      }                      if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w) @@ -9151,7 +9241,7 @@ public class WindowManagerService extends IWindowManager.Stub                      updateResizingWindows(w);                  } -                mDisplayManagerService.setDisplayHasContent(displayId, +                mDisplayManagerInternal.setDisplayHasContent(displayId,                          mInnerFields.mDisplayHasContent,                          true /* inTraversal, must call performTraversalInTrans... below */); @@ -9168,7 +9258,7 @@ public class WindowManagerService extends IWindowManager.Stub              // Give the display manager a chance to adjust properties              // like display rotation if it needs to. -            mDisplayManagerService.performTraversalInTransactionFromWindowManager(); +            mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();          } catch (RuntimeException e) {              Log.wtf(TAG, "Unhandled exception in Window Manager", e); @@ -9243,57 +9333,7 @@ public class WindowManagerService extends IWindowManager.Stub                  // Don't remove this window until rotation has completed.                  continue;              } -            final WindowStateAnimator winAnimator = win.mWinAnimator; -            try { -                if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, -                        "Reporting new frame to " + win + ": " + win.mCompatFrame); -                int diff = 0; -                boolean configChanged = win.isConfigChanged(); -                if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) -                        && configChanged) { -                    Slog.i(TAG, "Sending new config to window " + win + ": " -                            + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH -                            + " / " + mCurConfiguration + " / 0x" -                            + Integer.toHexString(diff)); -                } -                win.setConfiguration(mCurConfiguration); -                if (DEBUG_ORIENTATION && -                        winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i( -                        TAG, "Resizing " + win + " WITH DRAW PENDING"); -                final IWindow client = win.mClient; -                final Rect frame = win.mFrame; -                final Rect overscanInsets = win.mLastOverscanInsets; -                final Rect contentInsets = win.mLastContentInsets; -                final Rect visibleInsets = win.mLastVisibleInsets; -                final boolean reportDraw -                        = winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING; -                final Configuration newConfig = configChanged ? win.mConfiguration : null; -                if (win.mClient instanceof IWindow.Stub) { -                    // To prevent deadlock simulate one-way call if win.mClient is a local object. -                    mH.post(new Runnable() { -                        @Override -                        public void run() { -                            try { -                                client.resized(frame, overscanInsets, contentInsets, -                                        visibleInsets, reportDraw, newConfig); -                            } catch (RemoteException e) { -                                // Not a remote call, RemoteException won't be raised. -                            } -                        } -                    }); -                } else { -                   client.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw, -                           newConfig); -                } -                win.mOverscanInsetsChanged = false; -                win.mContentInsetsChanged = false; -                win.mVisibleInsetsChanged = false; -                winAnimator.mSurfaceResized = false; -            } catch (RemoteException e) { -                win.mOrientationChanging = false; -                win.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() -                        - mDisplayFreezeTime); -            } +            win.reportResized();              mResizingWindows.remove(i);          } @@ -9341,9 +9381,13 @@ public class WindowManagerService extends IWindowManager.Stub                      }                  }              } +        } -            // Time to remove any exiting applications? -            AppTokenList exitingAppTokens = displayContent.mExitingAppTokens; +        // Time to remove any exiting applications? +        for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) { +            // Initialize state of exiting applications. +            final AppTokenList exitingAppTokens = +                    mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;              for (i = exitingAppTokens.size() - 1; i >= 0; i--) {                  AppWindowToken token = exitingAppTokens.get(i);                  if (!token.hasVisible && !mClosingApps.contains(token)) { @@ -9354,10 +9398,7 @@ public class WindowManagerService extends IWindowManager.Stub                      token.mAppAnimator.animating = false;                      if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,                              "performLayout: App token exiting now removed" + token); -                    final Task task = mTaskIdToTask.get(token.groupId); -                    if (task != null && task.removeAppToken(token)) { -                        mTaskIdToTask.delete(token.groupId); -                    } +                    removeAppFromTaskLocked(token);                      exitingAppTokens.remove(i);                  }              } @@ -9392,18 +9433,18 @@ public class WindowManagerService extends IWindowManager.Stub          setHoldScreenLocked(mInnerFields.mHoldScreen);          if (!mDisplayFrozen) {              if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) { -                mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1); +                mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);              } else { -                mPowerManager.setScreenBrightnessOverrideFromWindowManager( +                mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(                          toBrightnessOverride(mInnerFields.mScreenBrightness));              }              if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) { -                mPowerManager.setButtonBrightnessOverrideFromWindowManager(-1); +                mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);              } else { -                mPowerManager.setButtonBrightnessOverrideFromWindowManager( +                mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(                          toBrightnessOverride(mInnerFields.mButtonBrightness));              } -            mPowerManager.setUserActivityTimeoutOverrideFromWindowManager( +            mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(                      mInnerFields.mUserActivityTimeout);          } @@ -9438,8 +9479,9 @@ public class WindowManagerService extends IWindowManager.Stub              for (i = 0; i < N; i++) {                  WindowState w = mPendingRemoveTmp[i];                  removeWindowInnerLocked(w.mSession, w); -                if (!displayList.contains(w.mDisplayContent)) { -                    displayList.add(w.mDisplayContent); +                final DisplayContent displayContent = w.getDisplayContent(); +                if (displayContent != null && !displayList.contains(displayContent)) { +                    displayList.add(displayContent);                  }              } @@ -9449,6 +9491,11 @@ public class WindowManagerService extends IWindowManager.Stub              }          } +        // Remove all deferred Stacks, tasks, and activities. +        for (int stackNdx = mPendingStacksRemove.size() - 1; stackNdx >= 0; --stackNdx) { +            mPendingStacksRemove.removeAt(stackNdx).checkForDeferredActions(); +        } +          setFocusedStackFrame();          // Check to see if we are now in a state where the screen should @@ -9537,8 +9584,7 @@ public class WindowManagerService extends IWindowManager.Stub          }      } -    @Override -    public void requestTraversal() { +    void requestTraversal() {          synchronized (mWindowMap) {              requestTraversalLocked();          } @@ -9916,6 +9962,7 @@ public class WindowManagerService extends IWindowManager.Stub              }              // TODO(multidisplay): rotation on main screen only. +            displayContent.updateDisplayInfo();              screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,                      mFxSession, inTransaction, mPolicy.isDefaultOrientationForced());              mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation); @@ -10735,7 +10782,7 @@ public class WindowManagerService extends IWindowManager.Stub              displayInfo.overscanTop = rect.top;              displayInfo.overscanRight = rect.right;              displayInfo.overscanBottom = rect.bottom; -            mDisplayManagerService.setDisplayInfoOverrideFromWindowManager( +            mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(                      displayId, displayInfo);          }          configureDisplayPolicyLocked(displayContent); @@ -10805,20 +10852,20 @@ public class WindowManagerService extends IWindowManager.Stub          return displayContent != null ? displayContent.getWindowList() : null;      } -    @Override      public void onDisplayAdded(int displayId) {          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); +            }          }      } -    @Override      public void onDisplayRemoved(int displayId) {          mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));      } @@ -10826,21 +10873,19 @@ public class WindowManagerService extends IWindowManager.Stub      private void handleDisplayRemovedLocked(int displayId) {          final DisplayContent displayContent = getDisplayContentLocked(displayId);          if (displayContent != null) { +            if ((displayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0) { +                displayContent.mDeferredActions |= DisplayContent.DEFER_REMOVAL; +                return; +            }              mDisplayContents.delete(displayId);              displayContent.close();              if (displayId == Display.DEFAULT_DISPLAY) {                  unregisterPointerEventListener(displayContent.mTapDetector);              } -            WindowList windows = displayContent.getWindowList(); -            while (!windows.isEmpty()) { -                final WindowState win = windows.get(windows.size() - 1); -                removeWindowLocked(win.mSession, win); -            }          }          mAnimator.removeDisplayLocked(displayId);      } -    @Override      public void onDisplayChanged(int displayId) {          mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));      } @@ -10856,4 +10901,11 @@ public class WindowManagerService extends IWindowManager.Stub      public Object getWindowManagerLock() {          return mWindowMap;      } + +    private final class LocalService extends WindowManagerInternal { +        @Override +        public void requestTraversalFromDisplayManager() { +            requestTraversal(); +        } +    }  } diff --git a/services/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 4d53cea4370d..9f3415e63586 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -16,8 +16,11 @@  package com.android.server.wm; -import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY; +import static com.android.server.wm.WindowManagerService.DEBUG_CONFIGURATION;  import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT; +import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION; +import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE; +import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;  import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;  import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; @@ -29,7 +32,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD;  import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;  import android.app.AppOpsManager; +import android.os.Debug;  import android.os.RemoteCallbackList; +import android.os.SystemClock;  import android.util.TimeUtils;  import android.view.IWindowFocusObserver;  import android.view.IWindowId; @@ -370,19 +375,17 @@ final class WindowState implements WindowManagerPolicy.WindowState {                  mAttachedWindow.mChildWindows.add(this);              } else {                  for (int i = 0; i < children_size; i++) { -                    WindowState child = (WindowState)mAttachedWindow.mChildWindows.get(i); -                    if (this.mSubLayer < child.mSubLayer) { +                    WindowState child = mAttachedWindow.mChildWindows.get(i); +                    if (mSubLayer < child.mSubLayer) {                          mAttachedWindow.mChildWindows.add(i, this);                          break; -                    } else if (this.mSubLayer > child.mSubLayer) { +                    } else if (mSubLayer > child.mSubLayer) {                          continue;                      } -                    if (this.mBaseLayer <= child.mBaseLayer) { +                    if (mBaseLayer <= child.mBaseLayer) {                          mAttachedWindow.mChildWindows.add(i, this);                          break; -                    } else { -                        continue;                      }                  }                  if (children_size == mAttachedWindow.mChildWindows.size()) { @@ -463,8 +466,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;              } @@ -593,9 +596,12 @@ final class WindowState implements WindowManagerPolicy.WindowState {          }          if (mIsWallpaper && (fw != mFrame.width() || fh != mFrame.height())) { -            final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo(); -            mService.updateWallpaperOffsetLocked(this, -                    displayInfo.logicalWidth, displayInfo.logicalHeight, false); +            final DisplayContent displayContent = getDisplayContent(); +            if (displayContent != null) { +                final DisplayInfo displayInfo = displayContent.getDisplayInfo(); +                mService.updateWallpaperOffsetLocked(this, +                        displayInfo.logicalWidth, displayInfo.logicalHeight, false); +            }          }          if (DEBUG_LAYOUT || WindowManagerService.localLOGV) Slog.v(TAG, @@ -708,8 +714,16 @@ final class WindowState implements WindowManagerPolicy.WindowState {          return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged;      } +    public DisplayContent getDisplayContent() { +        return mAppToken == null ? mDisplayContent : getStack().getDisplayContent(); +    } +      public int getDisplayId() { -        return mDisplayContent.getDisplayId(); +        final DisplayContent displayContent = getDisplayContent(); +        if (displayContent == null) { +            return -1; +        } +        return displayContent.getDisplayId();      }      TaskStack getStack() { @@ -717,21 +731,28 @@ 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: " + this + " couldn't find taskId=" + wtoken.groupId +                    + " Callers=" + Debug.getCallers(4));              }          }          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() { @@ -1190,7 +1211,12 @@ final class WindowState implements WindowManagerPolicy.WindowState {      @Override      public boolean isDefaultDisplay() { -        return mDisplayContent.isDefaultDisplay; +        final DisplayContent displayContent = getDisplayContent(); +        if (displayContent == null) { +            // Only a window that was on a non-default display can be detached from it. +            return false; +        } +        return getDisplayContent().isDefaultDisplay;      }      public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) { @@ -1207,7 +1233,11 @@ final class WindowState implements WindowManagerPolicy.WindowState {                  && win.mAppToken != null && win.mAppToken.showWhenLocked) {              // Save some cycles by not calling getDisplayInfo unless it is an application              // window intended for all users. -            final DisplayInfo displayInfo = win.mDisplayContent.getDisplayInfo(); +            final DisplayContent displayContent = win.getDisplayContent(); +            if (displayContent == null) { +                return true; +            } +            final DisplayInfo displayInfo = displayContent.getDisplayInfo();              if (win.mFrame.left <= 0 && win.mFrame.top <= 0                      && win.mFrame.right >= displayInfo.appWidth                      && win.mFrame.bottom >= displayInfo.appHeight) { @@ -1249,7 +1279,8 @@ final class WindowState implements WindowManagerPolicy.WindowState {      }      WindowList getWindowList() { -        return mDisplayContent.getWindowList(); +        final DisplayContent displayContent = getDisplayContent(); +        return displayContent == null ? null : displayContent.getWindowList();      }      /** @@ -1278,6 +1309,54 @@ final class WindowState implements WindowManagerPolicy.WindowState {          }      } +    void reportResized() { +        try { +            if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this +                    + ": " + mCompatFrame); +            boolean configChanged = isConfigChanged(); +            if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) { +                Slog.i(TAG, "Sending new config to window " + this + ": " +                        + mWinAnimator.mSurfaceW + "x" + mWinAnimator.mSurfaceH +                        + " / " + mService.mCurConfiguration); +            } +            setConfiguration(mService.mCurConfiguration); +            if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) +                Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING"); + +            final Rect frame = mFrame; +            final Rect overscanInsets = mLastOverscanInsets; +            final Rect contentInsets = mLastContentInsets; +            final Rect visibleInsets = mLastVisibleInsets; +            final boolean reportDraw = mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING; +            final Configuration newConfig = configChanged ? mConfiguration : null; +            if (mClient instanceof IWindow.Stub) { +                // To prevent deadlock simulate one-way call if win.mClient is a local object. +                mService.mH.post(new Runnable() { +                    @Override +                    public void run() { +                        try { +                            mClient.resized(frame, overscanInsets, contentInsets, +                                    visibleInsets, reportDraw, newConfig); +                        } catch (RemoteException e) { +                            // Not a remote call, RemoteException won't be raised. +                        } +                    } +                }); +            } else { +                mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw, +                        newConfig); +            } +            mOverscanInsetsChanged = false; +            mContentInsetsChanged = false; +            mVisibleInsetsChanged = false; +            mWinAnimator.mSurfaceResized = false; +        } catch (RemoteException e) { +            mOrientationChanging = false; +            mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() +                    - mService.mDisplayFreezeTime); +        } +    } +      public void registerFocusObserver(IWindowFocusObserver observer) {          synchronized(mService.mWindowMap) {              if (mFocusCallbacks == null) { @@ -1302,7 +1381,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {      }      void dump(PrintWriter pw, String prefix, boolean dumpAll) { -        pw.print(prefix); pw.print("mDisplayId="); pw.print(mDisplayContent.getDisplayId()); +        pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId());                  pw.print(" mSession="); pw.print(mSession);                  pw.print(" mClient="); pw.println(mClient.asBinder());          pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid); diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index c405170da280..ffb17f1fb374 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -150,8 +150,6 @@ class WindowStateAnimator {      int mAttrFlags;      int mAttrType; -    final int mLayerStack; -      public WindowStateAnimator(final WindowState win) {          final WindowManagerService service = win.mService; @@ -159,7 +157,7 @@ class WindowStateAnimator {          mAnimator = service.mAnimator;          mPolicy = service.mPolicy;          mContext = service.mContext; -        final DisplayInfo displayInfo = win.mDisplayContent.getDisplayInfo(); +        final DisplayInfo displayInfo = win.getDisplayContent().getDisplayInfo();          mAnimDw = displayInfo.appWidth;          mAnimDh = displayInfo.appHeight; @@ -171,7 +169,6 @@ class WindowStateAnimator {          mAttrFlags = win.mAttrs.flags;          mAttrType = win.mAttrs.type;          mIsWallpaper = win.mIsWallpaper; -        mLayerStack = win.mDisplayContent.getDisplay().getLayerStack();      }      public void setAnimation(Animation anim) { @@ -243,7 +240,8 @@ class WindowStateAnimator {          // Save the animation state as it was before this step so WindowManagerService can tell if          // we just started or just stopped animating by comparing mWasAnimating with isAnimating().          mWasAnimating = mAnimating; -        if (mService.okToDisplay()) { +        final DisplayContent displayContent = mWin.getDisplayContent(); +        if (displayContent != null && mService.okToDisplay()) {              // We will run animations as long as the display isn't frozen.              if (mWin.isDrawnLw() && mAnimation != null) { @@ -258,7 +256,7 @@ class WindowStateAnimator {                          " scale=" + mService.mWindowAnimationScale);                      mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),                              mAnimDw, mAnimDh); -                    final DisplayInfo displayInfo = mWin.mDisplayContent.getDisplayInfo(); +                    final DisplayInfo displayInfo = displayContent.getDisplayInfo();                      mAnimDw = displayInfo.appWidth;                      mAnimDh = displayInfo.appHeight;                      mAnimation.setStartTime(currentTime); @@ -337,7 +335,9 @@ class WindowStateAnimator {                          + mWin.mPolicyVisibilityAfterAnim);              }              mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim; -            mWin.mDisplayContent.layoutNeeded = true; +            if (displayContent != null) { +                displayContent.layoutNeeded = true; +            }              if (!mWin.mPolicyVisibility) {                  if (mService.mCurrentFocus == mWin) {                      if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.i(TAG, @@ -363,11 +363,13 @@ class WindowStateAnimator {          } else if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.mPolicyVisibility) {              // Upon completion of a not-visible to visible status bar animation a relayout is              // required. -            mWin.mDisplayContent.layoutNeeded = true; +            if (displayContent != null) { +                displayContent.layoutNeeded = true; +            }          }          finishExit(); -        final int displayId = mWin.mDisplayContent.getDisplayId(); +        final int displayId = mWin.getDisplayId();          mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);          if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(                  "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId)); @@ -414,6 +416,7 @@ class WindowStateAnimator {              mService.mPendingRemove.add(mWin);              mWin.mRemoveOnExit = false;          } +        mService.mPendingStacksRemove.add(mWin.getStack());          mAnimator.hideWallpapersLocked(mWin);      } @@ -732,7 +735,10 @@ class WindowStateAnimator {                      mSurfaceY = mWin.mFrame.top + mWin.mYOffset;                      mSurfaceControl.setPosition(mSurfaceX, mSurfaceY);                      mSurfaceLayer = mAnimLayer; -                    mSurfaceControl.setLayerStack(mLayerStack); +                    final DisplayContent displayContent = mWin.getDisplayContent(); +                    if (displayContent != null) { +                        mSurfaceControl.setLayerStack(displayContent.getDisplay().getLayerStack()); +                    }                      mSurfaceControl.setLayer(mAnimLayer);                      mSurfaceControl.setAlpha(0);                      mSurfaceShown = false; @@ -921,8 +927,7 @@ class WindowStateAnimator {                  tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());              }              //TODO (multidisplay): Magnification is supported only for the default display. -            if (mService.mDisplayMagnifier != null -                    && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) { +            if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) {                  MagnificationSpec spec = mService.mDisplayMagnifier                          .getMagnificationSpecForWindowLocked(mWin);                  if (spec != null && !spec.isNop()) { @@ -1002,7 +1007,7 @@ class WindowStateAnimator {                  && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer);          MagnificationSpec spec = null;          //TODO (multidisplay): Magnification is supported only for the default display. -        if (mService.mDisplayMagnifier != null && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) { +        if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) {              spec = mService.mDisplayMagnifier.getMagnificationSpecForWindowLocked(mWin);          }          if (applyUniverseTransformation || spec != null) { @@ -1080,7 +1085,11 @@ class WindowStateAnimator {      void updateSurfaceWindowCrop(final boolean recoveringMemory) {          final WindowState w = mWin; -        DisplayInfo displayInfo = w.mDisplayContent.getDisplayInfo(); +        final DisplayContent displayContent = w.getDisplayContent(); +        if (displayContent == null) { +            return; +        } +        DisplayInfo displayInfo = displayContent.getDisplayInfo();          // Need to recompute a new system decor rect each time.          if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) { @@ -1181,8 +1190,7 @@ class WindowStateAnimator {                          "SIZE " + width + "x" + height, null);                  mSurfaceResized = true;                  mSurfaceControl.setSize(width, height); -                final int displayId = w.mDisplayContent.getDisplayId(); -                mAnimator.setPendingLayoutChanges(displayId, +                mAnimator.setPendingLayoutChanges(w.getDisplayId(),                          WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);                  if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {                      w.getStack().startDimmingIfNeeded(this); @@ -1444,7 +1452,10 @@ class WindowStateAnimator {                          // do a layout.  If called from within the transaction                          // loop, this will cause it to restart with a new                          // layout. -                        c.mDisplayContent.layoutNeeded = true; +                        final DisplayContent displayContent = c.getDisplayContent(); +                        if (displayContent != null) { +                            displayContent.layoutNeeded = true; +                        }                      }                  }              } 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/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 4a1b55d5d9d5..4a1b55d5d9d5 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..0542ce012130 100644 --- a/services/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -1143,7 +1143,7 @@ static void nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,  }  static jint nativeInjectInputEvent(JNIEnv* env, jclass clazz, -        jlong ptr, jobject inputEventObj, jint injectorPid, jint injectorUid, +        jlong ptr, jobject inputEventObj, jint displayId, jint injectorPid, jint injectorUid,          jint syncMode, jint timeoutMillis, jint policyFlags) {      NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); @@ -1156,7 +1156,7 @@ static jint nativeInjectInputEvent(JNIEnv* env, jclass clazz,          }          return (jint) im->getInputManager()->getDispatcher()->injectInputEvent( -                & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis, +                & keyEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis,                  uint32_t(policyFlags));      } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {          const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj); @@ -1166,7 +1166,7 @@ static jint nativeInjectInputEvent(JNIEnv* env, jclass clazz,          }          return (jint) im->getInputManager()->getDispatcher()->injectInputEvent( -                motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis, +                motionEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis,                  uint32_t(policyFlags));      } else {          jniThrowRuntimeException(env, "Invalid input event type."); @@ -1326,7 +1326,7 @@ static JNINativeMethod gInputManagerMethods[] = {              (void*) nativeUnregisterInputChannel },      { "nativeSetInputFilterEnabled", "(JZ)V",              (void*) nativeSetInputFilterEnabled }, -    { "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIII)I", +    { "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIIII)I",              (void*) nativeInjectInputEvent },      { "nativeSetInputWindows", "(J[Lcom/android/server/input/InputWindowHandle;)V",              (void*) nativeSetInputWindows }, 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/devicepolicy/Android.mk b/services/devicepolicy/Android.mk new file mode 100644 index 000000000000..a55d1386671c --- /dev/null +++ b/services/devicepolicy/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := services.devicepolicy + +LOCAL_SRC_FILES += \ +      $(call all-java-files-under,java) + +LOCAL_JAVA_LIBRARIES := conscrypt + +include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 2bb99d68ed77..296d852248d1 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; @@ -25,6 +25,7 @@ import com.android.internal.util.JournaledFile;  import com.android.internal.util.XmlUtils;  import com.android.internal.widget.LockPatternUtils;  import com.android.org.conscrypt.TrustedCertificateStore; +import com.android.server.SystemService;  import org.xmlpull.v1.XmlPullParser;  import org.xmlpull.v1.XmlPullParserException; @@ -117,7 +118,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"; @@ -149,6 +150,26 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {       */      private boolean mHasFeature; +    public static final class Lifecycle extends SystemService { +        private DevicePolicyManagerService mService; + +        public Lifecycle(Context context) { +            super(context); +            mService = new DevicePolicyManagerService(context); +        } + +        @Override +        public void onStart() { +            publishBinderService(Context.DEVICE_POLICY_SERVICE, mService); +        } + +        @Override +        public void onBootPhase(int phase) { +            if (phase == PHASE_LOCK_SETTINGS_READY) { +                mService.systemReady(); +            } +        } +    }      public static class DevicePolicyData {          int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;          int mActivePasswordLength = 0; @@ -186,7 +207,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 +239,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 +324,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 +434,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 +556,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 +628,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 +638,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 +835,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 +967,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 +978,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 +1007,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 +1038,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 +1082,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 +1102,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 +1218,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 +1489,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 +1835,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 +1917,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 +1927,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 +1956,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 +2000,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 +2066,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 +2141,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 +2159,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 +2180,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 +2192,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 +2219,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 +2310,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 +2435,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 +2516,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 +2542,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 +2928,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 +2953,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 +2983,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/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/SystemServer.java b/services/java/com/android/server/SystemServer.java index a42cbcfe0d64..afd7845034cb 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -17,6 +17,9 @@  package com.android.server;  import android.app.ActivityManagerNative; +import android.app.ActivityThread; +import android.app.IAlarmManager; +import android.app.INotificationManager;  import android.bluetooth.BluetoothAdapter;  import android.content.ComponentName;  import android.content.ContentResolver; @@ -28,8 +31,10 @@ import android.content.res.Configuration;  import android.media.AudioService;  import android.net.wifi.p2p.WifiP2pService;  import android.os.Environment; +import android.os.FactoryTest;  import android.os.Handler; -import android.os.HandlerThread; +import android.os.IBinder; +import android.os.IPowerManager;  import android.os.Looper;  import android.os.RemoteException;  import android.os.ServiceManager; @@ -47,26 +52,32 @@ import android.view.WindowManager;  import com.android.internal.R;  import com.android.internal.os.BinderInternal;  import com.android.internal.os.SamplingProfilerIntegration; -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.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; @@ -77,62 +88,210 @@ import java.io.File;  import java.util.Timer;  import java.util.TimerTask; -class ServerThread { +public final class SystemServer {      private static final String TAG = "SystemServer"; +      private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";      private static final String ENCRYPTED_STATE = "1"; -    ContentResolver mContentResolver; +    private static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr -    void reportWtf(String msg, Throwable e) { -        Slog.w(TAG, "***********************************************"); -        Log.wtf(TAG, "BOOT FAILURE " + msg, e); +    // The earliest supported time.  We pick one day into 1970, to +    // give any timezone code room without going into negative time. +    private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000; + +    /* +     * 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.BackupManagerService$Lifecycle"; +    private static final String DEVICE_POLICY_MANAGER_SERVICE_CLASS = +            "com.android.server.devicepolicy.DevicePolicyManagerService$Lifecycle"; +    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"; + +    private final int mFactoryTestMode; +    private Timer mProfilerSnapshotTimer; + +    private Context mSystemContext; +    private SystemServiceManager mSystemServiceManager; + +    // TODO: remove all of these references by improving dependency resolution and boot phases +    private Installer mInstaller; +    private PowerManagerService mPowerManagerService; +    private ActivityManagerService mActivityManagerService; +    private DisplayManagerService mDisplayManagerService; +    private ContentResolver mContentResolver; + +    /** +     * Called to initialize native system services. +     */ +    private static native void nativeInit(); + +    /** +     * The main entry point from zygote. +     */ +    public static void main(String[] args) { +        new SystemServer().run();      } -    public void initAndLoop() { -        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, -            SystemClock.uptimeMillis()); +    public SystemServer() { +        mFactoryTestMode = FactoryTest.getMode(); +    } -        Looper.prepareMainLooper(); +    private void run() { +        // If a device's clock is before 1970 (before 0), a lot of +        // APIs crash dealing with negative numbers, notably +        // java.io.File#setLastModified, so instead we fake it and +        // hope that time from cell towers or NTP fixes it shortly. +        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { +            Slog.w(TAG, "System clock is before 1970; setting to 1970."); +            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); +        } -        android.os.Process.setThreadPriority( -                android.os.Process.THREAD_PRIORITY_FOREGROUND); +        // Here we go! +        Slog.i(TAG, "Entered the Android system server!"); +        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); + +        // In case the runtime switched since last boot (such as when +        // the old runtime was removed in an OTA), set the system +        // property so that it is in sync. We can't do this in +        // libnativehelper's JniInvocation::Init code where we already +        // had to fallback to a different runtime because it is +        // running as root and we need to be the system user to set +        // the property. http://b/11463182 +        SystemProperties.set("persist.sys.dalvik.vm.lib", VMRuntime.getRuntime().vmLibrary()); + +        // Enable the sampling profiler. +        if (SamplingProfilerIntegration.isEnabled()) { +            SamplingProfilerIntegration.start(); +            mProfilerSnapshotTimer = new Timer(); +            mProfilerSnapshotTimer.schedule(new TimerTask() { +                @Override +                public void run() { +                    SamplingProfilerIntegration.writeSnapshot("system_server", null); +                } +            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); +        } + +        // Mmmmmm... more memory! +        VMRuntime.getRuntime().clearGrowthLimit(); +        // The system server has to run all of the time, so it needs to be +        // as efficient as possible with its memory usage. +        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); + +        // Within the system server, it is an error to access Environment paths without +        // explicitly specifying a user. +        Environment.setUserRequired(true); + +        // Ensure binder calls into the system always run at foreground priority.          BinderInternal.disableBackgroundScheduling(true); + +        // Prepare the main looper thread (this thread). +        android.os.Process.setThreadPriority( +                android.os.Process.THREAD_PRIORITY_FOREGROUND);          android.os.Process.setCanSelfBackground(false); +        Looper.prepareMainLooper(); + +        // Initialize native services. +        System.loadLibrary("android_servers"); +        nativeInit();          // Check whether we failed to shut down last time we tried. -        { -            final String shutdownAction = SystemProperties.get( -                    ShutdownThread.SHUTDOWN_ACTION_PROPERTY, ""); -            if (shutdownAction != null && shutdownAction.length() > 0) { -                boolean reboot = (shutdownAction.charAt(0) == '1'); - -                final String reason; -                if (shutdownAction.length() > 1) { -                    reason = shutdownAction.substring(1, shutdownAction.length()); -                } else { -                    reason = null; -                } +        // This call may not return. +        performPendingShutdown(); + +        // Initialize the system context. +        createSystemContext(); + +        // Create the system service manager. +        mSystemServiceManager = new SystemServiceManager(mSystemContext); +        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); + +        // Start services. +        try { +            startBootstrapServices(); +            startCoreServices(); +            startOtherServices(); +        } catch (RuntimeException ex) { +            Slog.e("System", "******************************************"); +            Slog.e("System", "************ Failure starting system services", ex); +            throw ex; +        } -                ShutdownThread.rebootOrShutdown(reboot, reason); +        // For debug builds, log event loop stalls to dropbox for analysis. +        if (StrictMode.conditionallyEnableDebugLogging()) { +            Slog.i(TAG, "Enabled StrictMode for system server main thread."); +        } + +        // Loop forever. +        Looper.loop(); +        throw new RuntimeException("Main thread loop unexpectedly exited"); +    } + +    private void reportWtf(String msg, Throwable e) { +        Slog.w(TAG, "***********************************************"); +        Log.wtf(TAG, "BOOT FAILURE " + msg, e); +    } + +    private void performPendingShutdown() { +        final String shutdownAction = SystemProperties.get( +                ShutdownThread.SHUTDOWN_ACTION_PROPERTY, ""); +        if (shutdownAction != null && shutdownAction.length() > 0) { +            boolean reboot = (shutdownAction.charAt(0) == '1'); + +            final String reason; +            if (shutdownAction.length() > 1) { +                reason = shutdownAction.substring(1, shutdownAction.length()); +            } else { +                reason = null;              } + +            ShutdownThread.rebootOrShutdown(reboot, reason);          } +    } + +    private void createSystemContext() { +        ActivityThread activityThread = ActivityThread.systemMain(); +        mSystemContext = activityThread.getSystemContext(); +        mSystemContext.setTheme(android.R.style.Theme_Holo); +    } -        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")); +    private void startBootstrapServices() { +        // Wait for installd to finish starting up so that it has a chance to +        // create critical directories such as /data/user with the appropriate +        // permissions.  We need this to complete before we initialize other services. +        mInstaller = mSystemServiceManager.startService(Installer.class); + +        // Power manager needs to be started early because other services need it. +        // TODO: The conversion to the new pattern is incomplete.  We need to switch +        // the power manager's dependencies over then we can use boot phases to arrange +        // initialization order and remove the mPowerManagerService field. +        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); + +        // Activity manager runs the show. +        mActivityManagerService = mSystemServiceManager.startService( +                ActivityManagerService.Lifecycle.class).getService(); +    } + +    private void startCoreServices() { +        // Display manager is needed to provide display metrics before package manager +        // starts up. +        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); +    } -        Installer installer = null; +    private void startOtherServices() { +        final Context context = mSystemContext;          AccountManagerService accountManager = null;          ContentService contentService = null; -        LightsService lights = null; -        PowerManagerService power = null; -        DisplayManagerService display = null; +        LightsManager lights = null;          BatteryService battery = null;          VibratorService vibrator = null; -        AlarmManagerService alarm = null; +        IAlarmManager alarm = null;          MountService mountService = null;          NetworkManagementService networkManagement = null;          NetworkStatsService networkStats = null; @@ -142,14 +301,11 @@ class ServerThread {          WifiService wifi = null;          NsdService serviceDiscovery= null;          IPackageManager pm = null; -        Context context = null;          WindowManagerService wm = null;          BluetoothManagerService bluetooth = null;          DockObserver dock = null;          UsbService usb = null;          SerialService serial = null; -        TwilightService twilight = null; -        UiModeManagerService uiMode = null;          RecognitionManagerService recognition = null;          NetworkTimeUpdateService networkTimeUpdater = null;          CommonTimeManagementService commonTimeMgmtService = null; @@ -157,48 +313,8 @@ class ServerThread {          TelephonyRegistry telephonyRegistry = null;          ConsumerIrService consumerIr = null; -        // Create a handler thread just for the window manager to enjoy. -        HandlerThread wmHandlerThread = new HandlerThread("WindowManager"); -        wmHandlerThread.start(); -        Handler wmHandler = new Handler(wmHandlerThread.getLooper()); -        wmHandler.post(new Runnable() { -            @Override -            public void run() { -                //Looper.myLooper().setMessageLogging(new LogPrinter( -                //        android.util.Log.DEBUG, TAG, android.util.Log.LOG_ID_SYSTEM)); -                android.os.Process.setThreadPriority( -                        android.os.Process.THREAD_PRIORITY_DISPLAY); -                android.os.Process.setCanSelfBackground(false); - -                // For debug builds, log event loop stalls to dropbox for analysis. -                if (StrictMode.conditionallyEnableDebugLogging()) { -                    Slog.i(TAG, "Enabled StrictMode logging for WM Looper"); -                } -            } -        }); - -        // bootstrap services          boolean onlyCore = false;          boolean firstBoot = false; -        try { -            // Wait for installd to finished starting up so that it has a chance to -            // create critical directories such as /data/user with the appropriate -            // permissions.  We need this to complete before we initialize other services. -            Slog.i(TAG, "Waiting for installd to be ready."); -            installer = new Installer(); -            installer.ping(); - -            Slog.i(TAG, "Power Manager"); -            power = new PowerManagerService(); -            ServiceManager.addService(Context.POWER_SERVICE, power); - -            Slog.i(TAG, "Activity Manager"); -            context = ActivityManagerService.main(factoryTest); -        } catch (RuntimeException e) { -            Slog.e("System", "******************************************"); -            Slog.e("System", "************ Failure starting bootstrap service", e); -        } -          boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);          boolean disableMedia = SystemProperties.getBoolean("config.disable_media", false);          boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false); @@ -209,10 +325,6 @@ class ServerThread {          boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);          try { -            Slog.i(TAG, "Display Manager"); -            display = new DisplayManagerService(context, wmHandler); -            ServiceManager.addService(Context.DISPLAY_SERVICE, display, true); -              Slog.i(TAG, "Telephony Registry");              telephonyRegistry = new TelephonyRegistry(context);              ServiceManager.addService("telephony.registry", telephonyRegistry); @@ -222,10 +334,8 @@ class ServerThread {              AttributeCache.init(context); -            if (!display.waitForDefaultDisplay()) { -                reportWtf("Timeout waiting for default display to be initialized.", -                        new Throwable()); -            } +            // We need the default display before we can initialize the package manager. +            mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);              Slog.i(TAG, "Package Manager");              // Only run "core" apps if we're encrypting the device. @@ -238,15 +348,15 @@ class ServerThread {                  onlyCore = true;              } -            pm = PackageManagerService.main(context, installer, -                    factoryTest != SystemServer.FACTORY_TEST_OFF, +            pm = PackageManagerService.main(context, mInstaller, +                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF,                      onlyCore);              try {                  firstBoot = pm.isFirstBoot();              } catch (RemoteException e) {              } -            ActivityManagerService.setSystemProcess(); +            mActivityManagerService.setSystemProcess();              Slog.i(TAG, "Entropy Mixer");              ServiceManager.addService("entropy", new EntropyMixer(context)); @@ -269,13 +379,13 @@ class ServerThread {              Slog.i(TAG, "Content Manager");              contentService = ContentService.main(context, -                    factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL); +                    mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL);              Slog.i(TAG, "System Content Providers"); -            ActivityManagerService.installSystemProviders(); +            mActivityManagerService.installSystemProviders(); -            Slog.i(TAG, "Lights Service"); -            lights = new LightsService(context); +            mSystemServiceManager.startService(LightsService.class); +            lights = LocalServices.getService(LightsManager.class);              Slog.i(TAG, "Battery Service");              battery = new BatteryService(context, lights); @@ -285,49 +395,49 @@ class ServerThread {              vibrator = new VibratorService(context);              ServiceManager.addService("vibrator", vibrator); -            Slog.i(TAG, "Consumer IR Service"); -            consumerIr = new ConsumerIrService(context); -            ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr); - +            // TODO: use boot phase              // 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, +            mPowerManagerService.init(lights, battery,                      BatteryStatsService.getService(), -                    ActivityManagerService.self().getAppOpsService(), display); +                    mActivityManagerService.getAppOpsService()); -            Slog.i(TAG, "Alarm Manager"); -            alarm = new AlarmManagerService(context); -            ServiceManager.addService(Context.ALARM_SERVICE, alarm); +            Slog.i(TAG, "Consumer IR Service"); +            consumerIr = new ConsumerIrService(context); +            ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr); + +            mSystemServiceManager.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().addThread(wmHandler, "WindowManager thread"); +            final Watchdog watchdog = Watchdog.getInstance(); +            watchdog.init(context, mActivityManagerService);              Slog.i(TAG, "Input Manager"); -            inputManager = new InputManagerService(context, wmHandler); +            inputManager = new InputManagerService(context);              Slog.i(TAG, "Window Manager"); -            wm = WindowManagerService.main(context, power, display, inputManager, -                    wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL, +            wm = WindowManagerService.main(context, inputManager, +                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,                      !firstBoot, onlyCore);              ServiceManager.addService(Context.WINDOW_SERVICE, wm);              ServiceManager.addService(Context.INPUT_SERVICE, inputManager); -            ActivityManagerService.self().setWindowManager(wm); +            mActivityManagerService.setWindowManager(wm);              inputManager.setWindowManagerCallbacks(wm.getInputMonitor());              inputManager.start(); -            display.setWindowManager(wm); -            display.setInputManager(inputManager); +            // TODO: Use service dependencies instead. +            mDisplayManagerService.windowManagerAndInputReady();              // Skip Bluetooth if we have an emulator kernel              // TODO: Use a more reliable check to see if this product should              // support Bluetooth - see bug 988521              if (SystemProperties.get("ro.kernel.qemu").equals("1")) {                  Slog.i(TAG, "No Bluetooh Service (emulator)"); -            } else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { +            } else if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {                  Slog.i(TAG, "No Bluetooth Service (factory test)");              } else if (!context.getPackageManager().hasSystemFeature                         (PackageManager.FEATURE_BLUETOOTH)) { @@ -344,23 +454,19 @@ 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;          TextServicesManagerService tsms = null;          LockSettingsService lockSettings = null; -        DreamManagerService dreamy = null;          AssetAtlasService atlas = null; -        PrintManagerService printManager = null;          MediaRouterService mediaRouter = null;          // Bring up services needed for UI. -        if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { +        if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {              //if (!disableNonCoreServices) { // TODO: View depends on these; mock them?              if (true) {                  try { @@ -373,8 +479,8 @@ class ServerThread {                  try {                      Slog.i(TAG, "Accessibility Manager"); -                    ServiceManager.addService(Context.ACCESSIBILITY_SERVICE, -                            new AccessibilityManagerService(context)); +                    ServiceManager.addService(Context.ACCESSIBILITY_SERVICE, (IBinder) +                            getClass().getClassLoader().loadClass("com.android.server.accessibility.AccessibilityManagerService").getConstructor(Context.class).newInstance(context));                  } catch (Throwable e) {                      reportWtf("starting Accessibility Manager", e);                  } @@ -397,11 +503,11 @@ class ServerThread {              ActivityManagerNative.getDefault().showBootMessage(                      context.getResources().getText(                              com.android.internal.R.string.android_upgrading_starting_apps), -                            false); +                    false);          } catch (RemoteException e) {          } -        if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { +        if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {              if (!disableStorage &&                  !"0".equals(SystemProperties.get("system_init.startmountservice"))) {                  try { @@ -427,9 +533,10 @@ class ServerThread {                  }                  try { -                    Slog.i(TAG, "Device Policy"); -                    devicePolicy = new DevicePolicyManagerService(context); -                    ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy); +                    if (pm.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) { +                        mSystemServiceManager.startServiceIfExists( +                                DEVICE_POLICY_MANAGER_SERVICE_CLASS); +                    }                  } catch (Throwable e) {                      reportWtf("starting DevicePolicyService", e);                  } @@ -487,7 +594,8 @@ class ServerThread {                  try {                      Slog.i(TAG, "NetworkPolicy Service");                      networkPolicy = new NetworkPolicyManagerService( -                            context, ActivityManagerService.self(), power, +                            context, mActivityManagerService, +                            (IPowerManager)ServiceManager.getService(Context.POWER_SERVICE),                              networkStats, networkManagement);                      ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);                  } catch (Throwable e) { @@ -567,22 +675,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); -            } +            mSystemServiceManager.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); -            } +            mSystemServiceManager.startService(DeviceStorageMonitorService.class);              if (!disableLocation) {                  try { @@ -624,10 +722,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 +779,23 @@ class ServerThread {                  }              } -            try { -                Slog.i(TAG, "Twilight Service"); -                twilight = new TwilightService(context); -            } catch (Throwable e) { -                reportWtf("starting TwilightService", e); -            } +            mSystemServiceManager.startService(TwilightService.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); -            } +            mSystemServiceManager.startService(UiModeManagerService.class);              if (!disableNonCoreServices) {                  try { -                    Slog.i(TAG, "Backup Service"); -                    ServiceManager.addService(Context.BACKUP_SERVICE, -                            new BackupManagerService(context)); +                    if (pm.hasSystemFeature(PackageManager.FEATURE_BACKUP)) { +                        mSystemServiceManager.startServiceIfExists(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); +                    if (pm.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)) { +                        mSystemServiceManager.startServiceIfExists(APPWIDGET_SERVICE_CLASS); +                    }                  } catch (Throwable e) {                      reportWtf("starting AppWidget Service", e);                  } @@ -770,16 +855,10 @@ class ServerThread {                  }              } -            if (!disableNonCoreServices &&  -                context.getResources().getBoolean(R.bool.config_dreamsSupported)) { -                try { -                    Slog.i(TAG, "Dreams Service"); -                    // Dreams (interactive idle-time views, a/k/a screen savers) -                    dreamy = new DreamManagerService(context, wmHandler); -                    ServiceManager.addService(DreamService.DREAM_SERVICE, dreamy); -                } catch (Throwable e) { -                    reportWtf("starting DreamManagerService", e); -                } +            if (!disableNonCoreServices +                    && context.getResources().getBoolean(R.bool.config_dreamsSupported)) { +                // Dreams (interactive idle-time views, a/k/a screen savers) +                mSystemServiceManager.startService(DreamManagerService.class);              }              if (!disableNonCoreServices) { @@ -800,9 +879,9 @@ class ServerThread {              }              try { -                Slog.i(TAG, "Print Service"); -                printManager = new PrintManagerService(context); -                ServiceManager.addService(Context.PRINT_SERVICE, printManager); +                if (pm.hasSystemFeature(PackageManager.FEATURE_PRINTING)) { +                    mSystemServiceManager.startServiceIfExists(PRINT_MANAGER_SERVICE_CLASS); +                }              } catch (Throwable e) {                  reportWtf("starting Print Service", e);              } @@ -822,7 +901,7 @@ class ServerThread {          // we are in safe mode.          final boolean safeMode = wm.detectSafeMode();          if (safeMode) { -            ActivityManagerService.self().enterSafeMode(); +            mActivityManagerService.enterSafeMode();              // Post the safe mode state in the Zygote class              Zygote.systemInSafeMode = true;              // Disable the JIT for the system_server process @@ -848,21 +927,10 @@ class ServerThread {              }          } -        if (devicePolicy != null) { -            try { -                devicePolicy.systemReady(); -            } catch (Throwable e) { -                reportWtf("making Device Policy Service ready", e); -            } -        } +        // Needed by DevicePolicyManager for initialization +        mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); -        if (notification != null) { -            try { -                notification.systemReady(); -            } catch (Throwable e) { -                reportWtf("making Notification Service ready", e); -            } -        } +        mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);          try {              wm.systemReady(); @@ -871,7 +939,7 @@ class ServerThread {          }          if (safeMode) { -            ActivityManagerService.self().showSafeModeOverlay(); +            mActivityManagerService.showSafeModeOverlay();          }          // Update the configuration for this context by hand, because we're going @@ -884,7 +952,8 @@ class ServerThread {          context.getResources().updateConfiguration(config, metrics);          try { -            power.systemReady(twilight, dreamy); +            // TODO: use boot phase +            mPowerManagerService.systemReady();          } catch (Throwable e) {              reportWtf("making Power Manager Service ready", e);          } @@ -896,7 +965,8 @@ class ServerThread {          }          try { -            display.systemReady(safeMode, onlyCore); +            // TODO: use boot phase and communicate these flags some other way +            mDisplayManagerService.systemReady(safeMode, onlyCore);          } catch (Throwable e) {              reportWtf("making Display Manager Service ready", e);          } @@ -911,9 +981,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; @@ -923,11 +990,9 @@ class ServerThread {          final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;          final TextServicesManagerService textServiceManagerServiceF = tsms;          final StatusBarManagerService statusBarF = statusBar; -        final DreamManagerService dreamyF = dreamy;          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 @@ -935,17 +1000,19 @@ class ServerThread {          // where third party code can really run (but before it has actually          // started launching the initial applications), for us to complete our          // initialization. -        ActivityManagerService.self().systemReady(new Runnable() { +        mActivityManagerService.systemReady(new Runnable() {              public void run() {                  Slog.i(TAG, "Making services ready");                  try { -                    ActivityManagerService.self().startObservingNativeCrashes(); +                    mActivityManagerService.startObservingNativeCrashes();                  } 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 +1055,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 +1063,9 @@ class ServerThread {                  // It is now okay to let the various system services start their                  // third party code... +                mSystemServiceManager.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); @@ -1049,11 +1102,6 @@ class ServerThread {                      reportWtf("Notifying TextServicesManagerService running", e);                  }                  try { -                    if (dreamyF != null) dreamyF.systemRunning(); -                } catch (Throwable e) { -                    reportWtf("Notifying DreamManagerService running", e); -                } -                try {                      if (atlasF != null) atlasF.systemRunning();                  } catch (Throwable e) {                      reportWtf("Notifying AssetAtlasService running", e); @@ -1072,26 +1120,14 @@ 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);                  } + +                mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETE);              }          }); - -        // For debug builds, log event loop stalls to dropbox for analysis. -        if (StrictMode.conditionallyEnableDebugLogging()) { -            Slog.i(TAG, "Enabled StrictMode for system server main thread."); -        } - -        Looper.loop(); -        Slog.d(TAG, "System ServerThread is exiting!");      }      static final void startSystemUi(Context context) { @@ -1102,80 +1138,3 @@ class ServerThread {          context.startServiceAsUser(intent, UserHandle.OWNER);      }  } - -public class SystemServer { -    private static final String TAG = "SystemServer"; - -    public static final int FACTORY_TEST_OFF = 0; -    public static final int FACTORY_TEST_LOW_LEVEL = 1; -    public static final int FACTORY_TEST_HIGH_LEVEL = 2; - -    static Timer timer; -    static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr - -    // The earliest supported time.  We pick one day into 1970, to -    // give any timezone code room without going into negative time. -    private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000; - -    /** -     * Called to initialize native system services. -     */ -    private static native void nativeInit(); - -    public static void main(String[] args) { - -        /* -         * In case the runtime switched since last boot (such as when -         * the old runtime was removed in an OTA), set the system -         * property so that it is in sync. We can't do this in -         * libnativehelper's JniInvocation::Init code where we already -         * had to fallback to a different runtime because it is -         * running as root and we need to be the system user to set -         * the property. http://b/11463182 -         */ -        SystemProperties.set("persist.sys.dalvik.vm.lib", -                             VMRuntime.getRuntime().vmLibrary()); - -        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { -            // If a device's clock is before 1970 (before 0), a lot of -            // APIs crash dealing with negative numbers, notably -            // java.io.File#setLastModified, so instead we fake it and -            // hope that time from cell towers or NTP fixes it -            // shortly. -            Slog.w(TAG, "System clock is before 1970; setting to 1970."); -            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); -        } - -        if (SamplingProfilerIntegration.isEnabled()) { -            SamplingProfilerIntegration.start(); -            timer = new Timer(); -            timer.schedule(new TimerTask() { -                @Override -                public void run() { -                    SamplingProfilerIntegration.writeSnapshot("system_server", null); -                } -            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); -        } - -        // Mmmmmm... more memory! -        dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); - -        // The system server has to run all of the time, so it needs to be -        // as efficient as possible with its memory usage. -        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); - -        Environment.setUserRequired(true); - -        System.loadLibrary("android_servers"); - -        Slog.i(TAG, "Entered the Android system server!"); - -        // Initialize native services. -        nativeInit(); - -        // This used to be its own separate thread, but now it is -        // just the loop we run on the main thread. -        ServerThread thr = new ServerThread(); -        thr.initAndLoop(); -    } -} 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/dreams/DreamManagerService.java b/services/java/com/android/server/dreams/DreamManagerService.java deleted file mode 100644 index b6e778170d17..000000000000 --- a/services/java/com/android/server/dreams/DreamManagerService.java +++ /dev/null @@ -1,425 +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.dreams; - -import com.android.internal.util.DumpUtils; - -import android.app.ActivityManager; -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.PackageManager.NameNotFoundException; -import android.os.Binder; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.PowerManager; -import android.os.SystemClock; -import android.os.UserHandle; -import android.provider.Settings; -import android.service.dreams.IDreamManager; -import android.util.Slog; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; - -import libcore.util.Objects; - -/** - * Service api for managing dreams. - * - * @hide - */ -public final class DreamManagerService extends IDreamManager.Stub { -    private static final boolean DEBUG = false; -    private static final String TAG = "DreamManagerService"; - -    private final Object mLock = new Object(); - -    private final Context mContext; -    private final DreamHandler mHandler; -    private final DreamController mController; -    private final PowerManager mPowerManager; - -    private Binder mCurrentDreamToken; -    private ComponentName mCurrentDreamName; -    private int mCurrentDreamUserId; -    private boolean mCurrentDreamIsTest; - -    public DreamManagerService(Context context, Handler mainHandler) { -        mContext = context; -        mHandler = new DreamHandler(mainHandler.getLooper()); -        mController = new DreamController(context, mHandler, mControllerListener); - -        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); -    } - -    public void systemRunning() { -        mContext.registerReceiver(new BroadcastReceiver() { -            @Override -            public void onReceive(Context context, Intent intent) { -                synchronized (mLock) { -                    stopDreamLocked(); -                } -            } -        }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); -    } - -    @Override -    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { -        if (mContext.checkCallingOrSelfPermission("android.permission.DUMP") -                != PackageManager.PERMISSION_GRANTED) { -            pw.println("Permission Denial: can't dump DreamManager from pid=" -                    + Binder.getCallingPid() -                    + ", uid=" + Binder.getCallingUid()); -            return; -        } - -        pw.println("DREAM MANAGER (dumpsys dreams)"); -        pw.println(); - -        pw.println("mCurrentDreamToken=" + mCurrentDreamToken); -        pw.println("mCurrentDreamName=" + mCurrentDreamName); -        pw.println("mCurrentDreamUserId=" + mCurrentDreamUserId); -        pw.println("mCurrentDreamIsTest=" + mCurrentDreamIsTest); -        pw.println(); - -        DumpUtils.dumpAsync(mHandler, new DumpUtils.Dump() { -            @Override -            public void dump(PrintWriter pw) { -                mController.dump(pw); -            } -        }, pw, 200); -    } - -    @Override // Binder call -    public ComponentName[] getDreamComponents() { -        checkPermission(android.Manifest.permission.READ_DREAM_STATE); - -        final int userId = UserHandle.getCallingUserId(); -        final long ident = Binder.clearCallingIdentity(); -        try { -            return getDreamComponentsForUser(userId); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } - -    @Override // Binder call -    public void setDreamComponents(ComponentName[] componentNames) { -        checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); - -        final int userId = UserHandle.getCallingUserId(); -        final long ident = Binder.clearCallingIdentity(); -        try { -            Settings.Secure.putStringForUser(mContext.getContentResolver(), -                    Settings.Secure.SCREENSAVER_COMPONENTS, -                    componentsToString(componentNames), -                    userId); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } - -    @Override // Binder call -    public ComponentName getDefaultDreamComponent() { -        checkPermission(android.Manifest.permission.READ_DREAM_STATE); - -        final int userId = UserHandle.getCallingUserId(); -        final long ident = Binder.clearCallingIdentity(); -        try { -            String name = Settings.Secure.getStringForUser(mContext.getContentResolver(), -                    Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT, -                    userId); -            return name == null ? null : ComponentName.unflattenFromString(name); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } - -    @Override // Binder call -    public boolean isDreaming() { -        checkPermission(android.Manifest.permission.READ_DREAM_STATE); - -        synchronized (mLock) { -            return mCurrentDreamToken != null && !mCurrentDreamIsTest; -        } -    } - -    @Override // Binder call -    public void dream() { -        checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            // Ask the power manager to nap.  It will eventually call back into -            // startDream() if/when it is appropriate to start dreaming. -            // Because napping could cause the screen to turn off immediately if the dream -            // cannot be started, we keep one eye open and gently poke user activity. -            long time = SystemClock.uptimeMillis(); -            mPowerManager.userActivity(time, true /*noChangeLights*/); -            mPowerManager.nap(time); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } - -    @Override // Binder call -    public void testDream(ComponentName dream) { -        checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); - -        if (dream == null) { -            throw new IllegalArgumentException("dream must not be null"); -        } - -        final int callingUserId = UserHandle.getCallingUserId(); -        final int currentUserId = ActivityManager.getCurrentUser(); -        if (callingUserId != currentUserId) { -            // This check is inherently prone to races but at least it's something. -            Slog.w(TAG, "Aborted attempt to start a test dream while a different " -                    + " user is active: callingUserId=" + callingUserId -                    + ", currentUserId=" + currentUserId); -            return; -        } -        final long ident = Binder.clearCallingIdentity(); -        try { -            synchronized (mLock) { -                startDreamLocked(dream, true /*isTest*/, callingUserId); -            } -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } - -    @Override // Binder call -    public void awaken() { -        checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); - -        final long ident = Binder.clearCallingIdentity(); -        try { -            // Treat an explicit request to awaken as user activity so that the -            // device doesn't immediately go to sleep if the timeout expired, -            // for example when being undocked. -            long time = SystemClock.uptimeMillis(); -            mPowerManager.userActivity(time, false /*noChangeLights*/); -            stopDream(); -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } - -    @Override // Binder call -    public void finishSelf(IBinder token) { -        // Requires no permission, called by Dream from an arbitrary process. -        if (token == null) { -            throw new IllegalArgumentException("token must not be null"); -        } - -        final long ident = Binder.clearCallingIdentity(); -        try { -            if (DEBUG) { -                Slog.d(TAG, "Dream finished: " + token); -            } - -            // Note that a dream finishing and self-terminating is not -            // itself considered user activity.  If the dream is ending because -            // the user interacted with the device then user activity will already -            // have been poked so the device will stay awake a bit longer. -            // If the dream is ending on its own for other reasons and no wake -            // locks are held and the user activity timeout has expired then the -            // device may simply go to sleep. -            synchronized (mLock) { -                if (mCurrentDreamToken == token) { -                    stopDreamLocked(); -                } -            } -        } finally { -            Binder.restoreCallingIdentity(ident); -        } -    } - -    /** -     * Called by the power manager to start a dream. -     */ -    public void startDream() { -        int userId = ActivityManager.getCurrentUser(); -        ComponentName dream = chooseDreamForUser(userId); -        if (dream != null) { -            synchronized (mLock) { -                startDreamLocked(dream, false /*isTest*/, userId); -            } -        } -    } - -    /** -     * Called by the power manager to stop a dream. -     */ -    public void stopDream() { -        synchronized (mLock) { -            stopDreamLocked(); -        } -    } - -    private ComponentName chooseDreamForUser(int userId) { -        ComponentName[] dreams = getDreamComponentsForUser(userId); -        return dreams != null && dreams.length != 0 ? dreams[0] : null; -    } - -    private ComponentName[] getDreamComponentsForUser(int userId) { -        String names = Settings.Secure.getStringForUser(mContext.getContentResolver(), -                Settings.Secure.SCREENSAVER_COMPONENTS, -                userId); -        ComponentName[] components = componentsFromString(names); - -        // first, ensure components point to valid services -        List<ComponentName> validComponents = new ArrayList<ComponentName>(); -        if (components != null) { -            for (ComponentName component : components) { -                if (serviceExists(component)) { -                    validComponents.add(component); -                } else { -                    Slog.w(TAG, "Dream " + component + " does not exist"); -                } -            } -        } - -        // fallback to the default dream component if necessary -        if (validComponents.isEmpty()) { -            ComponentName defaultDream = getDefaultDreamComponent(); -            if (defaultDream != null) { -                Slog.w(TAG, "Falling back to default dream " + defaultDream); -                validComponents.add(defaultDream); -            } -        } -        return validComponents.toArray(new ComponentName[validComponents.size()]); -    } - -    private boolean serviceExists(ComponentName name) { -        try { -            return name != null && mContext.getPackageManager().getServiceInfo(name, 0) != null; -        } catch (NameNotFoundException e) { -            return false; -        } -    } - -    private void startDreamLocked(final ComponentName name, -            final boolean isTest, final int userId) { -        if (Objects.equal(mCurrentDreamName, name) -                && mCurrentDreamIsTest == isTest -                && mCurrentDreamUserId == userId) { -            return; -        } - -        stopDreamLocked(); - -        if (DEBUG) Slog.i(TAG, "Entering dreamland."); - -        final Binder newToken = new Binder(); -        mCurrentDreamToken = newToken; -        mCurrentDreamName = name; -        mCurrentDreamIsTest = isTest; -        mCurrentDreamUserId = userId; - -        mHandler.post(new Runnable() { -            @Override -            public void run() { -                mController.startDream(newToken, name, isTest, userId); -            } -        }); -    } - -    private void stopDreamLocked() { -        if (mCurrentDreamToken != null) { -            if (DEBUG) Slog.i(TAG, "Leaving dreamland."); - -            cleanupDreamLocked(); - -            mHandler.post(new Runnable() { -                @Override -                public void run() { -                    mController.stopDream(); -                } -            }); -        } -    } - -    private void cleanupDreamLocked() { -        mCurrentDreamToken = null; -        mCurrentDreamName = null; -        mCurrentDreamIsTest = false; -        mCurrentDreamUserId = 0; -    } - -    private void checkPermission(String permission) { -        if (mContext.checkCallingOrSelfPermission(permission) -                != PackageManager.PERMISSION_GRANTED) { -            throw new SecurityException("Access denied to process: " + Binder.getCallingPid() -                    + ", must have permission " + permission); -        } -    } - -    private static String componentsToString(ComponentName[] componentNames) { -        StringBuilder names = new StringBuilder(); -        if (componentNames != null) { -            for (ComponentName componentName : componentNames) { -                if (names.length() > 0) { -                    names.append(','); -                } -                names.append(componentName.flattenToString()); -            } -        } -        return names.toString(); -    } - -    private static ComponentName[] componentsFromString(String names) { -        if (names == null) { -            return null; -        } -        String[] namesArray = names.split(","); -        ComponentName[] componentNames = new ComponentName[namesArray.length]; -        for (int i = 0; i < namesArray.length; i++) { -            componentNames[i] = ComponentName.unflattenFromString(namesArray[i]); -        } -        return componentNames; -    } - -    private final DreamController.Listener mControllerListener = new DreamController.Listener() { -        @Override -        public void onDreamStopped(Binder token) { -            synchronized (mLock) { -                if (mCurrentDreamToken == token) { -                    cleanupDreamLocked(); -                } -            } -        } -    }; - -    /** -     * Handler for asynchronous operations performed by the dream manager. -     * Ensures operations to {@link DreamController} are single-threaded. -     */ -    private final class DreamHandler extends Handler { -        public DreamHandler(Looper looper) { -            super(looper, null, true /*async*/); -        } -    } -} 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/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java deleted file mode 100644 index d358b4c6ed67..000000000000 --- a/services/java/com/android/server/wm/DisplayContent.java +++ /dev/null @@ -1,523 +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.wm; - -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.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 com.android.server.EventLogTags; - -import java.io.PrintWriter; -import java.util.ArrayList; - -class DisplayContentList extends ArrayList<DisplayContent> { -} - -/** - * Utility class for keeping track of the WindowStates and other pertinent contents of a - * particular Display. - * - * IMPORTANT: No method from this class should ever be used without holding - * WindowManagerService.mWindowMap. - */ -class DisplayContent { - -    /** Unique identifier of this stack. */ -    private final int mDisplayId; - -    /** Z-ordered (bottom-most first) list of all Window objects. Assigned to an element -     * from mDisplayWindows; */ -    private WindowList mWindows = new WindowList(); - -    // This protects the following display size properties, so that -    // getDisplaySize() doesn't need to acquire the global lock.  This is -    // needed because the window manager sometimes needs to use ActivityThread -    // while it has its global state locked (for example to load animation -    // resources), but the ActivityThread also needs get the current display -    // size sometimes when it has its package lock held. -    // -    // These will only be modified with both mWindowMap and mDisplaySizeLock -    // held (in that order) so the window manager doesn't need to acquire this -    // lock when needing these values in its normal operation. -    final Object mDisplaySizeLock = new Object(); -    int mInitialDisplayWidth = 0; -    int mInitialDisplayHeight = 0; -    int mInitialDisplayDensity = 0; -    int mBaseDisplayWidth = 0; -    int mBaseDisplayHeight = 0; -    int mBaseDisplayDensity = 0; -    private final DisplayInfo mDisplayInfo = new DisplayInfo(); -    private final Display mDisplay; - -    Rect mBaseDisplayRect = new Rect(); - -    // Accessed directly by all users. -    boolean layoutNeeded; -    int pendingLayoutChanges; -    final boolean isDefaultDisplay; - -    /** -     * Window tokens that are in the process of exiting, but still -     * on screen for animations. -     */ -    final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>(); - -    /** -     * Application tokens that are in the process of exiting, but still -     * on screen for animations. -     */ -    final AppTokenList mExitingAppTokens = new AppTokenList(); - -    /** Array containing the home StackBox and possibly one more which would contain apps. Array -     * is stored in display order with the current bottom stack at 0. */ -    private ArrayList<StackBox> mStackBoxes = new ArrayList<StackBox>(); - -    /** True when the home StackBox is at the top of mStackBoxes, false otherwise. */ -    private TaskStack mHomeStack = null; - -    /** Detect user tapping outside of current focused stack bounds .*/ -    StackTapPointerEventListener mTapDetector; - -    /** Detect user tapping outside of current focused stack bounds .*/ -    Region mTouchExcludeRegion = new Region(); - -    /** Save allocating when retrieving tasks */ -    private ArrayList<Task> mTaskHistory = new ArrayList<Task>(); - -    /** Save allocating when calculating rects */ -    Rect mTmpRect = new Rect(); - -    final WindowManagerService mService; - -    /** -     * @param display May not be null. -     * @param service TODO(cmautner): -     */ -    DisplayContent(Display display, WindowManagerService service) { -        mDisplay = display; -        mDisplayId = display.getDisplayId(); -        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() { -        return mDisplayId; -    } - -    WindowList getWindowList() { -        return mWindows; -    } - -    Display getDisplay() { -        return mDisplay; -    } - -    DisplayInfo getDisplayInfo() { -        return mDisplayInfo; -    } - -    /** -     * Returns true if the specified UID has access to this display. -     */ -    public boolean hasAccess(int uid) { -        return mDisplay.hasAccess(uid); -    } - -    boolean homeOnTop() { -        return mStackBoxes.get(0).mStack != mHomeStack; -    } - -    public boolean isPrivate() { -        return (mDisplay.getFlags() & Display.FLAG_PRIVATE) != 0; -    } - -    /** -     * Retrieve the tasks on this display in stack order from the bottommost TaskStack up. -     * @return All the Tasks, in order, on this display. -     */ -    ArrayList<Task> getTasks() { -        return mTaskHistory; -    } - -    void addTask(Task task, boolean toTop) { -        mTaskHistory.remove(task); - -        final int userId = task.mUserId; -        int taskNdx; -        final int numTasks = mTaskHistory.size(); -        if (toTop) { -            for (taskNdx = numTasks - 1; taskNdx >= 0; --taskNdx) { -                if (mTaskHistory.get(taskNdx).mUserId == userId) { -                    break; -                } -            } -            ++taskNdx; -        } else { -            for (taskNdx = 0; taskNdx < numTasks; ++taskNdx) { -                if (mTaskHistory.get(taskNdx).mUserId == userId) { -                    break; -                } -            } -        } - -        mTaskHistory.add(taskNdx, task); -        EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.taskId, toTop ? 1 : 0, taskNdx); -    } - -    void removeTask(Task task) { -        mTaskHistory.remove(task); -    } - -    TaskStack getHomeStack() { -        return mHomeStack; -    } - -    void updateDisplayInfo() { -        mDisplay.getDisplayInfo(mDisplayInfo); -    } - -    void getLogicalDisplayRect(Rect out) { -        updateDisplayInfo(); -        // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked. -        int width = mDisplayInfo.logicalWidth; -        int left = (mBaseDisplayWidth - width) / 2; -        int height = mDisplayInfo.logicalHeight; -        int top = (mBaseDisplayHeight - height) / 2; -        out.set(left, top, left + width, top + height); -    } - -    /** @return The number of tokens in all of the Tasks on this display. */ -    int numTokens() { -        int count = 0; -        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { -            count += mTaskHistory.get(taskNdx).mAppTokens.size(); -        } -        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); -        if (stackId == HOME_STACK_ID) { -            if (mStackBoxes.size() != 1) { -                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."); -            } -        } -        if (newStack != null) { -            layoutNeeded = true; -        } -        EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, relativeStackBoxId, position, -                (int)(weight * 100 + 0.5)); -        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 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!"); -        } -    } - -    /** -     * Propagate the new bounds to all child stack boxes, applying weights as we move down. -     * @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; -    } - -    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; -            } -        } -        return null; -    } - -    int stackIdFromPoint(int x, int y) { -        StackBox topBox = mStackBoxes.get(mStackBoxes.size() - 1); -        return topBox.stackIdFromPoint(x, y); -    } - -    void setTouchExcludeRegion(TaskStack focusedStack) { -        mTouchExcludeRegion.set(mBaseDisplayRect); -        WindowList windows = getWindowList(); -        for (int i = windows.size() - 1; i >= 0; --i) { -            final WindowState win = windows.get(i); -            final TaskStack stack = win.getStack(); -            if (win.isVisibleLw() && stack != null && stack != focusedStack) { -                mTmpRect.set(win.mVisibleFrame); -                mTmpRect.intersect(win.mVisibleInsets); -                mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE); -            } -        } -    } - -    void switchUserStacks(int oldUserId, int newUserId) { -        final WindowList windows = getWindowList(); -        for (int i = 0; i < windows.size(); i++) { -            final WindowState win = windows.get(i); -            if (win.isHiddenFromUserLocked()) { -                if (DEBUG_VISIBILITY) Slog.w(TAG, "user changing " + newUserId + " hiding " -                        + win + ", attrs=" + win.mAttrs.type + ", belonging to " -                        + win.mOwnerUid); -                win.hideLw(false); -            } -        } - -        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { -            mStackBoxes.get(stackBoxNdx).switchUserStacks(newUserId); -        } -    } - -    void resetAnimationBackgroundAnimator() { -        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { -            mStackBoxes.get(stackBoxNdx).resetAnimationBackgroundAnimator(); -        } -    } - -    boolean animateDimLayers() { -        boolean result = false; -        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { -            result |= mStackBoxes.get(stackBoxNdx).animateDimLayers(); -        } -        return result; -    } - -    void resetDimming() { -        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { -            mStackBoxes.get(stackBoxNdx).resetDimming(); -        } -    } - -    boolean isDimming() { -        boolean result = false; -        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { -            result |= mStackBoxes.get(stackBoxNdx).isDimming(); -        } -        return result; -    } - -    void stopDimmingIfNeeded() { -        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { -            mStackBoxes.get(stackBoxNdx).stopDimmingIfNeeded(); -        } -    } - -    void close() { -        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) { -            mStackBoxes.get(stackBoxNdx).close(); -        } -    } - -    public void dump(String prefix, PrintWriter pw) { -        pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId); -        final String subPrefix = "  " + prefix; -        pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x"); -            pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity); -            pw.print("dpi"); -            if (mInitialDisplayWidth != mBaseDisplayWidth -                    || mInitialDisplayHeight != mBaseDisplayHeight -                    || mInitialDisplayDensity != mBaseDisplayDensity) { -                pw.print(" base="); -                pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight); -                pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi"); -            } -            pw.print(" cur="); -            pw.print(mDisplayInfo.logicalWidth); -            pw.print("x"); pw.print(mDisplayInfo.logicalHeight); -            pw.print(" app="); -            pw.print(mDisplayInfo.appWidth); -            pw.print("x"); pw.print(mDisplayInfo.appHeight); -            pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth); -            pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight); -            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); -        } -        int ndx = numTokens(); -        if (ndx > 0) { -            pw.println(); -            pw.println("  Application tokens in Z order:"); -            getTasks(); -            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { -                AppTokenList tokens = mTaskHistory.get(taskNdx).mAppTokens; -                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { -                    final AppWindowToken wtoken = tokens.get(tokenNdx); -                    pw.print("  App #"); pw.print(ndx--); -                            pw.print(' '); pw.print(wtoken); pw.println(":"); -                    wtoken.dump(pw, "    "); -                } -            } -        } -        if (mExitingTokens.size() > 0) { -            pw.println(); -            pw.println("  Exiting tokens:"); -            for (int i=mExitingTokens.size()-1; i>=0; i--) { -                WindowToken token = mExitingTokens.get(i); -                pw.print("  Exiting #"); pw.print(i); -                pw.print(' '); pw.print(token); -                pw.println(':'); -                token.dump(pw, "    "); -            } -        } -        if (mExitingAppTokens.size() > 0) { -            pw.println(); -            pw.println("  Exiting application tokens:"); -            for (int i=mExitingAppTokens.size()-1; i>=0; i--) { -                WindowToken token = mExitingAppTokens.get(i); -                pw.print("  Exiting App #"); pw.print(i); -                  pw.print(' '); pw.print(token); -                  pw.println(':'); -                  token.dump(pw, "    "); -            } -        } -        pw.println(); -    } -} 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/Android.mk b/services/print/Android.mk new file mode 100644 index 000000000000..33604b711159 --- /dev/null +++ b/services/print/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := services.print + +LOCAL_SRC_FILES += \ +      $(call all-java-files-under,java) + +include $(BUILD_STATIC_JAVA_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..c6fdbe5c90c8 --- /dev/null +++ b/services/print/java/com/android/server/print/PrintManagerService.java @@ -0,0 +1,689 @@ +/* + * 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 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 final PrintManagerImpl mPrintManagerImpl; + +    public PrintManagerService(Context context) { +        super(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/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)) diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index d8e113a2d140..62200d91996a 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -1631,9 +1631,18 @@ String8 AaptFile::getPrintableSource() const  // =========================================================================  // ========================================================================= -status_t AaptGroup::addFile(const sp<AaptFile>& file) +status_t AaptGroup::addFile(const sp<AaptFile>& file, const bool overwriteDuplicate)  { -    if (mFiles.indexOfKey(file->getGroupEntry()) < 0) { +    ssize_t index = mFiles.indexOfKey(file->getGroupEntry()); +    if (index >= 0 && overwriteDuplicate) { +        fprintf(stderr, "warning: overwriting '%s' with '%s'\n", +                mFiles[index]->getSourceFile().string(), +                file->getSourceFile().string()); +        removeFile(index); +        index = -1; +    } + +    if (index < 0) {          file->mPath = mPath;          mFiles.add(file->getGroupEntry(), file);          return NO_ERROR; @@ -1739,7 +1748,8 @@ void AaptDir::removeDir(const String8& name)      mDirs.removeItem(name);  } -status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file) +status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file, +        const bool overwrite)  {      sp<AaptGroup> group;      if (mFiles.indexOfKey(leafName) >= 0) { @@ -1749,12 +1759,12 @@ status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file)          mFiles.add(leafName, group);      } -    return group->addFile(file); +    return group->addFile(file, overwrite);  }  ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,                              const AaptGroupEntry& kind, const String8& resType, -                            sp<FilePathStore>& fullResPaths) +                            sp<FilePathStore>& fullResPaths, const bool overwrite)  {      Vector<String8> fileNames;      { @@ -1813,7 +1823,7 @@ ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,                  notAdded = true;              }              ssize_t res = subdir->slurpFullTree(bundle, pathName, kind, -                                                resType, fullResPaths); +                                                resType, fullResPaths, overwrite);              if (res < NO_ERROR) {                  return res;              } @@ -1823,7 +1833,7 @@ ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,              count += res;          } else if (type == kFileTypeRegular) {              sp<AaptFile> file = new AaptFile(pathName, kind, resType); -            status_t err = addLeafFile(fileNames[i], file); +            status_t err = addLeafFile(fileNames[i], file, overwrite);              if (err != NO_ERROR) {                  return err;              } @@ -2089,24 +2099,24 @@ ssize_t AaptAssets::slurpFromArgs(Bundle* bundle)      /*       * If a directory of custom assets was supplied, slurp 'em up.       */ -    if (bundle->getAssetSourceDir()) { -        const char* assetDir = bundle->getAssetSourceDir(); - -        FileType type = getFileType(assetDir); +    const Vector<const char*>& assetDirs = bundle->getAssetSourceDirs(); +    const int AN = assetDirs.size(); +    for (int i = 0; i < AN; i++) { +        FileType type = getFileType(assetDirs[i]);          if (type == kFileTypeNonexistent) { -            fprintf(stderr, "ERROR: asset directory '%s' does not exist\n", assetDir); +            fprintf(stderr, "ERROR: asset directory '%s' does not exist\n", assetDirs[i]);              return UNKNOWN_ERROR;          }          if (type != kFileTypeDirectory) { -            fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDir); +            fprintf(stderr, "ERROR: '%s' is not a directory\n", assetDirs[i]);              return UNKNOWN_ERROR;          } -        String8 assetRoot(assetDir); +        String8 assetRoot(assetDirs[i]);          sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir));          AaptGroupEntry group;          count = assetAaptDir->slurpFullTree(bundle, assetRoot, group, -                                            String8(), mFullAssetPaths); +                                            String8(), mFullAssetPaths, true);          if (count < 0) {              totalCount = count;              goto bail; @@ -2116,9 +2126,10 @@ ssize_t AaptAssets::slurpFromArgs(Bundle* bundle)          }          totalCount += count; -        if (bundle->getVerbose()) +        if (bundle->getVerbose()) {              printf("Found %d custom asset file%s in %s\n", -                   count, (count==1) ? "" : "s", assetDir); +                   count, (count==1) ? "" : "s", assetDirs[i]); +        }      }      /* diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h index 5cfa91350063..9cc9007e4d48 100644 --- a/tools/aapt/AaptAssets.h +++ b/tools/aapt/AaptAssets.h @@ -235,7 +235,7 @@ public:      const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& getFiles() const          { return mFiles; } -    status_t addFile(const sp<AaptFile>& file); +    status_t addFile(const sp<AaptFile>& file, const bool overwriteDuplicate=false);      void removeFile(size_t index);      void print(const String8& prefix) const; @@ -301,12 +301,14 @@ private:      status_t addDir(const String8& name, const sp<AaptDir>& dir);      sp<AaptDir> makeDir(const String8& name);      status_t addLeafFile(const String8& leafName, -                         const sp<AaptFile>& file); +                         const sp<AaptFile>& file, +                         const bool overwrite=false);      virtual ssize_t slurpFullTree(Bundle* bundle,                                    const String8& srcDir,                                    const AaptGroupEntry& kind,                                    const String8& resType, -                                  sp<FilePathStore>& fullResPaths); +                                  sp<FilePathStore>& fullResPaths, +                                  const bool overwrite=false);      String8 mLeaf;      String8 mPath; diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index 5089b9de28a8..26b10a65f79d 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -55,7 +55,6 @@ public:            mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL),            mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),            mAutoAddOverlay(false), mGenDependencies(false), -          mAssetSourceDir(NULL),             mCrunchedOutputDir(NULL), mProguardFile(NULL),            mAndroidManifestFile(NULL), mPublicOutputFile(NULL),            mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL), @@ -123,8 +122,8 @@ public:      /*       * Input options.       */ -    const char* getAssetSourceDir() const { return mAssetSourceDir; } -    void setAssetSourceDir(const char* dir) { mAssetSourceDir = dir; } +    const android::Vector<const char*>& getAssetSourceDirs() const { return mAssetSourceDirs; } +    void addAssetSourceDir(const char* dir) { mAssetSourceDirs.insertAt(dir,0); }      const char* getCrunchedOutputDir() const { return mCrunchedOutputDir; }      void setCrunchedOutputDir(const char* dir) { mCrunchedOutputDir = dir; }      const char* getProguardFile() const { return mProguardFile; } @@ -272,6 +271,7 @@ private:      android::Vector<const char*> mPackageIncludes;      android::Vector<const char*> mJarFiles;      android::Vector<const char*> mNoCompressExtensions; +    android::Vector<const char*> mAssetSourceDirs;      android::Vector<const char*> mResourceSourceDirs;      const char* mManifestMinSdkVersion; diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index 8a6faed585a2..5d4232d97537 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -1896,7 +1896,7 @@ int doPackage(Bundle* bundle)      N = bundle->getFileSpecCount();      if (N < 1 && bundle->getResourceSourceDirs().size() == 0 && bundle->getJarFiles().size() == 0 -            && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDir() == NULL) { +            && bundle->getAndroidManifestFile() == NULL && bundle->getAssetSourceDirs().size() == 0) {          fprintf(stderr, "ERROR: no input files\n");          goto bail;      } diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp index 977226b61471..d1d3deb0106b 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -345,7 +345,7 @@ int main(int argc, char* const argv[])                      goto bail;                  }                  convertPath(argv[0]); -                bundle.setAssetSourceDir(argv[0]); +                bundle.addAssetSourceDir(argv[0]);                  break;              case 'G':                  argc--;  |